1. 程式人生 > >批量梯度下降演算法的簡單Python實現

批量梯度下降演算法的簡單Python實現

演算法理論

為了實現監督學習,假設對於因變數y有自變數x1x2,則有y=θ1x1+θ2x2+θ0

θ0是偏移量,令θ0=1,得到:

我們再定義誤差函式j(θ)(係數為1/2是用來消去後面的2)來表示h(x)與y的接近程度:

目的是使誤差函式最小,需要求得使誤差函式最小時的引數θ。對θ先隨機初始化然後不斷更新,更新演算法使用梯度下降演算法:

該更新公式的大致推導如下:

那麼需要計算的是誤差函式j(θ)的偏導:

由此可知其偏導值即為自變數矩陣與誤差值乘積

簡單Python實現

使用一組簡單的線性關係資料,員工工作年齡與薪水之間的關係:特徵自變數只有一個即工作年齡,因變數為薪水。

先將資料匯入Python中,得到自變數矩陣和因變數矩陣:

import numpy as np
import pandas as pd
import scipy as sp
import matplotlib.pyplot as plt
f=open("Salary_Data.csv",encoding='utf-8')
file=pd.read_csv(f)
Xi=np.array(file["YearsExperience"])
Yi=np.array(file["Salary"])
plt.scatter(Xi,Yi)
plt.show()
trainxi=np.ones((Xi.shape[0],2))//自變數矩陣是一個m*2的矩陣,m為樣本數量,第一列是自變數,第二列是一個均為1的偏移量,即公式中的x0
trainxi[:,0]=Xi
trainyi=np.zeros((Yi.shape[0],1))
trainyi[:,0]=Yi

資料大體散點圖,看圖誤差不是特別大,沒有極端資料(否則一般訓練集都必須先進行處理)

演算法實現,定義批量梯度下降函式,x,y是訓練集的變數,theta是我們要求得的引數,alpha是學習率,m為樣本總數,maxx為最大迭代次數

def bgd(x,y,theta,alpha,m,maxx):
    x_trans=x.transpose()
    for i in range(0,maxx):
        hy=np.dot(x,theta)            //計算出預測的因變數結果值,m*2與2*1得到m*1的因變數矩陣
        loss=hy-y                     //計算偏差值                   
        gradient=np.dot(x,loss)/m     //計算當前的梯度(即偏導值),有m個樣本計算的是平均值
        theta=theta-alpha*gradient    //更新當前的theta,繼續沿著梯度向下走
    return theta

定義預測函式,看對得到的theta計算值與真實值的偏差

#對得到的引數θ進行預測
def predict(x,theta):
    y=np.dot(x,theta) 
    print(y)          #返回該測試得出的值,與真實值進行比較

演算法迭代迴圈的次數也不是任意的,一般需要達到某一個要求停止迴圈:

1.權重的更新低於某個閾值; 2.預測的錯誤率低於某個閾值; 3.達到預設的最大迴圈次數; 其中達到任意一種,就停止演算法的迭代迴圈,得出最終結果。

theta=np.ones((2,1))    #建立初始引數矩陣,形狀行數為2(因為只有一個變數),數值初始化為1
alpha=0.01              #指定學習率
maxx=1000
theta= bgd(trainxi,trainyi,theta,alpha,Xi.shape[0],maxx)
x=np.array([[2,1],[2.9,1],[10.5,1]])   #x為測試集,簡單的測試工作年齡為2、2.9、10.5的員工薪水大約應為多少錢
predict(x,theta)

得到返回結果為

[[ 42672.78156477]
 [ 51561.26965072]
 [126619.61348763]]

大體上與真實資料接近但不夠十分精確,但是最初的雛形有了。