用學(xué)習(xí)曲線 learning curve 來判別過擬合問題

本文結(jié)構(gòu):

  • 學(xué)習(xí)曲線是什么?
  • 怎么解讀?
  • 怎么畫?

學(xué)習(xí)曲線是什么?

學(xué)習(xí)曲線就是通過畫出不同訓(xùn)練集大小時訓(xùn)練集和交叉驗證的準(zhǔn)確率,可以看到模型在新數(shù)據(jù)上的表現(xiàn),進(jìn)而來判斷模型是否方差偏高或偏差過高,以及增大訓(xùn)練集是否可以減小過擬合。


怎么解讀?

當(dāng)訓(xùn)練集和測試集的誤差收斂但卻很高時,為高偏差。
左上角的偏差很高,訓(xùn)練集和驗證集的準(zhǔn)確率都很低,很可能是欠擬合。
我們可以增加模型參數(shù),比如,構(gòu)建更多的特征,減小正則項。
此時通過增加數(shù)據(jù)量是不起作用的。

當(dāng)訓(xùn)練集和測試集的誤差之間有大的差距時,為高方差。
當(dāng)訓(xùn)練集的準(zhǔn)確率比其他獨立數(shù)據(jù)集上的測試結(jié)果的準(zhǔn)確率要高時,一般都是過擬合。
右上角方差很高,訓(xùn)練集和驗證集的準(zhǔn)確率相差太多,應(yīng)該是過擬合。
我們可以增大訓(xùn)練集,降低模型復(fù)雜度,增大正則項,或者通過特征選擇減少特征數(shù)。

理想情況是是找到偏差和方差都很小的情況,即收斂且誤差較小。


怎么畫?

在畫學(xué)習(xí)曲線時,橫軸為訓(xùn)練樣本的數(shù)量,縱軸為準(zhǔn)確率。

例如同樣的問題,左圖為我們用 naive Bayes 分類器時,效果不太好,分?jǐn)?shù)大約收斂在 0.85,此時增加數(shù)據(jù)對效果沒有幫助。

右圖為 SVM(RBF kernel),訓(xùn)練集的準(zhǔn)確率很高,驗證集的也隨著數(shù)據(jù)量增加而增加,不過因為訓(xùn)練集的還是高于驗證集的,有點過擬合,所以還是需要增加數(shù)據(jù)量,這時增加數(shù)據(jù)會對效果有幫助。


上圖的代碼如下:

模型這里用 GaussianNBSVC 做比較,
模型選擇方法中需要用到 learning_curve 和交叉驗證方法 ShuffleSplit

import numpy as np
import matplotlib.pyplot as plt

from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

from sklearn.datasets import load_digits
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit

首先定義畫出學(xué)習(xí)曲線的方法,
核心就是調(diào)用了 sklearn.model_selectionlearning_curve
學(xué)習(xí)曲線返回的是 train_sizes, train_scores, test_scores
畫訓(xùn)練集的曲線時,橫軸為 train_sizes, 縱軸為 train_scores_mean
畫測試集的曲線時,橫軸為 train_sizes, 縱軸為 test_scores_mean

def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,
                        n_jobs=1, train_sizes=np.linspace(.1, 1.0, 5)):
    ~~~
    train_sizes, train_scores, test_scores = learning_curve(
        estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
    train_scores_mean = np.mean(train_scores, axis=1)
    test_scores_mean = np.mean(test_scores, axis=1)  
    ~~~     

在調(diào)用 plot_learning_curve 時,首先定義交叉驗證 cv 和學(xué)習(xí)模型 estimator。

這里交叉驗證用的是 ShuffleSplit, 它首先將樣例打散,并隨機(jī)取 20% 的數(shù)據(jù)作為測試集,這樣取出 100 次,最后返回的是 train_index, test_index,就知道哪些數(shù)據(jù)是 train,哪些數(shù)據(jù)是 test。

estimator 用的是 GaussianNB,對應(yīng)左圖:

cv = ShuffleSplit(n_splits=100, test_size=0.2, random_state=0)
estimator = GaussianNB()
plot_learning_curve(estimator, title, X, y, ylim=(0.7, 1.01), cv=cv, n_jobs=4)

再看 estimator 是 SVC 的時候,對應(yīng)右圖:

cv = ShuffleSplit(n_splits=10, test_size=0.2, random_state=0)
estimator = SVC(gamma=0.001)
plot_learning_curve(estimator, title, X, y, (0.7, 1.01), cv=cv, n_jobs=4)

資料:
http://scikit-learn.org/stable/modules/learning_curve.html#learning-curve
http://scikit-learn.org/stable/auto_examples/model_selection/plot_learning_curve.html#sphx-glr-auto-examples-model-selection-plot-learning-curve-py


推薦閱讀 歷史技術(shù)博文鏈接匯總
http://www.lxweimin.com/p/28f02bb59fe5
也許可以找到你想要的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容