对于线性回归问题,除了前面提到的最小二乘法可以解决一元线性回归的问题外,对于多元线性回归,可以用正规方程来解决,也就是得到一个数学上的解析解。也就是说可以铜鼓数学计算,一次性求得最优解。它可以解决下面这个公式描述的问题:
(1) y = a 0 + a 1 x 1 + a 2 x 2 + ⋯ + a k x k y=a_0+a_1x_1+a_2x_2+\dots+a_kx_k \tag{1} y=a0+a1x1+a2x2+⋯+akxk(1)
或者写成神经网络模型的方式:
(2) Z = w 1 x 1 + w 2 x 2 + w 3 x 3 + b = W ⋅ X + B Z = w_1x_1+w_2x_2+w_3x_3+b = W \cdot X + B \tag{2} Z=w1x1+w2x2+w3x3+b=W⋅X+B(2)
简单的推导方法
在做函数拟合(回归)时,我们假设函数H为:
(3) H ( w , b ) = b + w 1 x 1 + w 2 x 2 + . . . + w n x n H(w,b) = b + w_1x_1+w_2x_2+...+w_nx_n \tag{3} H(w,b)=b+w1x1+w2x2+...+wnxn(3)
令 b = w 0 b=w_0 b=w0,则:
(4) H ( w ) = w 0 ⋅ 1 + w 1 ⋅ x 1 + w 2 ⋅ x 2 + . . . + w n ⋅ x n = W ⋅ X = X ⋅ W H(w) = w_0 \cdot 1 + w_1 \cdot x_1+w_2 \cdot x_2+...+w_n \cdot x_n = W \cdot X = X \cdot W \tag{4} H(w)=w0⋅1+w1⋅x1+w2⋅x2+...+wn⋅xn=W⋅X=X⋅W(4)
(5) X m × ( n + 1 ) = ( 1 x 1 , 1 x 1 , 2 … x 1 , n 1 x 2 , 1 x 2 , 2 … x 2 , n … 1 x m , 1 x m , 2 … x m , n ) X^{m \times (n+1)} = \begin{pmatrix} 1 & x_{1,1} & x_{1,2} & \dots & x_{1,n} \ 1 & x_{2,1} & x_{2,2} & \dots & x_{2,n} \ \dots \ 1 & x_{m,1} & x_{m,2} & \dots & x_{m,n} \end{pmatrix} \tag{5} Xm×(n+1)=(1x1,1x1,2…x1,n 1x2,1x2,2…x2,n … 1xm,1xm,2…xm,n)(5)
(6) W ( n + 1 ) × 1 = ( w 0 w 1 … w n ) W^{(n+1) \times 1}= \begin{pmatrix} w_0 \ w_1 \ \dots \ w_n \end{pmatrix} \tag{6} W(n+1)×1=(w0 w1 … wn)(6)
(7) Y m × 1 = ( y 1 y 2 … y m ) Y^{m \times 1}= \begin{pmatrix} y_1 \ y_2 \ \dots \ y_m \end{pmatrix} \tag{7} Ym×1=(y1 y2 … ym)(7)
我们期望假设函数的输出与真实值一致,则有:
(8) H ( w ) = X ⋅ W = Y H(w) = X \cdot W = Y \tag{8} H(w)=X⋅W=Y(8)
直观上看,W = Y/X,但是这里三个值都是矩阵,但是矩阵没有除法,所以要得到X的逆矩阵,但是X不一定是方阵,所以要先把左侧变成方阵,就可能会有逆矩阵存在了,两边同时乘上X的转置矩阵:
(9) X T X W = X T Y X^T X W = X^T Y \tag{9} XTXW=XTY(9)
其中, X T X^T XT是X的转置矩阵, X T X X^T X XTX一定是个方阵,并且假设其存在逆矩阵,把它移到等式右侧来:
(10) W = X T Y X T X = ( X T X ) − 1 X T Y W = \frac{X^T Y}{X^T X}=(X^T X)^{-1}{X^T Y} \tag{10} W=XTXXTY=(XTX)−1XTY(10)
至此可以求出W的正规方程。
复杂的推导方法
我们仍然使用均方差损失函数:
J ( w , b ) = ∑ ( z i − y i ) 2 J(w,b) = \sum (z_i - y_i)^2 J(w,b)=∑(zi−yi)2
把b看作是一个恒等于1的feature,并把z=XW计算公式带入,并变成矩阵形式:
J ( w ) = ∑ ( x i w i − y i ) 2 = ( X W − Y ) T ⋅ ( X W − Y ) J(w) = \sum (x_i w_i -y_i)^2=(XW - Y)^T \cdot (XW - Y) J(w)=∑(xiwi−yi)2=(XW−Y)T⋅(XW−Y)
对w求导,令导数为0,就是W的最小值解:
∂ J ( w ) ∂ w = ∂ ∂ w [ ( X W − Y ) T ⋅ ( X W − Y ) ] {\partial J(w) \over \partial w} = {\partial \over \partial w}[(XW - Y)^T \cdot (XW - Y)] ∂w∂J(w)=∂w∂[(XW−Y)T⋅(XW−Y)] = ∂ ∂ w [ ( X T W T − Y T ) ⋅ ( X W − Y ) ] ={\partial \over \partial w}[(X^TW^T - Y^T) \cdot (XW - Y)] =∂w∂[(XTWT−YT)⋅(XW−Y)] = ∂ ∂ w [ ( X T X W T W − X T W T Y − Y T X W + Y T Y ) ] ={\partial \over \partial w}[(X^TXW^TW -X^TW^TY - Y^TXW + Y^TY)] =∂w∂[(XTXWTW−XTWTY−YTXW+YTY)]
第一项的结果是: 2 X T X W 2X^TXW 2XTXW
第二项和第三项的结果都是: X T Y X^TY XTY
第四项的结果是:0
再令导数为0:
J ′ ( w ) = 2 X T X W − X T Y − X T Y = 0 J'(w)=2X^TXW -X^TY - X^TY=0 J′(w)=2XTXW−XTY−XTY=0 2 X T X W = 2 X T Y 2X^TXW = 2X^TY 2XTXW=2XTY X T X W = X T Y X^TXW = X^TY XTXW=XTY W = X T Y X T X = ( X T X ) − 1 X T Y W={X^TY \over X^TX}=(X^TX)^{-1}X^TY W=XTXXTY=(XTX)−1XTY
以上推导的基本公式可以参考第0章的公式60-69。
逆矩阵 ( X T X ) − 1 (X^TX)^{-1} (XTX)−1可能不存在的原因是:
特征值冗余,比如 x 2 = x 1 2 x_2=x^2_1 x2=x12,即正方形的边长与面积的关系,不能做为两个特征同时存在
特征数量过多,比如特征数n比样本数m还要大
我们先看一下样本数据的样子:
样本序号 | 1 | 2 | 3 | 4 | … | 1000 |
---|---|---|---|---|---|---|
朝向(东南西北) | 1 | 4 | 2 | 4 | … | 2 |
地理位置(几环) | 3 | 2 | 6 | 3 | … | 3 |
居住面积(平米) | 96 | 100 | 54 | 72 | … | 69 |
整套价格(万元) | 434 | 500 | 321 | 482 | … | 410 |
根据公式(5),我们应该建立如下的X,Y矩阵:
(20) X 1000 × 4 = ( 1 1 3 96 1 4 2 100 1 2 6 54 1 4 3 72 … 1 2 3 69 ) X^{1000 \times 4} = \begin{pmatrix} 1 & 1 & 3 & 96 \ 1 & 4 & 2 & 100 \ 1 & 2 & 6 & 54 \ 1 & 4 & 3 & 72 \ \dots \ 1 & 2 & 3 & 69 \end{pmatrix} \tag{20} X1000×4=(11396 142100 12654 14372 … 12369)(20)
(21) Y 1000 × 1 = ( 434 500 321 482 … 410 ) Y^{1000 \times 1}= \begin{pmatrix} 434 \ 500 \ 321 \ 482 \ \dots \ 410 \end{pmatrix} \tag{21} Y1000×1=(434 500 321 482 … 410)(21)
根据公式(10),
(10) W = X T Y X T X = ( X T X ) − 1 X T Y W = \frac{X^T Y}{X^T X}=(X^T X)^{-1}{X^T Y} \tag{10} W=XTXXTY=(XTX)−1XTY(10)
if __name__ == '__main__':
X,Y = LoadData()
num_example = X.shape[1]
one = np.ones((num_example,1))
x = np.column_stack((one, (X[:,0:num_example]).T))
y = (Y[:,0:num_example]).T
a = np.dot(x.T, x)
b = np.asmatrix(a)
c = np.linalg.inv(b)
d = np.dot(c, x.T)
e = np.dot(d, y)
print(e)
w1=e[1]
w2=e[2]
w3=e[3]
b=e[0]
print("w1=%f,w2=%f,w3=%f,b=%f"%(w1,w2,w3,b))
z = w1 * 2 + w2 * 5 + w3 * 93 + b
print(z)
结果:
[[110.]
[ 2.]
[-10.]
[ 5.]]
w1=2.000000,w2=-10.000000,w3=5.000000,b=110.000000
z=[[529.]]
https://github.com/microsoft/ai-edu/blob/master/B-教学案例与实践/B6-神经网络基本原理简明教程/05.1-正规方程法.md