详解标准方程法(内含公式推导和代码)

标准方程法

标准方程法就是通过一些方法直接求出权值ω的值,以往的文章已将讲过了代价函数的相关内容,这里直接给出代价函数的公式:
J ( ω 0 , ω 1 , ω 2 , … , ω n ) = ∑ i = 1 m [ y i − h ω ( x i ) ] 2 J(ω_0,ω_1,ω_2,\dots,ω_n)=\sum_{i=1}^m[y_i-h_ω(x_i)]^2 J(ω0,ω1,ω2,,ωn)=i=1m[yihω(xi)]2
其中 h ω ( x ) h_ω(x) hω(x)的公式如下:
h ω ( x ) = ω 0 + ω 1 x 1 + ω 2 x 2 + ⋯ + ω n x n h_ω(x)=ω_0+ω_1x_1+ω_2x_2+\dots+ω_nx_n hω(x)=ω0+ω1x1+ω2x2++ωnxn
如果数据集中只有一条数据,通过矩阵可以描述成一下形式:
X = [ x 0 x 1 x 2 … x n ] , 其 中 x 0 = 1 X = \begin{bmatrix} x_0 & x_1 & x_2 & \dots & x_n \end{bmatrix},其中x_0=1 X=[x0x1x2xn],x0=1

w = [ ω 0 ω 1 ω 2 ⋮ ω n ] w=\begin{bmatrix} ω_0 \\ ω_1 \\ ω_2 \\ \vdots \\ ω_n \end{bmatrix} w=ω0ω1ω2ωn

h ω ( x ) = X ∗ w = [ x 0 x 1 x 2 … x n ] ∗ [ ω 0 ω 1 ω 2 ⋮ ω n ] = ω 0 + ω 1 x 1 + ω 2 x 2 + ⋯ + ω n x n \begin{aligned} h_ω(x)=X*w=\begin{bmatrix} x_0 & x_1 & x_2 & \dots & x_n \end{bmatrix} *\begin{bmatrix} ω_0 \\ ω_1 \\ ω_2 \\ \vdots \\ ω_n \end{bmatrix} \\ =ω_0+ω_1x_1+ω_2x_2+\dots+ω_nx_n \end{aligned} hω(x)=Xw=[x0x1x2xn]ω0ω1ω2ωn=ω0+ω1x1+ω2x2++ωnxn

一般数据集中,会有很多条数据,每一条数据通过上述公式都会得到一个 h ω ( x ) h_ω(x) hω(x),故通过矩阵可以描述成以下形式:
x 0 x 1 x 2 … x n X = [ 1 a 1 a 2 … a n 1 b 1 b 2 … b n … … … … … 1 n 1 n 2 … n n ] n ∗ ( n + 1 ) x_0\quad x_1\quad x_2 \quad \dots \quad x_n \\ X = \begin{bmatrix} 1 & a_1 & a_2 & \dots & a_n \\ 1 & b_1 & b_2 & \dots & b_n \\ \dots & \dots & \dots & \dots & \dots \\ 1 & n_1 & n_2 & \dots & n_n \end{bmatrix}_{n*(n+1)} x0x1x2xnX=111a1b1n1a2b2n2anbnnnn(n+1)

w = [ ω 0 ω 1 ω 2 ⋮ ω n ] ( n + 1 ) ∗ 1 w=\begin{bmatrix} ω_0 \\ ω_1 \\ ω_2 \\ \vdots \\ ω_n \end{bmatrix}_{(n+1)*1} w=ω0ω1ω2ωn(n+1)1

h ω ( x ) = X ∗ w = [ 1 a 1 a 2 … a n 1 b 1 b 2 … b n … … … … … 1 n 1 n 2 … n n ] ∗ [ ω 0 ω 1 ω 2 ⋮ ω n ] = [ ω 0 + ω 1 a 1 + ω 2 a 2 + ⋯ + ω n a n ω 0 + ω 1 b 1 + ω 2 b 2 + ⋯ + ω n b n ⋮ ω 0 + ω 1 n 1 + ω 2 n 2 + ⋯ + ω n n n ] = [ h ω ( x 1 ) h ω ( x 2 ) ⋮ h ω ( x n ) ] n ∗ 1 \begin{aligned} h_ω(x)=X*w&=\begin{bmatrix} 1 & a_1 & a_2 & \dots & a_n \\ 1 & b_1 & b_2 & \dots & b_n \\ \dots & \dots & \dots & \dots & \dots \\ 1 & n_1 & n_2 & \dots & n_n \end{bmatrix} *\begin{bmatrix} ω_0 \\ ω_1 \\ ω_2 \\ \vdots \\ ω_n \end{bmatrix} \\ &=\begin{bmatrix} ω_0+ω_1a_1+ω_2a_2+\dots+ω_na_n \\ ω_0+ω_1b_1+ω_2b_2+\dots+ω_nb_n \\ \vdots \\ ω_0+ω_1n_1+ω_2n_2+\dots+ω_nn_n \end{bmatrix} \\ &=\begin{bmatrix} h_ω(x_1) \\ h_ω(x_2) \\ \vdots \\ h_ω(x_n) \end{bmatrix}_{n*1} \end{aligned} hω(x)=Xw=111a1b1n1a2b2n2anbnnnω0ω1ω2ωn=ω0+ω1a1+ω2a2++ωnanω0+ω1b1+ω2b2++ωnbnω0+ω1n1+ω2n2++ωnnn=hω(x1)hω(x2)hω(xn)n1

