起源

起源:最小二乘法源於天文學和大地測量學領域。因為這兩個領域對精度的高要求而被髮明。

1801年,義大利天文學家朱塞普·皮亞齊發現了第一顆小行星穀神星。進行了40天的跟蹤觀測後,但由於穀神星執行到太陽背後,失去了具體位置資訊。隨後全世界的科學家利用皮亞齊的觀測資料開始尋找穀神星,但是根據大多數人計算的結果來尋找穀神星都沒有結果。時年24歲的高斯也計算了穀神星的軌道。奧地利天文學家海因裡希·奧伯斯根據高斯計算出來的軌道重新發現了穀神星。高斯使用的最小二乘法的方法發表於1809年他的著作《天體運動論》中,這個高斯正是著名數學家 卡爾·弗里德里希·高斯 ,沒錯就是我們大學數學認識的那個高斯。

機器學習本質其實就是求最優解的過程,最小二乘法是迴歸演算法中求最優解的方法之一,還有一個是梯度下降法,以後會講~。

思考

我們在正式講最小二乘法之前,讀者大大們可以想下下面這個問題臨近中秋,小明想要自己做月餅,現在已知五種規格月餅所需的麵粉重量如下:

月餅重量(g)麵粉重量(g)
30 20
100 81
80 110
190 90
220 180

現在小明想做規格為140g的月餅,請問他需要多少克月餅現在讀者大大們根據平時經驗,可以思考下怎麼求。九年義務教育讓我看見這種題目就條件反射列方程求未知數,不知道讀者大大們是不是也是這樣~

原理

我們從另一個角度來看這個問題我們將這5個月餅用座標系標出來,如下圖 然後我們先用畫出一條接近這5個點的線,假設線性關係為

 

 

是不是隻要我們找出一條最接近這5個點的線就可以了,這樣算出來的值是最接近真實值的。

由圖可以得出,需要這條線跟這個5個點的誤差最小, 每個點跟線的誤差如下所示

因為誤差是長度,所以要算絕對值,計算起來不方便,用平方來替代

最後將所有誤差值累加得出

最小二乘法呼之欲出,這就是最小二乘法的原理了,即讓誤差的平方總和儘可能小。從求一條最接近這五個點的線的問題轉化成求最小化誤差的問題。

求解

那麼怎麼求呢,繼續以上面的為例子。這是一個二次函式。總誤差的平方:

根據多元微積分,當

這個時候 ϵ 取得最小值,求的a,b的解為

a,b求出後,這條最接近的線也就出來了

進一步現在假設這條線是 二次函式,結果怎樣

我們可以選擇不同的 f(x),根據最小二乘法得出不一樣的擬合函式。不過選擇f(x)還是不能太隨意,不然要麼不準,要麼容易過擬合。程式碼實現整個思路如下

 

目標函式:代入生成的x,生成對應的y

def real_func(x):
  return np.sin(2*np.pi*x)

隨機生成10個x進行實驗:

x = np.linspace(0, 1, 10)

構造多項式擬合函式:

#多項式
def fit_func(p,x):
    """
    eg:p = np.poly1d([2,3,5,7])

   print(p)==>>2x3 + 3x2 + 5x + 7
    """
    f = np.poly1d(p)
    return f(x)

計算誤差:

#殘差
def residuals_func(p, x, y):
    ret = fit_func(p, x) - y
    return ret

leastsq 是 scipy 庫 進行最小二乘法計算的函式,也就是通過誤差函式以及資料點進行我們前面講的對引數進行求導操作,最後得出我們擬合出來的函式。

def fitting(M=0):
    """
    n 為 多項式的次數
    """    
    # 隨機初始化多項式引數
    #numpy.random.rand(d0)的隨機樣本位於[0, 1)之間。d0表示返回多少個
    p_init = np.random.rand(M+1) #生成M+1個隨機數的列表
    # 最小二乘法
    p_lsq = leastsq(residuals_func, p_init, args=(x, y)) # 三個引數:誤差函式、函式引數列表、資料點
    print('Fitting Parameters:', p_lsq[0])
    
    # 視覺化
    plt.plot(x_points, real_func(x_points), label='real')
    plt.plot(x_points, fit_func(p_lsq[0], x_points), label='fitted curve')
    plt.plot(x, y, 'bo', label='noise')
    plt.legend()
    return p_lsq
    
    # M=0
    p_lsq = fitting(M=0)

我們從一次函式依次增加項式,找到最合適的擬合曲線。


到9次的時候,已經完全擬合這些點了 。

總結

我們可以看出,最小二乘法的原理其實非常簡單,運用起來也簡潔,應用廣泛。但是它也有一定的侷限性,比如如果擬合函式不是線性的,就無法用最小二乘法了。還有一點,本文講的最小二乘法是最簡潔的,但是它對噪聲的容忍度很低,容易造成過擬合,所以還需要加上正則化,這個有興趣的讀者可以瞭解下。最小二乘法運用誤差角度求最優解的思路是我們機器學習中一個很經典也很常用的思維方向之一,為學習機器學習打下一個好基礎。這也是把它放在我們的機器學習系列最開始的原因。

ps:需要完整程式碼,關注公眾號,回覆‘最小二乘法’獲得~

本文首發微信公眾號“哈爾的資料城堡”.