正则化(Regularization)
- 概念及原因
正则化是一种为了减小测试误差的行为(有时候会增加训练误差)。在构造机器学习模型时,最终目的是让模型在面对新数据的时候,可以有很好的表现。但是当使用比较复杂的模型比如神经网络,去拟合数据时,很容易出现过拟合现象(训练集表现很好,测试集表现较差),这会导致模型的泛化能力下降,这时候,我们就需要使用正则化,降低模型的复杂度。
- 正则化代价函数
L1正则化:
J
(
θ
)
=
1
2
m
[
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
2
+
λ
∑
j
=
1
n
∣
θ
j
∣
]
J(\theta)=\frac{1}{2 m}\left[\sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right)^{2}+\lambda \sum_{j=1}^{n}\left|\theta_{j}\right|\right]
J(θ)=2m1[i=1∑m(hθ(x(i))−y(i))2+λj=1∑n∣θj∣]
L2正则化:
J ( θ ) = 1 2 m [ ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 + λ ∑ j = 1 n θ j 2 ] J(\theta)=\frac{1}{2 m}\left[\sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right)^{2}+\lambda \sum_{j=1}^{n} \theta_{j}^{2}\right] J(θ)=2m1[i=1∑m(hθ(x(i))−y(i))2+λj=1∑nθj2]
岭回归(Ridge Regression)
- 概念及原理
在线性回归模型中,关于最小二乘估计法得到的参数 w = ( X T X ) − 1 X T y \mathrm{w}=\left(X^{T} X\right)^{-1} X^{T} \mathrm{y} w=(XTX)−1XTy 当 X T X X^{T} X XTX不可逆时则无法求出相应的系数,并且如果 ∣ X T X ∣ |X^{T} X| ∣XTX∣趋近0时候会使得回归系数趋向于无穷大,此时得到的回归系数是无意义的。解决这类问题可以使用岭回归和LASSO回归。
其中岭回归的公式如下:
w
=
(
X
T
X
+
λ
I
)
−
1
X
T
y
\mathrm{w}=\left(X^{T} X+\lambda I\right)^{-1} X^{T} \mathrm{y}
w=(XTX+λI)−1XTy
λ
\lambda
λ为岭系数, I 为单位矩阵(对角线上全为1 , 其他元素全为 0 )
- 参数推导
线性回归模型的目标函数
J
(
θ
)
=
1
2
∑
i
=
1
n
(
h
θ
(
x
i
)
−
y
i
)
2
J(\theta)=\frac{1}{2} \sum_{i=1}^{n}\left(h_{\theta}\left(x_{i}\right)-y_{i}\right)^{2}
J(θ)=21i=1∑n(hθ(xi)−yi)2
为了保证回归系数可求,岭回归模型在目标函数上加了一个L2范数的惩罚项
J ( θ ) = 1 2 ∑ i = 1 n ( h θ ( x i ) − y i ) 2 + λ ∑ i n θ i 2 J ( θ ) = 1 2 ( X θ − Y ) T ( X θ − Y ) + λ θ T θ = 1 2 ( θ T X T X θ − θ T X T Y − Y T X θ + Y T Y ) + λ θ T θ ∂ J ( θ ) ∂ θ = X T X θ − X T Y + λ θ θ = ( X T X + λ I ) − 1 X T Y \begin{aligned} J(\theta) &=\frac{1}{2} \sum_{i=1}^{n}\left(h_{\theta}\left(x_{i}\right)-y_{i}\right)^{2}+\lambda \sum_{i}^{n} \theta_{i}^{2} \\ J(\theta) &=\frac{1}{2}(X \theta-Y)^{T}(X \theta-Y)+\lambda \theta^{T} \theta \\ &=\frac{1}{2}\left(\theta^{T} X^{T} X \theta-\theta^{T} X^{T} Y-Y^{T} X \theta+Y^{T} Y\right)+\lambda \theta^{T} \theta \\ \frac{\partial J(\theta)}{\partial \theta} &=X^{T} X \theta-X^{T} Y+\lambda \theta \\ \theta &=\left(X^{T} X+\lambda I\right)^{-1} X^{T} Y \end{aligned} J(θ)J(θ)∂θ∂J(θ)θ=21i=1∑n(hθ(xi)−yi)2+λi∑nθi2=21(Xθ−Y)T(Xθ−Y)+λθTθ=21(θTXTXθ−θTXTY−YTXθ+YTY)+λθTθ=XTXθ−XTY+λθ=(XTX+λI)−1XTY
- λ的选择 此部分转载传送门
选择λ值,使得:
1.各回归系数的岭估计基本稳定。
2.残差平方和增大不太多。
随着模型复杂度的提升,在训练集上的效果就越好,即模型的偏差就越小;但是同时模型的方差就越大。对于岭回归的λ而言,随着λ的增大,
∣
X
T
X
+
λ
I
∣
\left|X^{T} X+\lambda I\right|
∣∣XTX+λI∣∣就越大,,
(
X
T
X
+
λ
I
)
−
1
\left(X^{T} X+\lambda I\right)^{-1}
(XTX+λI)−1
就越小,模型的方差就越小;而λ越大使得β的估计值更加偏离真实值,模型的偏差就越大。所以岭回归的关键是找到一个合理的λλ值来平衡模型的方差和偏差。
根据凸优化,可以将岭回归模型的目标函数J(β)J(β)最小化问题等价于:
{
argmin
{
∑
(
y
−
X
β
2
)
}
∑
β
2
≤
t
\left\{\begin{array}{l} \operatorname{argmin}\left\{\sum\left(y-X \beta^{2}\right)\right\} \\ \sum \beta^{2} \leq t \end{array}\right.
{argmin{∑(y−Xβ2)}∑β2≤t
其中t为一个常数。以最简单的二维为例,即
β
(
β
1
,
β
2
)
\beta\left(\beta_{1}, \beta_{2}\right)
β(β1,β2)其几何图形是:
(1)岭迹法确定λ值(定性)
由 β = ( X T X + λ I ) − 1 X T y \beta=\left(X^{T} X+\lambda I\right)^{-1} X^{T} y β=(XTX+λI)−1XTy 可知β是λ的函数,当 λ ∈ [ 0 , ∞ ) \lambda \in[0, \infty) λ∈[0,∞)时,在平面直角坐标系中的β−λ曲线称为岭迹曲线。当β趋于稳定的点就是所要寻找的λ值。
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import Ridge
import matplotlib.pyplot as plt
data=pd.read_excel(r'C:\Users\Administrator\Desktop\diabetes.xlsx')
#拆分为训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,
test_size=0.2,random_state=1234)
#构造不同的lambda值
Lambdas=np.logspace(-5,2,200)
#存放偏回归系数
ridge_cofficients=[]
for Lambda in Lambdas:
ridge=Ridge(alpha=Lambda,normalize=True)
ridge.fit(x_train,y_train)
ridge_cofficients.append(ridge.coef_)
#绘制岭迹曲线
plt.rcParams['font.sans-serif']=['Microsoft YaHei']
plt.rcParams['axes.unicode_minus']=False
plt.style.use('ggplot')
plt.plot(Lambdas,ridge_cofficients)
#x轴做对数处理
plt.xscale('log')
plt.xlabel('Log(Lambda)')
plt.ylabel('Cofficients')
plt.show()
(2)交叉验证法确定λλ值
交叉验证法的思想是,将数据集拆分为k个数据组(每组样本量大体相当),从k组中挑选k-1组用于模型的训练,剩下的1组用于模型的测试,则会有k-1个训练集和测试集配对,每一种训练集和测试集下都会有对应的一个模型及模型评分(如均方误差),进而可以得到一个平均评分。对于λλ值则选择平均评分最优的λ值。
RidgeCV(alphas=(0.1, 1.0, 10.0), fit_intercept=True, normalize=False, scoring=None, cv=None, gcv_mode=None, store_cv_values=False)
• lambdas:用于指定多个λλ值的元组或数组对象,默认包含0.1,1,10三种值。
• fit_intercept:bool类型,是否需要拟合截距项,默认为True。
• normalize:bool类型,建模时是否对数据集做标准化处理,默认为False。
• scoring:指定用于模型评估的度量方法。
• cv:指定交叉验证的重数。
• gcv_mode:指定广义交叉验证的方法。
• store_cv_values:bool类型,是否保存每个λλ下交叉验证的评估信息,默认为False,只有cv为None时有效。
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import RidgeCV
data=pd.read_excel(r'C:\Users\Administrator\Desktop\diabetes.xlsx')
#拆分为训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,
test_size=0.2,random_state=1234)
#构造不同的lambda值
Lambdas=np.logspace(-5,2,200)
#设置交叉验证的参数,使用均方误差评估
ridge_cv=RidgeCV(alphas=Lambdas,normalize=True,scoring='neg_mean_squared_error',cv=10)
ridge_cv.fit(x_train,y_train)
print(ridge_cv.alpha_)