一元線性回歸-梯度下降法

在高數(shù)中列林,我們求解一個函數(shù)的最小值時,最常用的方法就是求出它的導(dǎo)數(shù)為0的那個點烛愧,進而判斷這個點是否能夠取最小值油宜。但是掂碱,在實際很多情況,我們很難求解出使函數(shù)的導(dǎo)數(shù)為0的方程验庙,這個時候就可以使用梯度下降顶吮。我們知道對于一個函數(shù)沿著梯度的那個方向是下降是最快的社牲。例如為了選取一個θ使J(θ)最小粪薛,我們可以先隨機選擇θ一個初始值,然后不斷的修改θ以減小J(θ)搏恤,直到θ的值不再改變违寿。對于梯度下降法,可以表示為:

θj=θj?α*?J(θ)/?θj

即不斷地向梯度的那個方向(減小最快的方向)更新θ熟空,最終使得J(θ)最小藤巢。其中α稱為學(xué)習(xí)速率(learning rate),取值太小會導(dǎo)致迭代過慢息罗,取值太大可能錯過最值點掂咒。
假設(shè)我們有一堆數(shù)據(jù)集,這些數(shù)據(jù)集用散點圖的方式迈喉,可以用一元線性回歸方程表示绍刮,那么我們表示成如下公式
數(shù)據(jù)集為


image.png

假設(shè)我們建立模型 y=h(x)=θ0+θ1x
那么我們的預(yù)期是讓通過對兩個參數(shù)θ0和θ1的調(diào)整,將y的實際值和模型輸出預(yù)測值的偏移量盡量的小挨摸,于是有

image.png

θ0和θ1兩個參數(shù)的變化我們用J(θ0孩革,θ1)表示


image.png

如何求出J(θ0,θ1)的最小值得运,這里就引入了梯度下降算法膝蜈。主要思想是,J(θ0熔掺,θ1)好比是層巒疊嶂的群山饱搏,任意指定一個θ0和θ1,好比你在群山中的任意一個點置逻,如何下山推沸,一般都會瞭望四周,選擇當(dāng)前下山最陡的方向向下走诽偷。于是你又從A到達B坤学,在B點,同樣的情景报慕,你將會選擇下一步何去何從深浮,同樣的,選擇當(dāng)前最陡的路徑向下走去眠冈。
如此周而復(fù)始飞苇,終將到達一個相對低菌瘫,局部最優(yōu)的位置。
如何將這一思想落實在數(shù)學(xué)上布卡,是機器學(xué)習(xí)的基礎(chǔ)雨让。
首先先復(fù)習(xí)一下幾個基本概念。
1.導(dǎo)數(shù)和微分

image.png

導(dǎo)數(shù)的定義如下

image.png

導(dǎo)數(shù)反映的是函數(shù)y=f(x)在某一點處沿x軸正方向的變化率忿等。也就是在x軸上某一點處栖忠,如果f’(x)>0,說明f(x)的函數(shù)值在x點沿x軸正方向是趨于增加的贸街;如果f’(x)<0庵寞,說明f(x)的函數(shù)值在x點沿x軸正方向是趨于減少的。

偏導(dǎo)數(shù)的定義

image.png

偏導(dǎo)數(shù)的定義和導(dǎo)數(shù)類似薛匪,都是當(dāng)自變量的變化量趨于0時捐川,函數(shù)值的變化量與自變量變化量比值的極限。直觀地說逸尖,偏導(dǎo)數(shù)也就是函數(shù)在某一點上沿坐標軸正方向的的變化古沥。區(qū)別在于導(dǎo)數(shù)為一元變量,偏導(dǎo)數(shù)為多元變量娇跟。
方向?qū)?shù)的定義

image.png

即:某一點在某一趨近方向上的導(dǎo)數(shù)值岩齿。 通俗的解釋是: 我們不僅要知道函數(shù)在坐標軸正方向上的變化率(即偏導(dǎo)數(shù)),而且還要設(shè)法求得函數(shù)在其他特定方向上的變化率逞频。而方向?qū)?shù)就是函數(shù)在其他特定方向上的變化率纯衍。

梯度的定義如下

image.png

