天天看點

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

一、梯度下降算法理論知識

我們給出一組房子面積,卧室數目以及對應房價資料,如何從資料中找到房價y與面積x1和卧室數目x2的關系?

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

為了實作監督學習,我們選擇采用自變量x1、x2的線性函數來評估因變量y值,得到:

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

這裡,sita1、sita2代表自變量x1、x2的權重(weights),sita0代表偏移量。為了友善,我們将評估值寫作h(x),令x0=1,則h(x)可以寫作:

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

其中n為輸入樣本數的數量。為了得到weights的值,我們需要令我們目前的樣本資料評估出的h(x)盡可能的接近真實y值。我們定義誤差函數(cost function)來表示h(x)和y值相接近的程度:

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

這裡的系數1/2是為了後面求解偏導數時可以與系數互相抵消。我們的目的是要誤差函數盡可能的小,即求解weights使誤差函數盡可能小。首先,我們随機初始化weigths,然後不斷反複的更新weights使得誤差函數減小,直到滿足要求時停止。這裡更新算法我們選擇梯度下降算法,利用初始化的weights并且反複更新weights:

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

這裡a代表學習率,表示每次向着J最陡峭的方向邁步的大小。為了更新weights,我們需要求出函數J的偏導數。首先計算隻有一個資料樣本(x,y)時,如何計算J的偏導數:

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

對于隻含有一組資料的訓練樣本,我們可以得到更新weights的規則為:

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

擴充到多組資料樣本,更新公式為:

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

稱為批處理梯度下降算法,這種更新算法所需要的運算成本很高,尤其是資料量較大時。考慮下面的更新算法:

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

該算法又叫做随機梯度下降法,這種算法不停的更新weights,每次使用一個樣本資料進行更新。當資料量較大時,一般使用後者算法進行更新。

二、梯度下降Python實作

自己建立了一組資料,存為csv格式,如下圖所示:

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

待訓練資料A、B為自變量,C為因變量。

在寫程式之前,要先導入我們需要的子產品。

importnumpy as npfrom numpy import genfromtxt

首先将資料讀入Python中,程式如下所示:

dataPath = r"E:\learning\house.csv"dataSet= genfromtxt(dataPath, delimiter=',')

接下來将讀取的資料分别得到自變量矩陣和因變量矩陣:

defgetData(dataSet):

m, n=np.shape(dataSet)

trainData=np.ones((m, n))

trainData[:,:-1] = dataSet[:,:-1]

trainLabel= dataSet[:,-1]return trainData, trainLabel

這裡需要注意的是,在原有自變量的基礎上,需要主觀添加一個均為1的偏移量,即公式中的x0。原始資料的前n-1列再加上添加的偏移量組成自變量trainData,最後一列為因變量trainLabel。

下面開始實作批處理梯度下降算法:

defgetData(dataSet):

m, n=np.shape(dataSet)

trainData=np.ones((m, n))

trainData[:,:-1] = dataSet[:,:-1]

trainLabel= dataSet[:,-1]return trainData, trainLabel

x為自變量訓練集,y為自變量對應的因變量訓練集;theta為待求解的權重值,需要事先進行初始化;alpha是學習率;m為樣本總數;maxIterations為最大疊代次數;

求解權重過程,初始化batchGradientDescent函數需要的各個參數:

trainData, trainLabel =getData(dataSet)

m, n=np.shape(trainData)

theta=np.ones(n)

alpha= 0.05maxIteration= 1000

alpha和maxIterations可以更改,之後帶入到batchGradientDescent中可以求出最終權重值。

theta = batchGradientDescent(trainData, trainLabel, theta, alpha, m, maxIteration)

之後我們給出一組資料,需要進行預測,預測函數:

defpredict(x, theta):

m, n=np.shape(x)

xTest= np.ones((m, n+1))

xTest[:, :-1] =x

yPre=np.dot(xTest, theta)return yPre

x為待預測值的自變量,thta為已經求解出的權重值,yPre為預測結果

我們給出測試集

python sklearn 梯度下降法_【轉】梯度下降算法以及其Python實作

對該組資料進行預測,程式如下:

x = np.array([[3.1, 5.5], [3.3, 5.9], [3.5, 6.3], [3.7, 6.7], [3.9, 7.1]])print predict(x, theta)

輸出結果如下:

[9.49608552 10.19523475 10.89438398 11.59353321 12.29268244]

我們可以更改學習率和疊代次數進行預測結果的對比:

更改學習率由0.05變為0.1時,結果為:

[ 9.49997917 10.19997464 10.89997012 11.59996559 12.29996106]

發現預測結果要由于學習率為0.05時,這說明學習率0.05選擇的偏小,即每一次邁步偏小。

固定學習率為0.05,更改疊代次數為5000時,結果為:

[ 9.5 10.2 10.9 11.6 12.3]

這正是我們想要的預測結果,這說明有限循環次數内,循環次數越多,越接近真實值。但是也不能無限循環下去,需要尋找一個度。

一般達到以下的任意一種情況即可以停止循環:

1.權重的更新低于某個門檻值;

2.預測的錯誤率低于某個門檻值;

3.達到預設的最大循環次數;

其中達到任意一種,就停止算法的疊代循環,得出最終結果。

完整的程式如下:

#coding=utf-8

importnumpy as npimportrandomfrom numpy importgenfromtxtdefgetData(dataSet):

m, n=np.shape(dataSet)

trainData=np.ones((m, n))

trainData[:,:-1] = dataSet[:,:-1]

trainLabel= dataSet[:,-1]returntrainData, trainLabeldefbatchGradientDescent(x, y, theta, alpha, m, maxIterations):

xTrains=x.transpose()for i inrange(0, maxIterations):

hypothesis=np.dot(x, theta)

loss= hypothesis -y#print loss

gradient = np.dot(xTrains, loss) /m

theta= theta - alpha *gradientreturnthetadefpredict(x, theta):

m, n=np.shape(x)

xTest= np.ones((m, n+1))

xTest[:, :-1] =x

yP=np.dot(xTest, theta)returnyP

dataPath= r"E:\learning\house.csv"dataSet= genfromtxt(dataPath, delimiter=',')

trainData, trainLabel=getData(dataSet)

m, n=np.shape(trainData)

theta=np.ones(n)

alpha= 0.1maxIteration= 5000theta=batchGradientDescent(trainData, trainLabel, theta, alpha, m, maxIteration)

x= np.array([[3.1, 5.5], [3.3, 5.9], [3.5, 6.3], [3.7, 6.7], [3.9, 7.1]])print predict(x, theta)

我是一個機器學習的小白,剛剛開始接觸,從最基本的也是很重要的梯度下降開始學習。這篇文章是我對梯度下降的了解,還有很多不完善的地方,我隻給出了批量梯度下降算法的python實作,随機梯度下降還需要我進一步編寫,而且關于循環停止,本文隻是最簡單的循環次數停止,等等,還有很多問題,以後會繼續更近并改進該文章。寫下來就是為了随時随地翻出來看看,鞏固知識,并不斷改進。