學習曲線——判斷欠擬合還是過擬合

在機器學習領域,模型的欠擬合問題和過擬合問題一直都是我們關注的重點,正確的診斷出你的模型屬於哪一類問題對改善模型至關重要。

所謂欠擬合一般是指模型沒有很好的抓住數據的特徵,沒有對數據進行很好的擬合,使得偏差較大。這時一般要通過增加特徵項或者減少正則化參數來改進模型。

而過擬合一般是由於模型使用了太多的特徵引起的,使得模型將部分數據的“特性”也學習到了,導致模型的泛化能力較弱。這時一般要通過刪減特徵項或者增大正則化參數來改進模型。

本文通過單變量的線性迴歸來說明應該通過哪些操作來診斷模型是屬於欠擬合還是過擬合。

對於單變量的線性迴歸,我們最簡單的一個模型就是一次方程。我們的假設函數如下。


利用這個模型來擬合數據,繪製的擬合效果圖如下。


不難看出,這個模型對數據的擬合效果不好,我們可以直觀的判定這個模型存在欠擬合問題。但能不能通過什麼有效的方法判斷一個模型到底是存在欠擬合還是過擬合的問題呢。

答案是肯定的,我們可以繪製這個模型的學習曲線,通過學習曲線的形態來判斷。所謂學習曲線就是訓練集得分和驗證集得分隨着訓練樣本數的增大而變化的曲線。

當模型出現欠擬合和過擬合情況時,學習曲線一般有不同形狀,如下圖所示。


欠擬合情況:隨着訓練樣本數增大,訓練集得分和驗證集得分收斂,並且兩者的收斂值很接近。

過擬合情況隨着訓練樣本數增大,訓練集得分和驗證集得分相差還是很大。

下面利用sklearn包繪製單變量線性迴歸的Python代碼如下。

import scipy.io as sio
from sklearn.model_selection import learning_curve
from sklearn import linear_model
import matplotlib.pyplot as plt
import numpy as np

# 讀取以MATLAB矩陣存儲的數據集
data = sio.loadmat('data.mat')

X_train = data['X']
X_cv = data['Xval']
X_train = np.concatenate((X_train,X_cv),axis=0)

Y_train = data['y']
Y_cv = data['yval']
Y_train = np.concatenate((Y_train,Y_cv),axis=0)
Y_train = Y_train.reshape([1, len(Y_train)])[0]

reg = linear_model.Ridge(alpha=0)
train_sizes, train_scores, valid_scores = learning_curve(reg, X_train, Y_train, train_sizes=range(1,25,1), cv=4)
train_std=train_scores.mean(axis=1)
test_std=valid_scores.mean(axis=1)
plt.plot(train_sizes,train_std,color='red')
plt.plot(train_sizes,test_std,color='blue')
plt.xlabel('')
plt.show()

得到的學習曲線如下。


通過觀察學習曲線,可以判斷模型存在欠擬合問題。我們試着利用多項式迴歸來改進模型。此時模型的假設函數形式如下。


其中Xp=X1的p次方。

我們可以用p=1、2、...、8依次試探,但有什麼策略選出最好的p值嗎?答案是肯定的,我先給出如下一張圖。


這幅圖描繪的是訓練誤差和驗證誤差隨着多項式次數的增加而變化的圖。當d很小的時候,訓練誤差和驗證誤差都很大,並且很接近,此時模型存在欠擬合問題;當d較大時,訓練誤差很小,但驗證誤差還是很大,此時模型存在過擬合問題。我們要取中間較均衡的d作爲多項式的次數。

利用sklearn繪製的圖如下所示。

通過上圖的觀察,我們可以取3作爲多項式模型的次數。此時模型的擬合效果如下圖所示。

好了,本次的文章就寫到這裏了。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章