筋肉で解決しないために。

日々出会うモノに対する考察をしたり、主に以下のテーマに関して書いています。 データサイエンス/人工知能/AI/機械学習/DeepLearning/Python//数学/統計学/統計処理

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')

>>>

f:id:watarumon:20180711132955p:plain

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')

>>>

f:id:watarumon:20180711133007p:plain

値を確認してみます。

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近傍法を実装することができました。

お疲れ様でした!

それじゃー、また。