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取更高的話,那麼訓練數據集的誤差會更低。但是問題在於,測試數據集的誤差相對是比較大的,並且訓練數據集的誤差和測試數據集的誤差相差比較大(表現在圖上相差比較遠),這就說明了此時我們的模型的泛化能力不夠好,對新的數據來說誤差較大。