學習曲線就是經過畫出不一樣訓練集大小時訓練集和交叉驗證的準確率,能夠看到模型在新數據上的表現,進而來判斷模型是否方差偏高或誤差太高,以及增大訓練集是否能夠減少過擬合。python
當訓練集和測試集的偏差收斂但卻很高時,爲高誤差。
左上角的誤差很高,訓練集和驗證集的準確率都很低,極可能是欠擬合。
咱們能夠增長模型參數,好比,構建更多的特徵,減少正則項。
此時經過增長數據量是不起做用的。git
當訓練集和測試集的偏差之間有大的差距時,爲高方差。
當訓練集的準確率比其餘獨立數據集上的測試結果的準確率要高時,通常都是過擬合。
右上角方差很高,訓練集和驗證集的準確率相差太多,應該是過擬合。
咱們能夠增大訓練集,下降模型複雜度,增大正則項,或者經過特徵選擇減小特徵數。dom
理想狀況是是找到誤差和方差都很小的狀況,即收斂且偏差較小。學習
在畫學習曲線時,橫軸爲訓練樣本的數量,縱軸爲準確率。測試
例如一樣的問題,左圖爲咱們用 naive Bayes 分類器時,效果不太好,分數大約收斂在 0.85,此時增長數據對效果沒有幫助。spa
右圖爲 SVM(RBF kernel),訓練集的準確率很高,驗證集的也隨着數據量增長而增長,不過由於訓練集的仍是高於驗證集的,有點過擬合,因此仍是須要增長數據量,這時增長數據會對效果有幫助。.net
模型這裏用 GaussianNB 和 SVC 作比較,
模型選擇方法中須要用到 learning_curve 和交叉驗證方法 ShuffleSplit。code
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
首先定義畫出學習曲線的方法,
核心就是調用了 sklearn.model_selection 的 learning_curve,
學習曲線返回的是 train_sizes, train_scores, test_scores,
畫訓練集的曲線時,橫軸爲 train_sizes, 縱軸爲 train_scores_mean,
畫測試集的曲線時,橫軸爲 train_sizes, 縱軸爲 test_scores_mean:blog
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) ~~~
在調用 plot_learning_curve 時,首先定義交叉驗證 cv 和學習模型 estimator。get
這裏交叉驗證用的是 ShuffleSplit, 它首先將樣例打散,並隨機取 20% 的數據做爲測試集,這樣取出 100 次,最後返回的是 train_index, test_index,就知道哪些數據是 train,哪些數據是 test。
estimator 用的是 GaussianNB,對應左圖:
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 的時候,對應右圖:
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)