Machine learning.簡單繪制ROC曲線
ROC曲線,又可以稱之為接受者操作特征曲線(Receiver Operating Characteristic Curve),ROC曲線下的面積,稱為AUC(Area Under Cureve),可以衡量評估二分類模型的分類好壞。
本文視圖使用Python中的Matplotlib模塊來進行簡單的ROC曲線的畫法:
准備工作
#查看matplotlib的版本 import matplotlib import matplotlib.pyplot as plt matplotlib.__version__ #output '3.3.3' #首先導入實例乳腺癌二分類數據集 from sklearn.datasets import load_breast_cancer #訓練集測試集划分 from skelarn.model_selection import train_test_split #導入plot_roc_curve,roc_curve和roc_auc_score模塊 from sklearn.metrics import plot_roc_curve,roc_curve,auc,roc_auc_score #導入三個不同的分類器:LogisticRegression,DecisionTree和KNN from sklearn.linear_model import LogisticRegression from sklearn.tree import DecisionTreeClassifier from sklearn.neighbors import KNeighborsClassifier #train_test_split划分 cancer = load_breast_cancer() cancer_X = cancer.data cancer_y = cancer.target cancer_X_train, cancer_X_test, cancer_y_train, cancer_y_test = train_test_split(cancer_X,cancer_y) #創建模型 lr_clf = LogisticRegression(solver='saga',max_iter=10000) dt_clf = DecisionTreeClassifier() knn_clf = KNeighborsClassifier() #訓練模型 lr_clf.fit(cancer_X_train,cancer_y_train) dt_clf.fit(cancer_X_train,cancer_y_train) knn_clf.fit(cancer_X_train,cancer_y_train)
方法一
最新的matplotlib版本自動封裝了繪制ROC曲線的plot_roc_curve()方法,可以快速便捷地直接繪制出不同模型的ROC曲線。
#創建畫布
fig,ax = plt.subplots(figsize=(12,10))
lr_roc = plot_roc_curve(estimator=lr_clf, X=cancer_X_test,
y=cancer_y_test, ax=ax, linewidth=1)
dt_roc = plot_roc_curve(estimator=dt_clf, X=cancer_X_test,
y=cancer_y_test, ax=ax, linewidth=1)
knn_roc = plot_roc_curve(estimator=knn_clf, X=cancer_X_test,
y=cancer_y_test, ax=ax, linewidth=1)
#注意:這里的ax一定要傳給所創建畫布的ax,否則三個模型的ROC曲線分別繪制三張圖而不在一張圖中
#更改圖例字體大小
ax.legend(fontsize=12)
#顯示繪制的ROC曲線
plt.show()
方法二
方法一的繪制ROC曲線的畫法只針對於matplotlib比較新的情況,方法一的畫法快速省力。但當我們所使用的版本比較舊時,就只能使用方法二來進行繪制。
#首先我們使用建立好的模型對測試集數據進行預測預測的概率
score_lr = lr_clf.predict_proba(cancer_X_test)[:,1]
score_dt = dt_clf.predict_proba(cancer_X_test)[:,1]
score_knn = knn_clf.predict_proba(cancer_X_test)[:,1]
#使用roc_curve方法得到三個模型的真正率TP,假正率FP和閾值threshold
fpr_lr,tpr_lr,thres_lr = roc_curve(cancer_y_test,score_lr,)
fpr_dt,tpr_dt,thres_dt = roc_curve(cancer_y_test,score_dt,)
fpr_knn,tpr_knn,thres_knn = roc_curve(cancer_y_test,score_knn,)
print("LogitReg的AUC為:",auc(fpr_lr,tpr_lr))
print("DecisionTree的AUC為:",auc(fpr_dt,tpr_dt))
print("kNN的AUC為:",auc(fpr_knn,tpr_knn))
#Out
LogitReg的AUC為: 0.9852366478506297
DecisionTree的AUC為: 0.9423577941815023
kNN的AUC為: 0.9666739036039949
#創建畫布
fig,ax = plt.subplots(figsize=(10,8))
#自定義標簽名稱label=''
ax.plot(fpr_lr,tpr_lr,linewidth=2,
label='Logistic Regression (AUC={})'.format(str(round(auc(fpr_lr,tpr_lr),3))))
ax.plot(fpr_dt,tpr_dt,linewidth=2,
label='Decision Tree (AUC={})'.format(str(round(auc(fpr_dt,tpr_dt),3))))
ax.plot(fpr_knn,tpr_knn,linewidth=2,
label='K Nearest Neibor (AUC={})'.format(str(round(auc(fpr_knn,tpr_knn),3))))
#繪制對角線
ax.plot([0,1],[0,1],linestyle='--',color='grey')
#調整字體大小
plt.legend(fontsize=12)
plt.show()
可以看到,方法二所繪制的ROC曲線所需要調整的參數相比於方法一略微多一些。
方法二相比於方法一主要是需要:
(1)手動添加標簽名字,用於判斷相應的模型;
(2)需要手動添加對應模型的AUC值,可以使用format配套AUC函數來解決;
(3)需要手動添加X軸和Y軸的名稱,可以使用ax.set_xlabel()和ax.set_ylabel()來解決;
(4)需要手動添加圖例,使用ax.legend()來顯示。而方法一種即使不手動設置legend()圖例也會自動顯示,但需要修改字體大小和其他參數就需要手動調整ax.legend()參數。
注意事項
使用roc_auc_score()計算AUC的時候,傳入的第一個參數應該是預測的真實標簽,第二個參數應該是模型預測為“真(1)”的概率而不是模型預測的“0-1標簽”。如果傳入后者,會造成比實際AUC值偏低的情況。
#得到模型預測的0-1標簽
y_pre_lr = lr_clf.predict(cancer_X_test)
y_pre_dt = dt_clf.predict(cancer_X_test)
y_pre_knn = knn_clf.predict(cancer_X_test)
#模型預測的“真”概率值
score_lr = lr_clf.predict_proba(cancer_X_test)[:,1]
score_dt = dt_clf.predict_proba(cancer_X_test)[:,1]
score_knn = knn_clf.predict_proba(cancer_X_test)[:,1]
#正確做法
print("LogitReg的AUC為:",roc_auc_score(cancer_y_test,score_lr))
print("DecisionTree的AUC為:",roc_auc_score(cancer_y_test,score_dt))
print("kNN的AUC為:",roc_auc_score(cancer_y_test,score_knn))
#output
LogitReg的AUC為: 0.9852366478506297
DecisionTree的AUC為: 0.9423577941815023
kNN的AUC為: 0.9666739036039949
#錯誤做法
print("LogitReg的AUC為:",roc_auc_score(cancer_y_test,y_pre_lr))
print("DecisionTree的AUC為:",roc_auc_score(cancer_y_test,y_pre_dt))
print("kNN的AUC為:",roc_auc_score(cancer_y_test,y_pre_knn))
#output
LogitReg的AUC為: 0.9383412939643941
DecisionTree的AUC為: 0.9423577941815023
kNN的AUC為: 0.9223838471558836
剛剛我們用第二種方法畫ROC曲線的時候,使用auc中的TPR和FPR驗證了實際的AUC值應該是正確做法中的結果。
總結
介紹了兩種簡單畫ROC曲線的方法
- 方法一:plot_roc_curve(),配合實際模型與X、y數據繪制,簡單直接;
- 方法二:需roc_curve()傳出FPR和TPR,以及auc()配合繪制,靈活性強;
注意計算AUC需要傳入預測為“真(1)”概率,而不是實際的標簽。
參考文獻:
[2] 周志華.機器學習.ROC曲線
[3] scikit-learn官方文檔.roc_curve.https://scikit-learn.org/stable
