在前两篇博客 再读线性回归 Linear Regression 和 再读线性回归 Linear Regression (过拟合问题) 中,我分别简单的回顾了线性回归的基本思路(即梯度下降),以及线性回归缓解过拟合问题的方式(即正则化),可以说基本涵盖了线性回归的基本算法,这一篇想谈谈线性回归中的另一种参数估计计算方法,最小二乘法,Least Square Method。这可能需要一点矩阵的基本知识 1。
在梯度下降中,我们定义了基于预测值和真实值的平方差的代价函数 J ( θ ) J(\theta) J(θ),代价函数可写为,
J ( θ ) = 1 2 m ∑ i = 1 m ( f θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (f_{\theta}(x^{(i)})-y^{(i)})^2 J(θ)=2m1i=1∑m(fθ(x(i))−y(i))2
由于 J ( θ ) J(\theta) J(θ) 是凸的, 因此 J ( θ ) J(\theta) J(θ) 的极小值点一定出在其导数为 0 的地方(凸函数只有一个全局最优点,极小值点就是最小值点)。因此,最小二乘法的核心思想直接计算出使得代价函数的梯度(偏导数)为零的参数向量 θ \theta θ 的值。也即求出满足下列等式的 θ \theta θ 值。
∇ J ( θ ) = ( ∂ J ( θ ) ∂ θ 0 , ∂ J ( θ ) ∂ θ 1 , . . . , ∂ J ( θ ) ∂ θ n ) = ( 0 , 0 , . . . , 0 ) , i ∈ [ 0 , n ] \nabla J(\theta) = (\frac{\partial J(\theta)}{\partial \theta_0}, \frac{\partial J(\theta)}{\partial \theta_1},...,\frac{\partial J(\theta)}{\partial \theta_n}) = (0,0,...,0),i \in [0, n] ∇J(θ)=(∂θ0∂J(θ),∂θ1∂J(θ),...,∂θn∂J(θ))=(0,0,...,0),i∈[0,n]
我们将代价函数写成矩阵形式,先定义符号令 向量 x ( i ) = ( x 1 ( i ) ; x 2 ( i ) ; . . . ; x n ( i ) ) x^{(i)}=(x^{(i)}_1;x^{(i)}_2;...;x^{(i)}_n) x(i)=(x1(i);x2(i);...;xn(i)) 表示第 i i i 个样本的 n n n 个特征。我们用 X ∈ R m × ( n + 1 ) X \in \mathbb{R}^{m \times (n+1)} X∈Rm×(n+1) 表示特征矩阵,用 Y ∈ R m × 1 Y \in \mathbb{R}^{m \times 1} Y∈Rm×1 代表标签矩阵,用 θ ∈ R ( n + 1 ) × 1 \theta \in \mathbb{R}^{(n+1) \times 1} θ∈R(n+1)×1 表示特征矩阵,即,
X = ( 1 , x 1 ( 1 ) , x 2 ( 1 ) , x 3 ( 1 ) , . . . , X n ( 1 ) 1 , x 1 ( 2 ) , x 2 ( 2 ) , x 3 ( 2 ) , . . . , X n ( 2 ) . . . 1 , x 1 ( m ) , x 2 ( m ) , x 3 ( m ) , . . . , X n ( m ) ) , θ = ( θ 0 θ 1 . . . θ n ) , Y = ( y ( 1 ) y ( 2 ) . . . y ( m ) ) X = \begin{pmatrix} 1, x^{(1)}_1, x^{(1)}_2, x^{(1)}_3, ... , X^{(1)}_n \\ 1, x^{(2)}_1, x^{(2)}_2, x^{(2)}_3, ... , X^{(2)}_n \\ ...\\ 1, x^{(m)}_1, x^{(m)}_2, x^{(m)}_3,... , X^{(m)}_n \end{pmatrix} , \theta = \begin{pmatrix} \theta_0 \\ \theta_1 \\ ...\\ \theta_{n} \end{pmatrix}, Y = \begin{pmatrix} y^{(1)} \\ y^{(2)} \\ ...\\ y^{(m)} \end{pmatrix} X=⎝⎜⎜⎜⎛1,x1(1),x2(1),x3(1),...,Xn(1)1,x1(2),x2(2),x3(2),...,Xn(2)...1,x1(m),x2(m),x3(m),...,Xn(m)⎠⎟⎟⎟⎞,θ=⎝⎜⎜⎛θ0θ1...θn⎠⎟⎟⎞,Y=⎝⎜⎜⎛y(1)y(2)...y(m)⎠⎟⎟⎞
因此代价函数可以改写为,注意,最终的 J ( θ ) J(\theta) J(θ) 是一个值。
J ( θ ) = 1 2 m ( X θ − Y ) T ( X θ − Y ) J(\theta) = \frac{1}{2m} (X\theta-Y)^T(X\theta-Y) J(θ)=2m1(Xθ−Y)T(Xθ−Y)
对 J ( θ ) J(\theta) J(θ) 中的 θ \theta θ 求导,有,
∇ J ( θ ) = 1 2 m × ∂ ∂ θ [ ( X θ − Y ) T ( X θ − Y ) ] \nabla J(\theta) = \frac{1}{2m}\times \frac{\partial}{\partial \theta}[(X\theta-Y)^T(X\theta-Y)] ∇J(θ)=2m1×∂θ∂[(Xθ−Y)T(Xθ−Y)]
化简第一个括号 ( X θ − Y ) T (X\theta-Y)^T (Xθ−Y)T,
∇ J ( θ ) = 1 2 m × ∂ ∂ θ [ ( θ T X T − Y T ) ( X θ − Y ) ] \nabla J(\theta) = \frac{1}{2m}\times \frac{\partial}{\partial \theta}[(\theta^TX^T-Y^T)(X\theta-Y)] ∇J(θ)=2m1×∂θ∂[(θTXT−YT)(Xθ−Y)]
将 2 个括号展开
∇ J ( θ ) = 1 2 m × ∂ ∂ θ [ ( θ T X T X θ − θ T X T Y − Y T X θ + Y T Y ] \nabla J(\theta) = \frac{1}{2m}\times \frac{\partial}{\partial \theta}[(\theta^TX^TX\theta-\theta^TX^TY-Y^TX\theta+Y^TY] ∇J(θ)=2m1×∂θ∂[(θTXTXθ−θTXTY−YTXθ+YTY]
依次对 4 个项分别求导,因为最后一项 Y T Y Y^TY YTY 是不含 θ \theta θ 的常数项,因此导数为 0 0 0。
∇ J ( θ ) = 1 2 m × [ ∂ ∂ θ ( θ T X T X θ ) − ∂ ∂ θ ( θ T X T Y ) − ∂ ∂ θ ( Y T X θ ) ] \nabla J(\theta) = \frac{1}{2m}\times [\frac{\partial}{\partial \theta}(\theta^TX^TX\theta) - \frac{\partial}{\partial \theta}(\theta^TX^TY) - \frac{\partial}{\partial \theta}(Y^TX\theta)] ∇J(θ)=2m1×[∂θ∂(θTXTXθ)−∂θ∂(θTXTY)−∂θ∂(YTXθ)]
现在的问题就是针对中括号中的3项求导了,根据矩阵的求导准则,我们有,
∂ ∂ θ ( θ T X T X θ ) = 2 X T X θ , ∂ ∂ θ ( θ T X T Y ) = X T Y ∂ ∂ θ ( Y T X θ ) = ( Y T X ) T = X T Y \frac{\partial}{\partial \theta}(\theta^TX^TX\theta) = 2X^TX\theta , \frac{\partial}{\partial \theta}(\theta^TX^TY) = X^TY \\ \frac{\partial}{\partial \theta}(Y^TX\theta) = (Y^TX)^T=X^TY ∂θ∂(θTXTXθ)=2XTXθ,∂θ∂(θTXTY)=XTY∂θ∂(YTXθ)=(YTX)T=XTY
最终梯度 ∇ J ( θ ) \nabla J(\theta) ∇J(θ) 可以化简为,
∇ J ( θ ) = 1 2 m × [ 2 X T X θ − 2 X T Y ] = X T X θ − X T Y \nabla J(\theta) = \frac{1}{2m}\times [2X^TX\theta - 2X^TY] = X^TX\theta-X^TY ∇J(θ)=2m1×[2XTXθ−2XTY]=XTXθ−XTY
当梯度 ∇ J ( θ ) \nabla J(\theta) ∇J(θ) 为零时,我们可以得到最优参数向量 θ \theta θ,
X T X θ − X T Y = 0 → X T X θ = X T Y → θ = ( X T X ) − 1 X T Y X^TX\theta-X^TY=0 \rightarrow X^TX\theta=X^TY \rightarrow \theta=(X^TX)^{-1}X^TY XTXθ−XTY=0→XTXθ=XTY→θ=(XTX)−1XTY
由上述式子可知,当我们已知特征矩阵 X X X 和 标签矩阵 Y Y Y 时,可以直接求解出最优参数 θ \theta θ。最小二乘法的优点就是不用一步步的调整参数,而是直接求解出的最优的参数,即 θ = ( X T X ) − 1 X T Y \theta=(X^TX)^{-1}X^TY θ=(XTX)−1XTY。
这里有人会问 “那万一 ( X T X ) (X^TX) (XTX) 不可逆怎么办?”。首先,理论上讲,不可逆就无法求出最终的 θ \theta θ,这也是最小二乘的缺陷之一,因为我们自然界有很多的矩阵没有逆矩阵(成为“奇异矩阵”或“退化矩阵”)。其次,聪明的科学家们发明了一种可替代方法,就是伪逆矩阵,这种矩阵专门来处理 ( X T X ) (X^TX) (XTX) 不可逆的情况。
用一条直线来拟合平面上的点 { ( 1 , 7 ) , ( 8 , 3 ) , ( 3 , 11.2 ) , ( 4 , 13.2 ) , ( 5 , 14.1 ) } \{(1,7),(8,3),(3,11.2),(4,13.2),(5,14.1)\} {(1,7),(8,3),(3,11.2),(4,13.2),(5,14.1)},我们将每个点看做 ( x , y ) (x,y) (x,y) 的组合, x x x 代表一维特征, y y y 代表标签。利用最小二乘法我们写出 Least_Square_Method()
函数。值得一提的是,该函数返回的参数与 sklearn 包里的 sklearn.linear_model.LinearRegression
的结果是一样的,侧面说明 sklearn 里的实现方法就是最小二乘法,有兴趣的可以查看一下它的源码2。
def Least_Square_Method(train_X, train_Y):
'''
利用最小二乘法计算出最优参数 theta。
Parameters
-------------
:train_X: 特征矩阵
:train_Y: 标签矩阵
Returns
-------------
:theta: 最优参数组合
'''
X = np.matrix(train_X)
X = np.insert(X,0,values=1,axis=1)
Y = np.matrix(train_Y)
# theta = ((X.T)·X)^{-1}(X.T)·Y
theta = np.linalg.pinv(X.T.dot(X)).dot(X.T).dot(Y) # pinv 求解的是伪逆矩阵
return theta
通过计算得知 theta=(5.03;1.91)
,再将它们反映到二维平面上,如下所示,这个拟合程度已经很高了。
多项式回归是基本线性回归的升级版。顾名思义,多项式回归学习的函数 f θ ( x ) f_{\theta}(x) fθ(x) 中的每一项可以是单个特征,如 x i x_i xi,也可以是两个或多个特征的组合方式,如 x i ⋅ x j x_i·x_j xi⋅xj,也有可能对数或指数,如 log ( x i ) \log(x_i) log(xi)。因此多项式回归可以是如下样子。
f θ ( x ) = θ 0 + θ 1 x 1 + . . . + θ p x 1 ⋅ x 2 + . . . + θ q log ( x 1 ) + . . . f_{\theta}(x)=\theta_0+\theta_1x_1+...+\theta_px_1·x_2 + ... + \theta_q\log(x_1) + ... fθ(x)=θ0+θ1x1+...+θpx1⋅x2+...+θqlog(x1)+...
值得注意的是,在训练多项式回归前,需要人工确定的哪些项要放到函数 f ( θ ) f(\theta) f(θ) 中去。那么实际的做法其实就是在原有的数据集上增加新的维度,如通过 x 1 x_1 x1 和 x 2 x_2 x2 生成新的项 x 1 ⋅ x 2 x_1·x_2 x1⋅x2,那么特征集由原来的 n n n 维增加到了 ( n + 1 ) (n+1) (n+1) 维。sklearn 包里有现成的多项式回归方法,但是仅仅支持 degree=2,3
,也就是说只支持 x 1 ⋅ x 2 x_1·x_2 x1⋅x2 和 x 1 ⋅ x 2 ⋅ x 3 x_1·x_2·x_3 x1⋅x2⋅x3 两种情况。
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
def Generate_New_X(X, deg=3):
'''
根据确定回归的新的特征矩阵
Parameters
--------------
:X: 原特征矩阵
:deg: 回归项的最高次数
Returns
--------------
:new_X: 新合成的特征
'''
quadratic_featurizer = PolynomialFeatures(deg)
new_X = quadratic_featurizer.fit_transform(X)
return new_X
例如,对于只有 2 个维度的样本 x x x,使用合成技术会将其拓展到了 10 维。注意第 1 维是 1,表示 θ 0 \theta_0 θ0。
x = ( x 1 , x 2 ) → x = ( 1 , x 1 , x 2 , x 1 2 , x 1 ⋅ x 2 , x 2 2 , x 1 3 , x 1 x 1 x 3 , x 1 x 2 x 2 , x 2 3 ) x = (x_1,x_2) \rightarrow x=(1,x_1,x_2,x_1^2,x_1·x_2,x_2^2,x_1^3,x_1x_1x_3,x_1x_2x_2,x_2^3) x=(x1,x2)→x=(1,x1,x2,x12,x1⋅x2,x22,x13,x1x1x3,x1x2x2,x23)
针对第 2 节的例子,我们由新的特征矩阵 new_X
进行线性回归并训练参数,即原来的 1 维特征 ( x 1 ) (x_1) (x1) 变成了 4 维 ( 1 ; x 1 ; x 1 2 ; x 1 3 ) (1; x_1; x_1^2; x_1^3) (1;x1;x12;x13)。训练结果如右下图所示,可见当特征的维度提到 10 个时,曲线的拟合程度会更到位(当然这也有可能导致过拟合问题)。
虽然貌似特征越多,曲线拟合的越完美,但是现实开发中,不可能用到比 2 或 3 更高的次数(degree
),因为这会引起组合爆照问题。如果想要在线性回归中选用合适的特征,我们也可以结合特征选择技术3,使得训练时用到的特征与结果十分相关。
CV_ML_DP. 矩阵基本知识及矩阵求导 (博客). Link ↩︎
Scikit-learn. LinearRegression 的 Github 源码 (源码). Link ↩︎
Chikily_yongfeng. 特征选择的探索 (博客). Link ↩︎