线性回归linear regression
1.普通的最小二乘法
LinearRegression 拟合一个带有系数
w
=
(
w
1
,
w
2
,
.
.
.
,
w
n
)
w=(w_1,w_2,...,w_n)
w=(w1,w2,...,wn)的线性模型,使得数据集实际观测数据和预测数据(估计值)之间的残差平方和最小。其数学表达式为:
m
i
n
w
=
∣
∣
X
w
−
y
∣
∣
2
min_{w}=||Xw-y||^2
minw=∣∣Xw−y∣∣2
复杂度:
该方法使用 X 的奇异值分解来计算最小二乘解。如果
X
X
X 是一个 size 为
(
n
,
p
)
(n, p)
(n,p) 的矩阵,设
n
≥
p
n \geq p
n≥p,则该方法的复杂度为
O
(
n
p
2
)
O(np^2)
O(np2)
python 代码:
lr = linear_model.LinearRegression()
x = [[1], [4], [5], [7], [8]]
y = [1.002, 4.1, 4.96, 6.78, 8.2]
lr.fit(x, y)
k = lr.coef_ # 各个系数
b = lr.intercept_ # 求截距
print(k, b)
x0 = np.arange(0, 10, 0.2)
y0 = k * x0 + b
plt.scatter(x, y)
plt.plot(x0, y0)
plt.show()
2. L1正则化/Lasso回归
L
1
L1
L1正则化将系数
w
w
w的
L
1
L1
L1范数作为惩罚项加到损失函数上,由于正则项非零,这就迫使那些弱的特征所对应的系数变成0。因此
L
1
L1
L1正则化往往会使学到的模型很稀疏(系数
w
w
w经常为0),这个特性使得L1正则化成为一种很好的特征选择方法。
Lasso回归于岭回归非常相似,它们的差别在于使用了不同的正则化项。最终都实现了约束参数从而防止过拟合的效果。但是Lasso之所以重要,还有另一个原因是:Lasso能够将一些作用比较小的特征的参数训练为0,从而获得稀疏解。也就是说用这种方法,在训练模型的过程中实现了降维(特征筛选)的目的。
Lasso回归的代价函数为:
J
(
θ
)
=
1
2
m
∑
i
=
1
n
(
y
(
i
)
−
(
w
x
(
i
)
+
b
)
)
2
+
λ
∣
∣
w
∣
∣
1
=
1
2
M
S
E
(
θ
)
+
λ
∑
i
=
1
n
∣
θ
i
∣
(
2.1
)
J(\theta)=\frac{1}{2m}\sum_{i=1}^n (y^{(i)}-(wx^{(i)}+b))^2+\lambda||w||_1=\frac{1}{2}MSE(\theta)+\lambda\sum_{i=1}^n|\theta_i| \text{ }\text{ }\text{ }\text{ }(2.1)
J(θ)=2m1i=1∑n(y(i)−(wx(i)+b))2+λ∣∣w∣∣1=21MSE(θ)+λi=1∑n∣θi∣ (2.1)
上式中的
w
w
w是长度为
n
n
n的向量,不包括截距项的系数
θ
0
θ_0
θ0,
θ
θ
θ是长度为
n
+
1
n+1
n+1的向量,包括截距项的系数
θ
0
θ_0
θ0,
m
m
m为样本数,
n
n
n为特征数,
∣
∣
w
∣
∣
1
||w||_1
∣∣w∣∣1表示参数
w
w
w的
l
1
l_1
l1范数,也是一种表示距离的函数。假设
w
w
w表示3维空间中的一个点
(
x
,
y
,
z
)
(x,y,z)
(x,y,z),那么
∣
∣
w
∣
∣
1
=
∣
x
∣
+
∣
y
∣
+
∣
z
∣
||w||_1=|x|+|y|+|z|
∣∣w∣∣1=∣x∣+∣y∣+∣z∣,即各个方向上的绝对值(长度)之和。
式子2−1的梯度为:
∇
θ
M
S
E
(
θ
)
+
λ
(
s
i
g
n
(
θ
1
)
s
i
g
n
(
θ
2
)
.
.
.
s
i
g
n
(
θ
n
)
)
\nabla_\theta MSE(θ)+\lambda \left( \begin{matrix} sign(\theta_1)\\ sign(\theta_2) \\ . \\ .\\.\\ sign(\theta_n) \end{matrix} \right)
∇θMSE(θ)+λ⎝⎜⎜⎜⎜⎜⎜⎛sign(θ1)sign(θ2)...sign(θn)⎠⎟⎟⎟⎟⎟⎟⎞
其中 s i g n ( θ i ) sign(\theta_i) sign(θi)由 θ i > 0 , s i g n ( θ i ) = 1 ; θ i = 0 , s i g n ( θ i ) = 0 ; θ i < 0 , s i g n ( θ i ) = − 1 \theta_i>0, sign(\theta_i)=1;\theta_i=0, sign(\theta_i)=0;\theta_i<0, sign(\theta_i)=-1 θi>0,sign(θi)=1;θi=0,sign(θi)=0;θi<0,sign(θi)=−1
2.1.Lasso回归解法
Lasso 回归主要的解法有两种:坐标轴下降法(coordinate descent)和最小角回归法( Least Angle Regression)。
2.1.1.坐标轴下降法
坐标下降优化方法是一种非梯度优化算法。为了找到一个函数的局部极小值,在每次迭代中可以在当前点处沿一个坐标方向进行一维搜索。在整个过程中循环使用不同的坐标方向。一个周期的一维搜索迭代过程相当于一个梯度迭代。 其实,gradient descent 方法是利用目标函数的导数(梯度)来确定搜索方向的,而该梯度方向可能不与任何坐标轴平行。而coordinate descent方法是利用当前坐标系统进行搜索,不需要求目标函数的导数,只按照某一坐标方向进行搜索最小值。坐标下降法在稀疏矩阵上的计算速度非常快,同时也是Lasso回归最快的解法。
reg = linear_model.Lasso(alpha=0.1)
reg.fit([[0, 0], [1, 1]], [0, 1])
k = reg.coef_
b = reg.intercept_
arr = reg.predict([[1, 1]])
print(k, b, arr)
或者
alphas, active, coef_path_lars = linear_model.lars_path(X, y, method='lasso')
2.1.2.最小角回归法
在阐述最小角回归( Least Angle Regression)算法之前,这里需要对两种更为简单直观的前向(Forward)算法做一些说明,最小回归算法是以这两种前向算法为基础的:
前向选择算法
前向选择(Forward Selection)算法,是一种典型的贪心算法。它在自变量
x
i
,
i
∈
[
1
,
N
]
xi,i∈[1,N]
xi,i∈[1,N]中,选择和目标
y
y
y最为接近的一个自变量
x
k
x_k
xk,用
x
k
x_k
xk来逼近
y
y
y,得到
y
~
=
β
k
x
k
\tilde{y}= \beta_k x_k
y~=βkxk
其中:
β
k
=
<
x
k
,
y
>
∣
∣
x
k
∣
∣
2
\beta_k= \dfrac{<x_k,y>}{||x_k||_2}
βk=∣∣xk∣∣2<xk,y>
即:
y
~
\tilde{y}
y~是
y
y
y在
x
k
x_k
xk上的投影。那么,可以定义残差(residual):
y
r
e
s
=
y
−
y
~
y_{res}=y-\tilde{y}
yres=y−y~
很容易知道
y
r
e
s
y_{res}
yres和
x
k
x_k
xk是正交的。再以
y
r
e
s
y_{res}
yres为新的因变量,除去
x
k
x_k
xk后,剩下的自变量的集合
x
i
,
i
=
1
,
2
,
3...
k
−
1
,
k
+
1
,
.
.
.
N
{x_i,i=1,2,3...k−1,k+1,...N}
xi,i=1,2,3...k−1,k+1,...N为新的自变量集合,重复刚才投影和残差的操作,直到残差为0,或者所有的自变量都用完了,才停止算法。
此算法对每个变量只需要执行一次操作,效率高,速度快。但也容易看出,当自变量不是正交的时候,由于每次都是在做投影,所有算法只能给出最优解的一个近似解。
前向梯度算法
前向梯度(Forward Stagewise)和前向选择算法类似,也是每次取相关性最大的一个特征
x
k
x_k
xk,然后用xk逼近目标y。但与之不同的是,前向梯度算法的残差并不是直接使用投影得到的,其计算方式为:
y
r
e
s
=
y
−
ϵ
x
k
y_{res}=y- \epsilon x_k
yres=y−ϵxk
然后和前向选择算法一样,使用
y
r
e
s
y_{res}
yres为新的目标,但是不将
x
k
x_k
xk从自变量的集合中剔除出去,因为
x
k
x_{k}
xk的相关度可能仍然是最高的。如此进行下去,直到
y
r
e
s
y_{res}
yres减小到一定的范围,算法停止。
这个算法在
ϵ
\epsilon
ϵ很小的时候,可以很精确的给出最优解,当然,其计算复杂度也随之增加。
最小角回归
计算机领域的很多算法的提出都是这样:先给出两种算法,一种是速度快的,精度低;另一种是精度高的,太复杂。于是计算机领域中,就会出现一个结合前两个算法的第三个算法,是前两种算法的折中,其速度不算特别慢,精度也还不错。在本文,下面就要提出最小角回归(Least Angle Regression)。
LARS算法是结合前两种前向算法(前向选择算法和前向梯度算法)所得到的。
首先,还是找到与因变量
y
y
y相关度最高的自变量
x
k
x_k
xk,使用类似于前向梯度算法中的残差计算方法,得到新的目标
y
r
e
s
y_{res}
yres,重复这个过程。直到出现一个
x
l
x_l
xl,使得
x
l
x_l
xl和
y
r
e
s
y_{res}
yres的相关度和
x
k
x_k
xk与
y
r
e
s
y_{res}
yres的相关度是一样的,此时就在
x
l
x_l
xl和
x
k
x_k
xk的角分线方向上,继续使用类似于前向梯度算法中的残差计算方法,逼近y。
当出现第三个特征
x
p
x_p
xp和
y
r
e
s
y_{res}
yres的相关度足够大的时候,将其也加入到
y
y
y的逼近特征集合中,并用y的逼近特征集合的共同角分线,作为新的逼近方向。以此循环,直到
y
r
e
s
y_{res}
yres足够的小,或者说所有的变量都已经取完了,算法停止。
LARS算法是一个适用于高维数据的回归算法,
其主要的优点如下:
1.对于特征维度
n
n
n远高于样本点数
m
m
m 的情况
(
n
≥
m
)
(n≥m)
(n≥m),该算法有极高的数值计算效率;
2.该算法的最坏计算复杂度和最小二乘法(OLS)类似,但是其计算速度几乎和前向选择算法一样;
3.它可以产生分段线性结果的完整路径,这在模型的交叉验证中极为有用。
其主要的缺点:
由于LARS的迭代方向是根据目标的残差yres定的,所以该算法对样本的噪声是极为敏感的。
# lasso_path():坐标下降算法计算
# lars_path():其中参数method默认是lar,属于最小角回归方法
method="lasso",是坐标轴下降法
reg = linear_model.LassoLars(alpha=.1)
reg.fit([[0, 0], [1, 1]], [0, 1])
k = reg.coef_
print(k)
或者method默认为lar
alphas, active, coef_path_lars = linear_model.lars_path(X, y, method='lar')
3. L2正则化/岭回归
L2正则化将系数向量的L2范数添加到了损失函数中。由于L2惩罚项中系数是二次方的,这使得L2和L1有着诸多差异,最明显的一点就是,L2正则化会让系数的取值变得平均。对于关联特征,这意味着他们能够获得更相近的对应系数。还是以
Y
=
X
1
+
X
2
Y=X_1+X_2
Y=X1+X2为例,假设
X
1
X_1
X1和
X
2
X_2
X2具有很强的关联,如果用L1正则化,不论学到的模型是
Y
=
X
1
+
X
2
Y=X_1+X_2
Y=X1+X2还是
Y
=
2
X
1
Y=2X_1
Y=2X1,惩罚都是一样的,都是2alpha。但是对于L2来说,第一个模型的惩罚项是2alpha,但第二个模型的是4alpha。可以看出,系数之和为常数时,各系数相等时惩罚是最小的,所以才有了L2会让各个系数趋于相同的特点。
可以看出,L2正则化对于特征选择来说一种稳定的模型,不像L1正则化那样,系数会因为细微的数据变化而波动。所以L2正则化和L1正则化提供的价值是不同的,L2正则化对于特征理解来说更加有用:表示能力强的特征对应的系数是非零。
岭回归与多项式回归唯一的不同在于代价函数上的差别。岭回归的代价函数如下:
J
(
θ
)
=
1
m
∑
i
=
1
n
(
y
(
i
)
−
(
w
x
(
i
)
+
b
)
)
2
+
λ
∣
∣
w
∣
∣
2
2
=
M
S
E
(
θ
)
+
λ
∑
i
=
1
n
θ
i
2
(
3.1
)
J(\theta)=\frac{1}{m}\sum_{i=1}^n (y^{(i)}-(wx^{(i)}+b))^2+\lambda||w||_2^2=MSE(\theta)+\lambda\sum_{i=1}^n\theta_i^2 \text{ }\text{ }\text{ }\text{ }(3.1)
J(θ)=m1i=1∑n(y(i)−(wx(i)+b))2+λ∣∣w∣∣22=MSE(θ)+λi=1∑nθi2 (3.1)
为了方便计算导数,通常也写成下面的形式:
J
(
θ
)
=
1
2
m
∑
i
=
1
n
(
y
(
i
)
−
(
w
x
(
i
)
+
b
)
)
2
+
λ
2
∣
∣
w
∣
∣
2
2
=
1
2
M
S
E
(
θ
)
+
λ
2
∑
i
=
1
n
θ
i
2
(
3.2
)
J(\theta)=\frac{1}{2m}\sum_{i=1}^n (y^{(i)}-(wx^{(i)}+b))^2+\frac{\lambda}{2}||w||_2^2=\frac{1}{2}MSE(\theta)+\frac{\lambda}{2}\sum_{i=1}^n\theta_i^2\text{ }\text{ }\text{ }\text{ }(3.2)
J(θ)=2m1i=1∑n(y(i)−(wx(i)+b))2+2λ∣∣w∣∣22=21MSE(θ)+2λi=1∑nθi2 (3.2)
上式中的
w
w
w是长度为
n
n
n的向量,不包括截距项的系数
θ
0
θ_0
θ0;
θ
θ
θ是长度为
n
+
1
n+1
n+1的向量,包括截距项的系数
θ
0
θ_0
θ0;m为样本数;n为特征数.
岭回归的代价函数仍然是一个凸函数,因此可以利用梯度等于0的方式求得全局最优解(正规方程):
θ
=
(
X
T
X
+
λ
I
)
−
1
(
X
T
y
)
(
3.3
)
\theta=(X^TX+\lambda I)^{-1}(X^Ty) \text{ }\text{ }\text{ }\text{ }\text{ }\text{ }(3.3)
θ=(XTX+λI)−1(XTy) (3.3)
上述正规方程与一般线性回归的正规方程相比,多了一项
λ
I
λI
λI,其中
I
I
I表示单位矩阵。假如
X
T
X
X^TX
XTX是一个奇异矩阵(不满秩),添加这一项后可以保证该项可逆。由于单位矩阵的形状是对角线上为1其他地方都为0,看起来像一条山岭,因此而得名。
除了上述正规方程之外,还可以使用梯度下降的方式求解,这里采用式子1−2来求导:
∇
θ
J
(
θ
)
=
1
m
X
T
(
X
θ
−
y
)
+
λ
w
(
3.4
)
\nabla_\theta J( \theta )=\frac{1}{m}X^T(X\theta-y)+\lambda w\text{ }\text{ }\text{ }\text{ }(3.4)
∇θJ(θ)=m1XT(Xθ−y)+λw (3.4)
因为式子(3.2)中和式第二项不包含
θ
0
θ_0
θ0,因此求梯度后,上式第二项中的
w
w
w本来也不包含
θ
0
θ_0
θ0。为了计算方便,添加
θ
0
=
0
θ_0=0
θ0=0到
w
w
w.
因此在梯度下降的过程中,参数的更新可以表示成下面的公式:
θ
=
θ
−
(
α
m
X
T
(
X
θ
−
y
)
+
λ
w
)
(
3.5
)
\theta =\theta-(\frac{\alpha}{m}X^T(X\theta-y)+\lambda w)\text{ }\text{ }\text{ }\text{ }(3.5)
θ=θ−(mαXT(Xθ−y)+λw) (3.5)
scikit中的RidgeCV类的损失函数和损失函数的优化方法完全与Ridge类相同,区别在于验证方法。
验证方法:
RidgeCV类对超参数
α
α
α使用了交叉验证,来帮忙我们选择一个合适的
α
α
α。在初始化RidgeCV类时候,我们可以传一组备选的
α
α
α值,10个,100个都可以。RidgeCV类会帮我们选择一个合适的
α
α
α。免去了我们自己去一轮轮筛选
α
α
α的苦恼。
4.几种算法的对比
4.1.Lasso
Lasso回归的损失函数优化方法常用的有两种,坐标轴下降法和最小角回归法。Lasso类采用的是坐标轴下降法,后面讲到的LassoLars类采用的是最小角回归法。
验证方法:
Lasso类并没有用到交叉验证之类的验证方法,和Ridge类类似。需要我们自己把数据集分成训练集和测试集,需要自己设置好超参数α。然后训练优化。
使用场景:
一般来说,对于高维的特征数据,尤其线性关系是稀疏的,我们会采用Lasso回归。或者是要在一堆特征里面找出主要的特征,那么Lasso回归更是首选了。但是Lasso类需要自己对α调优,所以不是Lasso回归的首选,一般用到的是下一节要讲的LassoCV类。
4.2. LassoCV
LassoCV类的损失函数和损失函数的优化方法完全与Lasso类相同,区别在于验证方法。
验证方法:
LassoCV类对超参数α使用了交叉验证,来帮忙我们选择一个合适的α。在初始LassoCV类时候,我们可以传一组备选的α值,10个,100个都可以。LassoCV类会帮我们选择一个合适的α。免去了我们自己去一轮轮筛选α的苦恼。
使用场景:
LassoCV类是进行Lasso回归的首选。当我们面临在一堆高位特征中找出主要特征时,LassoCV类更是必选。当面对稀疏线性关系时,LassoCV也很好用。
4.3. LassoLars
LassoLars类的损失函数和验证方法与Lasso类相同,区别在于损失函数的优化方法。
损失函数的优化方法:
Lasso回归的损失函数优化方法常用的有两种,坐标轴下降法和最小角回归法。LassoLars类采用的是最小角回归法,前面讲到的Lasso类采用的是坐标轴下降法。
使用场景:
LassoLars类需要自己对α调优,所以不是Lasso回归的首选,一般用到的是下一节要讲的LassoLarsCV类。
4.4. LassoLarsCV
LassoLarsCV类的损失函数和损失函数的优化方法完全与LassoLars类相同,区别在于验证方法。
验证方法:
LassoLarsCV类对超参数α使用了交叉验证,来帮忙我们选择一个合适的α。在初始化LassoLarsCV类时候,我们可以传一组备选的α值,10个,100个都可以。LassoLarsCV类会帮我们选择一个合适的α。免去了我们自己去一轮轮筛选α的苦恼。
使用场景:
LassoLarsCV类是进行Lasso回归的第二选择。第一选择是前面讲到LassoCV类。那么LassoLarsCV类有没有适用的场景呢?换句话说,用最小角回归法什么时候比坐标轴下降法好呢?场景一:如果我们想探索超参数α更多的相关值的话,由于最小角回归可以看到回归路径,此时用LassoLarsCV比较好。场景二: 如果我们的样本数远小于样本特征数的话,用LassoLarsCV也比LassoCV好。其余场景最好用LassoCV。