機器學習 -- 多項式迴歸(Ⅳ 學習曲線)

1. 什麼是學習曲線?

隨着訓練樣本的逐漸增多,算法訓練出的模型的表現能力的變化情況。

 

2. 學習曲線的比較

(1)生成測試用例

import numpy as np
import matplotlib.pyplot as plt

x = np.random.uniform(-3, 3, size=100)
X = x.reshape(-1, 1)
# 一元二次方程
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)

圖像:

(2)劃分數據集

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=10)
X_train.shape
# (75, 1)

(3)繪製學習曲線

① 線性迴歸的學習曲線

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# 保存每次預測結果
train_score = []
test_score = []

# 每一次都實例化一個線性模型
for i in range(1, 76):
    lin_reg = LinearRegression()
    lin_reg.fit(X_train[:i], y_train[:i])
    
    y_train_predict = lin_reg.predict(X_train[:i])
    train_score.append(mean_squared_error(y_train[:i], y_train_predict))
    
    y_test_predict = lin_reg.predict(X_test)
    test_score.append(mean_squared_error(y_test, y_test_predict))

繪製圖像(橫軸爲訓練數據集大小,縱軸爲均方根誤差):

plt.plot([i for i in range(1, 76)], np.sqrt(train_score), label="train")
plt.plot([i for i in range(1, 76)], np.sqrt(test_score), label="test")
plt.legend()
plt.show()

趨勢:

(1)在訓練數據集上,誤差是逐漸升高的。這是因爲我們的訓練數據越來越多,我們的數據點越難得到全部的累積,不過整體而言,在剛開始的時候誤差變化的比較快,後來就幾乎不變了。
(2)在測試數據集上,在使用非常少的樣本進行訓練的時候,剛開始我們的測試誤差非常的大,當訓練樣本大到一定程度後,我們的測試誤差就會逐漸減小,減小到一定程度後,也不會小太多,達到一種相對穩定的情況。
(3)在最終,測試誤差和訓練誤差趨於相等,不過測試誤差還是高於訓練誤差一些,這是因爲,訓練數據在數據非常多的情況下,可以將數據擬合的比較好,誤差小一些,但是泛化到測試數據集的時候,還是有可能多一些誤差。

 

提取繪製學習曲線的函數:

def plot_learning_curve(algo, X_train, X_test, y_train, y_test): #algo代表不同算法
    train_score = []
    test_score = []
    for i in range(1,len(X_train)+1):
        algo.fit(X_train[:i],y_train[:i])
        
        y_train_predict = algo.predict(X_train[:i])
        train_score.append(mean_squared_error(y_train_predict, y_train[:i]))
        
        y_test_predict = algo.predict(X_test)
        test_score.append(mean_squared_error(y_test_predict, y_test))
        
    plt.plot([i for i in range(1, 76)], np.sqrt(test_score), label='train')
    plt.plot([i for i in range(1, 76)], np.sqrt(train_score), label='test')
    plt.legend()
    plt.axis([0, len(X_train) + 1, 0, 4])  # 縮小y軸顯示的範圍
    plt.show()

線性迴歸法調用此函數:

plot_learning_curve(LinearRegression(), X_train, X_test, y_train, y_test)

② 多項式迴歸學習曲線

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
def PolynomialRegression(degree):
    return Pipeline([
        ("poly",PolynomialFeatures(degree=degree)),
        ("std_scaler",StandardScaler()),
        ("lin_reg",LinearRegression())
    ])    


poly2_reg = PolynomialRegression(degree=2)
plot_learning_curve(poly2_reg, X_train, X_test, y_train,y_test)  # 穩定性比線性迴歸低

趨勢:首先整體從趨勢上,和線性迴歸的學習曲線是類似的。仔細觀察,多項式迴歸和線性迴歸曲線的不同在於,線性迴歸的學習曲線誤差穩定在1.7,1.8左右,而2階多項式迴歸穩定在了1.0左右,所以2階多項式穩定的誤差比較低,說明使用二階線性迴歸的性能是比較好的。

若使用20階多項式迴歸:

# 使用20階多項式迴歸
poly20_reg = PolynomialRegression(20)
plot_learning_curve(poly20_reg, X_train, X_test, y_train, y_test)

在使用20階多項式迴歸訓練模型的時候可以發現,在數據量偏多的時候,我們的訓練數據集擬合的是比較好的,但是測試數據集的誤差相對來說增大了很多,離訓練數據集比較遠,通常這就是過擬合的結果,泛化能力是不夠的。

 

3. 總結比較

(1)欠擬合曲線與最佳曲線

        對於欠擬合曲線比最佳的情況趨於穩定的那個位置要高一些,說明無論對於訓練數據集還是測試數據集來說,誤差都比較大。這是因爲我們本身模型選的就不對,所以即使在訓練數據集上,他的誤差也是大的,所以纔會呈現出這樣的一種形態。

 

(2)過擬合曲線與最佳曲線

        對於過擬合的情況,在訓練數據集上,他的誤差不大,和最佳的情況是差不多的,甚至在極端情況,如果degree取更高的話,那麼訓練數據集的誤差會更低。但是問題在於,測試數據集的誤差相對是比較大的,並且訓練數據集的誤差和測試數據集的誤差相差比較大(表現在圖上相差比較遠),這就說明了此時我們的模型的泛化能力不夠好,對新的數據來說誤差較大。

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