k近傍法やロジスティック回帰を使った多クラス分類の実装
はじめに
このエントリでは、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、ロジスティック回帰を用いた多クラス分類やk近傍法を実装してみます。 サンプルデータは、Iris(アヤメ)という植物のデータで、3種類のアヤメについて、それぞれ50サンプルのデータに4つの特徴量が含まれています。
おまじない
#前処理 import numpy as np import pandas as pd from pandas import Series,DataFrame #可視化 import matplotlib.pyplot as plt import seaborn as sns sns.set_style('whitegrid') %matplotlib inline #機械学習 from sklearn import linear_model from sklearn.datasets import load_iris from sklearn import metrics
目的とタスクの設定
目的とタスクの設定をするために、まずは元データをみてみます。
#データセットのロード iris = load_iris() #説明変数をXとする X = iris.data #目的変数をYとする Y = iris.target
X[1:5] >>> array([[4.9, 3. , 1.4, 0.2], [4.7, 3.2, 1.3, 0.2], [4.6, 3.1, 1.5, 0.2], [5. , 3.6, 1.4, 0.2]])
Y >>> array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
まずは、可視化するためにXとYをdataframeにして、seabornでプロットしてみようと思います。 これをタスク1と呼ぶことにします。
データの傾向をつかんだところで、ロジスティック回帰を実装してみます。 これをタスク2と呼ぶことにします。
最後に、k近傍法を実装し、適切なkの値について検討を行ってみます。 これをタスク3と呼ぶことにします。
タスク1
#Xをdataframeにし、カラム名をつけます iris_data = DataFrame(X,columns=['Sepal Length','Sepal Width','Petal Length','Petal Width']) #Yをdataframeにし、カラム名をつけます iris_target = DataFrame(Y,columns=['Species'])
#Yの要素を名前に置き換えます def flower(num): ''' 数字を受け取って、対応する名前を返します。''' if num == 0: return 'Setosa' elif num == 1: return 'Veriscolour' else: return 'Virginica' iris_target['Species'] = iris_target['Species'].apply(flower)
iris_target.head() >>> Species 0 Setosa 1 Setosa 2 Setosa 3 Setosa 4 Setosa
#XとYをまとめます iris = pd.concat([iris_data,iris_target],axis=1) iris.head() >>> Sepal Length Sepal Width Petal Length Petal Width Species 0 5.1 3.5 1.4 0.2 Setosa 1 4.9 3.0 1.4 0.2 Setosa 2 4.7 3.2 1.3 0.2 Setosa 3 4.6 3.1 1.5 0.2 Setosa 4 5.0 3.6 1.4 0.2 Setosa
ここまでで、可視化の前処理が終わりました。 プロットします。
sns.pairplot(iris,hue='Species')
>>>
Setosaは最も特徴的な目的変数であることが見て取れます。
タスク2
ロジスティック回帰を実装します。
#ロジスティック回帰のインスタンスを作成 logreg = LogisticRegression() #データを訓練データとテストデータに分割します。この場合ではテストが全体の40%になるようにしています。 #再現性のため引数random_stateを設定しています。実際の機械学習では用いないことが多いです。 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.4,random_state=3) #訓練データを使って学習させます。 logreg.fit(X_train, Y_train)
テストデータを用いて、モデルの精度を確認します。
Y_pred = logreg.predict(X_test) # 精度を比較してみます print(metrics.accuracy_score(Y_test,Y_pred) >>> 0.933333333333
60%の訓練データ、40%がテストデータにて、ロジスティック回帰でモデルを作成した場合では、93%の精度が得られました。
タスク3
k近傍法によるモデルを実装し、適切なkの値について検討を行ってみます。
from sklearn.neighbors import KNeighborsClassifier #k=1のとき、つまりもっとも近いサンプルの分類がその分類と等しいと予測するモデルです #インスタンスを作ります knn = KNeighborsClassifier(n_neighbors = 1) #訓練データを使って学習させます knn.fit(X_train,Y_train) #テストデータで予測をします Y_pred = knn.predict(X_test) #精度を調べてみます print(metrics.accuracy_score(Y_test,Y_pred)) >>> 0.9666666666666667
最後に、kの値を任意に変化させてプロットすることで、適切なkの値について検討してみます。
k_range = range(1, 90) accuracy = [] for k in k_range: knn = KNeighborsClassifier(n_neighbors=k) knn.fit(X_train, Y_train) Y_pred = knn.predict(X_test) accuracy.append(metrics.accuracy_score(Y_test, Y_pred))
print (type(accuracy)) print (type(k_range)) >>> <class 'list'> <class 'range'>
kの変化をk_rangeに、精度の変化をaccuracyというlistにすることができました。
plt.plot(k_range, accuracy) plt.xlabel('K') plt.ylabel('Testing Accuracy') >>>
値を確認してみます。
df = DataFrame(accuracy,columns=['accuracy'],index=k_range) df[50:60] >>> accuracy 51 0.850000 52 0.850000 53 0.850000 54 0.900000 55 0.833333 56 0.850000 57 0.816667 58 0.500000 59 0.500000 60 0.500000
今回の訓練データとテストデータの分け方では、k=57とk=58に大きな差があることがわかりました。
さいごに
今回は、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、ロジスティック回帰を用いた多クラス分類やk近傍法を実装することができました。
お疲れ様でした!
それじゃー、また。