在試著認識與實作迴歸、感知器時,最重要的是認識過程中是如何設定需求、步驟與逐步達到目標,每一步都必須反覆思考,想想它們是為了解決哪些小任務,而這些小任務又是如何解決整體任務。

向平均值迴歸

如果我們想要接觸機器學習的開發應用,往往一開始就會面對迴歸(Regression),透過觀察資料的趨勢,找出合適趨勢的函數。

就資料可視化來說,若成對資料的趨勢呈線性關係,迴歸函數可以畫出一條直線,原始資料大致座落在線的附近;若是三個一組的資料呈線性趨勢,迴歸函數可以畫出平面,原始資料大致座落在平面的附近。

有關迴歸的描述,最早可追溯至十九世紀英國的Francis Galton,他觀察到,父母極端的特徵不會完全呈現在子女身上,而是迴歸至平均點(regress towards a mediocre point),例如:父母很高,子女可能很高、卻比父母矮;若父母很矮,子女可能很矮、但比父母高。藉由數以百計的身高資料,他能把迴歸至平均進行量化,進而預估父母對於子女的身高影響。

而預估不就是機器學習的目的之一嗎?那麼,學習的部份呢?首先我們要有相當數量的資料,觀察趨勢,決定迴歸函式的階數與變數,例如,若成對數值的趨勢呈線性,可以定義迴歸函式為fΘ(x)=Θ0+Θ1*x,而目標是藉由資料,找出合適的Θ0、Θ1,讓資料座落在直線附近。

不過,座落在直線附近要有個明確的定義,直覺的想法是,若每筆資料是(xi,yi),yi-fΘ(xi)是yi與函數值的誤差,因為yi-fΘ(xi)有正有負,為了正負不要相抵,可以取絕對值或者是平方後再加總,如果加總值越小,迴歸函數就會越合適,也就是說,若E(Θ)代表加總值,目標就是找出E(Θ)的極小值。

談到函數的極小值,就想到函數微分後極點值會是0,為了便於微分,E(Θ)取平方後再加總會比較方便,因為E(Θ)有Θ0、Θ1兩個變數,分別取偏微分,從Θ0、Θ1兩個方向來求極值,當然,一開始Θ0、Θ1是未知的,可以觀察分布趨勢、選個初值,或者是隨機值開始也可以,這時E(Θ)的兩個偏微分並不會是零。

對於微分來說,代入值後的結果不是零,代表是向上(正值)或向下(負值)的趨勢,因為是要求極小值,若向上就將Θ0、Θ1往左一點,若向下就將Θ0、Θ1往右,這種方式是梯度下降法,這個過程需要相當數量的資料,讓Θ0、Θ1重複地往左、往右,接近極小值處的Θ0、Θ1,這就像是從資料中學習,找出最合適的Θ0、Θ1。

使用法向量分類的感知器

機器學習另一課題是分類(Classification),當然,若條件已知,進行對象的分類不難,如對於基本的二元分類來說,數字大於0、小於0、圖片的高度是否大於寬度,透過寫程式來判斷是很簡單的。

然而,有時分類的條件並不明確,例如,判斷圖片中是貓或狗、男或女、胖或瘦等;對人類來說,看到圖片或許很簡單就能分辨,但人們往往並不清楚辨識的條件,畢竟是從過去經驗不斷學習而來。

不過,若能先請人們標記照片是貓或狗,並整理一下他們認為的觀察要點,也就是借助人們的大量觀察,若觀察要點抓取適當,可以建立起適當模型,用來對新照片進行分類;當然,一下子就想學會分類貓狗太難,就假設讓人來標記照片的人是不是過胖,而每張照片都有對應的身高與腰圍,將身高與腰圍以散布圖繪製,並根據標記給予O或X,若發現O或X很明顯分為兩邊,可以用直線分隔,這就是屬於線性可分的二元分類。

