基於jupyter notebook的python編程-----利用梯度下降算法求解多元線性迴歸方程,並與最小二乘法求解進行精度對比


梯度下降算法是迭代法的一種,可以用於求解最小二乘問題(線性和非線性都可以),在求解機器學習算法的模型參數,即無約束優化問題時,梯度下降(Gradient Descent)是最常採用的方法之一。
在機器學習中,基於基本的梯度下降法發展了兩種梯度下降方法,分別爲隨機梯度下降法和批量梯度下降法。
所以,本次博客,林君學長將帶大家瞭解,如何通過梯度下降算法,求解迴歸曲線的方程,並與最小二乘法求解方程的精度進行對比

一、梯度下降算法的基本原理

1、梯度下降算法的基本原理

1)、梯度下降算法的基本原理就是通過多次迭代,求得與精度值匹配的最後結果,他的迭代公式如下所示:
在這裏插入圖片描述
在這裏插入圖片描述
2)、梯度下降算法的特點

梯度下降法是一個最優化算法,通常也稱爲最速下降法。最速下降法是求解無約束優化問題最簡單和最古老的方法之一,雖然現在已經不具有實用性,但是許多有效算法都是以它爲基礎進行改進和修正而得到的。最速下降法是用負梯度方向爲搜索方向的,最速下降法越接近目標值,步長越小,前進越慢。

二、題目、表格數據、以及python環境搭建

1、多元線性迴歸分析求解題目

1)、多元線性迴歸的題目描述如下:
爲求得某個地區的商品店的月營業額是與店鋪的面積相關性大,還是與該店距離車站距離的相關性大,需要我們以店鋪面積、距離車站的距離、以及月營業額建立線性迴歸方程,並求解該方程,和相關係數:
在這裏插入圖片描述

2、準備的多元線性迴歸方程的變量的表格數據

1)、該題目所用的數據如下所示:
在這裏插入圖片描述
在這裏插入圖片描述
從左到右,一次爲店鋪面積、距離車站距離和月營業額!

3、搭建python環境

1)、打開Windows終端命令行,輸入jupyter notebook,打開我們的jupyter工具,如下所示:
在這裏插入圖片描述
2)、在jupyter的web網頁中創建python文件,如下所示:
在這裏插入圖片描述
3)、現在就可以在jupyter的代碼行裏面輸入我們的代碼啦!

三、梯度下降算法求解多元線性迴歸的方程的python代碼實現

1、導入基本庫、數據,併爲變量賦值

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
data=np.genfromtxt('D:/面積距離車站數據.csv',delimiter=',')
x_data=data[:,:-1]
y_data=data[:,2]

2、定義係數初始值以及學習率和迭代次數

#定義學習率、斜率、截據
#設方程爲y=theta1*x1+theta2*x2+theta0
lr=0.00001
theta0=0
theta1=0
theta2=0
#定義最大迭代次數,因爲梯度下降法是在不斷迭代更新k與b
epochs=10000

3、定義最小二乘法函數-損失函數(代價函數)

#定義最小二乘法函數-損失函數(代價函數)
def compute_error(theta0,theta1,theta2,x_data,y_data):
    totalerror=0
    for i in range(0,len(x_data)):#定義一共有多少樣本點
        totalerror=totalerror+(y_data[i]-(theta1*x_data[i,0]+theta2*x_data[i,1]+theta0))**2
    return totalerror/float(len(x_data))/2

通過代價方程,求解迭代過程中的錯誤率哦!直觀看出求解誤差

4、定義梯度下降算法求解線性迴歸方程係數python函數

#梯度下降算法求解參數
def gradient_descent_runner(x_data,y_data,theta0,theta1,theta2,lr,epochs):
    m=len(x_data)
    for i in range(epochs):
        theta0_grad=0
        theta1_grad=0
        theta2_grad=0
        for j in range(0,m):
            theta0_grad-=(1/m)*(-(theta1*x_data[j,0]+theta2*x_data[j,1]+theta2)+y_data[j])
            theta1_grad-=(1/m)*x_data[j,0]*(-(theta1*x_data[j,0]+theta2*x_data[j,1]+theta0)+y_data[j])
            theta2_grad-=(1/m)*x_data[j,1]*(-(theta1*x_data[j,0]+theta2*x_data[j,1]+theta0)+y_data[j])
        theta0=theta0-lr*theta0_grad
        theta1=theta1-lr*theta1_grad
        theta2=theta2-lr*theta2_grad
    return theta0,theta1,theta2

該函數的主要功能就是利用梯度下降算法進行係數的求解,通過多次的迭代,完成近視值的求解!

5、代用函數,進行係數求解,並打印

