1. 程式人生 > >【轉】分類/迴歸模型評估—ROC,AUC,RMSE等指標/調參—Grid Search

【轉】分類/迴歸模型評估—ROC,AUC,RMSE等指標/調參—Grid Search

看到此篇文章內容乾貨較多,轉載過來學習。

連結:https://www.52ml.net/20410.html

模型評估的方法

        一般情況來說,F1評分或者R平方(R-Squared value)等數值評分可以告訴我們訓練的機器學習模型的好壞。也有其它許多度量方式來評估擬合模型。

你應該猜出來,我將提出使用視覺化的方法結合數值評分來更直觀的評判機器學習模型。接下來的幾個部分將分享一些有用的工具。

        首先想宣告的,單單一個評分或者一條線,是無法完全評估一個機器學習模型。偏離真實場景來評估機器學習模型(’good’ or ‘bad’)都是“耍流氓”。某個機器學習模型若可“駕馭”小樣本資料集生成最多預測模型(即,命中更多預測資料集)。如果一個擬合模型比其它擬合過的模型形式或者你昨天的預測模型能夠得到更好的結果,那即是好(’good’)。

       下面是一些標準指標: confusion_matrix,mean_squared_error, r2_score,這些可以用來評判分類器或者回歸的好壞。表格中給出的是Scikit-Learn中的函式以及描述:

評估分類模型:

指標 描述 Scikit-learn函式
Precision 精準度 from sklearn.metrics import precision_score
Recall 召回率 from sklearn.metrics import recall_score 
F1  F1值 from sklearn.metrics import f1_score 
Confusion Matrix  混淆矩陣 from sklearn.metrics import confusion_matrix
ROC ROC曲線 from sklearn.metrics import roc 
AUC  ROC曲線下的面積 from sklearn.metrics import auc 

評估迴歸模型:

指標 描述 Scikit-learn函式
Mean Square Error (MSE, RMSE)  平均方差 from sklearn.metrics import mean_squared_error
Absolute Error (MAE, RAE)  絕對誤差  from sklearn.metrics import mean_absolute_error, median_absolute_error 
R-Squared R平方值 from sklearn.metrics import r2_score 

下面開始使用Scikit-Learn的視覺化工具來更直觀的展現模型的好壞。

評估分類模型

      我們評估分類器是判斷預測值時否很好的與實際標記值相匹配。正確的鑑別出正樣本(True Positives)或者負樣本(True Negatives)都是True。同理,錯誤的判斷正樣本(False Positive,即一類錯誤)或者負樣本(False Negative,即二類錯誤)。

       注意:True和False是對於評價預測結果而言,也就是評價預測結果是正確的(True)還是錯誤的(False)。而Positive和Negative則是樣本分類的標記。

         通常,我們希望通過一些引數來告知模型評估如何。為此,我們使用混淆矩陣。

混淆矩陣

       幸運的是,Scikit-Learn提供內建函式(sklearn.metrics.confusion_matrix)來計算混淆矩陣。輸入資料集實際值和模型預測值作為引數,輸出即為混淆矩陣,結果類似這樣:

[[1238 19] # True Positives = 1238, False Negatives = 19
[ 2 370]] # False Positives = 2, True Negatives = 370

分類報告

分類報告除了包括混淆矩陣,也增加了其它優勢,比如,混淆矩陣會標示樣例是否被正確鑑別,同時也提供precision,recall和 F1 值三種評估指標。

from sklearn.metrics import classification_report
print(classification_report(y_true, y_pred, target_names=target_names))

…………

…………

ROC曲線

      另一種評估分類模型的方法是ROC(Receiver Operating Characteristic)曲線。我們能從Scikit-Learn 指標模組中import roc_curve,計算 true positive率和false positive 率的數值。我們也可以畫出ROC曲線來權衡模型的敏感性和特異性。

       下面的程式碼將畫出ROC,Y軸代表true positive率,X軸代表false positive 率。同時,我們也可以增加同時比較兩種不同的擬合模型,這裡看到的是 KNeighborsClassifier 分類器遠勝 LinearSVC 分類器:

…………

此處省略,可參見上述地址

…………

       在ROC空間,ROC曲線越凸向左上方向效果越好;越靠近對角線,分類器越趨向於隨機分類器。

      同時,我們也會計算曲線下的面積(AUC),可以結合上圖。如果AUC的值達到0.80,那說明分類器分類非常準確;如果AUC值在0.60~0.80之間,那分類器還算好,但是我們調調引數可能會得到更好的效能;如果AUC值小於0.60,那就慘不忍睹了,你得好好分析下咯。

為什麼使用ROC曲線

       既然已經這麼多評價標準,為什麼還要使用ROC和AUC呢?因為ROC曲線有個很好的特性:當測試集中的正負樣本的分佈變化的時候,ROC曲線能夠保持不變。在實際的資料集中經常會出現類不平衡(class imbalance)現象,即負樣本比正樣本多很多(或者相反),而且測試資料中的正負樣本的分佈也可能隨著時間變化。下圖是ROC曲線和Precision-Recall曲線的對比:

       在上圖中,(a)和(c)為ROC曲線,(b)和(d)為Precision-Recall曲線。(a)和(b)展示的是分類其在原始測試集(正負樣本分佈平衡)的結果,(c)和(d)是將測試集中負樣本的數量增加到原來的10倍後,分類器的結果。可以明顯的看出,ROC曲線基本保持原貌,而Precision-Recall曲線則變化較大。
