人工智能之用excel和python實現一元二元函數梯度下降

梯度下降法和牛頓法的總結與比較

機器學習的本質是建立優化模型,通過優化方法,不斷迭代參數向量,找到使目標函數最優的參數向量。最終建立模型

通常用到的優化方法:梯度下降方法、牛頓法、擬牛頓法等。這些優化方法的本質就是在更新參數。

一、梯度下降法

0、梯度下降的思想

通過搜索方向和步長來對參數進行更新。其中搜索方向是目標函數在當前位置的負梯度方向。因爲這個方向是最快的下降方向。步長確定了沿着這個搜索方向下降的大小。

迭代的過程就像是在不斷的下坡,最終到達坡地。
接下來的目標函數以線性迴歸的目標函數爲例:
在這裏插入圖片描述

在這裏插入圖片描述

1、批量梯度下降法

在這裏插入圖片描述
在這裏插入圖片描述

2、隨機梯度下降法

在這裏插入圖片描述

在這裏插入圖片描述

3.隨機梯度下降和梯度下降的比較

批量梯度下降:1.是最小化所有樣本的損失函數,最終得到全局最優解。

2.由於每次更新參數需要重新訓練一次全部的樣本,代價比較大,適用於小規模樣本訓練的情況。

隨機梯度下降:1.是最優化每個樣本的損失函數。每一次迭代得到的損失函數不是,每次每次向着全局最優的方向,但是大體是向着全局最優,最終的結果往往是在最優解的附近。

2.當目標函數是凸函數的時候,結果一定是全局最優解。

3.適合大規模樣本訓練的情況。

小批量梯度下降法

將上述兩種方法作結合。每次利用一小部分數據更新迭代參數。即樣本在1和m之間。

二、牛頓法

首先牛頓法是求解函數值爲0時的自變量取值的方法。

利用牛頓法求解目標函數的最小值其實是轉化成求使目標函數的一階導爲0的參數值。這一轉換的理論依據是,函數的極值點處的一階導數爲0.

其迭代過程是在當前位置x0求該函數的切線,該切線和x軸的交點x1,作爲新的x0,重複這個過程,直到交點和函數的零點重合。此時的參數值就是使得目標函數取得極值的參數值。

其迭代過程如下:

在這裏插入圖片描述

迭代的公式如下:
在這裏插入圖片描述
當θ是向量時,牛頓法可以使用下面式子表示:
在這裏插入圖片描述
其中H叫做海森矩陣,其實就是目標函數對參數θ的二階導數。

三、牛頓法和梯度下降法的比較

1.牛頓法:是通過求解目標函數的一階導數爲0時的參數,進而求出目標函數最小值時的參數。

收斂速度很快。

海森矩陣的逆在迭代過程中不斷減小,可以起到逐步減小步長的效果。

缺點:海森矩陣的逆計算複雜,代價比較大,因此有了擬牛頓法。

2.梯度下降法:是通過梯度方向和步長,直接求解目標函數的最小值時的參數。

越接近最優值時,步長應該不斷減小,否則會在最優值附近來回震盪。

一元函數梯度下降

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import math
from mpl_toolkits.mplot3d import Axes3D
import warnings

"""
對當前一維原始圖像求最小點:
1、隨機取一個點(橫座標爲x),設定阿爾法參數值。  
2、對這個點求導數 ,x =x - α*(dY/dx)。  
3、重複第二步、設置迭代 y的變化量小於多少時 不再繼續迭代。
"""
# 導數
def h1(x):
    return 0.5 * 2 * (x-0.25)
X = np.arange(-4,4,0.05)
Y = np.array(list(map(lambda t: f1(t),X)))
Y

 
x = 4
alpha = 0.5
f_change = f1(x) # y的變化量
iter_num = 0 # 迭代次數
GD_X = [x] #保存梯度下降所經歷的點
GD_Y = [f1(x)]
 
while(f_change > 1e-10) and iter_num<100:
    tmp = x - alpha * h1(x)
    f_change =  np.abs(f1(x) - f1(tmp))
    x = tmp
    GD_X.append(x)
    GD_Y.append(f1(x))
    iter_num += 1
    
print(u"最終結果爲:(%.5f,%.5f)"%(x,f1(x)))
print(u"迭代過程中X的取值,迭代次數:%d" % iter_num)
print(GD_X)
 
%matplotlib inline
plt.figure(facecolor='w')
plt.plot(X,Y,'r-',linewidth=2) #第三個參數是顏色和形狀,red圈就是ro-,red直線就是r-
plt.plot(GD_X, GD_Y, 'bo-', linewidth=2)
plt.title(u'函數$ y = 0.5 * (x-0.25)^2$;\n學習率%.3f;最終解:(%.3f,%.3f),迭代次數:%d'%(alpha,x,f1(x),iter_num))

二元函數梯度下降

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.定義係數初始值以及學習率和迭代次數

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

3.打印

#進行迭代求解
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)

4.畫圖

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()

運行結果

在這裏插入圖片描述

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

代碼如下:

#利用線性代數的矩陣模擬最小二乘法求解法求解多元線性迴歸方程的係數
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)

運行結果

在這裏插入圖片描述

excel分析

在這裏插入圖片描述
在這裏插入圖片描述

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