データ分析ガチ勉強アドベントカレンダー 9日目。
データを学習器に入れるところまではできた。後は学習させるだけ! だが、学習器といってもたくさんある。どういう学習器を選べばよいのだろうか。
そのためにはモデルをうまく評価するしくみを作らなければならない。
今回は、sklearn.metrics
を見ながら、学習の評価をどのように行うかについて学ぶ
機械学習に使う指標総まとめ(教師あり学習編)
学習器の評価には、さまざまな指標が用意されている。 以前、教師あり学習については全力でまとめている。なので、そちらを見ていただければと思う。
しかし、こちらの記事では、数式も多く、実感もわかないだろう。なので今回はこの中の指標の実装も行ってみる。
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 | なし | |
jaccard_similarity |
jaccard類似度 | なし | |
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()
結果はこんな感じ
回帰の定量指標
正解が数値で与えられる回帰にも、いくつか指標がある。これも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にあげている。
結果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を一部改変してつくった