机器学习算法2-线性回归-多项式回归

Posted by Hilda on August 10, 2025

在多篇博客中已经提及了多项式回归:比如

机器学习算法2-线性回归-实战、岭回归、Lasso回归

这篇博客再做一些补充。


1.多项式回归

在做升维的时候,最常见的手段就是将已知维度进行相乘(或者自乘)来构建新的维度。普通线性方程, 无法拟合规律, 必须是多项式, 才可以完美拟合曲线规律。 对于多项式回归来说主要是为了扩展线性回归算法来适应更广泛的数据集, 比如我们数据集有两个维度x1、x2, 那么用多元线性回归公式就是: \(y=w_0+w_1x_1+w_2x_2\), 当我们使用二阶多项式升维的时候, 数据集就从原来的\(x_1\)、\(x_2\)扩展成了\(x_1\)、\(x_2\)、\(x_1^2\)、\(x_2^2\)、\(x_1x_2\), 因此多元线性回归就得去计算三个维度所对应的w值: \(y=w_0+w_1x_1+w_2x_2+w_3x_1^2+w_4x_2^2+w_5x_1x_2\), 此时拟合出来的方程就是曲线, 可以解决一些线性回归的欠拟合问题!

2.代码参考

演示多项式回归如何解决普通线性回归在处理非线性数据时的欠拟合问题,通过对原始数据进行“升维”来扩展特征,从而使线性模型能够拟合非线性的曲线。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression, Lasso
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline

# 1. 创建数据,并进行可视化
np.random.seed(42)  # 设置随机种子,保证结果可复现
X = np.linspace(-1, 11, num=100).reshape(-1, 1)
y = (X.flatten() - 5)**2 + 3*X.flatten() - 12 + np.random.randn(100) * 2

plt.figure(figsize=(10, 7))
plt.scatter(X, y, label='原始数据', alpha=0.7)

# 2. 创建预测数据
X_test = np.linspace(-2, 12, num=200).reshape(-1, 1)

# 3. 模型对比: 线性回归 vs 多项式回归 vs 带正则化的多项式回归

# 3.1 模型1: 普通线性回归 (未升维)
model_linear = LinearRegression()
model_linear.fit(X, y)
y_pred_linear = model_linear.predict(X_test)
plt.plot(X_test, y_pred_linear, color='red', linestyle='--', linewidth=2, label='普通线性回归')

# 3.2 模型2: 二次多项式回归 (升维)
# 使用PolynomialFeatures进行特征升维,再用LinearRegression拟合
poly = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly.fit_transform(X)
X_test_poly = poly.transform(X_test)

model_poly = LinearRegression()
model_poly.fit(X_poly, y)
y_pred_poly = model_poly.predict(X_test_poly)
plt.plot(X_test, y_pred_poly, color='green', linewidth=2, label='二次多项式回归')

# 3.3 模型3: 高阶多项式回归 + Lasso正则化
# 使用管道(pipeline)简化操作,将升维和模型训练打包
# 这里使用15次多项式模拟过拟合,并用Lasso进行正则化
pipeline_lasso = make_pipeline(
    PolynomialFeatures(degree=15, include_bias=False),
    Lasso(alpha=1, max_iter=10000) # alpha控制正则化强度,max_iter防止收敛问题
)
pipeline_lasso.fit(X, y)
y_pred_lasso = pipeline_lasso.predict(X_test)
plt.plot(X_test, y_pred_lasso, color='purple', linestyle='-', linewidth=2, label='Lasso (15阶多项式, alpha=1)')

# 4. 可视化设置
plt.title("不同回归模型的拟合效果对比", fontsize=16)
plt.xlabel("X", fontsize=12)
plt.ylabel("Y", fontsize=12)
plt.ylim(-15, 75)
plt.legend()
plt.grid(True)
plt.show()

image-20250810224241062

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.linear_model import SGDRegressor, LinearRegression, Ridge
from sklearn.pipeline import Pipeline

# 1、创建数据,并进行可视化
X = np.linspace(-1, 11, num=100)
y = (X - 5)**2 + 3*X - 12 + np.random.randn(100)
X = X.reshape(-1, 1)

# 2、创建预测数据
X_test = np.linspace(-2, 12, num=200).reshape(-1, 1)

# 3、定义需要对比的模型和管道
models_to_compare = [
    ('Linear Regression (Baseline)', LinearRegression(), None),
    ('PolynomialFeatures (d=2) with SGD', SGDRegressor(penalty='l2', eta0=0.01, max_iter=10000, tol=1e-3, early_stopping=True), PolynomialFeatures(degree=2)),
    ('PolynomialFeatures (d=3) with SGD', SGDRegressor(penalty='l2', eta0=0.01, max_iter=10000, tol=1e-3, early_stopping=True), PolynomialFeatures(degree=3)),
    ('PolynomialFeatures (d=2) with Ridge', Ridge(alpha=1.0), PolynomialFeatures(degree=2))
]

# 4、绘制原始数据
plt.figure(figsize=(10, 6))
plt.scatter(X, y, label='Original Data')

# 5、循环训练和预测
for name, model, feature_transformer in models_to_compare:
    if feature_transformer is not None:
        pipeline = Pipeline([
            ('features', feature_transformer),
            ('scaler', StandardScaler()),
            ('regressor', model)
        ])
    else:
        pipeline = Pipeline([
            ('scaler', StandardScaler()),
            ('regressor', model)
        ])
    
    pipeline.fit(X, y)
    y_test = pipeline.predict(X_test)
    plt.plot(X_test, y_test, label=name)

# 6、添加图例和标题
plt.title('Comparison of Different Learning Models')
plt.xlabel('X')
plt.ylabel('y')
plt.legend()
plt.grid(True)
plt.savefig('model_comparison.png')

image-20250812162516859