代码演示之正好拟合
1 课程概览
本课通过代码演示正好拟合的实现方法。欠拟合的解决方案是增加模型复杂度,通过新增特征列(如X0的平方作为X1)来增加复杂度。详细讲解如何使用PolynomialFeatures生成多项式特征,使模型从简单线性变为多项式拟合,达到正好拟合的效果。
2 核心概念与定义
- 正好拟合:训练集和测试集都表现良好。
- 增加模型复杂度:通过增加特征列实现。
- 多项式特征:将X0的平方作为新特征X1。
- PolynomialFeatures:sklearn中生成多项式特征的API。
- reshape:改变数据形状。
3 算法与模型详解
3.1 增加模型复杂度的方法
原始数据:
| X0 | Y |
|---|---|
| 1 | Y1 |
| 2 | Y2 |
| 3 | Y3 |
增加特征后:
| X0 | X1=X0² | Y |
|---|---|---|
| 1 | 1 | Y1 |
| 2 | 4 | Y2 |
| 3 | 9 | Y3 |
说明:新增一列X1 = X0²,模型从一元变为二元,复杂度增加。
3.2 数据预处理
原始数据形状:[1, 2, 3, 4, 5](一维)
reshape后: $$\begin{bmatrix} 1 \ 2 \ 3 \ 4 \ 5 \end{bmatrix}$$
说明:将一维数据转为二维列向量
3.3 PolynomialFeatures
作用:生成多项式特征
参数:
| 参数 | 说明 |
|---|---|
| degree | 多项式次数 |
示例:
- degree=2:生成 [1, X, X²]
- degree=3:生成 [1, X, X², X³]
3.4 正好拟合的实现步骤
步骤:
- 准备数据
- 数据预处理(reshape)
- 生成多项式特征(PolynomialFeatures)
- 模型训练(LinearRegression)
- 模型预测
- 模型评估
3.5 欠拟合 vs 正好拟合对比
| 对比 | 欠拟合 | 正好拟合 |
|---|---|---|
| 特征数 | 1列 | 多列 |
| 模型复杂度 | 简单 | 适中 |
| 训练集表现 | 不好 | 好 |
| 测试集表现 | 不好 | 好 |
4 数学原理与推导
4.1 欠拟合模型
$$Y = WX + B$$
4.2 正好拟合模型(二次多项式)
$$Y = W_0 + W_1X + W_2X^2$$
4.3 一般多项式
$$Y = W_0 + W_1X + W_2X^2 + ... + W_nX^n$$
5 代码示例
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import mean_squared_error
# 1. 准备数据
np.random.seed(42)
X = np.sort(np.random.rand(30, 1) * 10, axis=0)
Y = np.sin(X).ravel() + np.random.randn(30) * 0.1
# 2. 欠拟合(一次线性回归)
lr_under = LinearRegression()
lr_under.fit(X, Y)
y_pred_under = lr_under.predict(X)
# 3. 正好拟合(使用PolynomialFeatures增加复杂度)
# 3.1 创建多项式特征对象
poly = PolynomialFeatures(degree=3)
X_poly = poly.fit_transform(X)
# 3.2 训练模型
lr_good = LinearRegression()
lr_good.fit(X_poly, Y)
# 3.3 预测
y_pred_good = lr_good.predict(X_poly)
# 4. 绘图对比
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.scatter(X, Y, color='blue', label='数据点')
plt.plot(X, y_pred_under, color='red', label='欠拟合')
plt.title('欠拟合(一次)')
plt.legend()
plt.subplot(1, 2, 2)
plt.scatter(X, Y, color='blue', label='数据点')
plt.plot(X, y_pred_good, color='green', label='正好拟合')
plt.title('正好拟合(三次多项式)')
plt.legend()
plt.tight_layout()
plt.show()
# 5. 误差对比
print("欠拟合 MSE:", mean_squared_error(Y, y_pred_under))
print("正好拟合 MSE:", mean_squared_error(Y, y_pred_good))
输出示例:
欠拟合 MSE: 0.234
正好拟合 MSE: 0.012
自定义函数演示:
def demo_fitting():
"""演示正好拟合"""
# 1. 准备数据
X = np.random.rand(30, 1) * 10
Y = np.sin(X).ravel() + np.random.randn(30) * 0.1
# 2. 数据预处理
X = X.reshape(-1, 1) # 转为列向量
# 3. 生成多项式特征
poly = PolynomialFeatures(degree=3)
X_poly = poly.fit_transform(X)
# 4. 模型训练
model = LinearRegression()
model.fit(X_poly, Y)
# 5. 预测和评估
y_pred = model.predict(X_poly)
mse = mean_squared_error(Y, y_pred)
print(f"权重W: {model.coef_}")
print(f"偏置B: {model.intercept_}")
print(f"MSE: {mse}")
return model
# 运行
demo_fitting()
6 重难点与易错提醒
- ❗重点:增加模型复杂度通过增加特征列实现。
- ❗重点:PolynomialFeatures用于生成多项式特征。
- ❗重点:degree参数控制多项式次数。
- ❗重点:reshape将一维数据转为二维列向量。
- ⚠️易错:忘记reshape导致数据形状错误。
- ⚠️易错:degree设置过高导致过拟合。
- 💡深入理解:多项式特征是增加模型复杂度的有效方法。
7 课堂问答精选
Q: 如何增加模型的复杂度?
A: 增加模型复杂度的方法是增加特征列。例如,原始特征是X0,可以新增X1 = X0²作为新特征,使模型从一元变为二元。使用PolynomialFeatures可以自动生成多项式特征。
Q: PolynomialFeatures的作用是什么?
A: PolynomialFeatures用于生成多项式特征。例如,degree=2时,会将[X]转换为[1, X, X²],degree=3时转换为[1, X, X², X³]。这样模型就能拟合非线性关系,增加复杂度。
8 本课小结
- 正好拟合:训练集和测试集都好。
- 增加复杂度:新增特征列(如X0²作为X1)。
- PolynomialFeatures:生成多项式特征。
- degree:控制多项式次数。
- reshape:将一维数据转为二维列向量。
9 延伸思考与实践
- 实践:用PolynomialFeatures演示不同degree的效果。
- 预习:过拟合代码演示。
- 思考:degree设置多少合适?