梯度降低法及一元線性迴歸的python實現python
1、梯度降低法形象解釋算法
設想咱們處在一座山的半山腰的位置,如今咱們須要找到一條最快的下山路徑,請問應該怎麼走?根據生活經驗,咱們會用一種十分貪心的策略,即在如今所處的位置上找到一個可以保證咱們下山最快的方向,而後向着該方向行走;每到一個新位置,重複地應用上述貪心策略,咱們就能夠順利到達山底了。其實梯度降低法的運行過程和上述下山的例子沒有什麼區別,不一樣的是咱們人類能夠憑藉咱們的感官直覺,根據所處的位置來選擇最佳的行走方向,而梯度降低法所依據的是嚴格的數學法則來進行每一步的更新。本文再也不對該算法進行嚴格的數理討論,只介紹梯度降低法進行數據擬合的流程和利用梯度降低法解決一元線性迴歸的python實現。dom
2、梯度降低法算法應用流程ide
假設有一組數據X=[x1,x2,x3,...],Y=[y1,y2,y3,...],現求由X到Y的函數關係:函數
一、爲所須要擬合的數據,構造合適的假設函數:y=f(x;θ),以θ=[θ1,θ2,θ3,...]爲參數;學習
二、選擇合適的損失函數:cost(θ),用損失函數來衡量假設函數對數據的擬合程度;優化
三、設定梯度降低法的學習率 α,參數的優化初始值及迭代終止條件;spa
四、迭代更新θ,直到知足迭代終止條件,更新公式爲:3d
θ1=θ1-α*dcost(θ)/dθ1,code
θ2=θ2-α*dcost(θ)/dθ2,...
3、一元線性迴歸的python實現
下面以一個一元線性迴歸的例子來更進一步理解梯度降低法的過程。筆者經過在函數y=3*x+2的基礎之上添加一些服從均勻分佈的隨機數來構造以下的待擬合數據:X,Y,訓練數據圖像以下圖1所示。假設函數爲一元線性函數: y=f(x;θ,k)=θ*x+k,損失函數爲:cost(θ,k)=1/2*∑(f(xi;θ,k)-yi),xi屬於X,yi屬於Y,損失函數的圖像以下圖2所示。應用梯度降低法進行參數更新的過程如圖3中的藍色圓點所示。
(1)
(2)
(3)
程序源代碼以下:
1 import numpy as np 2 import matplotlib.pyplot as plt 3 from mpl_toolkits.mplot3d import Axes3D 4 5 np.random.seed(1) 6 #生成樣本數據 7 x=np.arange(-1,1,step=0.04)#自變量 8 noise=np.random.uniform(low=-0.5,high=0.5,size=50)#噪聲 9 y=x*3+2+noise#因變量 10 #顯示待擬合數據 11 plt.figure(1) 12 plt.xlabel('x') 13 plt.ylabel('y') 14 plt.scatter(x,y) 15 16 #假設函數爲一元線性函數:y=theta*x+k,須要求解的參數爲theta和k 17 #損失函數爲 18 def cost(theta, k, x, y): 19 return 1/2*np.mean((theta*x+k-y)**2) 20 21 def cost_mesh(theta_m, k_m, x, y): 22 z_m=np.zeros((theta_m.shape[0],theta_m.shape[1])) 23 for i in range(theta_m.shape[0]): 24 for j in range(theta_m.shape[1]): 25 z_m[i,j]=cost(theta_m[i,j], k_m[i,j],x,y) 26 return z_m 27 #可視化損失函數 28 theta_axis=np.linspace(start=0, stop=5,num=50) 29 k_axis=np.linspace(start=0, stop=5,num=50) 30 (theta_m, k_m)=np.meshgrid(theta_axis,k_axis)#網格化 31 z_m=cost_mesh(theta_m, k_m, x, y) 32 #繪製損失函數的3D圖像 33 fig=plt.figure(2) 34 ax=Axes3D(fig)#爲figure添加3D座標軸 35 ax.set_xlabel('theta') 36 ax.set_ylabel('k') 37 ax.set_zlabel('cost') 38 ax.plot_surface(theta_m, k_m, z_m,rstride=1, cstride=1,cmap=plt.cm.hot, alpha=0.5)#繪製3D的表面, rstide爲行跨度,cstride爲列跨度 39 40 41 #梯度降低法 42 #參數設置 43 lr=0.01#學習率 44 epoches=600#迭代次數,即迭代終止條件 45 46 #參數初始數值 47 theta=0 48 k=0 49 50 #迭代更新參數 51 for i in range(epoches): 52 theta_gra=np.mean((theta*x+k-y)*x)#theta梯度 53 k_gra=np.mean(theta*x+k-y)#k梯度 54 #更新梯度 55 theta-=theta_gra*lr 56 k-=k_gra*lr 57 #繪製當前參數所在的位置 58 if i%50==0: 59 ax.scatter3D(theta, k, cost(theta, k, x,y), marker='o', s=30, c='b') 60 print('最終的結果爲:theta=%f, k=%f'%(theta, k)) 61 plt.show()