プロクラシスト

今日の寄り道 明日の近道

【Day-9】機械学習で使う指標まとめ(実装編)


スポンサーリンク

f:id:imslotter:20171209195625p:plain データ分析ガチ勉強アドベントカレンダー 9日目。

データを学習器に入れるところまではできた。後は学習させるだけ! だが、学習器といってもたくさんある。どういう学習器を選べばよいのだろうか。

そのためにはモデルをうまく評価するしくみを作らなければならない。 今回は、sklearn.metricsを見ながら、学習の評価をどのように行うかについて学ぶ

機械学習に使う指標総まとめ(教師あり学習編)

学習器の評価には、さまざまな指標が用意されている。 以前、教師あり学習については全力でまとめている。なので、そちらを見ていただければと思う。

www.procrasist.com

しかし、こちらの記事では、数式も多く、実感もわかないだろう。なので今回はこの中の指標の実装も行ってみる。

sklearn.metricsによる定量指標

sklearn.metricsには、たくさんの指標が用意されている

分類の定量指標

先ほどの分布を分類した結果を評価したい。参考にしたのはこちらの公式ページ。 用意するものは、下記のものである。カッコ内は私が実装で用いた変数

  • テストデータの正解ラベル(y_test )
  • 学習器が判定した結果(pred_y )
  • そのときの判定スコア(pred_y_score)※

※判定スコアは、必要な指標と必要でない指標がある。使わない指標は、ただ分類結果だけをみて判定するのでわかりやすい。一方で判定スコアを使う場合は、指標がすこしわかりにくくなる一方で、いわゆる分類器の自信を考慮しながらの算出となるので、より詳細に分類器を評価している。

ここで、sklearn.metricsに入っている主要な分類指標を見てみる

クラス 分類指標 判定スコアの
使用
備考
confusion matrix -- なし 実際と予測のずれ具合を見る
accuracy Accuracy なし どのくらいあたったか
classification_report f値, recall, precision なし よく使う指標をまとめてくれてて良い
hamming_loss hamming loss なし f:id:imslotter:20171209182300p:plain
jaccard_similarity jaccard類似度 なし f:id:imslotter:20171209182351p:plain
log_loss logarithm loss あり 使い方あんまり自信がない公式
precision_recall_curve precision-recall曲線 あり トレードオフ具合をみる
roc_auc ROC曲線 あり 閾値判定とか

よく使いそうだなと思ったのが、accuracy. classification_report. roc_auc。主要な指標がきれいにまとまっている

sklearn.datasets.load_breast_cancer()の学習を簡易的に行い、上記の3つの指標の入力の仕方と出力の仕方を学ぶ。

コードをみる
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
breast_cancer = load_breast_cancer()
clf = LogisticRegression()
X_train, X_test, y_train, y_test = train_test_split(breast_cancer.data, breast_cancer.target,train_size=0.8)
clf.fit(X_train,y_train)
# 結果を返す
pred_y = clf.predict(X_test)
# スコアを出すための関数。
# ref : [decision_functionとの違いは?](https://stackoverflow.com/questions/36543137/whats-the-difference-between-predict-proba-and-decision-function-in-sklearn-py)
pred_y_score = clf.predict_proba(X_test)[:,1]
print("accuracy\n", metrics.accuracy_score(y_test, pred_y))
print("classification report\n",metrics.classification_report(y_test,pred_y))
# Compute ROC curve and ROC area for each class
fpr, tpr, _ = metrics.roc_curve(y_test, pred_y_score,pos_label=1)
roc_auc = metrics.auc(fpr, tpr)
print("auc area", roc_auc)
# ROC
plt.figure(figsize=(5,5))
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC curve: \nAUC={:.3f}'.format(roc_auc))
plt.show()

結果はこんな感じ

f:id:imslotter:20171209184215p:plain

回帰の定量指標

正解が数値で与えられる回帰にも、いくつか指標がある。これもsklearn.metrics内で実装されている。

sklearn.datasets,load_bostonデータセットを使って、試してみる

