2026-02-24 08:20:53

Elastic-Net是一种结合了L1和L2正则化的线性回归模型。它的目标是最小化一个损失函数,这个损失函数由三部分组成:

均方误差项:$$(\frac{1}{2n_{samples}})

Xw - y

^2$$,这部分是普通的线性回归损失,用于衡量模型的预测值与真实值之间的差异。

L1正则化项:$$αρ

w

_1$$,这部分是Lasso回归的惩罚项。它倾向于使一些系数变为零,从而实现特征选择,使模型变得稀疏。

L2正则化项:$$(α(1-ρ)/2)

w

_2^2$$,这部分是岭回归的惩罚项。它倾向于使所有系数都接近于零,以防止过拟合,但不会使系数完全变为零。

在scikit-learn中,ElasticNet的参数alpha对应于公式中的α,控制整体的惩罚力度。参数l1_ratio对应于公式中的ρ,它是一个介于0和1之间的混合比率。

当l1_ratio为0时,模型退化为纯L2正则化,即岭回归(Ridge)。

当l1_ratio为1时,模型退化为纯L1正则化,即Lasso回归。

当l1_ratio介于0和1之间时,它结合了Lasso和岭回归的优点,特别适用于特征之间存在高度相关性的情况。

1.代码模拟训练与不同模型对比

【1】导包,生成真实数据:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

import numpy as np

from sklearn.linear_model import ElasticNet, LinearRegression, Lasso

import matplotlib.pyplot as plt

np.random.seed(42)

n_samples, n_features = 100, 50

X = np.random.randn(n_samples, n_features)

# 引入相关性:让前两个特征线性相关

X[:,0] = X[:,1] * 2 + np.random.randn(n_samples) * 0.1

# 真实的稀疏的系数

true_w = np.zeros(n_features)

true_w[:5] = np.array([10, -5, 3, 2, -1]) # 只有前5个特征系数非零

true_b = 5

y = X.dot(true_w) + true_b + np.random.randn(n_samples) * 2

print(f"真实的系数数量:{np.count_nonzero(true_w)}")

【2】模型训练与比较

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

from sklearn.metrics import mean_squared_error

models = {

"普通线性回归": LinearRegression(),

"Lasso(alpha=0.1)": Lasso(alpha=0.1),

"Elastic Net(alpha=0.1,l1_ratio=0.7)": ElasticNet(alpha=0.1, l1_ratio=0.7)

}

coef_df = {

"真实系数":true_w

}

mse_results = {}

for name, model in models.items():

model.fit(X, y)

coef_df[name] = model.coef_

y_pred = model.predict(X)

mse = mean_squared_error(y, y_pred)

mse_results[name] = mse

print(f"- {name} : 均方误差(MSE)={mse:.2f}")

print(f"- 学到的非零系数的数量:{np.count_nonzero(model.coef_):.0f}")

【3】可视化

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

plt.figure(figsize=(15, 8))

x_axis = np.arange(n_features)

width = 0.2

plt.bar(x_axis - 1.5*width, coef_df['真实系数'], width, label='真实系数', color='black')

plt.bar(x_axis - 0.5*width, coef_df['普通线性回归'], width, label='普通线性回归', color='skyblue')

plt.bar(x_axis + 0.5*width, coef_df['Lasso(alpha=0.1)'], width, label='Lasso (alpha=0.1)', color='salmon')

plt.bar(x_axis + 1.5*width, coef_df['Elastic Net(alpha=0.1,l1_ratio=0.7)'], width, label='Elastic-Net (alpha=0.1, l1_ratio=0.7)', color='lightgreen')

plt.title("不同模型学习到的系数与真实系数对比", fontsize=16)

plt.xlabel("特征索引", fontsize=12)

plt.ylabel("系数大小", fontsize=12)

plt.legend()

plt.grid(axis='y', linestyle='--', alpha=0.7)

plt.tight_layout()

plt.show()

真实系数:只有前5个特征有非零值,其余都为0。

普通线性回归:由于没有正则化,模型会为所有50个特征都计算出一个系数,其中一些可能是由噪声或特征相关性引起的,与真实系数有较大偏差。

Lasso回归:由于L1正则化,Lasso会倾向于将许多不重要的特征系数压缩为0,因此其非零系数的数量会显著减少,更接近真实的稀疏结构。

Elastic-Net回归:由于结合了L1和L2正则化,它也会将许多不重要的系数设为0,其表现会介于普通线性回归和Lasso之间,并且在处理相关特征时可能比Lasso更稳定。

Previous

机器学习算法2-线性回归-梯度下降原理

Next

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