梯度的提出只為回答一個問題:
 函數(shù)在變量空間的某一點處,沿著哪一個方向有最大的變化率苗胀? 函數(shù)在某一點的梯度是這樣一個向量襟诸,它的方向與取得最大方向?qū)?shù)的方向一致,而它的模為方向?qū)?shù)的最大值基协。
 這里注意三點:
 1)梯度是一個向量歌亲,即有方向有大小澜驮;
 2)梯度的方向是最大方向?qū)?shù)的方向陷揪;
 3)梯度的值是最大方向?qū)?shù)的值。
既然在變量空間的某一點處杂穷,函數(shù)沿梯度方向具有最大的變化率悍缠,那么在優(yōu)化目標函數(shù)的時候,自然是沿著負梯度方向去減小函數(shù)值耐量,以此達到我們的優(yōu)化目標飞蚓。
 如何沿著負梯度方向減小函數(shù)值呢?既然梯度是偏導(dǎo)數(shù)的集合廊蜒,如下

image.png

同時梯度和偏導(dǎo)數(shù)都是向量趴拧,那么參考向量運算法則溅漾,我們在每個變量軸上減小對應(yīng)變量值即可,梯度下降法可以描述如下:  
梯度下降法

這就是梯度下降法的數(shù)據(jù)原理著榴。
參考http://blog.csdn.net/walilk/article/details/50978864

為什么從函數(shù)的梯度方向下降可以得到函數(shù)的最小值

梯度下降法添履,基于這樣的觀察:如果實值函數(shù)F(x)在點a 處可微且有定義,那么函數(shù) F(x)在a點沿著梯度相反的方向?▽F(a)?▽F(a)下降最快脑又。

因而暮胧,如果

b=a?α▽F(a)
b=a?α▽F(a)
那么F(b)≤F(a)F(b)≤F(a)。

考慮如下序列x0,x1,x2,...x0,x1,x2,...使得

xn+1=xn?α▽F(xn)
xn+1=xn?α▽F(xn)
因此可以得到: F(x0)≥F(x1)≥F(x2)≥...F(x0)≥F(x1)≥F(x2)≥... 如果順利的話序列最終可以收斂到期望的極值挂谍。
注意:梯度下降得到的結(jié)果可能是局部最優(yōu)值叔壤。如果F(x)F(x)是凸函數(shù)瞎饲,則可以保證梯度下降得到的是全局最優(yōu)值口叙。

批量梯度下降法的算法

批梯度下降法(batch gradient descent)的算法描述如下:

對每一個j重復(fù)以下過程直到收斂 {

image.png

}

其中假設(shè)訓(xùn)練樣本數(shù)有m個,每個樣本用zi可以表示為(xi,yi)嗅战⊥铮可以看出,使用批梯度下降法每一次更新θj都需要遍歷訓(xùn)練樣本中的所有樣本驮捍。

批量梯度下降法代碼
#coding=utf-8
##
#Calculate the hypothesis h = X * theta
#Calculate the loss = h - y and maybe the squared cost (loss^2)/2m
#Calculate the gradient = X' * loss / m
#Update the parameters theta = theta - alpha * gradient
###
import numpy as np
from numpy import *
import random
def loadDataSet(filename):
    numFeat = len(open(filename).readline().split(','))-1
    datMat = []; labelMat = []
    fr = open(filename)
    for line in fr.readlines():
        lineArr = []
        curLine = line.strip().split(',')
        for i in range(numFeat):
            lineArr.append(float(curLine[i]))
        datMat.append(lineArr)
        labelMat.append(float(curLine[-1]))
    return datMat,labelMat

#x為自變量訓(xùn)練集疟呐,y為自變量對應(yīng)的因變量訓(xùn)練集;theta為待求解的權(quán)重值东且,需要事先進行初始化启具;alpha是學(xué)習(xí)率;m為樣本總數(shù)珊泳;maxIterations為最大迭代次數(shù)鲁冯;
def batchGradientDescent(x, y, theta, alpha, m, maxIterations):
    xTrains = x.transpose()   #x 轉(zhuǎn)置
    for i in range(0, maxIterations):
        hypothesis = np.dot(x, theta) #矩陣乘法,https://migege.com/post/matrix-multiplication-in-numpy 計算f(x(k))
        loss = hypothesis - y
        #print(loss)
        #print(m)
        #print(type(loss))
        # avg cost per example (the 2 in 2*m doesn't really matter here.
        # But to be consistent with the gradient, I include it)
        cost = np.sum(loss ** 2) / (2 * m)
        print("Iteration %d | Cost: %f" % (i, cost))
        # avg gradient per example
        gradient = np.dot(xTrains, loss) / m  ##梯度
        #print("gradinet is ",gradient)
        # update
        theta = theta - alpha * gradient #x(k+1)
        #print("theta is ",theta)
    return theta