那么代价函数如何用这种形式表示呢?别急,看下面这个公式
∑ i = 1 n [ y i − h ω ( x i ) ] 2 = ( y i − X w ) T ( y i − X w ) \sum_{i=1}^n[y_i-h_ω(x_i)]^2=(y_i-Xw)^T(y_i-Xw) i=1n[yihω(xi)]2=(yiXw)T(yiXw)
证明如下
y i − X w = [ y 1 − h ω ( x 1 ) y 2 − h ω ( x 2 ) ⋮ y n − h ω ( x n ) ] y_i-Xw=\begin{aligned} \begin{bmatrix} y_1-h_ω(x_1) \\ y_2-h_ω(x_2) \\ \vdots \\ y_n-h_ω(x_n) \end{bmatrix} \end{aligned} yiXw=y1hω(x1)y2hω(x2)ynhω(xn)

( y i − X w ) T ( y i − X w ) = [ y 1 − h ω ( x 1 ) y 2 − h ω ( x 2 ) … y n − h ω ( x n ) ] ∗ [ y 1 − h ω ( x 1 ) y 2 − h ω ( x 2 ) ⋮ y n − h ω ( x n ) ] = ( y 1 − h ω ( x 1 ) ) 2 + ( y 2 − h ω ( x 2 ) ) 2 + ( y 1 − h ω ( x 1 ) ) 2 + ⋯ + ( y n − h ω ( x n ) ) 2 = ∑ i = 1 n [ y i − h ω ( x i ) ] 2 \begin{aligned} (y_i-Xw)^T(y_i-Xw)&=\begin{bmatrix} y_1-h_ω(x_1) & y_2-h_ω(x_2) & \dots & y_n-h_ω(x_n) \end{bmatrix}*\begin{bmatrix} y_1-h_ω(x_1) \\ y_2-h_ω(x_2) \\ \vdots \\ y_n-h_ω(x_n) \end{bmatrix} \\ &=(y_1-h_ω(x_1))^2+(y_2-h_ω(x_2))^2+(y_1-h_ω(x_1))^2+\dots+(y_n-h_ω(x_n))^2 \\ &=\sum_{i=1}^n[y_i-h_ω(x_i)]^2 \end{aligned} (yiXw)T(yiXw)=[y1hω(x1)y2hω(x2)ynhω(xn)]y1hω(x1)y2hω(x2)ynhω(xn)=(y1hω(x1))2+(y2hω(x2))2+(y1hω(x1))2++(ynhω(xn))2=i=1n[yihω(xi)]2

证明结束。