參考連結:https://www.jianshu.com/p/c61ae11cc5f6
 

評估迴歸模型

       對於混凝土資料集試驗一些不同的機器學習模型,然後評判哪種更好。在第二篇文章中,我們使用的平均方差和 R 平方值,比如:

Mean squared error = 116.268
R2 score = 0.606

       這些數值是有用的,特別是對不同的擬合模型比較平均方差和 R 平方值。但是,這是不夠的,它不能告訴我們為什麼一個模型遠勝於另外一個;也不能告訴我們如何對模型調引數提高評分。接下來,我們將看到兩種視覺化的評估技術來幫助診斷模型有效性:預測錯誤曲線 和 殘差曲線。

…………

此處省略,可參見上述地址

…………

機器學習視覺化調參

在文章開篇,我們提出了兩個問題:我們如何知道一個機器學習模型可以工作?我們如何讓這個模型工作(執行)的更好?

接下來,我們將回答第二個問題。如果你有注意,我們用的模型都是使用Scikit-Learn 預設的引數。對於我們的大部分擬合模型來講,評分已經相當好了。但有時並沒有那麼幸運,這時我們就得自己調引數。

視覺化訓練和驗證模型

       如何選擇最好的模型引數呢?一種方法是,用單一引數的不同值去驗證一個模型的評估分數。讓我們拿SVC 分類器來試驗,通過調不同的gama值來畫出訓練值和測試值的曲線。

       我們的關注點是訓練值和測試值都高的點。如果兩者都低,那是欠擬合(underfit);如果訓練值高但是測試值低,那說明是過擬合(overfit)。

       下面的程式碼畫出來的曲線是拿信用卡資料集來做例子,這裡用的 6折交叉驗證。

def plot_val_curve(features, labels, model):
p_range = np.logspace(-5, 5, 5)
train_scores, test_scores = validation_curve(
model, features, labels, param_name='gamma', param_range=p_range,
cv=6, scoring='accuracy', n_jobs=1
)
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
plt.title('Validation Curve')
plt.xlabel('$\gamma$')
plt.ylabel('Score')
plt.semilogx(p_range, train_scores_mean, label='Training score', color='#E29539')
plt.semilogx(p_range, test_scores_mean, label='Cross-validation score', color='#94BA65')
plt.legend(loc='best')
plt.show()
X = scale(credit[['limit','sex','edu','married','age','apr_delay']])
y = credit['default']
plot_val_curve(X, y, SVC())

Grid Search

      對於超引數調優,大部分人使用的grid search。Grid search是一種暴力調參方法,即遍歷所有可能的引數值。

      對於信用卡資料集使用 SVC模型,我們通過試驗不同核心係數gama來提高預測準確性:

from sklearn.grid_search import GridSearchCV
def blind_gridsearch(model, X, y):
C_range = np.logspace(-2, 10, 5)
gamma_range = np.logspace(-5, 5, 5)
param_grid = dict(gamma=gamma_range, C=C_range)
grid = GridSearchCV(SVC(), param_grid=param_grid)
grid.fit(X, y)
print(
'The best parameters are {} with a score of {:0.2f}.'.format(
grid.best_params_, grid.best_score_
)
)
features = credit[['limit','sex','edu','married','age','apr_delay']]
labels = credit['default']
blind_gridsearch(SVC(), features, labels)

       但是,grid search需要我們理解哪些引數是合適的,引數的意義,引數是如何影響模型的以及引數的合理的搜尋範圍來初始化搜尋。

        這裡,我們使用 visual_gridsearch 代替 blind_gridsearch 函式:

def visual_gridsearch(model, X, y):
    C_range = np.logspace(-2, 10, 5)
    gamma_range = np.logspace(-5, 5, 5)
    param_grid = dict(gamma=gamma_range, C=C_range)
    grid = GridSearchCV(SVC(), param_grid=param_grid)
    grid.fit(X, y)
    scores = [x[1] for x in grid.grid_scores_]
    scores = np.array(scores).reshape(len(C_range), len(gamma_range))
    plt.figure(figsize=(8, 6))
    plt.subplots_adjust(left=.2, right=0.95, bottom=0.15, top=0.95)
    plt.imshow(scores, interpolation='nearest', cmap=ddlheatmap)
    plt.xlabel('gamma')
    plt.ylabel('C')
    plt.colorbar()
    plt.xticks(np.arange(len(gamma_range)), gamma_range, rotation=45)
    plt.yticks(np.arange(len(C_range)), C_range)
    plt.title(
    "The best parameters are {} with a score of {:0.2f}.".format(
    grid.best_params_, grid.best_score_)
    )
    plt.show()
visual_gridsearch(SVC(), features, labels)

      visual_gridsearch 的方法可以幫助我們理解不同的模型引數下的精確值。但是超引數調優的路程很長,好些人為此研究了幾十年。

結論

      這是視覺化機器學習部分的最後一篇,視覺化在機器學習的過程佔用重要的角色。許多工具都提供這個功能,比如, Scikit-Learn ,Matplotlib , Pandas ,Bokeh 和 Seaborn。