由于文章較長(zhǎng),所以我還是先把目錄提前。
一、認(rèn)識(shí)管道流
1.1 數(shù)據(jù)導(dǎo)入
1.2 使用管道創(chuàng)建工作流
二、K折交叉驗(yàn)證
2.1 K折交叉驗(yàn)證原理
2.2 K折交叉驗(yàn)證實(shí)現(xiàn)
三、曲線調(diào)參
3.1 模型準(zhǔn)確度
3.2繪制學(xué)習(xí)曲線得到樣本數(shù)與準(zhǔn)確率的關(guān)系
3.3繪制驗(yàn)證曲線得到超參和準(zhǔn)確率關(guān)系
四、網(wǎng)格搜索
4.1兩層for循環(huán)暴力檢索
4.2構(gòu)建字典暴力檢索
五、嵌套交叉驗(yàn)證
六、相關(guān)評(píng)價(jià)指標(biāo)
6.1 混淆矩陣及其實(shí)現(xiàn)
6.2 相關(guān)評(píng)價(jià)指標(biāo)實(shí)現(xiàn)
6.3 ROC曲線及其實(shí)現(xiàn)
一、認(rèn)識(shí)管道流
今天先介紹一下管道工作流的操作。
“管道工作流”這個(gè)概念可能有點(diǎn)陌生,其實(shí)可以理解為一個(gè)容器,然后把我們需要進(jìn)行的操作都封裝在這個(gè)管道里面進(jìn)行操作,比如數(shù)據(jù)標(biāo)準(zhǔn)化、特征降維、主成分分析、模型預(yù)測(cè)等等,下面還是以一個(gè)實(shí)例來講解。
1.1 數(shù)據(jù)導(dǎo)入與預(yù)處理
本次我們導(dǎo)入一個(gè)二分類數(shù)據(jù)集 Breast Cancer Wisconsin,它包含569個(gè)樣本。首列為主鍵ID,第2列為類別值(M=惡性腫瘤,B=良性腫瘤),第3-32列是實(shí)數(shù)值的特征。
先導(dǎo)入數(shù)據(jù)集:
1#導(dǎo)入相關(guān)數(shù)據(jù)集 2importpandasaspd 3importurllib 4try: 5df=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases' 6'/breast-cancer-wisconsin/wdbc.data',header=None) 7excepturllib.error.URLError: 8df=pd.read_csv('https://raw.githubusercontent.com/rasbt/' 9'python-machine-learning-book/master/code/' 10'datasets/wdbc/wdbc.data',header=None) 11print('rows,columns:',df.shape) 12df.head()
使用我們學(xué)習(xí)過的LabelEncoder來轉(zhuǎn)化類別特征:
1fromsklearn.preprocessingimportLabelEncoder 2X=df.loc[:,2:].values 3y=df.loc[:,1].values 4le=LabelEncoder() 5#將目標(biāo)轉(zhuǎn)為0-1變量 6y=le.fit_transform(y) 7le.transform(['M','B'])
劃分訓(xùn)練驗(yàn)證集:
1##創(chuàng)建訓(xùn)練集和測(cè)試集 2fromsklearn.model_selectionimporttrain_test_split 3X_train,X_test,y_train,y_test= 4train_test_split(X,y,test_size=0.20,random_state=1)
1.2 使用管道創(chuàng)建工作流
很多機(jī)器學(xué)習(xí)算法要求特征取值范圍要相同,因此需要對(duì)特征做標(biāo)準(zhǔn)化處理。此外,我們還想將原始的30維度特征壓縮至更少維度,這就需要用到主成分分析,要用PCA來完成,再接著就可以進(jìn)行l(wèi)ogistic回歸預(yù)測(cè)了。
Pipeline對(duì)象接收元組構(gòu)成的列表作為輸入,每個(gè)元組第一個(gè)值作為變量名,元組第二個(gè)元素是sklearn中的transformer或Estimator。管道中間每一步由sklearn中的transformer構(gòu)成,最后一步是一個(gè)Estimator。
本次數(shù)據(jù)集中,管道包含兩個(gè)中間步驟:StandardScaler和PCA,其都屬于transformer,而邏輯斯蒂回歸分類器屬于Estimator。
本次實(shí)例,當(dāng)管道pipe_lr執(zhí)行fit方法時(shí):
1)StandardScaler執(zhí)行fit和transform方法;
2)將轉(zhuǎn)換后的數(shù)據(jù)輸入給PCA;
3)PCA同樣執(zhí)行fit和transform方法;
4)最后數(shù)據(jù)輸入給LogisticRegression,訓(xùn)練一個(gè)LR模型。
對(duì)于管道來說,中間有多少個(gè)transformer都可以。管道的工作方式可以用下圖來展示(一定要注意管道執(zhí)行fit方法,而transformer要執(zhí)行fit_transform):
上面的代碼實(shí)現(xiàn)如下:
1fromsklearn.preprocessingimportStandardScaler#用于進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化 2fromsklearn.decompositionimportPCA#用于進(jìn)行特征降維 3fromsklearn.linear_modelimportLogisticRegression#用于模型預(yù)測(cè) 4fromsklearn.pipelineimportPipeline 5pipe_lr=Pipeline([('scl',StandardScaler()), 6('pca',PCA(n_components=2)), 7('clf',LogisticRegression(random_state=1))]) 8pipe_lr.fit(X_train,y_train) 9print('TestAccuracy:%.3f'%pipe_lr.score(X_test,y_test)) 10y_pred=pipe_lr.predict(X_test)
Test Accuracy: 0.947
二、K折交叉驗(yàn)證
為什么要評(píng)估模型的泛化能力,相信這個(gè)大家應(yīng)該沒有疑惑,一個(gè)模型如果性能不好,要么是因?yàn)槟P瓦^于復(fù)雜導(dǎo)致過擬合(高方差),要么是模型過于簡(jiǎn)單導(dǎo)致導(dǎo)致欠擬合(高偏差)。如何評(píng)估它,用什么數(shù)據(jù)來評(píng)估它,成為了模型評(píng)估需要重點(diǎn)考慮的問題。
我們常規(guī)做法,就是將數(shù)據(jù)集劃分為3部分,分別是訓(xùn)練、測(cè)試和驗(yàn)證,彼此之間的數(shù)據(jù)不重疊。但,如果我們遇見了數(shù)據(jù)量不多的時(shí)候,這種操作就顯得不太現(xiàn)實(shí),這個(gè)時(shí)候k折交叉驗(yàn)證就發(fā)揮優(yōu)勢(shì)了。
2.1 K折交叉驗(yàn)證原理
先不多說,先貼一張?jiān)韴D(以10折交叉驗(yàn)證為例)。
k折交叉驗(yàn)證步驟:
Step 1:使用不重復(fù)抽樣將原始數(shù)據(jù)隨機(jī)分為k份;
Step2:其中k-1份數(shù)據(jù)用于模型訓(xùn)練,剩下的那1份數(shù)據(jù)用于測(cè)試模型;
Step 3:重復(fù)Step 2k次,得到k個(gè)模型和他的評(píng)估結(jié)果。
Step 4:計(jì)算k折交叉驗(yàn)證結(jié)果的平均值作為參數(shù)/模型的性能評(píng)估。
2.1 K折交叉驗(yàn)證實(shí)現(xiàn)
K折交叉驗(yàn)證,那么K的取值該如何確認(rèn)呢?一般我們默認(rèn)10折,但根據(jù)實(shí)際情況有所調(diào)整。我們要知道,當(dāng)K很大的時(shí)候,你需要訓(xùn)練的模型就會(huì)很多,這樣子對(duì)效率影響較大,而且每個(gè)模型的訓(xùn)練集都差不多,效果也差不多。我們常用的K值在5~12。
我們根據(jù)k折交叉驗(yàn)證的原理步驟,在sklearn中進(jìn)行10折交叉驗(yàn)證的代碼實(shí)現(xiàn):
1importnumpyasnp 2fromsklearn.model_selectionimportStratifiedKFold 3kfold=StratifiedKFold(n_splits=10, 4random_state=1).split(X_train,y_train) 5scores=[] 6fork,(train,test)inenumerate(kfold): 7pipe_lr.fit(X_train[train],y_train[train]) 8score=pipe_lr.score(X_train[test],y_train[test]) 9scores.append(score) 10print('Fold:%s,Classdist.:%s,Acc:%.3f'%(k+1, 11np.bincount(y_train[train]),score)) 12print(' CVaccuracy:%.3f+/-%.3f'%(np.mean(scores),np.std(scores)))
output:
當(dāng)然,實(shí)際使用的時(shí)候沒必要這樣子寫,sklearn已經(jīng)有現(xiàn)成封裝好的方法,直接調(diào)用即可。
1fromsklearn.model_selectionimportcross_val_score 2scores=cross_val_score(estimator=pipe_lr, 3X=X_train, 4y=y_train, 5cv=10, 6n_jobs=1) 7print('CVaccuracyscores:%s'%scores) 8print('CVaccuracy:%.3f+/-%.3f'%(np.mean(scores),np.std(scores)))
三、曲線調(diào)參
我們講到的曲線,具體指的是學(xué)習(xí)曲線(learning curve)和驗(yàn)證曲線(validation curve)。
3.1 模型準(zhǔn)確率(Accuracy)
模型準(zhǔn)確率反饋了模型的效果,大家看下圖:
1)左上角子的模型偏差很高。它的訓(xùn)練集和驗(yàn)證集準(zhǔn)確率都很低,很可能是欠擬合。解決欠擬合的方法就是增加模型參數(shù),比如,構(gòu)建更多的特征,減小正則項(xiàng)。
2)右上角子的模型方差很高,表現(xiàn)就是訓(xùn)練集和驗(yàn)證集準(zhǔn)確率相差太多。解決過擬合的方法有增大訓(xùn)練集或者降低模型復(fù)雜度,比如增大正則項(xiàng),或者通過特征選擇減少特征數(shù)。
3)右下角的模型就很好。
3.2 繪制學(xué)習(xí)曲線得到樣本數(shù)與準(zhǔn)確率的關(guān)系
直接上代碼:
1importmatplotlib.pyplotasplt 2fromsklearn.model_selectionimportlearning_curve 3pipe_lr=Pipeline([('scl',StandardScaler()), 4('clf',LogisticRegression(penalty='l2',random_state=0))]) 5train_sizes,train_scores,test_scores= 6learning_curve(estimator=pipe_lr, 7X=X_train, 8y=y_train, 9train_sizes=np.linspace(0.1,1.0,10),#在0.1和1間線性的取10個(gè)值 10cv=10, 11n_jobs=1) 12train_mean=np.mean(train_scores,axis=1) 13train_std=np.std(train_scores,axis=1) 14test_mean=np.mean(test_scores,axis=1) 15test_std=np.std(test_scores,axis=1) 16plt.plot(train_sizes,train_mean, 17color='blue',marker='o', 18markersize=5,label='trainingaccuracy') 19plt.fill_between(train_sizes, 20train_mean+train_std, 21train_mean-train_std, 22alpha=0.15,color='blue') 23plt.plot(train_sizes,test_mean, 24color='green',linestyle='--', 25marker='s',markersize=5, 26label='validationaccuracy') 27plt.fill_between(train_sizes, 28test_mean+test_std, 29test_mean-test_std, 30alpha=0.15,color='green') 31plt.grid() 32plt.xlabel('Numberoftrainingsamples') 33plt.ylabel('Accuracy') 34plt.legend(loc='lowerright') 35plt.ylim([0.8,1.0]) 36plt.tight_layout() 37plt.show()
Learning_curve中的train_sizes參數(shù)控制產(chǎn)生學(xué)習(xí)曲線的訓(xùn)練樣本的絕對(duì)/相對(duì)數(shù)量,此處,我們?cè)O(shè)置的train_sizes=np.linspace(0.1, 1.0, 10),將訓(xùn)練集大小劃分為10個(gè)相等的區(qū)間,在0.1和1之間線性的取10個(gè)值。learning_curve默認(rèn)使用分層k折交叉驗(yàn)證計(jì)算交叉驗(yàn)證的準(zhǔn)確率,我們通過cv設(shè)置k。
下圖可以看到,模型在測(cè)試集表現(xiàn)很好,不過訓(xùn)練集和測(cè)試集的準(zhǔn)確率還是有一段小間隔,可能是模型有點(diǎn)過擬合。
3.3 繪制驗(yàn)證曲線得到超參和準(zhǔn)確率關(guān)系
驗(yàn)證曲線是用來提高模型的性能,驗(yàn)證曲線和學(xué)習(xí)曲線很相近,不同的是這里畫出的是不同參數(shù)下模型的準(zhǔn)確率而不是不同訓(xùn)練集大小下的準(zhǔn)確率:
1fromsklearn.model_selectionimportvalidation_curve 2param_range=[0.001,0.01,0.1,1.0,10.0,100.0] 3train_scores,test_scores=validation_curve( 4estimator=pipe_lr, 5X=X_train, 6y=y_train, 7param_name='clf__C', 8param_range=param_range, 9cv=10) 10train_mean=np.mean(train_scores,axis=1) 11train_std=np.std(train_scores,axis=1) 12test_mean=np.mean(test_scores,axis=1) 13test_std=np.std(test_scores,axis=1) 14plt.plot(param_range,train_mean, 15color='blue',marker='o', 16markersize=5,label='trainingaccuracy') 17plt.fill_between(param_range,train_mean+train_std, 18train_mean-train_std,alpha=0.15, 19color='blue') 20plt.plot(param_range,test_mean, 21color='green',linestyle='--', 22marker='s',markersize=5, 23label='validationaccuracy') 24plt.fill_between(param_range, 25test_mean+test_std, 26test_mean-test_std, 27alpha=0.15,color='green') 28plt.grid() 29plt.xscale('log') 30plt.legend(loc='lowerright') 31plt.xlabel('ParameterC') 32plt.ylabel('Accuracy') 33plt.ylim([0.8,1.0]) 34plt.tight_layout() 35plt.show()
我們得到了參數(shù)C的驗(yàn)證曲線。和learning_curve方法很像,validation_curve方法使用采樣k折交叉驗(yàn)證來評(píng)估模型的性能。在validation_curve內(nèi)部,我們?cè)O(shè)定了用來評(píng)估的參數(shù)(這里我們?cè)O(shè)置C作為觀測(cè))。
從下圖可以看出,最好的C值是0.1。
四、網(wǎng)格搜索
網(wǎng)格搜索(grid search),作為調(diào)參很常用的方法,這邊還是要簡(jiǎn)單介紹一下。
在我們的機(jī)器學(xué)習(xí)算法中,有一類參數(shù),需要人工進(jìn)行設(shè)定,我們稱之為“超參”,也就是算法中的參數(shù),比如學(xué)習(xí)率、正則項(xiàng)系數(shù)或者決策樹的深度等。
網(wǎng)格搜索就是要找到一個(gè)最優(yōu)的參數(shù),從而使得模型的效果最佳,而它實(shí)現(xiàn)的原理其實(shí)就是暴力搜索;即我們事先為每個(gè)參數(shù)設(shè)定一組值,然后窮舉各種參數(shù)組合,找到最好的那一組。
4.1. 兩層for循環(huán)暴力檢索
網(wǎng)格搜索的結(jié)果獲得了指定的最優(yōu)參數(shù)值,c為100,gamma為0.001
1#naivegridsearchimplementation 2fromsklearn.datasetsimportload_iris 3fromsklearn.svmimportSVC 4fromsklearn.model_selectionimporttrain_test_split 5iris=load_iris() 6X_train,X_test,y_train,y_test=train_test_split(iris.data,iris.target,random_state=0) 7print("Sizeoftrainingset:%dsizeoftestset:%d"%(X_train.shape[0],X_test.shape[0])) 8best_score=0 9forgammain[0.001,0.01,0.1,1,10,100]: 10forCin[0.001,0.01,0.1,1,10,100]: 11#foreachcombinationofparameters 12#trainanSVC 13svm=SVC(gamma=gamma,C=C) 14svm.fit(X_train,y_train) 15#evaluatetheSVConthetestset 16score=svm.score(X_test,y_test) 17#ifwegotabetterscore,storethescoreandparameters 18ifscore>best_score: 19best_score=score 20best_parameters={'C':C,'gamma':gamma} 21print("bestscore:",best_score) 22print("bestparameters:",best_parameters)
output: Size of training set: 112 size of test set: 38 best score: 0.973684210526 best parameters: {'C': 100, 'gamma': 0.001}
4.2. 構(gòu)建字典暴力檢索
網(wǎng)格搜索的結(jié)果獲得了指定的最優(yōu)參數(shù)值,c為1
1fromsklearn.svmimportSVC 2fromsklearn.model_selectionimportGridSearchCV 3pipe_svc=Pipeline([('scl',StandardScaler()), 4('clf',SVC(random_state=1))]) 5param_range=[0.0001,0.001,0.01,0.1,1.0,10.0,100.0,1000.0] 6param_grid=[{'clf__C':param_range, 7'clf__kernel':['linear']}, 8{'clf__C':param_range, 9'clf__gamma':param_range, 10'clf__kernel':['rbf']}] 11gs=GridSearchCV(estimator=pipe_svc, 12param_grid=param_grid, 13scoring='accuracy', 14cv=10, 15n_jobs=-1) 16gs=gs.fit(X_train,y_train) 17print(gs.best_score_) 18print(gs.best_params_)
output: 0.978021978022 {'clf__C': 0.1, 'clf__kernel': 'linear'}
GridSearchCV中param_grid參數(shù)是字典構(gòu)成的列表。對(duì)于線性SVM,我們只評(píng)估參數(shù)C;對(duì)于RBF核SVM,我們?cè)u(píng)估C和gamma。最后, 我們通過best_parmas_得到最優(yōu)參數(shù)組合。
接著,我們直接利用最優(yōu)參數(shù)建模(best_estimator_):
1clf=gs.best_estimator_ 2clf.fit(X_train,y_train) 3print('Testaccuracy:%.3f'%clf.score(X_test,y_test))
網(wǎng)格搜索雖然不錯(cuò),但是窮舉過于耗時(shí),sklearn中還實(shí)現(xiàn)了隨機(jī)搜索,使用 RandomizedSearchCV類,隨機(jī)采樣出不同的參數(shù)組合。
五、嵌套交叉驗(yàn)證
嵌套交叉驗(yàn)證(nested cross validation)選擇算法(外循環(huán)通過k折等進(jìn)行參數(shù)優(yōu)化,內(nèi)循環(huán)使用交叉驗(yàn)證),對(duì)特定數(shù)據(jù)集進(jìn)行模型選擇。Varma和Simon在論文Bias in Error Estimation When Using Cross-validation for Model Selection中指出使用嵌套交叉驗(yàn)證得到的測(cè)試集誤差幾乎就是真實(shí)誤差。
嵌套交叉驗(yàn)證外部有一個(gè)k折交叉驗(yàn)證將數(shù)據(jù)分為訓(xùn)練集和測(cè)試集,內(nèi)部交叉驗(yàn)證用于選擇模型算法。
下圖演示了一個(gè)5折外層交叉沿則和2折內(nèi)部交叉驗(yàn)證組成的嵌套交叉驗(yàn)證,也被稱為5*2交叉驗(yàn)證:
我們還是用到之前的數(shù)據(jù)集,相關(guān)包的導(dǎo)入操作這里就省略了。
SVM分類器的預(yù)測(cè)準(zhǔn)確率代碼實(shí)現(xiàn):
1gs=GridSearchCV(estimator=pipe_svc, 2param_grid=param_grid, 3scoring='accuracy', 4cv=2) 5 6#Note:Optionally,youcouldusecv=2 7#intheGridSearchCVabovetoproduce 8#the5x2nestedCVthatisshowninthefigure. 9 10scores=cross_val_score(gs,X_train,y_train,scoring='accuracy',cv=5) 11print('CVaccuracy:%.3f+/-%.3f'%(np.mean(scores),np.std(scores)))
CV accuracy: 0.965 +/- 0.025
決策樹分類器的預(yù)測(cè)準(zhǔn)確率代碼實(shí)現(xiàn):
1fromsklearn.treeimportDecisionTreeClassifier 2 3gs=GridSearchCV(estimator=DecisionTreeClassifier(random_state=0), 4param_grid=[{'max_depth':[1,2,3,4,5,6,7,None]}], 5scoring='accuracy', 6cv=2) 7scores=cross_val_score(gs,X_train,y_train,scoring='accuracy',cv=5) 8print('CVaccuracy:%.3f+/-%.3f'%(np.mean(scores),np.std(scores)))
CV accuracy: 0.921 +/- 0.029
六、相關(guān)評(píng)價(jià)指標(biāo)
6.1 混淆矩陣及其實(shí)現(xiàn)
混淆矩陣,大家應(yīng)該都有聽說過,大致就是長(zhǎng)下面這樣子的:
所以,有幾個(gè)概念需要先說明:
TP(True Positive): 真實(shí)為0,預(yù)測(cè)也為0
FN(False Negative): 真實(shí)為0,預(yù)測(cè)為1
FP(False Positive): 真實(shí)為1,預(yù)測(cè)為0
TN(True Negative): 真實(shí)為1,預(yù)測(cè)也為1
所以,衍生了幾個(gè)常用的指標(biāo):
: 分類模型總體判斷的準(zhǔn)確率(包括了所有class的總體準(zhǔn)確率)
: 預(yù)測(cè)為0的準(zhǔn)確率
: 真實(shí)為0的準(zhǔn)確率
: 真實(shí)為1的準(zhǔn)確率
: 預(yù)測(cè)為1的準(zhǔn)確率
:對(duì)于某個(gè)分類,綜合了Precision和Recall的一個(gè)判斷指標(biāo),F(xiàn)1-Score的值是從0到1的,1是最好,0是最差
: 另外一個(gè)綜合Precision和Recall的標(biāo)準(zhǔn),F(xiàn)1-Score的變形
再舉個(gè)例子:
混淆矩陣網(wǎng)絡(luò)上有很多文章,也不用說刻意地去背去記,需要的時(shí)候百度一下你就知道,混淆矩陣實(shí)現(xiàn)代碼:
1fromsklearn.metricsimportconfusion_matrix 2 3pipe_svc.fit(X_train,y_train) 4y_pred=pipe_svc.predict(X_test) 5confmat=confusion_matrix(y_true=y_test,y_pred=y_pred) 6print(confmat)
output: [[71 1] [ 2 40]]
1fig,ax=plt.subplots(figsize=(2.5,2.5)) 2ax.matshow(confmat,cmap=plt.cm.Blues,alpha=0.3) 3foriinrange(confmat.shape[0]): 4forjinrange(confmat.shape[1]): 5ax.text(x=j,y=i,s=confmat[i,j],va='center',ha='center') 6 7plt.xlabel('predictedlabel') 8plt.ylabel('truelabel') 9 10plt.tight_layout() 11plt.show()
6.2 相關(guān)評(píng)價(jià)指標(biāo)實(shí)現(xiàn)
分別是準(zhǔn)確度、recall以及F1指標(biāo)的實(shí)現(xiàn)。
1fromsklearn.metricsimportprecision_score,recall_score,f1_score 2 3print('Precision:%.3f'%precision_score(y_true=y_test,y_pred=y_pred)) 4print('Recall:%.3f'%recall_score(y_true=y_test,y_pred=y_pred)) 5print('F1:%.3f'%f1_score(y_true=y_test,y_pred=y_pred))
Precision: 0.976 Recall: 0.952 F1: 0.964
指定評(píng)價(jià)指標(biāo)自動(dòng)選出最優(yōu)模型:
可以通過在make_scorer中設(shè)定參數(shù),確定需要用來評(píng)價(jià)的指標(biāo)(這里用了fl_score),這個(gè)函數(shù)可以直接輸出結(jié)果。
1fromsklearn.metricsimportmake_scorer 2 3scorer=make_scorer(f1_score,pos_label=0) 4 5c_gamma_range=[0.01,0.1,1.0,10.0] 6 7param_grid=[{'clf__C':c_gamma_range, 8'clf__kernel':['linear']}, 9{'clf__C':c_gamma_range, 10'clf__gamma':c_gamma_range, 11'clf__kernel':['rbf']}] 12 13gs=GridSearchCV(estimator=pipe_svc, 14param_grid=param_grid, 15scoring=scorer, 16cv=10, 17n_jobs=-1) 18gs=gs.fit(X_train,y_train) 19print(gs.best_score_) 20print(gs.best_params_)
0.982798668208 {'clf__C': 0.1, 'clf__kernel': 'linear'}
6.3 ROC曲線及其實(shí)現(xiàn)
如果需要理解ROC曲線,那你就需要先了解一下混淆矩陣了,具體的內(nèi)容可以查看一下之前的文章,這里重點(diǎn)引入2個(gè)概念:
真正率(true positive rate,TPR),指的是被模型正確預(yù)測(cè)的正樣本的比例:
假正率(false positive rate,FPR) ,指的是被模型錯(cuò)誤預(yù)測(cè)的正樣本的比例:
ROC曲線概念:
ROC(receiver operating characteristic)接受者操作特征,其顯示的是分類器的真正率和假正率之間的關(guān)系,如下圖所示:
ROC曲線有助于比較不同分類器的相對(duì)性能,其曲線下方的面積為AUC(area under curve),其面積越大則分類的性能越好,理想的分類器auc=1。
ROC曲線繪制:
對(duì)于一個(gè)特定的分類器和測(cè)試數(shù)據(jù)集,顯然只能得到一個(gè)分類結(jié)果,即一組FPR和TPR結(jié)果,而要得到一個(gè)曲線,我們實(shí)際上需要一系列FPR和TPR的值。
那么如何處理?很簡(jiǎn)單,我們可以根據(jù)模型預(yù)測(cè)的概率值,并且設(shè)置不同的閾值來獲得不同的預(yù)測(cè)結(jié)果。什么意思?
比如說:
5個(gè)樣本,真實(shí)的target(目標(biāo)標(biāo)簽)是y=c(1,1,0,0,1)
模型分類器將預(yù)測(cè)樣本為1的概率p=c(0.5,0.6,0.55,0.4,0.7)
我們需要選定閾值才能把概率轉(zhuǎn)化為類別,
如果我們選定閾值為0.1,那么5個(gè)樣本被分進(jìn)1的類別
如果選定0.3,結(jié)果仍然一樣
如果選了0.45作為閾值,那么只有樣本4被分進(jìn)0
之后把所有得到的所有分類結(jié)果計(jì)算FTR,PTR,并繪制成線,就可以得到ROC曲線了,當(dāng)threshold(閾值)取值越多,ROC曲線越平滑。
ROC曲線代碼實(shí)現(xiàn):
1fromsklearn.metricsimportroc_curve,auc 2fromscipyimportinterp 3 4pipe_lr=Pipeline([('scl',StandardScaler()), 5('pca',PCA(n_components=2)), 6('clf',LogisticRegression(penalty='l2', 7random_state=0, 8C=100.0))]) 9 10X_train2=X_train[:,[4,14]] 11 # 因?yàn)槿刻卣鱽G進(jìn)去的話,預(yù)測(cè)效果太好,畫ROC曲線不好看哈哈哈,所以只是取了2個(gè)特征 12 13 14cv=list(StratifiedKFold(n_splits=3, 15random_state=1).split(X_train,y_train)) 16 17fig=plt.figure(figsize=(7,5)) 18 19mean_tpr=0.0 20mean_fpr=np.linspace(0,1,100) 21all_tpr=[] 22 23fori,(train,test)inenumerate(cv): 24probas=pipe_lr.fit(X_train2[train], 25y_train[train]).predict_proba(X_train2[test]) 26 27fpr,tpr,thresholds=roc_curve(y_train[test], 28probas[:,1], 29pos_label=1) 30mean_tpr+=interp(mean_fpr,fpr,tpr) 31mean_tpr[0]=0.0 32roc_auc=auc(fpr,tpr) 33plt.plot(fpr, 34tpr, 35lw=1, 36label='ROCfold%d(area=%0.2f)' 37%(i+1,roc_auc)) 38 39plt.plot([0,1], 40[0,1], 41linestyle='--', 42color=(0.6,0.6,0.6), 43label='randomguessing') 44 45mean_tpr/=len(cv) 46mean_tpr[-1]=1.0 47mean_auc=auc(mean_fpr,mean_tpr) 48plt.plot(mean_fpr,mean_tpr,'k--', 49label='meanROC(area=%0.2f)'%mean_auc,lw=2) 50plt.plot([0,0,1], 51[0,1,1], 52lw=2, 53linestyle=':', 54color='black', 55label='perfectperformance') 56 57plt.xlim([-0.05,1.05]) 58plt.ylim([-0.05,1.05]) 59plt.xlabel('falsepositiverate') 60plt.ylabel('truepositiverate') 61plt.title('ReceiverOperatorCharacteristic') 62plt.legend(loc="lowerright") 63 64plt.tight_layout() 65plt.show()
查看下AUC和準(zhǔn)確率的結(jié)果:
1pipe_lr=pipe_lr.fit(X_train2,y_train) 2y_labels=pipe_lr.predict(X_test[:,[4,14]]) 3y_probas=pipe_lr.predict_proba(X_test[:,[4,14]])[:,1] 4#notethatweuseprobabilitiesforroc_auc 5#the`[:,1]`selectsthepositiveclasslabelonly
1fromsklearn.metricsimportroc_auc_score,accuracy_score 2print('ROCAUC:%.3f'%roc_auc_score(y_true=y_test,y_score=y_probas)) 3print('Accuracy:%.3f'%accuracy_score(y_true=y_test,y_pred=y_labels))
ROC AUC: 0.752 Accuracy: 0.711
責(zé)任編輯:xj
原文標(biāo)題:萬字長(zhǎng)文總結(jié)機(jī)器學(xué)習(xí)的模型評(píng)估與調(diào)參,附代碼下載
文章出處:【微信公眾號(hào):人工智能與大數(shù)據(jù)技術(shù)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
機(jī)器學(xué)習(xí)
+關(guān)注
關(guān)注
66文章
8357瀏覽量
132330 -
嵌套
+關(guān)注
關(guān)注
0文章
15瀏覽量
7923
原文標(biāo)題:萬字長(zhǎng)文總結(jié)機(jī)器學(xué)習(xí)的模型評(píng)估與調(diào)參,附代碼下載
文章出處:【微信號(hào):TheBigData1024,微信公眾號(hào):人工智能與大數(shù)據(jù)技術(shù)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論