但是呢,到这里肯定是还没有结束的,我们知道了代价函数,接下来一步就是去求最小值。提到函数和最小值,用我为数不多的数学知识那就是求导了,我现在脑海中只剩了一顿求导,令其为零了。好了,接下来就让我们一起来求导吧!!!
∂ ( y − X w ) T ( y − X w ) ∂ w = ∂ ( y T − w T X T ) ( y − X w ) ∂ w = ∂ ( y T y − y T X w − w T X T y + w T X T X w ) ∂ w = ∂ y T y ∂ w − ∂ y T X w ∂ w − ∂ w T X T y ∂ w + ∂ w T X T X w ∂ w \begin{aligned} &\frac{∂(y-Xw)^T(y-Xw)}{∂w} \\ &=\frac{∂(y^T-w^TX^T)(y-Xw)}{∂w} \\ &=\frac{∂(y^Ty-y^TXw-w^TX^Ty+w^TX^TXw)}{∂w} \\ &=\frac{∂y^Ty}{∂w}-\frac{∂y^TXw}{∂w}-\frac{∂w^TX^Ty}{∂w}+\frac{∂w^TX^TXw}{∂w} \end{aligned} w(yXw)T(yXw)=w(yTwTXT)(yXw)=w(yTyyTXwwTXTy+wTXTXw)=wyTywyTXwwwTXTy+wwTXTXw
对其各自求偏导得:
∂ y T y ∂ w = 0 ∂ y T X w ∂ w = X T y ∂ w T X T y ∂ w = ( ∂ w T X T y ) T ∂ w = ∂ y T X w ∂ w = X T y ∂ w T X T X w ∂ w = 2 X T X w \begin{aligned} \frac{∂y^Ty}{∂w}&=0 \\ \frac{∂y^TXw}{∂w}&=X^Ty \\ \frac{∂w^TX^Ty}{∂w}&=\frac{(∂w^TX^Ty)^T}{∂w}=\frac{∂y^TXw}{∂w}=X^Ty \\ \frac{∂w^TX^TXw}{∂w}&=2X^TXw \end{aligned} wyTywyTXwwwTXTywwTXTXw=0=XTy=w(wTXTy)T=wyTXw=XTy=2XTXw
整合一下:
∂ y T y ∂ w − ∂ y T X w ∂ w − ∂ w T X T y ∂ w + ∂ w T X T X w ∂ w = 0 − X T y − X T y + 2 X T X w \frac{∂y^Ty}{∂w}-\frac{∂y^TXw}{∂w}-\frac{∂w^TX^Ty}{∂w}+\frac{∂w^TX^TXw}{∂w}=0-X^Ty-X^Ty+2X^TXw wyTywyTXwwwTXTy+wwTXTXw=0XTyXTy+2XTXw
令其为零:
− 2 X T y + 2 X T X w = 0 X T X w = X T y ( X T X ) − 1 X T X w = ( X T X ) − 1 X T y w = ( X T X ) − 1 X T y \begin{aligned} -2X^Ty+2X^TXw&=0 \\ X^TXw&=X^Ty \\ (X^TX)^{-1}X^TXw&=(X^TX)^{-1}X^Ty \\ w&=(X^TX)^{-1}X^Ty \end{aligned} 2XTy+2XTXwXTXw(XTX)1XTXww=0=XTy=(XTX)1XTy=(XTX)1XTy
到这里 w w w就是我们苦苦寻求的值了,而其中 ( X T X ) − 1 (X^TX)^{-1} (XTX)1 X T X ) X^TX) XTX)的逆矩阵。

不可逆的情况

这里再给出两种不可逆的情况

  1. 线性相关特征(多重共线性)
    • x1为房屋面积,单位是平方英尺
    • x2为房屋面积,单位是平方米
  2. 特征数据太多(样本数m ≤ \le 特征数量n)

梯度下降和标准方程的比较

梯度下降法标准方程法
优点当特征值非常多的时候也可以很好的工作不需要学习率
不需要迭代
可以得到全局最优解
缺点需要选择合适的学习率
需要迭代很多个周期
最能得到最优解的近似值
需要计算 ( X T X ) − 1 (X^TX)^{-1} (XTX)1
时间复杂度大约是 O ( n 3 ) O(n^3) O(n3)
n是特征数量

代码实现

import numpy as np
from numpy import genfromtxt
import matplotlib.pyplot as plt

# 载入数据
data = np.genfromtxt("data.csv", delimiter=",")
x_data = data[:,0,np.newaxis]
y_data = data[:,1,np.newaxis]
plt.scatter(x_data,y_data)
plt.show()

print(np.mat(x_data).shape)
print(np.mat(y_data).shape)
# 给样本添加偏置项
X_data = np.concatenate((np.ones((100,1)),x_data),axis=1)
print(X_data.shape)

# 标准方程法求解回归参数
def weights(xArr, yArr):
    xMat = np.mat(xArr)
    yMat = np.mat(yArr)
    xTx = xMat.T*xMat # 矩阵乘法
    # 计算矩阵的值,如果值为0,说明该矩阵没有逆矩阵
    if np.linalg.det(xTx) == 0.0:
        print("This matrix cannot do inverse")
        return
    # xTx.I为xTx的逆矩阵
    ws = xTx.I*xMat.T*yMat
    return ws
    
#使用numpy本身函数求解
#相关函数可以点击链接查看
#https://www.numpy.org.cn/article/basics/numpy_matrices_vectors.html#%E7%94%A8numpy%E6%B1%82%E8%A7%A3%E6%96%B9%E7%A8%8B%E7%BB%84
def numpy_weights(xArr, yArr):
    xMat = np.mat(xArr)
    yMat = np.mat(yArr)
    xT = np.transpose(xMat)#转置矩阵
    xTx = np.dot(xT, xMat)#矩阵乘
    if np.linalg.det(xTx) == 0.0:
        print("This matrix cannot do inverse")
        return
    xTy = np.dot(xT, yMat)
    ws = np.linalg.solve(xTx,xTy)
    return ws

#调用函数
ws = weights(X_data,y_data)
ws1 = numpy_weights(X_data,y_data)
print(ws)
print(ws1)
    
 # 画图
x_test = np.array([[20],[80]])
y_test = ws[0] + x_test*ws[1]
plt.plot(x_data, y_data, 'b.')
plt.plot(x_test, y_test, 'r')
plt.show()
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值