如果直線方程式是以w0*x0+w1*x1=0表示,x0、x1可以是身高、腰圍,那麼w0、w1是什麼呢?若將w0*x0+w1*x1看成是內積,那麼可以寫成W.X,W是向量(w0,w1),X是向量(x0,x1),也就是說w0、w1是直線方程式的法向量,而且法向量指向的一面,身高、腰圍組成的向量與法向量內積總會大於零,另一面總會小於零。

當然,一開始w0、w1是未知的,我們可以觀察趨勢、選個適當初值,或者從隨機值開始,將身高、腰圍組成的向量與(w0,w1)求內積,若內積小於零,就旋轉法向量,這也意謂著旋轉直線,重複這個過程,直到全部的身高、腰圍都代入為止,看看最後直線是否畫分出兩個類別,這就像是從資料中學習,最合適的w0、w1會是什麼。

在更多變數的情況下,向量不會只有兩個維度,而是像w0*x0+w1*x1+w2*x2+w3*x3+...,這就像是神經元,可以接受複數個輸入,這樣的模型稱為感知器(Perceptron),W稱為權重向量,求得後,對於新的資料,就可以用來預期其屬於哪個分類。

數學原理與程式庫的搭配

從線性的問題中,理解迴歸與感知器的分類原理是比較簡單的,從中也可以發現,所謂的學習,基本上是從足夠的資料中反覆調整,而大量資料處理與重複的動作,正是程式最擅長的事情,例如,只要知道最小平方法求迴歸的原理,以及最後導出的更新式,若想求的迴歸函式是條直線,新手也能透過語言簡單的基礎語法來實現。

當然,現在有些程式庫封裝好迴歸與分類的相關功能,如NumPy的polyfit函式可以用來求多項式迴歸,能傳回資料x、y以及多項式級數,函式會傳回多項式的係數,若要控制更多細節,可以透過Polynomial的類別,其fit方法可以指定資料x、y、多項式級數、domain、window等參數,傳回的實例代表多項式,可以有linspace等方便的方法可以使用。

相較於僅使用NumPy,有些更高階的程式庫提供更多功能,例如sklearn的LinearRegression可以實現多元線性迴歸,提供了predict方法能直接進行預測,只不過這類程式庫API設計上會考量通用性,這意謂著對於更進階的需求,必須對相關的數學運算原理有更多認識。

例如,雖然說LinearRegression字面上是線性,不過,結合PolynomialFeatures的話,可以用來求非線性迴歸,事實上,PolynomialFeatures正如其名,代表多項式的特徵,例如,對於一元函式來說,fΘ(x)=Θ0+Θ1*x,它的特徵是(1,x),而對於fΘ(x)=Θ0+Θ1*x+Θ2*x^2,特徵會是(1,x,x^2),我們可以透過fit_transform方法來計算特徵值。

例如若是二階,(x,y)為(2,7),2對應的特徵就是(1,2,4),7=Θ0+Θ1*2+Θ2*4就只是線性關係,因此透過PolynomialFeatures來轉換特徵值,就可以進一步地透過LinearRegression進行線性擬合,從而間接達到求非線性迴歸之目的。

不要迷失在公式或API組合之中

簡單來說,理解數學原理是必要的,然而理解的重點在於,過程中是如何設定需求、步驟與逐步達到目標,這點其實跟寫程式滿像的,每一步的推導(微分、向量等細節),就像是程式碼實作細節,這每一步都得反覆思考,它們是為了解決哪些小任務,而這些小任務是如何解決整體任務。

摸清程式庫的API組合方式也是必要的,然而重點在於,這些API是模擬數學推導過程中哪個部分,而不是單純地只想知道這個API組合那個API,就可以求得想要的結果;這些過程會是學習數學與程式庫中最為辛苦的部份,然而若能從事這些反覆思考,就不易迷失在迷失在公式或API組合之中,後續在應用與程式實作上,就會紮實而得心應手。

專欄作者

熱門新聞

Advertisement