#進行迭代求解
theta0,theta1,theta2=gradient_descent_runner(x_data,y_data,theta0,theta1,theta2,lr,epochs)
print('結果:迭代次數:{0} 學習率:{1}之後 a0={2},a1={3},a2={4},代價函數爲{5}'.format(epochs,lr,theta0,theta1,theta2,compute_error(theta0,theta1,theta2,x_data,y_data)))
print("多元線性迴歸方程爲:y=",theta1,"X1+",theta2,"X2+",theta0)

6、畫出迴歸方程線性擬合圖

#畫圖
ax=plt.figure().add_subplot(111,projection='3d')
ax.scatter(x_data[:,0],x_data[:,1],y_data,c='r',marker='o')
x0=x_data[:,0]
x1=x_data[:,1]
#生成網格矩陣
x0,x1=np.meshgrid(x0,x1)
z=theta0+theta1*x0+theta2*x1
#畫3d圖
ax.plot_surface(x0,x1,z)
ax.set_xlabel('area')
ax.set_ylabel('distance')
ax.set_zlabel("Monthly turnover")
plt.show()

7、題目的整體python代碼

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
data=np.genfromtxt('D:/面積距離車站數據.csv',delimiter=',')
x_data=data[:,:-1]
y_data=data[:,2]
#定義學習率、斜率、截據
#設方程爲y=theta1x1+theta2x2+theta0
lr=0.00001
theta0=0
theta1=0
theta2=0
#定義最大迭代次數,因爲梯度下降法是在不斷迭代更新k與b
epochs=10000
#定義最小二乘法函數-損失函數(代價函數)
def compute_error(theta0,theta1,theta2,x_data,y_data):
    totalerror=0
    for i in range(0,len(x_data)):#定義一共有多少樣本點
        totalerror=totalerror+(y_data[i]-(theta1*x_data[i,0]+theta2*x_data[i,1]+theta0))**2
    return totalerror/float(len(x_data))/2
#梯度下降算法求解參數
def gradient_descent_runner(x_data,y_data,theta0,theta1,theta2,lr,epochs):
    m=len(x_data)
    for i in range(epochs):
        theta0_grad=0
        theta1_grad=0
        theta2_grad=0
        for j in range(0,m):
            theta0_grad-=(1/m)*(-(theta1*x_data[j,0]+theta2*x_data[j,1]+theta2)+y_data[j])
            theta1_grad-=(1/m)*x_data[j,0]*(-(theta1*x_data[j,0]+theta2*x_data[j,1]+theta0)+y_data[j])
            theta2_grad-=(1/m)*x_data[j,1]*(-(theta1*x_data[j,0]+theta2*x_data[j,1]+theta0)+y_data[j])
        theta0=theta0-lr*theta0_grad
        theta1=theta1-lr*theta1_grad
        theta2=theta2-lr*theta2_grad
    return theta0,theta1,theta2
#進行迭代求解
theta0,theta1,theta2=gradient_descent_runner(x_data,y_data,theta0,theta1,theta2,lr,epochs)
print('結果:迭代次數:{0} 學習率:{1}之後 a0={2},a1={3},a2={4},代價函數爲{5}'.format(epochs,lr,theta0,theta1,theta2,compute_error(theta0,theta1,theta2,x_data,y_data)))
print("多元線性迴歸方程爲:y=",theta1,"X1+",theta2,"X2+",theta0)
#畫圖
ax=plt.figure().add_subplot(111,projection='3d')
ax.scatter(x_data[:,0],x_data[:,1],y_data,c='r',marker='o')
x0=x_data[:,0]
x1=x_data[:,1]
#生成網格矩陣
x0,x1=np.meshgrid(x0,x1)
z=theta0+theta1*x0+theta2*x1
#畫3d圖
ax.plot_surface(x0,x1,z)
ax.set_xlabel('area')
ax.set_ylabel('distance')
ax.set_zlabel("Monthly turnover")
plt.show()

8、運行結果如下所示:

在這裏插入圖片描述
通過梯度下降算法求解的係數可用通過代價方程看出誤差哦,誤差還是很大的,基本不是太精確,接下來,我們看一下通過最小二乘法求解的係數吧!

四、最小二乘法法求解多元線性迴歸方程的python代碼實現

由於之前林君學長寫過通過最小二乘法來求解多元線性迴歸方程的分析博客,並且給出了具體的分析,這裏就只給出源碼和運行結果,如果小夥伴對以下代碼不理解的,請參考林君學長寫的最小二乘法求解多元線性迴歸方程的博客喲! 博客鏈接如下:
https://blog.csdn.net/qq_42451251/article/details/105019128

1、完整的python代碼如下:

1)、通過矩陣模擬最小二乘法進行多元線性方程求解的完整代碼如下:

