梯度下降法求解最小二乘
梯度下降(GD)是最小化風險函數(shù)、損失函數(shù)的一種常用方法,隨機梯度下降和批量梯度下降是兩種迭代求解思路,下面從公式和實現(xiàn)的角度對兩者進行分析
下面的h(x)是要擬合的函數(shù),J(theta)是損失函數(shù),theta是參數(shù),要迭代求解的值,theta求解出來了那最終要擬合的函數(shù)h(theta)就出來了。其中n是訓練集的樣本數(shù)量,j是參數(shù)的個數(shù)。
1、批量梯度下降法
(1)構(gòu)造損失函數(shù)
(2)求梯度
對J(theta)關(guān)于theta求偏導,得到損失函數(shù)關(guān)于每個theta對應(yīng)的的梯度
(3)設(shè)置參數(shù)
1.學習率:
學習率不能設(shè)置過大,否則每次theta改變的太快,可能會跳過全局最優(yōu)解。而陷入局部最優(yōu)解,但是也不能設(shè)置的過小,否則要經(jīng)過很多次迭代才能收斂到全局最優(yōu)解
2.最大迭代次數(shù):
即梯度下降法迭代的最大次數(shù)
3.誤差閾值:
和迭代次數(shù)一樣是用來控制迭代的結(jié)束條件的,當誤差小于某個閾值或者迭代次數(shù)大于最大迭代次數(shù)時就結(jié)束迭代
(4)迭代更新theta
梯度是函數(shù)增長最快的方向,因此最小化損失函數(shù),要沿著梯度的反方向進行尋優(yōu),來更新每個theta
從上面公式可以注意到,每迭代一步,都要用到訓練集所有的數(shù)據(jù),如果樣本數(shù)量n很大,那么批量梯度下降的迭代速度會很慢!所以,這就引入了另外一種方法,隨機梯度下降。
(5)python的實現(xiàn)
#coding=UTF-8
import numpy as np
import matplotlib.pyplot as plt
class linear_regression_gradient_descent:
def __init__(self,x,y,eps,alpha,max_iter_times):
'''
initalize feature、dependent variable 、learning rate、iteration times
:param x:
:param y:
:param alpha:
:param max_iter_times:
'''
self.x=x
self.y=y
self.n = len(self.x)
self.w=np.zeros((x.shape[1],1))
self.alpha=alpha
self.iteration=max_iter_times
self.eps=eps
self.cost_review=np.zeros((0,0))
def error_function(self):
'''
compute error of training data in every iteration
:return:a vector of error
'''
# step1 compute cost function
n = len(self.x)
y_pred = np.dot(self.x, self.w)
error = y_pred - self.y
return error
def partial_devative(self):
'''
compute the partial derivatives of cost functions on theta in every turn
:return:
'''
n = len(self.x)
error = self.error_function()
delta_w = np.dot(self.x.T, error) / n
return delta_w
def batch_gradient_descent(self):
'''
gradient descent to solve the parameter of linear regression
:return:
'''
n = len(self.x)
itera = 0
error = self.error_function()
cost = np.sum(error ** 2) / 2 * n
while (itera < self.iteration or cost > self.eps):
#step1 compute the partial derivatives of cost functions on theta
delta_w = self.partial_devative()
#step2 update theta
self.w = self.w - self.alpha * delta_w
#step3 compute cost function
error = self.error_function()
cost = np.sum(error ** 2) / 2 * n
# print cost
self.cost_review=np.append(self.cost_review, cost)
itera += 1
return self.w
if __name__=="__main__":
x = np.array([[1, 2, 2, 0, 1], [3, 4, 2, 0, 1], [2, 5, 1, 0, 2], [2, 3, 5, 1, 3], [1, 4, 2, 3, 1], [3, 4, 2, 2, 1]])
x_theta0 = np.ones(x.shape[0])
# insert a full-1 col in the first col of X matrix to get the design matrix
design_matrix = np.insert(x, 0, values=x_theta0, axis=1)
y = np.array([1.2, 0.4, 0.6, 2.1, 0.9, 0.3]).reshape((len(design_matrix), 1))
lr = linear_regression_gradient_descent(design_matrix,y,0.15,0.01,100)
w=lr.batch_gradient_descent()
print "parameter of linear regression:"+str(w)
print "iteration times are:"+str(len(lr.cost_review))
#show the curve of cost function
fig=plt.figure(1)
plt.plot(lr.cost_review,color='r')
plt.ylim(ymin=np.min(lr.cost_review),ymax=np.max(lr.cost_review))
plt.xlim(xmin=0,xmax=len(lr.cost_review)+1)
plt.ylabel("cost function")
plt.xlabel("id of iteration")
plt.title("cost function of linear regression")
plt.grid()
plt.show()
可以看出:雖然迭代次數(shù)設(shè)置了100次,但是因為誤差一直沒有達到設(shè)置的閾值0.15以內(nèi),因為一直在迭代,大約迭代了將近1000次才結(jié)束,在迭代的過程中,可以看到誤差一直在不斷減小,直至達到閾值要求
2、隨機梯度下降法
(1)構(gòu)造損失函數(shù)
上面批量梯度下降對應(yīng)的是所有的訓練樣本,可以寫成如下這種形式:
此時的損失函數(shù)對應(yīng)的是訓練集中每個樣本的損失函數(shù),是樣本粒度的
(2)求梯度
對每個樣本的損失函數(shù)關(guān)于theta求偏導得到梯度
梯度
(3)設(shè)置參數(shù)
參照批量梯度下降法
(4)迭代更新theta
迭代更新公式
3.SGD與BGD的比較
相同點:都是全局尋優(yōu)的:
BGD是最小化所有訓練樣本的損失函數(shù),使得最終求解的是全局的最優(yōu)解,即求解的參數(shù)是使得風險函數(shù)最小;
SGD是最小化每條樣本的損失函數(shù),SGD伴隨的一個問題是噪音較BGD要多,使得SGD并不是每次迭代都向著整體最優(yōu)化方向。但是大的整體的方向是向全局最優(yōu)化的,最終的結(jié)果往往是在全局最優(yōu)解附近。
總之,SGD和BGD都是在整個參數(shù)區(qū)間上進行搜索,學習率越大,每次參數(shù)的變動越大,那么可能容易陷入局部最小值,但是整體思想是全局尋優(yōu)的
不同點:
(1)效率上:
隨機梯度下降(SGD)是通過每個樣本來迭代更新一次,如果樣本量很大的情況(例如幾十萬),那么可能只用其中幾萬條或者幾千條的樣本,就已經(jīng)將theta迭代到最優(yōu)解了;
對比上面的批量梯度下降,迭代一次需要用到十幾萬訓練樣本,一次迭代不可能最優(yōu),如果迭代10次的話就需要遍歷訓練樣本10次。因此SGD在計算的效率上要高于BGD
(2)局部最小值問題
因為SGD是通過每次對部分樣本進行迭代,是對BGD的一個隨機近似,那么當目標函數(shù)有多個局部極小值時,SGD比BGD反而更可能避免進入局部極小值中。
(3)學習率η的選擇
對于步長 η的取值,一般BGD的η比SGD的大。因為GD的是使用準確的梯度,理直氣壯地走,SGD使用的是近似的梯度,就得小心翼翼地走,怕一不小心誤入歧途南轅北轍了。
4.梯度下降法和最小二乘法求解線性回歸的比較
(1)梯度下降法是迭代算法,通過每一次迭代不斷沿著函數(shù)減小最快的方向來改變代價函數(shù)的自變量theta,進而減小代價函數(shù)值,這一過程我們可以看出:梯度下降法是全局尋優(yōu)的過程,只要theta設(shè)置合理,就不會陷入局部最小值,我們會逐漸收斂到全局最優(yōu)值;
(2)最小二乘法是對代價函數(shù)直接求偏導令其為0,因此是局部尋優(yōu),實踐表明在屬性或者樣本數(shù)目比較多時,梯度下降法效果更好,且在參數(shù)設(shè)置合理的情況下,會收斂到全局最優(yōu)解
5、梯度下降用來求最優(yōu)解,哪些問題可以求得全局最優(yōu)?哪些問題可能局部最優(yōu)解?
對于linear regression問題,如果最優(yōu)化問題對theta的分布是****unimodal,即從圖形上面看只有一個peak,所以梯度下降最終求得的是全局最優(yōu)解。然而對于multimodal的問題,因為存在多個peak值,很有可能梯度下降的最終結(jié)果是局部最優(yōu)
轉(zhuǎn)載請注明出處: