1. 程式人生 > >機器學習-最小二乘法

機器學習-最小二乘法

red num class cat blank height mar 感覺 時間

一、引言

這段時間學習《機器學習》,學到第5章的“Logistic回歸”,感覺相當吃力。追本溯源,從“Logistic回歸”到“線性回歸”,再到“最小二乘法”。最終定格到了《高等數學》(第六版·下冊)第九章第10節“最小二乘法”,這才了解到最小二乘法背後的數學原理出自哪裏。

“最小二乘法”是最優化問題中建立經驗公式的一種實現方法。了解它的原理,對於了解“Logistic回歸”和“支持向量機的學習”都很有裨益。

二、背景知識

“最小二乘法”出現的歷史背景是很有意思的。(以下文字摘錄維基百科)

1801年,意大利天文學家朱賽普·皮亞齊發現了第一顆小行星谷神星。經過40天的跟蹤觀測後,由於谷神星運行至太陽背後,使得皮亞齊失去了谷神星的位置。隨後全世界的科學家利用皮亞齊的觀測數據開始尋找谷神星,但是根據大多數人計算的結果來尋找谷神星都沒有結果。時年24歲的高斯也計算了谷神星的軌道。奧地利天文學家海因裏希·奧爾伯斯根據高斯計算出來的軌道重新發現了谷神星。

高斯使用的最小二乘法的方法發表於1809年他的著作《天體運動論》中,而法國科學家勒讓德於1806年獨立發現“最小二乘法”,但因不為時人所知而默默無聞。兩人曾為誰最早創立最小二乘法原理發生爭執。

1829年,高斯提供了最小二乘法的優化效果強於其他方法的證明,見高斯-馬爾可夫定理。

三、知識運用

“最小二乘法”的核心就是保證所有數據偏差的平方和最小。(“平方”的在古時侯的稱謂為“二乘”)

假設我們收集到一些戰艦的長度與寬度數據

1

2

3

4

5

6

7

8

9

10

長度(m)

208

152

113

227

137

238

178

104

191

130

寬度(m)

21.6

15.5

10.4

31.0

13.0

32.4

19.0

10.4

19.0

11.8

根據這些數據我們用python畫出散點圖:

技術分享

畫散點圖的代碼如下:

# -*- coding: utf-8 -*
import numpy as np
import os
import matplotlib.pyplot as plt
def drawScatterDiagram(fileName):
    #改變工作路徑到數據文件存放的地方
    os.chdir("d:/workspace_ml")
    xcord=[];ycord=[]
    fr=open(fileName)
    for line in fr.readlines():
        lineArr=line.strip().split()
        xcord.append(float(lineArr[1]));ycord.append(float(lineArr[2]))
    plt.scatter(xcord,ycord,s=30,c=‘red‘,marker=‘s‘)
    plt.show()

假如我們取前兩個點(238,32.4)(152, 15.5)就可以得到兩個方程

152*a+b=15.5

328*a+b=32.4

解這兩個方程得a=0.197,b=-14.48

那樣的話,我們可以得到這樣的擬合圖:

技術分享

好了,新的問題來了,這樣的a,b是不是最優解呢?用專業的說法就是:a,b是不是模型的最優化參數?在回答這個問題之前,我們先解決另外一個問題:a,b滿足什麽條件才是最好的?答案是:保證所有數據偏差的平方和最小。至於原理,我們會在後面講,先來看看怎麽利用這個工具來計算最好的a和b。

假設所有數據的平方和為M,則技術分享

我們現在要做的就是求使得M最小的a和b。請註意這個方程中,我們已知yi和xi

那其實這個方程就是一個以(a,b)為自變量,M為因變量的二元函數。

回想一下高數中怎麽對一元函數就極值。我們用的是導數這個工具。那麽在二元函數中,

我們依然用導數。只不過這裏的導數有了新的名字“偏導數”。偏導數就是把兩個變量中的一個視為常數來求導。

通過對M來求偏導數,我們得到一個方程組

技術分享=0

技術分享=0

這兩個方程中xi和yi都是知道的。

很容易就求得a和b了。由於采用的是維基百科的數據,我這裏就直接用答案來畫出擬合圖像:

技術分享

