scikit-learnを用いた機械学習の初歩②~機械学習モデルの構築・評価~

はじめに

 前回の記事(scikit-learnを用いた機械学習の初歩①~データ及び解析手法~)では機械学習に用いるデータと機械学習のアルゴリズムの一つである「k近傍法」について説明をしました。今回は実際に学習モデルを構築し、評価を行っていきます。

データの分割

 まず初めに、前回の記事で読み込んだ150個あるアヤメのデータをトレーニングデータ(訓練データ、学習用データ)とテストデータ(評価用データ、検証用データ)に分割をします。pythonでデータサイエンスではトレーニングデータとテストデータは一般的に80:20,75:25,70:30の比率で分割するのが一般的とのことでしたので、今回は80:20で分割をしたいと思います。
 ちなみにこのようにデータを一定の割合でトレーニングデータとテストデータに分割することをホールドアウト検証というみたいです。ホールドアウト検証は単純な評価方法の一つですが、①集めたデータを2つに分割するため、学習に使えるデータ量が減ってしまう②分割する際、データに偏りが生じるとうまく評価をすることが出来ないといった2つのデメリットが存在します。
 データの分割はscikit-learnの「sklearn.model_selection.train_test_split」という関数を用います。
sklearn.model_selection.train_test_split(*arrays, **options)

arrays分割対象となる複数のリスト
test_size
小数または、整数で指定。小数の場合はテストデータの割合を指定(1.0で100%)
整数を指定した場合はテストデータに含めるデータ件数となる。
test_sizeを指定していない場合やNoneの場合はtrain_sizeを補うように設定される。
train_sizeを設定していない場合はデフォルト値として0.25となる。
train_size説明としてはtest_sizeとほぼ同じ。トレーニングデータについての指定。
random_state乱数生成のシードの設定。指定しなかった場合はNumpyのrandomを用いて乱数をセットする。
shuffleデータのシャッフルを行うかの指定。デフォルト値:True。
Falseとした場合はstratifyをNoneにする必要がある
stratifystratified samplingを行う場合に、クラスを示す行列を設定する。デフォルト値:None

何個か説明がわからなかった引数がありましたが、とりあえずデータの分割を行ってみます。

from sklearn.model_selection import train_test_split
iris_dataset = load_iris()
X_train,X_test,x_train,x_test = train_test_split(iris_dataset["data"],iris_dataset["target"],test_size = 0.2)
ここでX_trainはトレーニングデータ、X_testはテストデータ、x_trainはトレーニング用の正解ラベル、x_testはテスト用の正解ラベルです。
実際にX_train、X_testの中身を見てみると120個のデータと30個のデータに分割されていて、80:20にデータが分割されていることがわかります。ちなみにデータの順番はシャッフルされています。
import pandas as pd
print(pd.DataFrame(X_train,columns = iris_dataset.feature_names))
print(pd.DataFrame(X_test,columns = iris_dataset.feature_names))
図1:X_trainの中身

機械学習モデルの構築

ようやくすべての準備が整いましたので、実際にk近傍法を用いてクラス分類を行う学習モデルの構築を行います。k近傍法はscikit-learnのKNeighborsClassifierを用います。

sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, weights=uniform, algorithm=auto, leaf_size=30, p=2, metric=minkowski, metric_params=None, n_jobs=1, **kwargs)


n_neighborskの値。デフォルト値:5
weightsデータ間の距離に重み付けをするか。デフォルト:uniform
algorithm近傍点を計算するために用いるアルゴリズム。デフォルト値:auto
leaf_sizeメモリや速度に影響する数字?デフォルト値:30
pミンコフスキー距離のパラメータ。デフォルト値:2
metric距離として何を用いるか。デフォルト値:minkowski
metric_paramsメトリック関数に追加する引数。デフォルト値:None
n_jobs使用するCPUのコア数。-1ですべて使用。デフォルト値:1

やはり何個かよくわからない引数がありますが、とりあえずやってみます。


from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
iris_dataset = load_iris()
X_train,X_test,x_train,x_test = train_test_split(iris_dataset["data"],iris_dataset["target"],test_size = 0.2)

knn = KNeighborsClassifier()
knn.fit(X_train, x_train)#fit関数を用いてトレーニングデータの読み込み
X_temp_test = np.array([[4.4,2.9,1.4,0.2]])#学習データの中にあったSetosaのデータ
prediction = knn.predict(X_temp_test)#クラスに予想させる
print(iris_dataset["target_names"][prediction])#予想結果の表示
とりあえずKNeighborsClassifierはデフォルト値としました。作成した学習モデルにfit関数を用いてトレーニングデータの学習を行います。 正しく学習できているかの確認としてトレーニングデータ内にあったSetosaのデータを入力した場合の予想結果を表示したところSetosaとかえって来たので、無事学習できているみたいでした。

モデルの評価

今度はテストデータを使って、今回作成したモデルの精度を評価してみます。


x_pred =knn.predict(X_test)#テストデータを学習モデルにセット
x_judge = x_pred == x_test #予測したデータと答えが一致しているか
true_count = len(np.where(x_judge==True)[0])#正解した数
print(x_judge)
print(true_count/len(x_judge))#正答率
今回の場合では何回か試したところ30個のテストデータの全問正解するか一問だけ間違えるかのどちらかでした。なので正答率は93%から100%といった結果になりました。

まとめ

今回はscikit-learnを用いてアヤメの分類を行いました。
今回のデータの場合は93%以上の精度で予測が可能だということが分かりました。
モデルの評価法として別のやり方があるみたいなので、次回記事としてまとめます。
追記:次回記事

0 件のコメント :

コメントを投稿