日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

多元线性回归算法python实现_手写算法-Python代码推广多元线性回归

發布時間:2024/9/27 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多元线性回归算法python实现_手写算法-Python代码推广多元线性回归 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、梯度下降-矩陣形式

上篇文章介紹了一元線性回歸,包括Python實現和sklearn實現的實例、對比,以及一些問題點,詳情可以看這里:

鏈接: 手寫算法-Python代碼實現一元線性回歸

里面封裝的one_variable_linear()類只適用于一元線性回歸,

本篇文章修改代碼,推廣至多元線性回歸,并介紹2種更簡潔的方法。

先給大家復習一下矩陣的基本知識:

轉置矩陣:

損失函數可表示為:

可以求得:矩陣形式下,偏導的表達式是:

下面附上我的推導證明過程(剛寫的):

有了上述表達式,我們修改上次的代碼如下:

class linear(): def __init__(self): pass #梯度下降法迭代訓練模型參數,x為特征數據,y為標簽數據,a為學習率,epochs為迭代次數 def fit(self,x,y,a,epochs): #計算總數據量 m=x.shape[0] #給x添加偏置項 X = np.concatenate((np.ones((m,1)),x),axis=1) #計算總特征數 n = X.shape[1] #初始化W的值,要變成矩陣形式 W=np.mat(np.ones((n,1))) #X轉為矩陣形式 xMat = np.mat(X) #y轉為矩陣形式,這步非常重要,且要是m x 1的維度格式 yMat =np.mat(y.reshape(-1,1)) #循環epochs次 for i in range(epochs): W=W-a*xMat.T*(xMat*W-yMat) return W def predict(self,x,w): #這里的x也要加偏置,訓練時x是什么維度的數據,預測也應該保持一樣 return np.dot(x,w)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

依然用上次的測試數據集,2個代碼比較如下:

import numpy as np

import pandas as pd

from sklearn import datasets #sklearn生成數據集都在這里

from matplotlib import pyplot as plt

#生成一個特征的回歸數據集

x,y=datasets.make_regression(n_features=1,noise=15,random_state=2020)

plt.scatter(x,y)

plt.show() class one_variable_linear(): #初始化參數,k為斜率,b為截距,a為學習率,n為迭代次數 def __init__(self,k,b,a,n): self.k =k self.b=b self.a=a self.n = n #梯度下降法迭代訓練模型參數 def fit(self,x,y): #計算總數據量 m=len(x) #循環n次 for i in range(self.n): b_grad=0 k_grad=0 #計算梯度的總和再求平均 for j in range(m): b_grad += (1/m)*((self.k*x[j]+self.b)-y[j]) k_grad += (1/m)*((self.k*x[j]+self.b)-y[j])*x[j] #更新k,b self.b=self.b-(self.a*b_grad) self.k=self.k-(self.a*k_grad) #每迭代10次,就輸出一次圖像 if i%10==0: print('迭代{0}'.format(i)+'次') plt.plot(x,y,'b.') plt.plot(x,self.k*x+self.b,'r') plt.show() self.params= {'k':self.k,'b':self.b} #輸出系數 return self.params #預測函數 def predict(self,x): y_pred =self.k * x + self.b return y_pred

lr=one_variable_linear(k=1,b=1,a=0.1,n=60)

lr.fit(x,y)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

舊代碼得到的參數如上,

新代碼得到的參數如下:

model = linear()

w = model.fit(x,y,a=0.1,epochs=50)

print(w)1

2

3

我的天,這是什么鬼,怎么和上面的差的這么多(其實是我故意的),明顯這個是不正確的,模型完全沒有收斂,問題在哪里?

我們細想一下,正常的梯度下降法,前面是帶m的,而矩陣形式,我們直接約掉了m,相當于學習率就被放大了m倍,所以這里學習率a應該設置為a/m=0.001,這樣a就相等了,迭代次數也相等,冥冥中感覺這次的系數應該是一樣的才對。再跑一下代碼:

w = model.fit(x,y,a=0.001,epochs=50)

print(w)1

2

3

哈哈,完全一樣,破案了,這里也解釋了,之前說的,為什么損失函數前面1/2m這個值,其實對模型的參數沒有影響,

但是你的學習率要選擇得對,不能可能無法收斂。

現在這個類就是Python線性回歸代碼的一般式了,設置合理的學習率和迭代次數,就會得到不錯的結果。

2、標準方程法

下面來介紹第二種方法,標準方程法。

有了前面的鋪墊,這里就很容易理解了,損失函數:

因為這是一個凸函數,因此一定有極小值。根據最小二乘法的原理,我們要對這個損失函數對θ向量求導取0。結果如下式:

這個推導過程中也可以看到,1/2m對最終的系數沒有影響,可以直接被約掉。

編寫標準方程法代碼如下:

class normal(): def __init__(self): pass def fit(self,x,y): m=x.shape[0] X = np.concatenate((np.ones((m,1)),x),axis=1) xMat=np.mat(X) yMat =np.mat(y.reshape(-1,1)) xTx=xMat.T*xMat #xTx.I為xTx的逆矩陣 ws=xTx.I*xMat.T*yMat return ws model =normal()

model.fit(x,y)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

求出來的參數為:

這里要注意:XTX的逆矩陣不是什么時候都可以求得出來的,以下情況求不到XTX的逆矩陣:

1、特征數據高度線性相關;

2、n >>m,即特征數量大于樣本數量,此時為非滿秩矩陣;

sklearn實現對比標準方程法

from sklearn.linear_model import LinearRegression

LR=LinearRegression()

LR.fit(x,y)

LR.intercept_,LR.coef_1

2

3

4

和編寫的標準方程法得到的參數一模一樣,這里回答了之前說過為什么梯度下降法得到的參數和sklearn里面得到的參數不一樣的問題,也說明了sklearn中封裝的是標準方程法,畢竟真的簡單!

下篇介紹非線性回歸,當數據表現為非線性時,該怎么處理。

文章來源: blog.csdn.net,作者:Dream-YH,版權歸原作者所有,如需轉載,請聯系作者。

原文鏈接:blog.csdn.net/weixin_44700798/article/details/110452229

總結

以上是生活随笔為你收集整理的多元线性回归算法python实现_手写算法-Python代码推广多元线性回归的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。