# -*- coding: utf-8 -*
import numpy as np
import os
import matplotlib.pyplot as plt
def drawScatterDiagram(fileName):
    #改變工作路徑到數據文件存放的地方
    os.chdir("d:/workspace_ml")
    xcord=[];ycord=[]
    fr=open(fileName)
    for line in fr.readlines():
        lineArr=line.strip().split()
        xcord.append(float(lineArr[1]));ycord.append(float(lineArr[2]))
    plt.scatter(xcord,ycord,s=30,c=‘red‘,marker=‘s‘)
    #a=0.1965;b=-14.486
    a=0.1612;b=-8.6394
    x=np.arange(90.0,250.0,0.1)
    y=a*x+b
    plt.plot(x,y)
    plt.show()

四、原理探究

數據擬合中,為什麽要讓模型的預測數據與實際數據之差的平方而不是絕對值和最小來優化模型參數?

這個問題已經有人回答了,見鏈接(http://blog.sciencenet.cn/blog-430956-621997.html

個人感覺這個解釋是非常有意思的。特別是裏面的假設:所有偏離f(x)的點都是有噪音的。

一個點偏離越遠說明噪音越大,這個點出現的概率也越小。那麽偏離程度x與出現概率f(x)滿足什麽關系呢?——正態分布。

技術分享

已知N個點(用D來表示),求直線(用h來表示)出現的概率就可以表示為:P(h|D)

根據貝葉斯定理:P(h|D)=P(D|h)*P(h)/P(D)即P(h|D)∝P(D|h)*P(h) (∝表示“正比於”)

這就是一個生成模型了——由直線h生成點集D。

我們再作一個假設:h生成D中的每一個點都是獨立的(如果了解貝葉斯文本分類的話,這裏就很好理解了),那麽P(D|h)=p(d1|h)*p(d2|h)…

結合前面正態分布,我們可以寫出這樣的式子:p(di|h)∝ exp(-(ΔYi)^2)

那麽P(D|h)∝EXP[-(ΔY1)^2]* EXP[-(ΔY2)^2] * EXP[-(ΔY3)^2] * ..

又因為:ea*eb*ec=ea+b+c

所以p(D|h)∝ EXP{-[(ΔY1)^2 +(ΔY2)^2 + (ΔY3)^2 + ..]}

我們知道f(x)=ex的分布圖像為:

技術分享

因為e的指數永遠小於0,所以,想要p(D|h)最大,就必須使[(ΔY1)^2 + (ΔY2)^2 + (ΔY3)^2 + ..]無限接近於0,即:最大化p(D|h)就是要最小化[(ΔY1)^2 + (ΔY2)^2 + (ΔY3)^2 + ..]

到此,最小二乘法的原理得到了詮釋。

四、最小二乘法與梯度下降法

最小二乘法跟梯度下降法都是通過求導來求損失函數的最小值,那它們有什麽區別呢。

相同
  1.本質相同:兩種方法都是在給定已知數據(independent & dependent variables)的前提下對dependent variables算出出一個一般性的估值函數。然後對給定新數據的dependent variables進行估算。
  2.目標相同:都是在已知數據的框架內,使得估算值與實際值的總平方差盡量更小(事實上未必一定要使用平方),估算值與實際值的總平方差的公式為:

技術分享

其中技術分享為第i組數據的independent variable,技術分享為第i組數據的dependent variable,技術分享為系數向量。
不同
  1.實現方法和結果不同:最小二乘法是直接對技術分享求導找出全局最小,是非叠代法。而梯度下降法是一種叠代法,先給定一個技術分享,然後向技術分享下降最快的方向調整技術分享,在若幹次叠代之後找到局部最小。梯度下降法的缺點是到最小點的時候收斂速度變慢,並且對初始點的選擇極為敏感,其改進大多是在這兩方面下功夫。

五、拓展延伸

上面講的都是二維的情況,也就是只有一個自變量。但現實世界中影響最後結果的都是多種因素的疊加,即自變量會有多個的情況。

對於一般N元線性函數,用《線性代數》中的逆矩陣來求解就OK了;由於暫時沒有找到合適的例子,就作為一個引子,留在這裏了。

當然自然界更多的是多項式擬合,而非簡單的線性,那就是更高級的內容了。

機器學習-最小二乘法