在逻辑回归正则化一文中,我们详细解释了正则化的原理及作用:当有很多个特征X时,有些特征往往不重要,所以需要降低其的权重。而正则化则是为每个特征修改权重从而提升训练效果。
正则化在线性回归中也是相同的原理,我们还记得正则化分成了两种:L1正则化和L2正则化,两者的区别就是L1将某些特征的权重设为了0,而L2中则以一个极小的权重保留了特征。
在线性回归中,添加正则化有具体的回归名称分别是:Lasso回归(L1)、岭回归(L2)和弹性网络回归(L1和L2中和)。
Lasso回归,即最小绝对收缩和选择算子,是另一种使用收缩的线性回归方法。Lasso过程鼓励简单、稀疏的模型(即,参数更少的模型)。
通过引入一个惩罚项到OLS方程,该惩罚项限制了系数绝对值的和:
Lasso回归
:
min
?
β
{
∑
i
=
1
n
(
y
i
?
∑
j
=
1
p
x
i
j
β
j
)
2
+
λ
∑
j
=
1
p
∣
β
j
∣
}
\text{Lasso回归} : \min_{\beta} \{ \sum_{i=1}^{n}(y_i - \sum_{j=1}^{p}x_{ij}\beta_j)^2 + \lambda\sum_{j=1}^{p}|\beta_j| \}
Lasso回归:βmin?{i=1∑n?(yi??j=1∑p?xij?βj?)2+λj=1∑p?∣βj?∣}
Lasso惩罚的效果是在调节参数
λ
\lambda
λ足够大时,强制某些系数估计值精确地为零。这意味着Lasso也可以进行变量选择,并能产生更易于解释的模型。
岭回归也被称为Tikhonov正则化,它是用于分析存在多重共线性的多元回归数据的技术。当存在多重共线性时,最小二乘估计是无偏的,但它们的方差很大,因此可能会远离真实值。通过对回归估计添加一定程度的偏差,岭回归可以减小标准误差。
岭回归的关键在于向普通最小二乘(OLS)方程添加一个惩罚项:
岭回归
:
min
?
β
{
∑
i
=
1
n
(
y
i
?
∑
j
=
1
p
x
i
j
β
j
)
2
+
λ
∑
j
=
1
p
β
j
2
}
\text{岭回归} : \min_{\beta} \{ \sum_{i=1}^{n}(y_i - \sum_{j=1}^{p}x_{ij}\beta_j)^2 + \lambda\sum_{j=1}^{p}\beta_j^2 \}
岭回归:βmin?{i=1∑n?(yi??j=1∑p?xij?βj?)2+λj=1∑p?βj2?}
这里, λ \lambda λ是调节参数,决定了我们希望对模型的灵活性进行多大程度的惩罚。当 λ \lambda λ的值越大时,缩减作用越强,因此系数对共线性的鲁棒性就越强。
弹性网络是岭回归和Lasso回归的折中。它在多个特征彼此相关时特别有用。
弹性网络旨在保持L2和L1惩罚项的正则化属性:
弹性网络
:
min
?
β
{
∑
i
=
1
n
(
y
i
?
∑
j
=
1
p
x
i
j
β
j
)
2
+
λ
1
∑
j
=
1
p
β
j
2
+
λ
2
∑
j
=
1
p
∣
β
j
∣
}
\text{弹性网络} : \min_{\beta} \{ \sum_{i=1}^{n}(y_i - \sum_{j=1}^{p}x_{ij}\beta_j)^2 + \lambda_1\sum_{j=1}^{p}\beta_j^2 + \lambda_2\sum_{j=1}^{p}|\beta_j| \}
弹性网络:βmin?{i=1∑n?(yi??j=1∑p?xij?βj?)2+λ1?j=1∑p?βj2?+λ2?j=1∑p?∣βj?∣}
该模型建立在L1和L2惩罚项之间的平衡之上,由
λ
1
\lambda_1
λ1?和
λ
2
\lambda_2
λ2?调节。这种平衡允许学习一个像Lasso那样的稀疏模型,同时还保持了岭回归的正则化属性。
这里整理一下三个回归的代码,数据使用天池工业蒸汽量预测,得分仅针对本数据参考,不代表算法优劣:
from sklearn.linear_model import Lasso
import numpy as np
# Load the datasets
train_data = pd.read_csv('zhengqi_train.txt', sep='\t')
test_data = pd.read_csv('zhengqi_test.txt', sep='\t')
# Split the training data into features and target
X_train = train_data.drop(columns=['target'])
y_train = train_data['target']
# 创建Lasso回归模型实例
lasso_model = Lasso(alpha=1.0) # alpha 参数就是λ
# 拟合模型
lasso_model.fit(X_train, y_train)
# 预测新数据
predictions = lasso_model.predict(test_data)
output_path = 'zhengqi_gb_predictions.txt'
pd.DataFrame(predictions).to_csv(output_path, index=False, header=False)
from sklearn.linear_model import Ridge
import numpy as np
# Load the datasets
train_data = pd.read_csv('zhengqi_train.txt', sep='\t')
test_data = pd.read_csv('zhengqi_test.txt', sep='\t')
# Split the training data into features and target
X_train = train_data.drop(columns=['target'])
y_train = train_data['target']
# 创建岭回归模型实例
ridge_model = Ridge(alpha=1.0) # alpha 参数就是λ
# 拟合模型
ridge_model.fit(X_train, y_train)
# 预测新数据
predictions = ridge_model.predict(test_data)
# Save the predictions to a text file
output_path = 'zhengqi_gb_predictions.txt'
pd.DataFrame(predictions).to_csv(output_path, index=False, header=False)
from sklearn.linear_model import ElasticNet
import numpy as np
# Load the datasets
train_data = pd.read_csv('zhengqi_train.txt', sep='\t')
test_data = pd.read_csv('zhengqi_test.txt', sep='\t')
# Split the training data into features and target
X_train = train_data.drop(columns=['target'])
y_train = train_data['target']
# 创建弹性网络回归模型实例
elastic_model = ElasticNet(alpha=1.0, l1_ratio=0.5) # alpha 参数是λ,l1_ratio 是 L1 正则化比例
# 拟合模型
elastic_model.fit(X_train, y_train)
# 预测新数据
predictions = elastic_model.predict(test_data)
output_path = 'zhengqi_gb_predictions.txt'
pd.DataFrame(predictions).to_csv(output_path, index=False, header=False)