コードをみる
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
from sklearn import model_selection, metrics
import numpy as np
boston = load_boston()
reg = LinearRegression()
X_train, X_test, y_train, y_test = model_selection.train_test_split(boston.data, boston.target,train_size=0.8)
reg.fit(X_train,y_train)
pred_y = reg.predict(X_test)
print("Variance score", metrics.explained_variance_score(y_test, pred_y))
print("MAE : Mean absolute error", metrics.mean_absolute_error(y_test, pred_y))
print("MSE : Mean squared error", metrics.mean_squared_error(y_test, pred_y))
print("RMSE: Root mean squared error", np.sqrt(metrics.mean_squared_error(y_test, pred_y)))
print("R2 score", metrics.r2_score(y_test, pred_y))

出力は

Variance score 0.637022922972
MAE : Mean absolute error 3.16480595297
MSE : Mean squared error 19.7557043856
RMSE: Root mean squared error 4.44473895584
R2 score 0.633791811542

クラスタリング定量指標

Evaluating the performance of a clustering algorithm is not as trivial as counting the number of errors or the precision and recall of a supervised classification algorithm. (clustering performance evaluation)

とあるように、クラスタリングこそ絶対的な定量指標が存在しない。分け方なので、用途や意味によって変わってくるから。 けれど、一応指針みたいなのはあって、クラスタ内の散らばりの少なさクラスタ間の距離の長さをうまく定式化することで、定量化する。

上記サイトにはクラスタリングの指標も多数実装されている。*1

デモ実装(分類学習器ごとの差)

最後にデモを作る。

この図は、三日月形に分布するデータを分類しようとした結果を分類器別に分けてみたものである。 *2

線形、非線形、アンサンブル学習など、学習器の性質によってかなり異なることが見て取れて面白い。

こうやって分離状況を可視化していくと、大体どういう雰囲気で学習器が分布しているかはわかる。 でも、それでは定量的な指標とはいえない。ので、先ほどまでの指標を見て、定量化してみた

詳細は例のごとくgithubにあげている。

github.com

結果1(表)

大きく結果の順位が変わるようなことはないが、精度だけじゃなく、precisionとrecallなどを見ると開きがあるもの、ないものなど違いがあったりして、分類器の個性を詳細に知ることができる。

Algorithm accuracy precision recall f1-score ham. loss jaccard sim AUC
LogisticRegression 0.83 0.82 0.83 0.82 0.17 0.83 0.92
Nearest Neighbors 0.95 0.91 1 0.95 0.05 0.95 0.95
Linear SVM 0.8 0.8 0.77 0.79 0.2 0.8 0.92
RBF SVM 0.94 0.89 1 0.94 0.06 0.94 0.98
Gaussian Process 0.95 0.91 1 0.95 0.05 0.95 0.98
Decision Tree 0.92 0.92 0.92 0.92 0.08 0.92 0.92
Random Forest 0.89 0.88 0.9 0.89 0.11 0.89 0.93
Neural Net 0.83 0.82 0.83 0.82 0.17 0.83 0.92
AdaBoost 0.86 0.84 0.88 0.86 0.14 0.86 0.92
Naive Bayes 0.82 0.81 0.81 0.81 0.18 0.82 0.92
QDA 0.83 0.82 0.83 0.82 0.17 0.83 0.92

結果2(図)

代表的な3種の分類器でROC曲線とPrecision-Recall曲線を引いた。 両者とも、トレードオフのグラフになっているので、覆われた領域の面積が大きいほど、いい分類器であるといえる。 今回のデータに対しては、非線形分類器に軍配が上がりそうだ。

まとめ

以前まとめていた指標、理論ではわかっていても実際に使って動きをみてみると、知識として定着する。 いろいろと指標はあるが、sklearn.metricsを用いれば簡単に実装が可能なので、勉強したい方は是非一度手を動かしてみてはいかがでしょうか。

ちょっと長くなりましたが、今日はこの辺で。 明日はモデル選択(Cross Validation)とパラメータサーチ!

*1:余裕があれば加筆します...w

*2:Classifier Comparisonを一部改変してつくった

PROCRASIST