xArr,yArr = loadDataSet('gmvusers3.csv')
xArr1 = asarray(xArr)
yArr1 = asarray(yArr)
#print("xArr is ",asarray(xArr))
#print("yArr is ",asarray(yArr))
#print(asarray(xArr).dtype)
#print(asarray(yArr).dtype)
m, n = np.shape(xArr1)
print("m %d | n %d" %(m,n))
numIterations= 10000
alpha = 0.00000001
theta = [1,1]  #Return a new array of given shape and type, filled with ones. 初始值色查。
theta = batchGradientDescent(xArr1, yArr1, theta, alpha, m, numIterations)
print(theta)
####


# gen 100 points with a bias of 25 and 10 variance as a bit of noise
#x, y = genData(100, 25, 10)
#print(x)
#print(y)
#print(x.dtype)
#print(y.dtype)
#m, n = np.shape(x)
#numIterations= 100000
#alpha = 0.0001
#theta = np.ones(n)
#theta = batchGradientDescent(x, y, theta, alpha, m, numIterations)
#print(theta)


import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(yArr1,'go')

xCopy = xArr1.copy()
xCopy.sort(0)
yHat=xCopy*theta
ax.plot(xCopy[:,1],yHat)
plt.show()
print(yArr1)
print(yHat)
print(corrcoef(yHat.T,yArr1))  ???
'''
其他深度學(xué)習(xí)好的文章http://sebastianruder.com/optimizing-gradient-descent/
'''

學(xué)習(xí)速率的注意條件

參數(shù)α為初始學(xué)習(xí)速率薯演,代表著梯度下降的速率,需要選擇一個合適的參數(shù)秧了。
在學(xué)習(xí)速率為固定值的時候跨扮,這個參數(shù)不能太小,否則學(xué)習(xí)的步數(shù)太多验毡,程序的速度很慢衡创,你可能需要很長一段時間才能收斂;但是也不能選的太大晶通,
否則璃氢,你可能會發(fā)現(xiàn),或許一開始J很快就接近收斂了录择,但是步長太大拔莱,之后并沒有收斂碗降,而是出了點狀況。你會發(fā)現(xiàn)塘秦,代價函數(shù)的值不但遲遲不收斂讼渊,
反而可能會越來越發(fā)散,以至于結(jié)果變得糟糕起來尊剔,甚至?xí)?dǎo)致直接跨過谷底到達另一端爪幻,這就是所謂的“步子太大,邁過山谷”须误。至于這個參數(shù)如何選擇挨稿,
需要有一定的經(jīng)驗,不過可以提前多選幾個值做一下試驗京痢,比如用0.001奶甘,發(fā)現(xiàn)太慢,用0.1祭椰,發(fā)現(xiàn)過一段時間會發(fā)散臭家,0.01既不太慢也不會發(fā)散,那就選擇這個參數(shù)方淤。
或者我們可以根據(jù)梯度下降每一步的實際情況動態(tài)調(diào)整學(xué)習(xí)速率钉赁,使用可變的學(xué)習(xí)速率,這就是上式的由來携茂。我們設(shè)定一個初始的學(xué)習(xí)速率你踩,這個學(xué)習(xí)速率也不能太大,
否則一開始就會發(fā)散讳苦,當(dāng)然也不能太小带膜,否則速度太慢。在優(yōu)化的過程中医吊,學(xué)習(xí)速率應(yīng)該逐步減小钱慢,越接近“山谷”的時候,邁的“步伐”應(yīng)該越小卿堂。我們每走一步束莫,
數(shù)據(jù)分布與直線的誤差越小,而這時梯度也會減小草描,那么步伐也就應(yīng)當(dāng)相應(yīng)的減小览绿,這就是初始學(xué)習(xí)速率乘上代價函數(shù)負梯度的原因。本實例中穗慕,經(jīng)過我的試驗饿敲,學(xué)習(xí)
速率選擇為0.0001比較合適。
值得說明的是逛绵,在進行梯度下降的時候怀各,我們應(yīng)當(dāng)盡量使用限定迭代次數(shù)的循環(huán)倔韭,而不是用判斷是否收斂的循環(huán)。原因很簡單瓢对,一旦出現(xiàn)你的結(jié)果是發(fā)散的寿酌,限定
迭代次數(shù)的循環(huán)可以使你的程序很快停止下來,而因為你的結(jié)果永遠不會收斂硕蛹,所以醇疼,如果你用while進行判斷是否收斂的話,你將很有可能陷入死循環(huán)法焰,因為你的
結(jié)果永遠不可能收斂秧荆。這里我把迭代步數(shù)設(shè)為100步。
https://blog.ailemon.me/2017/02/10/machine-learningregression-statistic-model/