#利用線性代數的矩陣模擬最小二乘法求解法求解多元線性迴歸方程的係數
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
%matplotlib inline
data = np.genfromtxt("D:/面積距離車站數據.csv",delimiter=",")
X1=data[0:10,0]#自變量溫度
X2=data[0:10,1]#因變量銷售量
Y=data[0:10,2]#自變量溫度
#將因變量賦值給矩陣Y1
Y1=np.array([Y]).T
#爲自變量係數矩陣X賦值
X11=np.array([X1]).T
X22=np.array([X2]).T
A=np.array([[1],[1],[1],[1],[1],[1],[1],[1],[1],[1]])#創建係數矩陣
B=np.hstack((A,X11))#將矩陣a與矩陣X11合併爲矩陣b
X=np.hstack((B,X22))#將矩陣b與矩陣X22合併爲矩陣X
#求矩陣X的轉置矩陣
X_=X.T
#求矩陣X與他的轉置矩陣的X_的乘積
X_X=np.dot(X_,X)
#求矩陣X與他的轉置矩陣的X_的乘積的逆矩陣
X_X_=np.linalg.inv(X_X)
#求解係數矩陣W,分別對應截距b、a1、和a2
W=np.dot(np.dot((X_X_),(X_)),Y1)
b=W[0][0]
a1=W[1][0]
a2=W[2][0]
print("係數a1=",a1)
print("係數a2=",a2)
print("截距爲=",b)
print("多元線性迴歸方程爲:y=",a1,"X1+",a2,"X2+",b)
#畫出線性迴歸分析圖
data1=pd.read_excel('D:\面積距離車站數據.xlsx')
sns.pairplot(data1, x_vars=['area','distance'], y_vars='Y', height=3, aspect=0.8, kind='reg')  
plt.show() 
#求月銷售量Y的和以及平均值y1
sumy=0#因變量的和
y1=0#因變量的平均值
for i in range(0,len(Y)):
    sumy=sumy+Y[i]
y1=sumy/len(Y)
#求月銷售額y-他的平均值的和
y_y1=0#y-y1的值的和
for i in range(0,len(Y)):
    y_y1=y_y1+(Y[i]-y1)
print("銷售量-銷售量平均值的和爲:",y_y1)
#求預測值sales1
sales1=[]
for i in range(0,len(Y)):
    sales1.append(a1*X1[i]+a2*X2[i]+b)
#求預測值的平均值y2
y2=0
sumy2=0
for i in range(len(sales1)):
    sumy2=sumy2+sales1[i]
y2=sumy2/len(sales1)
#求預測值-平均值的和y11_y2
y11_y2=0
for i in range(0,len(sales1)):
   y11_y2=y11_y2+(sales1[i]-y2)
print("預測銷售值-預測銷售平均值的和爲:",y11_y2)
#求月銷售額y-他的平均值的平方和
Syy=0#y-y1的值的平方和
for i in range(0,len(Y)):
    Syy=Syy+((Y[i]-y1)*(Y[i]-y1))
print("Syy=",Syy)
#求y1-y1平均的平方和
Sy1y1=0
for i in range(0,len(sales1)):
    Sy1y1=Sy1y1+((sales1[i]-y2)*(sales1[i]-y2))
print("Sy1y1=",Sy1y1)
#(y1-y1平均)*(y-y平均)
Syy1=0
for i in range(0,len(sales1)):
    Syy1=Syy1+((Y[i]-y1)*(sales1[i]-y2))
print("Syy1=",Syy1)
#求R
R=Syy1/((Syy*Sy1y1)**0.5)
R2=R*R
print("判定係數R2=",R2)

2、運行結果如下

1)、運行結果如下:
在這裏插入圖片描述

六、兩種方法求解多元線性迴歸方程的精度對比

1、對運行結果的對比

1)、梯度下降法的運行結果:
在這裏插入圖片描述
2)、最小二乘法求解對比:
在這裏插入圖片描述
3)、通過excel計算結果對比:
在這裏插入圖片描述

通過以上對比結果可以知道,最小二乘法求解線性迴歸方程的精度優於梯度下降算法,這也是梯度下降算法的確定,求解精度太低,求解還需要很多次的迭代,所以,現代的人工智能機器學習的深度算法基本已經放棄梯度下降算法的求解,需要多次計算,這對計算機資源來說是一種浪費哦!現代多用於矩陣的最小二乘法進行線性迴歸係數的求解哦!

以上就是本次博客的全部內容啦,希望通過對本次博客的閱讀,小夥伴可以對人工智能機器學習的梯度下降算法有一定的理解哦,遇到問題的小夥伴記得評論區留言,林君學長看到會爲大家進行解答的,這個學長不太冷!
陳一月的又一天編程歲月^ _ ^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章