过拟合和欠拟合
欠拟合underfitting
算法所训练的模型不能完整的表述数据关系
高偏差,低方差
过拟合
算法所训练的模型过多地表达了数据间地噪音关系
低偏差,高方差。
模型的泛化能力
预测新的样本点的能力
测试模型的泛化能力,使用测试数据集
红线表明了,随着模型复杂度的提高,会出现由欠拟合到过拟合的变化
学习曲线
随着训练样本的逐渐增多,算法训练出的模型的表现能力
构造数据
In [118]: import numpy as np
...: import matplotlib.pyplot as plt
In [119]: np.random.seed(666)
...: x = np.random.uniform(-3.0,3.0,size=100)
...: X = x.reshape(-1,1)
...: y = 0.5 * x**2 + x + 2 + np.random.normal(0,1,size=100)
In [121]: from sklearn.model_selection import train_test_split
...: X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=666)
In [122]: X_train.shape
Out[122]: (75, 1)
绘制学习曲线
对于这75个数据,每次都多加入一些训练数据来训练我们的模型。
据此来观察我们得到的这个模型在训练数据集和测试数据集上的表现
最开始只给一个数据进行训练,每次训练一个模型。再逐渐增加
In [123]: 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))
In [124]: 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()
...:
下图说明,训练数据集的拟合误差小,但是泛化到测试数据集上,误差会增大
欠拟合
最佳拟合
下图是使用二阶多项式回归得到的学习曲线(degree=2)
整体趋势和线性回归差不多。但是二阶多项式回归稳定在1和0.9,说明二阶效果较好。
(degree=20)过拟合