特征量標準化

如果我們能夠?qū)⑤斎敫鱾€特征變量統(tǒng)一在相同范圍內(nèi)埃仪,則會加速梯度下降的效果乙濒。這是應(yīng)為 θ 在小范圍內(nèi)將會下降的很快,在大范圍內(nèi)將會下降的很慢.
為了避免無謂的計算贵试,理想狀態(tài)下琉兜,我們最好能將輸入變量限定在?1 ≤ x(i) ≤ 1或者?0.5 ≤ x(i) ≤ 0.5。由于目的只是為了將梯度下降效果優(yōu)化毙玻,只需將各個輸入X統(tǒng)一在一個較小的范圍內(nèi)即可。
一般選用兩種方法:

  1. Feature scaling. X(i) 除以最大值和最小值的差,讓X(i)在絕對值區(qū)間1之間.
  2. Mean normalization廊散,公式為:xi:=xi?μisi 桑滩; μi 為 feature (i) 的均值 and si 為值的范圍 (max - min), or si 為標準差。

除了批梯度下降法之外允睹,還有一種算法稱為——隨機梯度下降法(stochastic gradient descent运准,SGD)。算法描述如下:

image.png

每一次更新只使用了一個訓(xùn)練樣本缭受,但更新了m次胁澳。

批梯度下降法每更新一步都需要遍歷所有的樣本數(shù)據(jù),如果樣本數(shù)m很大的話米者,就會非常的耗時韭畸;而對于隨機梯度下降,每一遇到一個樣本數(shù)據(jù)蔓搞,就可以馬上更新胰丁。通常情況下,使用隨機梯度下降法的速度會比批梯度下降法快很多喂分。因此锦庸,當(dāng)樣本數(shù)很大的時候,我們通常都選擇使用隨機梯度下降法蒲祈。
參考
http://www.wengweitao.com/ti-du-xia-jiang-fa.html

另外梯度下降極容易受到異常值的影響甘萧,使用前最好刪掉異常值萝嘁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市扬卷,隨后出現(xiàn)的幾起案子酿愧,更是在濱河造成了極大的恐慌,老刑警劉巖邀泉,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嬉挡,死亡現(xiàn)場離奇詭異,居然都是意外死亡汇恤,警方通過查閱死者的電腦和手機庞钢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來因谎,“玉大人基括,你說我怎么就攤上這事〔撇恚” “怎么了风皿?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匠璧。 經(jīng)常有香客問我桐款,道長,這世上最難降的妖魔是什么夷恍? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任魔眨,我火速辦了婚禮,結(jié)果婚禮上酿雪,老公的妹妹穿的比我還像新娘遏暴。我一直安慰自己,他們只是感情好指黎,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布朋凉。 她就那樣靜靜地躺著,像睡著了一般醋安。 火紅的嫁衣襯著肌膚如雪杂彭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天茬故,我揣著相機與錄音盖灸,去河邊找鬼。 笑死磺芭,一個胖子當(dāng)著我的面吹牛赁炎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼徙垫,長吁一口氣:“原來是場噩夢啊……” “哼讥裤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起姻报,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤己英,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吴旋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體损肛,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年荣瑟,在試婚紗的時候發(fā)現(xiàn)自己被綠了治拿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡笆焰,死狀恐怖劫谅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嚷掠,我是刑警寧澤捏检,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站不皆,受9級特大地震影響贯城,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粟焊,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一冤狡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧项棠,春花似錦、人聲如沸挎峦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坦胶。三九已至透典,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間顿苇,已是汗流浹背峭咒。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留纪岁,地道東北人凑队。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像幔翰,于是被迫代替她去往敵國和親漩氨。 傳聞我的和親對象是個殘疾皇子西壮,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容