利用Python畫ROC曲線,以及AUC值的計算\
創(chuàng)新互聯(lián)主要從事網(wǎng)站設計制作、成都網(wǎng)站設計、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務濟水街道,十多年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:028-86922220
前言
ROC(Receiver Operating Characteristic)曲線和AUC常被用來評價一個二值分類器(binary classifier)的優(yōu)劣。這篇文章將先簡單的介紹ROC和AUC,而后用實例演示如何python作出ROC曲線圖以及計算AUC。
AUC介紹
AUC(Area Under Curve)是機器學習二分類模型中非常常用的評估指標,相比于F1-Score對項目的不平衡有更大的容忍性,目前常見的機器學習庫中(比如scikit-learn)一般也都是集成該指標的計算,但是有時候模型是單獨的或者自己編寫的,此時想要評估訓練模型的好壞就得自己搞一個AUC計算模塊,本文在查詢資料時發(fā)現(xiàn)libsvm-tools有一個非常通俗易懂的auc計算,因此摳出來用作日后之用。
AUC計算
AUC的計算分為下面三個步驟:
1、計算數(shù)據(jù)的準備,如果模型訓練時只有訓練集的話一般使用交叉驗證的方式來計算,如果有評估集(evaluate)一般就可以直接計算了,數(shù)據(jù)的格式一般就是需要預測得分以及其目標類別(注意是目標類別,不是預測得到的類別)
2、根據(jù)閾值劃分得到橫(X:False Positive Rate)以及縱(Y:True Positive Rate)點
3、將坐標點連成曲線之后計算其曲線下面積,就是AUC的值
直接上python代碼
#! -*- coding=utf-8 -*-
import pylab as pl
from math import log,exp,sqrt
evaluate_result="you file path"
db = [] #[score,nonclk,clk]
pos, neg = 0, 0
with open(evaluate_result,'r') as fs:
for line in fs:
nonclk,clk,score = line.strip().split('\t')
nonclk = int(nonclk)
clk = int(clk)
score = float(score)
db.append([score,nonclk,clk])
pos += clk
neg += nonclk
db = sorted(db, key=lambda x:x[0], reverse=True)
#計算ROC坐標點
xy_arr = []
tp, fp = 0., 0.
for i in range(len(db)):
tp += db[i][2]
fp += db[i][1]
xy_arr.append([fp/neg,tp/pos])
#計算曲線下面積
auc = 0.
prev_x = 0
for x,y in xy_arr:
if x != prev_x:
auc += (x - prev_x) * y
prev_x = x
print "the auc is %s."%auc
x = [_v[0] for _v in xy_arr]
y = [_v[1] for _v in xy_arr]
pl.title("ROC curve of %s (AUC = %.4f)" % ('svm',auc))
pl.xlabel("False Positive Rate")
pl.ylabel("True Positive Rate")
pl.plot(x, y)# use pylab to plot x and y
pl.show()# show the plot on the screen
輸入的數(shù)據(jù)集可以參考svm預測結果
其格式為:
nonclk \t clk \t score
其中:
1、nonclick:未點擊的數(shù)據(jù),可以看做負樣本的數(shù)量
2、clk:點擊的數(shù)量,可以看做正樣本的數(shù)量
3、score:預測的分數(shù),以該分數(shù)為group進行正負樣本的預統(tǒng)計可以減少AUC的計算量
運行的結果為:
如果本機沒安裝pylab可以直接注釋依賴以及畫圖部分
注意
上面貼的代碼:
1、只能計算二分類的結果(至于二分類的標簽隨便處理)
2、上面代碼中每個score都做了一次閾值,其實這樣效率是相當?shù)偷?,可以對樣本進行采樣或者在計算橫軸坐標時進行等分計算
隨機森林在R packages和Python scikit-learn中的實現(xiàn)是當下非常流行的,下列是在R和Python中載入隨機森林模型的具體代碼:
Python
#Import Library
fromsklearn.ensemble import RandomForestClassifier #use RandomForestRegressor for regression problem
#Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset
# Create Random Forest object
model= RandomForestClassifier(n_estimators=1000)
# Train the model using the training sets and check score
model.fit(X, y)
#Predict Output
predicted= model.predict(x_test)
R Code
library(randomForest)
x- cbind(x_train,y_train)
# Fitting model
fit- randomForest(Species ~ ., x,ntree=500)
summary(fit)
#Predict Output
predicted= predict(fit,x_test)
使用sklearn的一系列方法后可以很方便的繪制處ROC曲線,這里簡單實現(xiàn)以下。
主要是利用混淆矩陣中的知識作為繪制的數(shù)據(jù)(如果不是很懂可以先看看這里的基礎):
tpr(Ture Positive Rate):真陽率 圖像的縱坐標
fpr(False Positive Rate):陽率(偽陽率) 圖像的橫坐標
mean_tpr:累計真陽率求平均值
mean_fpr:累計陽率求平均值
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import StratifiedKFold
iris = datasets.load_iris()
X = iris.data
y = iris.target
X, y = X[y != 2], y[y != 2] # 去掉了label為2,label只能二分,才可以。
n_samples, n_features = X.shape
# 增加噪聲特征
random_state = np.random.RandomState(0)
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]
cv = StratifiedKFold(n_splits=6) #導入該模型,后面將數(shù)據(jù)劃分6份
classifier = svm.SVC(kernel='linear', probability=True,random_state=random_state) # SVC模型 可以換作AdaBoost模型試試
# 畫平均ROC曲線的兩個參數(shù)
mean_tpr = 0.0 # 用來記錄畫平均ROC曲線的信息
mean_fpr = np.linspace(0, 1, 100)
cnt = 0
for i, (train, test) in enumerate(cv.split(X,y)): #利用模型劃分數(shù)據(jù)集和目標變量 為一一對應的下標
cnt +=1
probas_ = classifier.fit(X[train], y[train]).predict_proba(X[test]) # 訓練模型后預測每條樣本得到兩種結果的概率
fpr, tpr, thresholds = roc_curve(y[test], probas_[:, 1]) # 該函數(shù)得到偽正例、真正例、閾值,這里只使用前兩個
mean_tpr += np.interp(mean_fpr, fpr, tpr) # 插值函數(shù) interp(x坐標,每次x增加距離,y坐標) 累計每次循環(huán)的總值后面求平均值
mean_tpr[0] = 0.0 # 將第一個真正例=0 以0為起點
roc_auc = auc(fpr, tpr) # 求auc面積
plt.plot(fpr, tpr, lw=1, label='ROC fold {0:.2f} (area = {1:.2f})'.format(i, roc_auc)) # 畫出當前分割數(shù)據(jù)的ROC曲線
plt.plot([0, 1], [0, 1], '--', color=(0.6, 0.6, 0.6), label='Luck') # 畫對角線
mean_tpr /= cnt # 求數(shù)組的平均值
mean_tpr[-1] = 1.0 # 坐標最后一個點為(1,1) 以1為終點
mean_auc = auc(mean_fpr, mean_tpr)
plt.plot(mean_fpr, mean_tpr, 'k--',label='Mean ROC (area = {0:.2f})'.format(mean_auc), lw=2)
plt.xlim([-0.05, 1.05]) # 設置x、y軸的上下限,設置寬一點,以免和邊緣重合,可以更好的觀察圖像的整體
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate') # 可以使用中文,但需要導入一些庫即字體
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()
1、sklearn里有現(xiàn)成的函數(shù)計算ROC曲線坐標點。
2、把隨機生成的置信度只保留小數(shù)點后一位,那么數(shù)據(jù)里有很多相同置信度的值,就可以實現(xiàn)ROC。
方法/步驟
1
首先,打開數(shù)據(jù),以A2列數(shù)據(jù)為例做曲線。
2
點擊“ Analyze -ROC curve ”。
3
彈出界面后,導入A2列數(shù)據(jù),調節(jié)其它參數(shù)。
4
點擊“OK”,出現(xiàn)結果。
5
雙擊ROC曲線,進入調節(jié)界面。
6
可以調節(jié)很多參數(shù),也可以把曲線調成平滑的。很方便實用吧!
2020/5/27,受一名同學所托,為他的腫瘤Hub基因分析文章做一個預測模型和模型的ROC曲線、AUC值來驗證Hub基因的可靠性。如果Hub基因有意義的話,用Hub基因作為特征建立的預測模型就應該能有效地分類癌組織或者正常組織。
本文結構如下:
首先,數(shù)據(jù)清洗和Hub基因篩選,他們已經(jīng)把Hub基因找到了,換句話說可以直接跳過數(shù)據(jù)清洗和特征工程階段。
一共10個關鍵基因,分為三類,高惡度癌(3)、低惡度癌(2)、正常對照組織(1),分別為9、20、20個樣本。
首先創(chuàng)建兩個.txt文件分別儲存圖2的特征值內容和標簽內容,features.txt 和 label_2.txt(當然也可以直接用Pandas讀取表格,個人習慣)然后用Python讀入數(shù)據(jù)。
我在這里定義了一個函數(shù),需要用主函數(shù)設置which_class,選擇繪制哪一類的ROC
ROC、AUC、micro/macro-average ROC curve的理論部分可以看這個 ROC理論 ,本節(jié)簡要解讀一下多類別ROC圖的結果:
這個是直接三分類的訓練集:測試集=1:1的ROC曲線,class0代表鑒別正常組織和兩種癌組織,class1代表鑒別低惡度癌和另外兩種組織,class2代表鑒別高惡度癌和另外兩種組織,可以看出class2的AUC值為1,表明Hub基因建立的模型確實可以有效鑒別ATC和另外兩種預后較好的組織。
[1] sklearn中文官方文檔:支持向量機
[2] Receiver Operating Characteristic (ROC)
[3] Receiver Operating Characteristic (ROC) with cross validation