驗證曲線的作用
我們知道誤差由偏差(bias)、方差(variance)和噪聲(noise)責成。
偏差:模型對於不同的訓練樣本集,預測結果的平均誤差。
方差:模型對於不同訓練樣本集的敏感程度
噪聲:數據集本身的一項屬性
同樣的數據(cos函數上的點加上噪聲),我們用同樣的模型(polynomial),但是超參數卻不同(degree=1, 4, 15),會得到不同的擬合效果:
第一個模型太簡單,模型本身就擬合不了這些數據(高偏差);
第二個模型可以看成幾乎完美地擬合了數據;
第三個模型完美擬合了所有訓練數據,但卻不能很好地擬合真實的函數,也就是對於不同的訓練數據很敏感(高方差)。
對於這兩個問題,我們可以選擇模型和超參數來得到效果更好的配置,也就是可以通過驗證曲線來調節。
驗證曲線是什么
驗證曲線和學習曲線的區別是,橫軸為某個超參數的一系列值,由此來看不同參數設置下模型准確率,而不是不同訓練集大小下的准確率。
從驗證曲線上可以看到隨着超參數設置的改變,模型可能從欠擬合到合適再到過擬合的過程,進而選擇一個合適的位置,來提高模型的性能。
需要注意的是如果我們使用驗證分數來優化超參數,那么該驗證分數是有偏差的,它無法再代表模型的泛化能力,我們就需要使用其他測試集來重新評估模型的泛化能力。
即我們需要把一個數據集分成三部分,train、validation和test,我們使用train訓練模型,並通過在validation上的表現不斷修改超參數值(例如svm中的C值、gamma值等),當模型超參數在validation上表現最優時,我們再使用全新的測試集test進行測試,以此來衡量模型的泛化能力。
不過有時畫出單個超參數與訓練分數和驗證分數的關系圖,有助於觀察該模型在相應的超參數取值時,是否過擬合或欠擬合的情況發生。
適用場景
當擁有大量樣本可供使用時,可以將數據分為train、validation和test;當樣本數量較少時,可以使用交叉驗證,但也一定要留出相同的一部分test數據集,在最后使用。而其余部分假如分成了k-fold,就可以循環讓k-1fold做訓練集,剩下一個fold做驗證集。
如何解讀
如圖是SVM在不同gamma時,它在訓練集和交叉驗證上的分數:
gamma很小時,訓練分數和驗證分數都很低,為欠擬合;
gamma逐漸增加時,兩個分數都較高,此時模型相對不錯;
gamma太高時,訓練分數高,驗證分數低,學習器會過擬合。
本例中,可以選驗證集准確率開始下降,而測試集越來越高那個轉折點作為gamma的最優選擇。
怎么畫
下面用SVC為例,調用validation_curve:
import matplotlib.pyplot as plt import numpy as np from sklearn.datasets import load_digits from sklearn.svm import SVC from sklearn.learning_curve import validation_curve
validation_curve要看的是SVC()的超參數gamma,gamma的范圍是取 10^-6 到 10^-1 5 個值, 評分用的是metrics.accuracy_score的accuracy:
param_range = np.logspace(-6, -1, 5)
train_scores, test_scores = validation_curve( SVC(), X, y, param_name="gamma", param_range=param_range, cv=10, scoring="accuracy", n_jobs=1)
畫圖時,橫軸為param_range,縱軸為train_scores_mean,test_scores_mean:
plt.semilogx(param_range, train_scores_mean, label="Training score", color="r") plt.semilogx(param_range, test_scores_mean, label="Cross-validation score", color="g")