机器学习-线性回归

线性回归

基本介绍 {#sec:basic}

假定数据集合中有 m m m个样本点,对于每一个样本点 x i x_i xi,具有值 y i y_i yi,且 x = { x i ∣ i ∈ { 0 , 1 , … , m − 1 } } x = \{x_i | i \in \{0, 1, \ldots, m-1\} \} x={xii{0,1,,m1}}与结果 y = { y i ∣ i ∈ { 0 , 1 , … , m − 1 } } y = \{y_i |i \in \{0, 1, \ldots, m-1\} \} y={yii{0,1,,m1}}呈现线性关系。
我们的目标是根据现有的 m m m个样本,拟合出一条直线,即
y = w ∗ x + b (1) y = w * x + b \tag{1} y=wx+b(1)
使得根据这条直线得到的结果与真实的结果误差最小。那么如何来衡量这个误差呢?我们引入平方损失函数,即对于样本 x i x_i xi,我们有误差 J i J_i Ji
J i = ( w ∗ x i + b − y i ) 2 J_i = (w*x_i+b - y_i)^2 Ji=(wxi+byi)2 因此,全部 m m m个样本的平均误差为:
J = 1 m ∑ i = 0 m − 1 J i J = \frac{1}{m}\sum_{i=0}^{m-1}{J_i} J=m1i=0m1Ji
从数学上表述为,我们要求得 w w w b b b ,使得 j j j最小,即
arg ⁡ min ⁡ 1 m ∑ i = 0 m − 1 J i \arg \min \frac{1}{m}\sum_{i=0}^{m-1}{J_i} argminm1i=0m1Ji

针对于最小化特定方程的,我们区分为几个section来介绍。

普通求导 {#par:simple}

根据多元函数求极值得方法,直接分别对 w w w b b b求偏导,且使得偏导为0,即:
∂ J ∂ w = 0 ,     ∂ J ∂ b = 0 \frac{\partial J}{\partial w} = 0, \ \ \ \frac{\partial J}{\partial b} = 0 wJ=0,   bJ=0
只有两个未知数,两个等式,因此可以解出 w , b w,b w,b

但是,这里面假定了样本点 x i x_i xi只有一列属性,也就是说每一个样本都可以在一个二维图像中描绘出来。当一个样本具有 n n n列属性的时候,上述就会有 n + 1 n+1 n+1个等式,即:
∂ J ∂ w 0 = 0 ,    … ,    ∂ J ∂ w n − 1 = 0 ,     ∂ J ∂ b = 0 \frac{\partial J}{\partial w_0} = 0, \ \ \ldots,\ \ \frac{\partial J}{\partial w_{n-1}} = 0, \ \ \ \frac{\partial J}{\partial b} = 0 w0J=0,  ,  wn1J=0,   bJ=0
这样联立线性方程组求解非常复杂.

向量求导

当未特殊说明,向量一律为列向量。
对于具有多个属性的 x i x_i xi,我们拟合的公式 ( 1 ) (1) (1)可以转化为: y = w T x + b y = w^T x + b y=wTx+b
为了统一化,我们将 w , b w,b w,b合并为向量 θ \theta θ,并给 x i x_i xi增加额外的一个属性,值为1.

这样我们有: y = θ T x = x T θ y = \theta^T x = x^T \theta y=θTx=xTθ

此时,平均误差公式可以进一步简化为: J ( θ ) = 1 m ∑ i = 0 m − 1 ( x i T θ − y i ) 2 = 1 m ( X θ − Y ) T ( X θ − Y ) \begin{aligned} J(\theta) &= \frac{1}{m} \sum_{i=0}^{m-1}( x_i^T \theta - y_i)^2 \\ &= \frac{1}{m} (X \theta - Y)^T (X \theta - Y)\end{aligned} J(θ)=m1i=0m1(xiTθyi)2=m1(Y)T(Y)
其中 X = [ x 0 T x 1 T ⋮ x m − 1 T ] X = \begin{bmatrix} x_0^T\\ x_1^T\\ \vdots \\ x_{m-1}^T \end{bmatrix} X= x0Tx1Txm1T ,且 Y = [ y 0 y 1 ⋮ y m − 1 ] Y= \begin{bmatrix} y_0\\ y_1\\ \vdots\\ y_{m-1} \end{bmatrix} Y= y0y1ym1

我们的目标是求得最小化 J ( θ ) J(\theta) J(θ)时的 θ \theta θ值,这可通过向量求导:
∂ J ( θ ) ∂ θ = 0 (2) \tag{2} \frac{\partial J(\theta)} {\partial \theta} = 0 θJ(θ)=0(2)

为了对公式 ( 2 ) (2) (2)进行求解,我们首先引入几个基本向量求导公式:
∂ x T a ∂ x = ∂ a x T ∂ x = a ∂ x T B x ∂ x = ( B + B T ) x \begin{aligned} \frac{\partial x^T a}{\partial x} &= \frac{\partial a x^T}{\partial x} = a \\ \frac{\partial x^T B x}{\partial x} &= (B + B^T) x\end{aligned} xxTaxxTBx=xaxT=a=(B+BT)x
对于上述的基本求导公式,它的证明只有一个思想:数对向量求导,相当于此数对向量中的各个元素逐个求导。上述的两个公式都是对列向量 x x x求导,因此结果仍然是一个列向量。

上述公式的简单记忆方法: 前导不变,后导转置,公式表达为:
∂ x T a ∂ x = a ,     ∂ b x ∂ x = b T \frac{\partial x^T a}{\partial x} = a, \ \ \ \frac{\partial b x}{\partial x} = b^T xxTa=a,   xbx=bT
注意: 这里的 b b b是行向量。

Z ( θ ) = ( X θ − Y ) T ( X θ − Y ) Z(\theta) = (X \theta - Y)^T (X \theta - Y) Z(θ)=(Y)T(Y)
J ( θ ) = 1 m Z ( θ ) J(\theta) = \frac{1}{m}Z(\theta) J(θ)=m1Z(θ),且 Z ( θ ) = ( θ T X T − Y T ) ( X θ − Y ) = θ T X T X θ − θ T X T Y − Y T X θ + Y T Y \begin{aligned} Z(\theta) &= (\theta^T X^T - Y^T) (X \theta - Y) \\ &= \theta^T X^T X \theta - \theta^T X^T Y - Y^T X \theta + Y^TY\end{aligned} Z(θ)=(θTXTYT)(Y)=θTXTθTXTYYT+YTY

因此我们有: ∂ ( Z ( θ ) ) ∂ θ = ( X T X + X T X ) θ − X T Y − X T Y + 0 = 2 X T X θ − 2 X T Y \begin{aligned} \frac{\partial {(Z(\theta))}} {\partial \theta} &= (X^TX + X^TX) \theta - X^TY - X^TY + 0 \\ &= 2X^TX \theta - 2 X^T Y \end{aligned} θ(Z(θ))=(XTX+XTX)θXTYXTY+0=2XT2XTY

代入 Z ( θ ) Z(\theta) Z(θ)到公式 ( 2 ) (2) (2),我们有: ∂ ( 1 m Z ( θ ) ) ∂ θ = 0 即: 1 m ( 2 X T X θ − 2 X T Y ) = 0 即: X T X θ − X T Y = 0 \begin{aligned} \frac{\partial {(\frac{1}{m}Z(\theta))}} {\partial \theta} &= 0 \\ \text{即:} \frac{1}{m}(2X^TX \theta - 2 X^T Y ) &= 0 \\ \text{即:} X^TX \theta - X^T Y &= 0\end{aligned} θ(m1Z(θ))即:m1(2XT2XTY)即:XTXTY=0=0=0

如果 X T X X^T X XTX可逆,那么我们有: θ = ( X T X ) − 1 X T Y \theta = (X^TX)^{-1} X^TY θ=(XTX)1XTY

上述的优化方法需要计算矩阵的逆,当数据量很小而且可逆的时候,速度快,效果好,但是并不适用于大量高维度的数据。是否有一些数学中的迭代的方式能不断的逼近最小值呢?这个答案有很多,下面将尽力逐个介绍。

梯度下降

梯度下降,顾名思义就是顺着梯度的方向的反方向下滑,直到滑动到某一个最低点为止。
我们可以把它想象成一个小山,如下图所示(
很抱歉是用latex写的,画图采用的tikz,第一次用不熟练,很丑),假定我们的起始点为start,然后顺着下山的方向,一步一步的就会滑落到它左边的最低点。

这可能会有一个问题: 如果它的右边有一个更低的最低点呢?
它有可能落不到全局最低,但是可以达到局部最低。不过,如果我们的函数是凸函数,也就是说只有一个极值点的时候,它的局部最优也就是全局最优了。

ABCD

梯度下降的``小山''图,从start点开始下落

原理篇

一维直观篇

为了与高等数学教材的保持一致,采用书里面的记法,在 △ x → 0 \triangle x \to 0 x0时,我们有:
f ( x + △ x ) = f ( x ) + △ x ⋅ f ′ ( x ) + o ( △ x ) f(x+ \triangle x) = f(x) + \triangle x \cdot f'(x) + \textit{o}(\triangle x) f(x+x)=f(x)+xf(x)+o(x)
此后我们简单的忽略 o ( △ x ) \textit{o}(\triangle x) o(x)这一项。

令上图中的start点的横坐标为 x 0 x_0 x0,代入 x = x 0 x=x_0 x=x0,我们有:
f ( x 0 + △ x ) = f ( x 0 ) + △ x ⋅ f ′ ( x 0 ) f(x_0+ \triangle x) = f(x_0) + \triangle x \cdot f'(x_0) f(x0+x)=f(x0)+xf(x0)

为了使它向着小山下方(左面)滑动,我们需要有 f ( x 0 + △ x ) < f ( x 0 ) f(x_0 + \triangle x) < f(x_0) f(x0+x)<f(x0),即
△ x ⋅ f ′ ( x 0 ) < 0 \triangle x \cdot f'(x_0) < 0 xf(x0)<0

那么 △ x \triangle x x需要满足什么条件呢?我们令 g = f ′ ( x ) ,    σ = △ x g=f'(x),\ \ \sigma = \triangle x g=f(x),  σ=x,我们有:
△ x ⋅ f ′ ( x 0 ) = g ⋅ σ \triangle x \cdot f'(x_0) = g \cdot \sigma xf(x0)=gσ
很显然,我们只需要 σ \sigma σ取得 g g g的相反的方向,例如 σ = − 0.01 g \sigma = -0.01g σ=0.01g,即可满足 g ⋅ σ < 0 g \cdot \sigma < 0 gσ<0。请原谅我,虽然进行 g g g σ \sigma σ的定义看起来多此一举,但请相信我,当将其映射到高维的时候,它能更好的帮助理解。

负梯度:这里面的 g g g是斜率,其实也是梯度。 σ \sigma σ g g g变化方向相反,因此我们称之为 x x x沿着梯度下降的方向,也就是负梯度方向。

学习率:
上面我们说 σ \sigma σ只需要与梯度的方向相反,那么 σ = − 0.1 g ,    σ = − 0.01 g \sigma = -0.1g, \ \ \sigma = -0.01g σ=0.1g,  σ=0.01g都可以满足要求,因此我们使用变量 α \alpha α表达学习率的概念,即 σ = − α ⋅ g \sigma = -\alpha \cdot g σ=αg

你应该已经知道学习率为何不能太大的原因了吧,上面的描述都是基于 σ = △ x → 0 \sigma = \triangle x \to 0 σ=x0的情况下,进行的推导,在实际中我们通常不会选用太大的 α \alpha α,不过太小的 α \alpha α意味着学习速度变慢,也就是说需要迭代更多的步数才可以到达最小值。

假定学习率 α = 0.01 \alpha = 0.01 α=0.01,从而我们有迭代公式:
x 1 = x 0 − 0.01 g ,     … ,     x n + 1 = x n − 0.01 g x_1 = x_0 -0.01g,\ \ \ \ldots, \ \ \ x_{n+1} = x_n -0.01g x1=x00.01g,   ,   xn+1=xn0.01g

利用如上的递推公式,我们就可以不断的使得 f ( x n + 1 ) < f ( x n ) f(x_{n+1}) < f(x_n) f(xn+1)<f(xn),即不断下滑到最低点。

二维梯度篇

我先从二维逐步扩展到高维的形式,二维的微分形式:
f ( x + △ x , y + △ y ) = f ( x , y ) + △ x f ′ ( x ) + △ y f ′ ( y ) + o ( △ 2 x + △ 2 y ) f(x+\triangle x, y+ \triangle y) = f(x, y) + \triangle x f'(x) + \triangle y f'(y) + \textit{o}(\sqrt{\triangle ^2 x + \triangle^2 y}) f(x+x,y+y)=f(x,y)+xf(x)+yf(y)+o(2x+2y )

我们的目标是使得在对于自变量 x , y x, y x,y进行相应的 △ x , △ y \triangle x, \triangle y x,y变化后,新的 f ( x + △ x , y + △ y ) f(x+\triangle x, y+ \triangle y) f(x+x,y+y)能够更小,也就是说使得:
△ x f ′ ( x ) + △ y f ′ ( y ) + o ( △ 2 x + △ 2 y ) < 0 \triangle x f'(x) + \triangle y f'(y) + \textit{o}(\sqrt{\triangle ^2 x + \triangle^2 y}) < 0 xf(x)+yf(y)+o(2x+2y )<0

△ x , △ y \triangle x, \triangle y x,y需要满足什么条件呢?
我们令 g T = ( f ′ ( x ) , f ′ ( y ) ) , σ T = ( △ x , △ y ) g^T = (f'(x), f'(y) ), \sigma ^T = (\triangle x, \triangle y) gT=(f(x),f(y)),σT=(x,y),我们有:
△ x f ′ ( x ) + △ y f ′ ( y ) = g T ⋅ σ = ∣ ∣ g ∣ ∣ ⋅ ∣ ∣ σ ∣ ∣ ⋅ c o s ( θ ) \triangle x f'(x) + \triangle y f'(y) = g^T \cdot \sigma = ||g|| \cdot ||\sigma|| \cdot cos(\theta) xf(x)+yf(y)=gTσ=∣∣g∣∣∣∣σ∣∣cos(θ)
很显然,我们应该使得 c o s ( θ ) = − 1 cos(\theta) = -1 cos(θ)=1,也就是说 σ \sigma σ的方向与梯度 g g g的方向相反。

如果加上学习率,我们可以令 σ = − α ⋅ g \sigma = -\alpha \cdot g σ=αg.
同样,与一维的情况一样,也是沿着负梯度的方向。

高维梯度篇

我们终于来到了高维情况,直接利用前面叙述的参数,梯度 g g g,学习率 α \alpha α,自变量变化 σ \sigma σ,注意 σ \sigma σ是一个向量,它代表各个自变量参数的变化情况,可简单把它想象成 { △ x , △ y , ⋯   } \{\triangle x, \triangle y, \cdots\} {x,y,}
我们有:
f ( X + σ ) = f ( X ) + g T ⋅ σ + o ( ∣ ∣ σ ∣ ∣ ) f(X + \sigma) = f(X) + g^T \cdot \sigma + \textit{o}(||\sigma||) f(X+σ)=f(X)+gTσ+o(∣∣σ∣∣)

同样,我们应该有 σ = − α ⋅ g \sigma = -\alpha \cdot g σ=αg

梯度下降简单实现demo篇

看到这里,有没有想实现一个梯度下降的冲动,反正我是有的,因此,我用python写了一个非常非常基本的二维的梯度下降,来实现线性回归。

请稍微回到我们在section 1.1中介绍的平面图上的m个点 ( x i , y i ) (x_i, y_i) (xi,yi),且呈现线性关系,我们的平均误差方程为:
J ( w , b ) = 1 m ∑ i = 0 m − 1 J i J(w,b) = \frac{1}{m}\sum_{i=0}^{m-1}{J_i} J(w,b)=m1i=0m1Ji
其中 J i ( w , b ) = ( w ∗ x i + b − y i ) 2 J_i(w,b) = (w*x_i+b - y_i)^2 Ji(w,b)=(wxi+byi)2。我们的目标是解出 w , b w,b w,b以使得 J J J最小。

梯度下降的4个要素:

  1. 初始值 w 0 = 0 , b 0 = 0 w_0=0, b_0=0 w0=0,b0=0

  2. 学习率 α = 0.01 → 0.0001 \alpha = 0.01 \to 0.0001 α=0.010.0001

  3. 梯度 ∂ J ( w , b ) ∂ w = 1 m ∑ i = 0 m − 1 2 ( w x i + b − y i ) x i ∂ J ( w , b ) ∂ b = 1 m ∑ i = 0 m − 1 2 ( w x i + b − y i ) \begin{aligned} \frac{\partial J(w,b)} {\partial w} &= \frac{1}{m} \sum_{i=0}^{m-1} {2(wx_i+b-y_i)x_i} \\ \frac{\partial J(w,b)} {\partial b} &= \frac{1}{m} \sum_{i=0}^{m-1} {2(wx_i+b-y_i)} \end{aligned} wJ(w,b)bJ(w,b)=m1i=0m12(wxi+byi)xi=m1i=0m12(wxi+byi)

  4. 梯度更新 w n + 1 = w n − α ⋅ ∂ J ( w , b ) ∂ w b n + 1 = b n − α ⋅ ∂ J ( w , b ) ∂ b \begin{aligned} w_{n+1} &= w_{n} - \alpha \cdot \frac{\partial J(w,b)} {\partial w} \\ b_{n+1} &= b_{n} - \alpha \cdot \frac{\partial J(w,b)} {\partial b} \end{aligned} wn+1bn+1=wnαwJ(w,b)=bnαbJ(w,b)

我们使用的数据点如下面的散点图所示,它是使用 w = 2 , b = 3 w=2, b=3 w=2,b=3的公式在 x ∈ { 0 , 1 , … , 99 } x \in \{0, 1, \ldots, 99 \} x{0,1,,99}中加入一定的随机数得到的。

linear_regression

线性回归之梯度下降数据分布图

生出散点图的python代码如下

import numpy as np
import random
import matplotlib.pyplot as plt
import pdb

random.seed(10)
x = np.arange(100)
w, b = 2, 3
y = np.array([w * i + b + random.randint(-5,5) for i in x])
one = np.ones(len(x))
plt.plot(x, y, '.')
plt.show()

利用梯度下降的4个要素编写的代码如下:

#alpha and g
alpha = 0.0003
w0, b0 = 0, 0

def gradient_w(w, b):
    return np.average([2*(w*xi + b - yi)* xi for (xi, yi) in list(zip(x,y))])
def gradient_b(w, b):
    return np.average([2*(w*xi + b - yi) for (xi, yi) in list(zip(x,y))])
    
for i in range(100000):
    w1 = w0 - alpha * gradient_w(w0, b0)
    b1 = b0 - alpha * gradient_b(w0, b0)
    w0, b0 = w1, b1
plt.plot(x, y, 'k+')
plt.plot(x, w0 * x + b0, 'r')
plt.show()

最终迭代出的结果为: w 1 = 1.99700571226 b 1 = 3.19821704612 w1 = 1.99700571226 b1 = 3.19821704612 w1=1.99700571226b1=3.19821704612

画出的曲线如下图所示
这里写图片描述

线性回归之梯度下降曲线结果

代码其实几分钟就写完了,但是一直都拟合不出来,当时我设置的学习率为 a l p h a = 0.001 alpha=0.001 alpha=0.001,还没有迭代多少步,就出现了值无穷大(nan)的情况,我一直以为是代码有问题,检查了一遍又一遍,还是感觉代码没问题,后来直到调整了学习率之后,才能够正确拟合出结果。

学习率的影响:
学习率过小,导致学习速度过慢,如果设置了最大迭代次数,那么很有可能还没有学到最终结果的时候,就已经终止了。不过我们可以看到它的误差,即 J ( w , b ) J(w,b) J(w,b)是呈现一个不断下降的趋势。
学习率过大,虽然学习速度上去了,但是很有可能跳出了最优解,这可能会导致算法最终并不会收敛,误差通常会溢出。

我从网上盗取了两张图,来分别展示学习率大小对结果的影响。

线性回归之梯度下降不同学习率小(左)和大(右)的情况

对于学习率引起的问题,我给上述的梯度下降代码加入了误差计算并存储,并画出误差图。

这里写图片描述
这里写图片描述

线性回归之梯度下降不同学习率小(左)和大(右)的误差情况

在使用学习率 α = 0.00001 \alpha = 0.00001 α=0.00001,迭代2000次后,我们得到 w 1 = 2.04427897398 ,   b 1 = 0.0626663170812 w1 = 2.04427897398,\ b1 = 0.0626663170812 w1=2.04427897398, b1=0.0626663170812,可以看出这与实际的 w = 2 , b = 3 w=2, b=3 w=2,b=3还是有不小的差距的,其误差画出曲线如误差图中的左图所示。
在使用学习率 α = 0.001 \alpha = 0.001 α=0.001,迭代2000次后,我们得到 w 1 = n a n , b 1 = n a n , e r r o r = n a n w1 = nan, b1 = nan, error = nan w1=nan,b1=nan,error=nan,它的误差如误差图的右图所示。

根据误差图,就可以很容易指导我们是学习率不够,迭代次数不够,还是学习率过大。当误差依然处于下降的趋势,我们的迭代次数通常是不够的,如果时间不允许,那么可以稍微调整学习率,使用更大的学习率来加快收敛,但是不能过大,以免出现误差不收敛。

牛顿法

牛顿法与梯度下降法具有很大的相似性,区别在于梯度下降是采用的一阶导数,而牛顿法采用的二阶导数。

一维直观篇

请拿上我们的高等数学中的泰勒展开,采用书里面的记法,在 △ x → 0 \triangle x \to 0 x0时,我们有:
f ( x + △ x ) = f ( x ) + △ x ⋅ f ′ ( x ) + 1 2 △ 2 x ⋅ f ′ ′ ( x ) + o ( △ 2 x ) f(x+\triangle x) = f(x) + \triangle x \cdot f'(x) + \frac{1}{2}\triangle^2 x \cdot f''(x) + \textit{o}(\triangle^2 x) f(x+x)=f(x)+xf(x)+212xf′′(x)+o(2x)

同样的,我们需要求得这样的 △ x \triangle x x,以使得 f ( x + △ x ) f(x+\triangle x) f(x+x)尽可能的小。回顾在梯度下降中,我们只是将泰勒展开到前面的两项,然后得到 △ x = − α ⋅ f ′ ( x ) \triangle x = -\alpha \cdot f'(x) x=αf(x)可以使得 f ( x + △ x ) f(x+\triangle x) f(x+x)呈现下降趋势,即沿着负梯度的方向。

在牛顿法中,我们的泰勒展开到了 △ x \triangle x x的平方项,这使得我们可以换个思路以最小化 f ( x + △ x ) f(x+\triangle x) f(x+x):将 △ x \triangle x x当成未知量,公式 f ( x ) + △ x ⋅ f ′ ( x ) + 1 2 △ 2 x ⋅ f ′ ′ ( x ) f(x) + \triangle x \cdot f'(x) + \frac{1}{2}\triangle^2 x \cdot f''(x) f(x)+xf(x)+212xf′′(x)是一个一元二次方程,曲线的开口向上,因此我们有 △ x = − f ′ ( x ) f ′ ′ ( x ) \triangle x = -\frac{f'(x)}{f''(x)} x=f′′(x)f(x)使得 f ( x + △ x ) f(x+\triangle x) f(x+x)取得最小值。
它与梯度下降很大的不同在于梯度下降的 △ x \triangle x x只要求方向与梯度方向相反即可,而牛顿法却可以精确的求出 △ x \triangle x x的值。

高维原理篇

假定有n个自变量参数 { x 1 , x 2 , … , x n } \{x_1, x_2, \ldots, x_n\} {x1,x2,,xn},,自变量变化 σ \sigma σ,注意 σ \sigma σ是一个向量,它代表各个自变量参数的变化情况,可简单把它想象成 { △ x 1 , △ x 2 , ⋯   } \{\triangle x_1, \triangle x_2, \cdots\} {x1,x2,},这里我们还需要额外的一个 G G G,它表示对自变量的二阶导数。

我们有学习率 α \alpha α(这是一个数),梯度向量 g g g: g = [ ∂ f ∂ x 1 ∂ f ∂ x 2 ⋮ ∂ f ∂ x n ] g = \begin{bmatrix} \frac{\partial f}{\partial x_1} \\ \frac{\partial f}{\partial x_2} \\ \vdots\\ \frac{\partial f}{\partial x_n} \end{bmatrix} g= x1fx2fxnf 自变量的变化 σ \sigma σ: σ = [ △ x 1 △ x 2 ⋮ △ x n ] \sigma = \begin{bmatrix} \triangle x_1\\ \triangle x_2\\ \vdots \\ \triangle x_n \end{bmatrix} σ= x1x2xn 二阶导数矩阵hessian矩阵 G G G G = [ ∂ 2 f ∂ x 1 2 ,   ∂ 2 f ∂ x 1 ∂ x 2 , … , ∂ 2 f ∂ x 1 ∂ x n ∂ 2 f ∂ x 2 ∂ x 1 , ∂ 2 f ∂ x 2 2 , … , ∂ 2 f ∂ x 2 ∂ x n ⋮ ∂ 2 f ∂ x n ∂ x 1 , ∂ 2 f ∂ x n ∂ x 2 , … , ∂ 2 f ∂ x n 2 ] G = \begin{bmatrix} \frac{\partial^2 f}{\partial x_1^2},\ \frac{\partial^2 f}{\partial x_1 \partial x_2}, \ldots, \frac{\partial^2 f}{\partial x_1 \partial x_n}\\ \frac{\partial^2 f}{\partial x_2 \partial x_1}, \frac{\partial^2 f}{\partial x_2^2}, \ldots, \frac{\partial^2 f}{\partial x_2 \partial x_n}\\ \vdots\\ \frac{\partial^2 f}{\partial x_n \partial x_1}, \frac{\partial^2 f}{\partial x_n \partial x_2}, \ldots, \frac{\partial^2 f}{ \partial x_n^2} \end{bmatrix} G= x122f, x1x22f,,x1xn2fx2x12f,x222f,,x2xn2fxnx12f,xnx22f,,xn22f 可以看出 G G G是对称矩阵,即 G = G T G = G^T G=GT

我们有:
f ( X + σ ) = f ( X ) + g T ⋅ σ + 1 2 σ T ⋅ G ⋅ σ + o ( ∣ ∣ σ ∣ ∣ 2 ) f(X + \sigma) = f(X) + g^T \cdot \sigma + \frac{1}{2}\sigma^T \cdot G \cdot \sigma + \textit{o}(||\sigma||^2) f(X+σ)=f(X)+gTσ+21σTGσ+o(∣∣σ2)

利用前面学到的向量求导公式,对 σ \sigma σ求导,使得导数为0,即
∂ f ( X + σ ) ∂ σ = g + 1 2 ( G + G T ) ⋅ σ = g + G ⋅ σ = 0 \begin{aligned} \frac{\partial f(X+\sigma)}{\partial \sigma} &= g + \frac{1}{2}(G+G^T) \cdot \sigma \\ &= g+G \cdot \sigma \\ &= 0\end{aligned} σf(X+σ)=g+21(G+GT)σ=g+Gσ=0 因此,我们有: σ = − G − 1 ⋅ g \sigma = - G^{-1} \cdot g σ=G1g
然后我们就可以利用得到的 σ \sigma σ,得到新的 X n e w = X + σ X_{new} = X + \sigma Xnew=X+σ,进行下一步迭代。

牛顿法代码Demo篇

计算 g g g G G G的代码:

def gradient_w(w, b):
    return np.average([2*(w*xi + b - yi)* xi for (xi, yi) in list(zip(x,y))])
def gradient_b(w, b):
    return np.average([2*(w*xi + b - yi) for (xi, yi) in list(zip(x,y))])

def gradient_w_w(w, b):
    return np.average([2 * xi * xi for (xi, yi) in list(zip(x, y))])
def gradient_w_b(w, b):
    return np.average([2 * xi for (xi, yi) in list(zip(x, y))])
def gradient_b_w(w, b):
    return np.average([2 * xi for (xi, yi) in list(zip(x,y))])
def gradient_b_b(w, b):
    return np.average([2 for (xi, yi) in list(zip(x,y))])
def error(w, b):
    return np.average([np.square(w*xi + b - yi) for (xi, yi) in list(zip(x,y))])

牛顿迭代的代码:

erros = [[], []]
for i in range(2000):
    g = np.mat([gradient_w(w0, b0), gradient_b(w0, b0)]).T
    G = np.mat([[gradient_w_w(w0, b0), gradient_w_b(w0, b0)], [gradient_b_w(w0, b0), gradient_b_b(w0, b0)]])
    
    sigma = -G.I * g
    w1 = w0 + sigma[0, 0]
    b1 = b0 + sigma[1, 0]
    
    erros[0].append(i)  
    erros[1].append(error(w1, b1))
    w0, b0 = w1, b1
    
plt.plot(x, y, 'k+')
plt.plot(x, w0 * x + b0, 'r')
plt.show()

从误差结果看,它一次迭代就可以得到最小值,后经过@景宽提醒,牛顿法本身计算的就是二阶泰勒展开的值。我们上述的直线方程只有两个系数,它的三阶泰勒值就是0,因此二阶泰勒展开就是它的最小值了。

最小二乘法的最大似然解释

前面在Section基本介绍中,我们直接用平方损失函数来最小化来得到最优直线。那么,你是否有疑问,为什么平方损失函数最小就可以得到最优的直线,而不是绝对值损失,或者四次方损失呢?

这其实涉及到概率论中的最大似然估计.
上述的问题,可以转化为:对于 m m m个点形成的集合 D = { d 1 , d 2 , … , d m } D = \{d1, d2, \ldots, d_m\} D={d1,d2,,dm},我们需要拟合一条直线 h h h,以使得拟合的直线最切合这个数据集合 D D D,也就是说我们要最大化概率 P ( h ∣ D ) P(h|D) P(hD)

由贝叶斯公式 P ( h ∣ D ) = P ( D ∣ h ) ⋅ P ( h ) P ( D ) ∝ P ( D ∣ h ) \begin{aligned} P(h | D) &= \frac{P(D|h) \cdot P(h)}{P(D)} \propto P(D|h)\end{aligned} P(hD)=P(D)P(Dh)P(h)P(Dh)
如果各个点相互独立,则
P ( h ∣ D ) ∝ P ( d 1 ∣ h ) ⋅ P ( d 2 ∣ h ) ⋅ … ⋅ P ( d n ∣ h ) P(h|D) \propto P(d_1|h) \cdot P(d_2|h) \cdot \ldots \cdot P(d_n |h) P(hD)P(d1h)P(d2h)P(dnh)

对于 P ( d i ∣ h ) P(d_i |h) P(dih)表示的是在给定直线 h h h的情况下,具有点 d i d_i di的概率。我们假设各个点的误差 △ y i = y i ‾ − y i \triangle y_i = \overline{y_i}-y_i yi=yiyi服从均值为0,方差为 σ \sigma σ的正态分布,也就是说,在给定直线 h h h的情况下,点 d i d_i di出现的概率为服从:
P ( d i ∣ h ) ∝ e − △ 2 y i 2 σ 2 P(d_i | h) \propto e^{-\frac{\triangle^2 y_i}{2 \sigma^2}} P(dih)e2σ22yi

于是,我们有:
P ( h ∣ D ) ∝ e ∑ i = 1 m ( − △ 2 y i 2 σ 2 ) P(h|D) \propto e^{\sum_{i=1}^{m}(-\frac{\triangle^2 y_i}{2 \sigma^2})} P(hD)ei=1m(2σ22yi)

从而最大化 P ( h ∣ D ) P(h|D) P(hD),等价于最小化 ∑ i = 1 m ( △ 2 y i ) \sum_{i=1}^{m}(\triangle^2 y_i) i=1m(2yi),也就是前面说的最小化平方误差。

另一种说法:
对于样本点 d i d_i di,对样本点的预测取决于参数 θ \theta θ的选取,且我们有
△ y i = y i ‾ − y i \triangle y_i = \overline{y_i} -y_i yi=yiyi
其中 y i ‾ \overline{y_i} yi y i y_i yi的预测值, y i y_i yi为真实值, △ y i \triangle y_i yi为误差。

一般我们认为误差服从正态分布,即 △ y i ∼ N ( 0 , σ ) \begin{aligned} \triangle y_i \sim \textit{N}(0, \sigma)\end{aligned} yiN(0,σ)
现在我们需要选取 θ \theta θ,以使得取得 y i y_i yi的概率最大,即
L ( θ ) = ∏ i = 1 m P ( y i ∣ θ ) = ∏ i = 1 m 1 2 π σ exp ⁡ ( − △ 2 y i 2 σ ) L(\theta) = \prod_{i=1}^{m} P(y_i | \theta) = \prod_{i=1}^m\frac{1}{\sqrt{2\pi}\sigma}\exp(-\frac{\triangle ^2 y_i}{2\sigma}) L(θ)=i=1mP(yiθ)=i=1m2π σ1exp(2σ2yi)
两边取 l o g log log,乘积变求和,因此同样转换为最小化 ∑ i = 1 m ( △ 2 y i ) \sum_{i=1}^{m}(\triangle^2 y_i) i=1m(2yi),也就是前面说的最小化平方误差。

参考文献:

https://www.cnblogs.com/21207-iHome/p/5222993.html

http://blog.csdn.net/ying_xu/article/details/51240291

https://www.cnblogs.com/happylion/p/4172632.html

http://blog.csdn.net/lydyangliu/article/details/9208635

http://www.fuzihao.org/blog/2014/06/13/为什么最小二乘法对误差的估计要用平方/

https://www.zhihu.com/question/20447622

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值