之前瀏覽Coursera上機器學習方面的課程,Andrew Ng的《Machine Learning》課程評分一直很高,于是添加在了自己的收藏列表,但一直沒學。今年本科畢業季時注冊了課程開始學習,基本上按照課程大綱看視頻,完成練習,最后終于在課程結束前一周多順利結業。線上教育作為教育的一個大趨勢,這門課程作為自己圓滿完成的第一個線上課程,自己在完成提交的時候感受到滿滿的成就感。因為自己以前也注冊過很多線上課程,但圓滿完成所有課程視頻和課后練習的,這個第一個。這是寫這篇博文的第一個原因。人生中很多重要的時刻都值得記憶并記錄,而大腦的記憶很多時候是短暫且不可靠的。寫這篇博文的第二個原因是想對自己學過的內容作一個梳理和復習,加深理解和記憶。不得不說,作為機器學習領域國際公認的大牛和Coursera的聯合創始人,Andrew的這門課程的視頻通俗易懂,練習也不難,是一門非常好的機器學習入門課程。由于本人剛剛進入這個領域開始學習,所以這篇文章如果有什么表述不準確的地方,還請大家多多指正。
介紹
什么是機器學習
在學習具體的機器學習算法之前,對機器學習的基本概念有一個清晰的認識很重要。目前對機器學習有兩種比較流行的定義。一個是美國人工智能和機器學習方面的先驅Arthur_Samuel給出的:
the Field of study that gives computers the ability to learn without being explicitly programmed
也就是說機器學習研究的是賦予計算機在沒有被明確編程的情況下一種學習的能力。這是Arthur_Samuel在1959年提出來的。另一個更正式和更現代的定義是由Tom M. Mitchell提出來的:
A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P if its performance at tasks in T, as measured by P, improves with experience E.
也就是說對于某類任務T和性能度量P,如果一個計算機程序在T上以P衡量的性能隨著經驗E而自我完善,那么稱這個計算機程序從經驗E中學習,這種學習就是機器學習。還是有點抽象。舉個手寫識別系統的例子,手寫識別系統的任務就是要識別和分類圖像中的手寫文字,該系統性能好壞的評判標準就是識別的準確率,一些已分類的手寫文字數據庫就是訓練經驗。手寫識別系統內的程序就是利用已分類的手寫文字數據庫來訓練,來提高對手寫文字的識別率。
機器學習的分類
根據輸入的訓練集的特征和要解決的問題的類型,機器學習主要分成兩大類:監督學習和非監督學習。
- 監督學習:給定有特定輸入和對應的正確的(或者說想要的)輸出的數據集,監督學習就是要學習出輸入和輸出之間的一種映射,找到輸入和輸出之間的關系。根據輸出值的不同監督學習問題又可分為分類問題和回歸問題。如果輸出值是一個離散的有限集合,要解決的就是分類問題,如果輸出值是連續的,那么就是回歸問題。舉個例子,把機器學習應用到股票分析上,給定一個上市公司以往的各種數據,預測該公司的未來的股價。如果是想要預測公司股價未來具體的價格,這就是一個回歸問題,如果想要預測該公司股價在未來是漲還是跌,這就是一個分類問題。
- 非監督學習:給定的數據集只有特定的輸入,沒有期望的輸出。非監督學習的任務就是要去發現這些數據集之間隱藏的結構關系。一個典型的學習是聚類,就是發現數據集中類似的東西。
為了更清楚和形象地說明監督學習和非監督學習,舉個簡單的例子。一位老師拿了一堆蘋果和香蕉的圖片給小朋友們,這堆圖片中包含不同場景下的蘋果和香蕉,把這堆圖片叫作“訓練集”。如果老師事先不告訴小朋友們這堆圖片是什么東西,只是讓他們自己去看,然后歸類,之后老師再單獨拿出另外一堆圖片(稱之為“測試集”)讓他們去判斷這些圖片是不是屬于剛剛看過的圖片中的某一類。小朋友們這種學習的過程其實就是一種非監督學習。如果老師事先告訴小朋友們訓練集中的圖片哪些是蘋果,哪些是香蕉,然后再拿出測試集,讓小朋友辨認哪些是蘋果,哪些是香蕉,這個過程就是監督學習。
監督學習
線性回歸
最簡單的線性回歸模型是單變量線性回歸,也就是從單個特征變量X的輸入去預測單個輸出值。構建一個假設函數h(x),再構建一個代價函數J(θ)去衡量假設函數擬合的準確度,這個代價函數一般也叫作“平方誤差函數”。擬合的最好的情況是所有點到擬合直線的垂直方向的距離的平方和的平均值最小,也就是說擬合直線盡可能穿過所有點。在這種情況下J(θ)的值等于0。當輸入的特征變量不是一個,而是多個時,就是多元線性回歸問題。假設函數和代價函數的構建和單變量線性回歸相同,只是變量個數不同而已。
有了假設函數和代價函數,就需要估計假設函數中的θ參數,找出使代價函數最小的θ值。這里就用到了梯度下降算法。為了便于直觀地理解梯度下降算法,我們畫出代價函數J(θ)關于θ參數的圖,單變量回歸的情況下就是曲線圖,多元回歸的情況下就是曲面圖。找出使代價函數最小時的θ值就是圖中最低點對應的θ值。梯度下降算法的基本思想是先確定一個初始的θ值和學習速率α,然后對代價函數J(θ)求梯度,θ值在求出的梯度的方向的指引下,以學習速率和梯度大小的乘積為步長進行迭代,直至收斂。
如果不同輸入特征變量之間的值域相差過大,就會導致梯度下降算法的運行速度很慢。為了解決這個問題,常用的一種方法是特征規整,通過特征規整把輸入變量變成大致相同的范圍,一般變成(-1,1)或者(-0.5,0.5),但也沒有一個明確的要求。常用的特征規整的方法又有特征縮放和均值歸一化。特征縮放就是用輸入變量值分別除以輸入值的值域區間長度。而均值歸一化就是用每個輸入值減去輸入值的均值后,除以輸入值的值域區間長度或者輸入值的標準差。調試梯度下降算法時,找到一個合適的學習速率很重要??梢岳L出J(θ)關于迭代次數的曲線,正常情況下曲線應該是下降的,如果觀察到曲線J(θ)隨著迭代次數在上升,那么可能需要減小學習速率的值。也可以做自動收斂測試,也就說如果J(θ)在迭代中下降的值小于某個閾值就認為收斂,但是這個閾值一般不好確定。
在特征的選取和假設函數的形式上有多種方法。比如可以把多個特征通過相乘的方式結合成一個特征,假設函數的形式也不必一定是線性的,比如可以是特征的平方項、三次項等,這就構成了多項式回歸。
在尋找最優θ參數時,也可以利用標準方程來直接求得θ的值,不需要通過梯度下降算法中的多次迭代,但由于需要求矩陣的逆,如果特征過多的話,方程的求解過程也會很慢。
邏輯回歸
雖然這類問題名字叫邏輯回歸,這是由于歷史命名的原因,但其實這類問題是分類問題。先從簡單的二分類問題開始,也就是說輸出值是0或者1。邏輯回歸的基本思想就是將線性回歸假設函數通過Sigmoid函數映射到(0,1)區間,這樣就得到了邏輯回歸的假設函數,為了得到離散的0,1分類,再將假設函數值不低于0.5的映射為1,小于0.5的映射為0。對于代價函數的表示,就利用了log函數,代價函數由兩項組成——輸出為1和輸出為0,當期望輸出為1時,假設函數的預測輸出越接近1,整個代價函數的值就越??;當期望輸出為0時,假設函數的預測輸出越接近0,整個代價函數的值就越小。對于邏輯回歸問題的θ值的優化求解問題,仍然可以用梯度下降算法,但為了更高的算法效率,可以采用更高級的算法像“共軛梯度”,“BFGS”,“L-BFGS”等。
對于多分類問題,也就是輸出值是(0,1,...,n)?;舅枷胧前讯喾诸悊栴}轉化為(n+1)個二分類問題,在每個二分類問題中,我們選擇一個類,然后把所有其他類都歸為第二類,這樣重復(n+1)次后,就得到了(n+1)個不同類的假設函數,使用這(n+1)個假設函數,返回最大的預測值概率的就是我們該預測的結果。
神經網絡(NN)
當特征個數比較少時,用回歸模型假設可能還不是很復雜,但隨著特征數增多,如果還用回歸模型的話,假設函數會變得非常復雜。神經網絡應運而生。神經網絡的工作原理就是模仿我們的大腦的工作方式。研究發現,大腦內部其實只用一個學習模塊來學習不同的功能??茖W家做過這樣一個實驗:他們切斷了動物的耳朵和他們大腦中聽覺皮層之間的神經連接,然后把聽覺皮層嫁接到視神經上,結果聽覺皮層也學會了看。
基本的神經網絡主要由三層組成:輸入層、輸出層和隱藏層。輸入層就是不同的特征輸入,輸出層就是假設函數的預測結果輸出,根據神經網絡復雜度的不同,可以有多個隱藏層。每層可以由多個節點組成。在神經網絡中0參數稱之為“權重”,每層都有各自的0參數,在計算下一層的輸出時,都要加上偏置單元。在處理邏輯回歸問題時,也使用Sigmoid函數進行映射。神經網絡的代價函數的大體結構和一般的邏輯回歸的代價函數一致,只是加和項更復雜。
在優化神經網絡的代價函數的過程中會用到反向傳播算法。算法本身有點復雜,不在本文中展開。在訓練神經網絡的過程中,為了保證反向傳播算法按照預想的方式工作,需要進行“梯度檢查”。另外,θ參數不能全部初始化為0,否則在執行反向傳播時,所有的節點都將更新到同一個值,為了避免這種情況,θ要進行隨機初始化。
總結一下訓練神經網絡的步驟:
- 隨機初始化θ參數;
- 執行前向傳播算法計算假設函數;
- 計算代價函數;
- 執行反向傳播算法計算偏導數;
- 執行梯度檢查,確保反向傳播算法工作正常,然后關閉梯度檢查算法;
- 運用梯度下降或者其他內置的高級優化算法來最小化代價函數,得到對應的θ參數。
支持向量機(SVM)
課程中支持向量機的引入是通過將邏輯回歸的代價函數中的log函數換成max函數再進行一些形式的變換后得到的。與邏輯回歸的假設函數輸出概率值不同,支持向量機的假設函數直接輸出類別,比如0或1。支持向量機的代價函數的非正則項有一個系數C(C=1/λ),C值的作用和λ的作用正好相反。當想避免過擬合時,減小C的值。支持向量機是一種大間距分類器(Large Margin Classifiers)。也就是說支持向量機產生的決策邊界盡可能地遠離正樣本和負樣本。決策邊界和最近的樣本之間的距離叫作margin。
課程中還提到了核函數,支持向量機可以利用不同的核函數進行分類。課程中就舉了高斯函數作為核函數的例子。
在支持向量機的使用中,需要考慮以下的問題:
- 選擇一個參數C
- 選擇核函數(相似度函數):
- 不用核函數(線性核函數),得到的是標準的線性分類器,這種情況適用于特征數很多而訓練樣本數很少;
- 使用高斯核函數,在使用高斯核函數之前需要進行特征縮放,同時需要確定標準差的大小,這種情況適用于特征數很少而訓練樣本很多
- 邏輯回歸與支持向量機的比較(n代表特征數,m代表訓練樣本數):
- 如果n相對于m來說很大,使用邏輯回歸或者不帶核函數的SVM;
- 如果n很小,m中等大小,使用帶高斯核函數的SVM;
- 如果n很小,m很大,那么就手動創建一些其他的特征,再使用邏輯回歸或者不帶核函數的SVM
非監督學習
非監督學習僅僅給了無標簽的數據集,由非監督學習算法去找出數據集內部的機構,非監督學習中一個主要的類別就是聚類分析。聚類分析在市場劃分、社交網絡分析,組織計算集群和天文數據分析中都扮演了重要的角色。
K均值算法
K均值算法的思想如下:
- 在數據集中隨機初始化K個點(K代表類的個數),這些點叫作聚類中心;
- 把數據集中所有點分配到離它最近的聚類中心;
- 計算屬于每個聚類中心的點的平均值,將聚類中心移到這些平均值處;
- 重復步驟2和3,直到聚類中心穩定。
K均值算法有時候會卡在局部最優解上,為了防止這種情況發生,聚類中心的隨機初始化可以使用下面的算法實現,即進行多次隨機初始化:
for i = 1 to 100:
randomly initialize k-means
run k-means to get 'c' and 'm'
compute the cost function (distortion) J(c,m)
pick the clustering that gave us the lowest cost
主成分分析(PCA)
數據降維:數據降維可以用于數據的壓縮,占用較少的存儲空間,同時可以加快算法的速度。另外數據降維后便于數據的可視化,因為對于超過三維的數據,數據就不便于可視化。值得注意的是,數據降維,降的是數據的特征數,而不是數據集中樣本的數量。很流行的數據降維算法就是主成分分析算法。
PCA的目標是將每個特征往一條直線或一個平面上投影,使得投影誤差的平均值最小。比如說,把數據從n維降到k維,就是找k個向量,使得數據在這些向量上的投影誤差最小。在這里需要說明一下,PCA不是線性回歸,線性回歸是最小化平方誤差,是垂直(vertical)距離,而PCA是最小化最短間距,或者說正交(orthogonal)距離。
主成分分析算法的主要步驟如下:
- 進行數據預處理:進行特征縮放或者均值歸一化
- 計算特征向量的協方差矩陣;
- 計算協方差矩陣的特征向量;
- 取求得的U矩陣的前K列,再計算降維后的特征向量。
算法在matlab中的實現代碼如下:
Sigma = (1/m) * X' * X; % compute the covariance matrix
[U,S,V] = svd(Sigma); % compute our projected directions
Ureduce = U(:,1:k); % take the first k directions
Z = X * Ureduce; % compute the projected data points
降維后的維度K的選?。?br> 在上面的代碼中的第二行計算特征向量時,返回了一個S矩陣,S矩陣是一個對角矩陣,選取的K值應該滿足S矩陣對角上的前K個值的和與對角上所有值的和的商大于0.99,滿足這一條件的K值都是可以的。
異常檢測
給定一個數據集,然后再給定一個測試樣本,判斷這個樣本是否異常,這類問題就是異常檢測問題。
算法
- 計算各個特征的平均值和方差,假設各個特征之間相互獨立,并且遵從高斯分布,建立概率預測函數P(x);
- 對于給定的樣本,計算P(x)的值;
- 若P(x)<ε,則為異常。
異常檢測系統的開發和評估
為了評估異常檢測算法的有效性,我們取一些帶標簽的數據,分為正常樣本和異常樣本兩類,正常樣本占大多數,將這個數據集分為三個子數據集:訓練集(60%,全是正常的),交叉驗證集(20%,其中0.1%屬于異常數據,其余為正常數據),測試集(20%,其中0.1%屬于異常數據,其余為正常數據)。從訓練集中訓練出模型P(x),應用在交叉驗證集上來確定決策閾值ε,在測試集上進行測試。誤差評估可以采用前面討論過的準確率、召回率或者F值。另外說明一下,特征的選取對于異常檢測系統的表現有很大影響,我們可以通過畫一個直方圖來看看數據集的分布是不是大致符合高斯分布,如果不符合,可以先對數據做一個變換,像log函數,平方根函數等,處理后的數據一般都會符合高斯分布。此外,我們還可以使用多變量高斯分布來描述P(x)。
一些應用
機器學習的一個很重要的應用就是推薦系統。推薦系統分為兩大類:基于內容的推薦系統和協同過濾。
基于內容的推薦系統的主要思想是已知電影的特征成分表達,比如說一部電影的愛情成分占多少,動作成分占多少等,將用戶對電影的評分用一個線性模型進行擬合,對于每個用戶學習出一個對應的參數θ。和前面討論的線性回歸模型基本一致。
協同過濾算法考慮到對一部電影中的特征成分進行標定是一件比較難的事,所以協同過濾算法從用戶處收集他們對不同類別的電影的評分,從這些評分中去學習電影的特征成分。協同過濾算法又可以分為兩類:基于用戶的協同過濾和基于物品的協同過濾。
搭建系統時的評估與建議
正則化
在講正則化之前,我們先弄清楚高偏差或者欠擬合和高方差或者過擬合的概念。高偏差或者欠擬合是指假設函數對數據的擬合程度很低,不能很好地描述數據的趨勢,通常是假設函數太簡單,利用的特征太少造成的。高方差或者過擬合是指假設函數對訓練集中的數據能有很好的擬合,但是預測新數據的準確性就太差,這通常是由于選擇的特征太多,假設函數太復雜造成的。對于過擬合的問題,通常有兩種解決方案,一種是減少特征的數量,另一種就是正則化。
簡單地說,正則化的思想就是減小特征前的θ參數來懲罰該特征項,而這種懲罰又是通過增加他們在代價函數的代價來實現的。通常是在原本的代價函數的基礎上額外加上一項,該項是由一個正則參數λ和θ項的平方和的乘積構成,當選擇一個較大的λ值時,為了使代價函數值最小,θ項的平方和必須很小,也就說通過λ值來懲罰θ參數。λ值也不能太大,太大就會懲罰過度,造成欠擬合。另外,在執行梯度下降的迭代時,也要加入正則項。
模型選擇與系統診斷
模型選擇
首先必須明確,一個假設函數對訓練集的擬合程度很好并不代表這是一個好的假設,用從訓練集得到的假設函數在訓練集上進行誤差分析,得到的誤差會比把這個假設函數用在其它數據集上得到的誤差要小。模型選擇要解決的問題是:如何選擇假設函數中的多項式的階數,哪些特征應該放進假設函數中,如何選擇正則參數λ。
為了解決這個問題,我們可以把數據集分為三個部分:60%作為訓練集,20%作為交叉驗證集,20%作為測試集。對于多項式階數的選擇問題,大致的步驟如下:
- 使用訓練集得到不同階數下的假設函數的θ參數;
- 計算1中得到的假設函數用在交叉驗證集上的誤差,選擇誤差最小時對應階數的模型;
- 將選擇的模型應用在測試集上,估計通用誤差。
系統診斷
系統診斷需要確定是偏差還是方差導致不好的預測結果,確定原因后再確定采取什么樣的解決辦法。
先來研究一下多項式的階數與偏差和方差之間的聯系。隨著多項式階數的增加,訓練集的誤差會一直減小,同時交叉驗證集的誤差也會隨之減小,但當階數增加到一定程度,交叉驗證集的誤差會轉而增加。所以最優的階數應該是在交叉驗證集的誤差的轉折點對應的階數。總結一下就是,出現高偏差(欠擬合)時,訓練集和交叉驗證集的誤差都很大,并且近似相等;出現高方差(過擬合)時,訓練集誤差依然很小,但是交叉驗證集的誤差會比訓練集誤差大很多。
現在來研究一下正則參數λ與偏差和方差之間的聯系。λ越大,對θ參數的懲罰就越大,假設函數就會被大大簡化,從而出現高偏差(欠擬合),此時訓練集誤差和交叉驗證集誤差都會很大;λ較小時,訓練集的誤差會較小,交叉驗證集的誤差會較大,出現高方差(過擬合)的問題。所以一個最優的λ值是使訓練誤差和交叉驗證集誤差都相對較小,并且近似相等。
為了選擇一個合適的模型和正則參數λ,我們可以依照下面的步驟來做:
- 創建一個λ的集合;
- 選擇一個λ進行計算;
- 創建一個不同階數或者其他的模型集合;
- 選擇一個模型去學習參數θ;
- 利用選擇的模型,使用帶有選擇的λ參數的代價函數去學習得到參數θ;
- 在訓練集上,利用學習得到的θ參數,使用不帶λ參數的代價函數(即誤差函數)計算訓練集誤差;
- 在交叉驗證集上,利用學習得到的θ參數,使用不帶λ參數的代價函數(即誤差函數)計算交叉驗證誤差;
- 在所有的模型和λ參數的組合上重復以上步驟,選擇使得交叉驗證集誤差最小的組合;
- 使用最佳組合的λ和θ參數,在測試集上計算測試集誤差。
接著再來研究一下誤差和訓練集的大小的關系,也叫作學習曲線。當一個系統遭受高偏差問題時,訓練集很小時,訓練集誤差會很小,但是交叉驗證集誤差會較大,隨著訓練集的增大,訓練集誤差會逐漸增大,交叉驗證集誤差會逐漸減小,訓練集增大到一定程度時,訓練集誤差和交叉驗證集誤差會趨于相等,但誤差都很大。所以,當系統遭受高偏差問題時,增大訓練集的大小幫助不大。當一個系統遭受高方差問題時,訓練集很小時,訓練集誤差較小,交叉驗證集誤差較大,隨著訓練集的增大,訓練集誤差和交叉驗證集的變化趨勢和高偏差問題一樣,但是當訓練集增大到一定程度,交叉驗證集誤差會大于訓練集誤差。所以,當系統遭受高方差問題時,增大訓練集的大小會有幫助。
總結一下在系統診斷時應該了解的一些原則:
- 增大訓練集的大小可以修復高方差的問題而不是高偏差;
- 減少特征可以修復高方差而不是高偏差;增加特征可以修復高偏差而不是高方差;
- 增加多項式項可以修復高偏差而不是高方差;
- 在使用梯度下降算法時,減小λ可以修復高偏差,增大λ可以修復高方差;
- 在使用神經網絡時,簡單的神經網絡更傾向于會產生欠擬合,復雜的神經網絡更傾向于產生過擬合。
系統設計
Andrew在課程中推薦的解決一個機器學習問題的步驟如下:
- 先從簡單的假設函數開始,快速實現它,并作早期測試;
- 畫出學習曲線,根據學習曲線來確定是否更多的數據或者更多的特征會對模型的改善有幫助;
- 在交叉驗證集上進行誤差分析。
說到誤差分析,有時候很難確定誤差數據的減小是否代表系統的改進。這種情況在偏斜類問題上很突出。所謂偏斜類,就是說我們要預測的類在整個數據集中數量很少。對于偏斜類的誤差分析,我們采用準確率/召回率進行衡量。也可以把這兩種度量變為一種度量:F值。
參考
Tom Mitchell: 《機器學習》
wikipedia:Machine Learning
ML Wiki Page: Machine Learning Lecture Notes