1. 程式人生 > 其它 >線性迴歸的兩種演算法實現 梯度下降和解析法(西瓜書學習)

線性迴歸的兩種演算法實現 梯度下降和解析法(西瓜書學習)

技術標籤:python機器學習演算法

線性迴歸演算法實現

規定

d個屬性描述的示例
x = ( x 1 . . . x d ) x= \begin{pmatrix} x_1\\ ...\\ x_d \end{pmatrix} x=x1...xd
x i x_i xi為第i個屬性的取值

即:
f ( x ) = w 1 x 1 + w 2 x 2 + . . . + w d x d + b f(x)=w_1x_1+w_2x_2+...+w_dx_d+b f(x)=w1x1+w2x2+...+wdxd+b
向量形式:
f ( x ) = w T x + b , w = ( w 1 . . . w d ) f(x)=w^Tx+b, w= \begin{pmatrix} w_1\\ ...\\ w_d \end{pmatrix}

f(x)=wTx+b,w=w1...wd

將w和b一起寫為向量形式
即:
W ^ = ( w b ) \hat{W}= \begin{pmatrix} w\\ b \end{pmatrix} W^=(wb)
資料集表示為
D = { ( x 1 , y 1 ) , . . . , ( x m , y m ) } , x i = ( x i 1 . . . x i d ) , y i ∈ R D=\{(x_1,y_1),...,(x_m,y_m)\}, x_i= \begin{pmatrix} x_{i1}\\ ...\\ x_{id} \end{pmatrix}, y_i\in R

D={(x1,y1),...,(xm,ym)},xi=xi1...xid,yiR

資料集轉化為矩陣
X = ( x 11 x 12 . . . x 1 d 1 x 21 x 22 . . . x 2 d 1 . . . . . . . . . . . . . . . x m 1 x m 2 . . . x m d 1 ) X= \begin{pmatrix} x_{11} & x_{12} & ... & x_{1d} & 1\\ x_{21} & x_{22} & ... & x_{2d} & 1\\ ... & ... & ... & ... & ...\\ x_{m1} & x_{m2} & ... & x_{md} & 1 \end{pmatrix}

X=x11x21...xm1x12x22...xm2............x1dx2d...xmd11...1
Y = ( y 1 . . . y m ) Y= \begin{pmatrix} y_1\\ ...\\ y_m \end{pmatrix} Y=y1...ym
代價函式
J ( W ^ ) = 1 2 m ( Y − X W ^ ) T ( Y − X W ^ ) J(\hat{W})=\frac{1}{2m}(Y-X\hat{W})^T(Y-X\hat{W}) J(W^)=2m1(YXW^)T(YXW^)

引數估計和解釋

( w , b ) = arg ⁡ min ⁡ ( w , b ) J ( W ^ ) (w,b)=\mathop{\arg\min}\limits_{(w,b)}J(\hat{W}) (w,b)=(w,b)argminJ(W^)
使得
f ( x ) = X W ^ ≃ Y f(x)=X\hat{W}\simeq Y f(x)=XW^Y
均方誤差有非常好的幾何意義,它對應了常用的歐式距離。基於均方誤差最小化進行模型求解的方法加最小二乘法。線上性迴歸中,最小二乘法就是試圖找到一個條直線,使得所有樣本到直線上的距離最小

梯度下降

J ( W ^ ) J(\hat{W}) J(W^)導數為
1 m X T ( X W ^ − Y ) \frac{1}{m}X^T(X\hat{W}-Y) m1XT(XW^Y)
W ^ − = J ′ ( W ^ ) \hat{W}-=J^{'}({\hat{W}}) W^=J(W^)

正規方程解法

公式為
W ^ = ( X T X ) − 1 X T Y = X − 1 Y \hat{W}=(X^TX)^{-1}X^TY =X^{-1}Y W^=(XTX)1XTY=X1Y

匯入庫

import numpy as np
import matplotlib.pyplot as plt

準備資料

# 樣本數量
m=100
# 初始化資料
X=np.linspace(0,10,m)
Y=X+2+np.random.randn(m)
# 展示樣本資料
plt.scatter(X,Y)
plt.show()
# 將樣本資料矩陣化
X=X.reshape((m,1))
X1=np.hstack((np.ones_like(X),X))
Y=Y.reshape((m,1))
# 引數
omiga=np.zeros(2).reshape((2,1))
# 步長
alpha=0.01
precision=1e-3

在這裡插入圖片描述

代價函式

# 代價函式
def cost(omiga,X,Y):
    return (Y-[email protected]).T @ (Y-[email protected])

梯度迭代

# 代價列表
costs=[]
while True:
    costs.append(cost(omiga,X1,Y)[0][0])
    omiga -=alpha /m * X1.T @ ( X1 @ omiga - Y )
    if len(costs)>1: 
        if costs[-2]-costs[-1]<=precision:
            break
# 代價函式曲線
plt.plot(np.arange(len(costs)),costs)
plt.show()

在這裡插入圖片描述

展示結果

plt.plot(X,X1 @ omiga)
plt.scatter(X,Y)
plt.show()


在這裡插入圖片描述

print(omiga)
[[1.80041713]
 [1.05535637]]

正規方程

# omiga = np.linalg.pinv(X1.T @ X1) @ X1.T @ Y
# print(omiga)
omiga=np.linalg.pinv(X1) @ Y
print(omiga)
[[1.88910625]
 [1.04202106]]
plt.plot(X,X1 @ omiga)
plt.scatter(X,Y)
plt.show()


在這裡插入圖片描述