#!/usr/bin/env python # coding: utf-8 # # Metrics # 下ごしらえ # In[1]: get_ipython().run_line_magic('matplotlib', 'inline') import pandas as pd import numpy as np from matplotlib import pyplot as plt from ipywidgets import interact # 今回は肺がんの予測をデータセットとして使います。 # In[2]: from sklearn.datasets import load_breast_cancer breast=load_breast_cancer() data=breast.data target=breast.target # datasetの中身 # In[3]: breast.keys() # In[4]: print(data.shape) print(target.shape) # In[5]: for i,j in enumerate(breast.target_names): print("{}: {}".format(j,sum(target==i))) # 特徴量(検査値) # In[6]: pd.DataFrame(data,columns=breast.feature_names).head() # 適当にモデルを作っときます。 # In[7]: from sklearn import cross_validation as cv data_train,data_test,target_train,target_test=cv.train_test_split( data,target,train_size=0.75) # In[8]: from sklearn.ensemble import RandomForestClassifier as RFC clf=RFC() clf.fit(data_train,target_train) predict=clf.predict(data_test) predict_proba=clf.predict_proba(data_test) # precision-recall curveにはスカラー値でのスコアリングが必要 # # 今回のお題 # In[9]: from sklearn import metrics # 簡単なところから # In[10]: # 正答率 metrics.accuracy_score(predict,target_test) # In[11]: # 混同行列 print(metrics.confusion_matrix(predict,target_test)) # 縦軸がpredict, 横軸がtarget_test(左下がFN,右上がFP) # ## precision-recall関係 # > [神嶌先生の解説参照](http://ibisforest.org/index.php?F%E5%80%A4) # 予測全体のPrecisionやRecall値 # In[12]: # Precision、RecallとF値とsupport(正解ラベルのデータの数) print(metrics.classification_report( predict,target_test,target_names=breast.target_names)) # In[13]: #Precision,Recall値を再利用したい場合はこちらで抽出する precision, recall, fscore, support=metrics.precision_recall_fscore_support( predict,target_test) print(precision,recall,fscore,support) # Precision-Recall Curve # In[14]: # precision-recall curve precision,recall,thresholds=metrics.precision_recall_curve(target_test,predict_proba[:,1]) plt.plot(recall,precision) # recallが先なのを注意 plt.title("Precision-Recall Curve") # In[15]: # AUC算出 metrics.auc(recall,precision) # こちらもrecallが先 # precision_recall_curve関数の返り値の中身 # In[16]: pd.DataFrame(np.c_[precision,recall],columns=["precision","recall"]).T # recallが閾値以下になった時のprecisionのカットオフにするとかなら # In[17]: for i,j in enumerate(recall): if j<0.8 and i==0:print("error");break elif j<0.8: print("criteria= {0:.3}".format(precision[i-1])) break # # みんな大好きROC curve # ROC curveも関数が用意されています # In[18]: fp_ratio, tp_ratio, thresholds = metrics.roc_curve( target_test,predict_proba[:,1]) # In[19]: plt.plot(fp_ratio,tp_ratio) # In[20]: metrics.auc(fp_ratio,tp_ratio) # ROCカーブのAUCは専用の関数があります # In[21]: metrics.roc_auc_score(target_test,predict_proba[:,1]) # あとで使うので、この入出力の形式を覚えておいてください # ## おまけ # In[22]: @interact(log_of_n_tree=(0,3,0.1)) def roc(log_of_n_tree=1): rslt=RFC(n_estimators=int(10**log_of_n_tree),n_jobs=-1).fit(data_train,target_train).predict_proba(data_test) fp_ratio, tp_ratio, thresholds = metrics.roc_curve(target_test,rslt[:,1]) auc=metrics.roc_auc_score(target_test,rslt[:,1]) plt.plot(fp_ratio,tp_ratio) plt.title("ROC Curve:n_trees={0}; auc={1:.3}".format(int(10**log_of_n_tree),auc)) # # スコアリング関数 # In[23]: from sklearn import cross_validation as cv # これで出てくる、scoringの話です # cross validationで使えるスコアリング方法はmetrics.scorer.SCORERSで定義されています # In[24]: print(list(metrics.scorer.SCORERS.keys())) # - 用意されているSCORER以外にもスコアリング関数を定義することが可能です。 # - 下記形式で予測結果に対してスカラー量を算出できる関数を作成すれば、make_scorerでSCORERとして使えます。 # > score_func(target, predict_proba) # # In[25]: custom_scorer=metrics.scorer.make_scorer(metrics.roc_auc_score) # こんな感じ # In[26]: cv_method=cv.StratifiedKFold(target_train,shuffle=True,n_folds=5) cv.cross_val_score(clf,data_train,target_train,cv=cv_method,scoring=custom_scorer) # - 実際には、scoring="roc_auc"で動作するSCORERはほぼ同じ方法で実装されています # In[27]: metrics.scorer.SCORERS["roc_auc"]