迴歸、分類與聚類:三大方向剖解機器學習演算法的優缺點
在本教程中,作者對現代機器學習演算法進行一次簡要的實戰梳理。雖然類似的總結有很多,但是它們都沒有真正解釋清楚每個演算法在實踐中的好壞,而這正是本篇梳理希望完成的。因此本文力圖基於實踐中的經驗,討論每個演算法的優缺點。而機器之心也在文末給出了這些演算法的具體實現細節。
對機器學習演算法進行分類不是一件容易的事情,總的來看,有如下幾種方式:生成與判別、引數與非引數、監督與非監督等等。
然而,就實踐經驗來看,這些都不是實戰過程中最有效的分類演算法的方式。因為對於應用機器學習而言,開發者一般會在腦海中有一個最終目標,比如預測一個結果或是對你的觀察進行分類。
因此,我們想介紹另一種對演算法進行分類的路數,其基於機器學習任務來分類。
沒有免費午餐定理
在機器學習中,有個定理被稱為「沒有免費的午餐」。簡而言之,就是說沒有一個演算法可以完美解決所有問題,而且這對於監督學習(即對預測的建模)而言尤其如此。
舉個例子,你不能說神經網路就一定任何時候都比決策樹優秀,反過來也是。這其中存在很多影響因素,比如你資料集的規模和結構。
所以,當你使用一個固定的資料測試集來評估效能,挑選最適合演算法時,你應該針對你的問題嘗試多種不同的演算法。
當然,你所使用的演算法必須要適合於你試圖解決的問題,這也就有了如何選擇正確的機器學習任務這一問題。做個類比,如果你需要打掃你的房子,你可能會用吸塵器、掃帚或者是拖把,但是你絕不會掏出一把鏟子然後開始挖地。
機器學習任務
在本次梳理中,我們將涵蓋目前「三大」最常見機器學習任務:
-
迴歸方法
-
分類方法
-
聚類方法
說明:
-
本文的梳理不會涵蓋具體領域的問題,比如自然語言處理。
-
本文也不會對每個演算法都進行梳理。因為現有太多演算法,而且新的演算法也層出不窮。然而,這份清單將向讀者展現對每個任務而言目前具有代表性的演算法概覽。
1、迴歸方法
迴歸方法是一種對數值型連續隨機變數進行預測和建模的監督學習演算法。使用案例一般包括房價預測、股票走勢或測試成績等連續變化的案例。
迴歸任務的特點是標註的資料集具有數值型的目標變數。也就是說,每一個觀察樣本都有一個數值型的標註真值以監督演算法。
1.1 線性迴歸(正則化)
線性迴歸是處理迴歸任務最常用的演算法之一。該演算法的形式十分簡單,它期望使用一個超平面擬合數據集(只有兩個變數的時候就是一條直線)。如果資料集中的變數存線上性關係,那麼其就能擬合地非常好。
在實踐中,簡單的線性迴歸通常被使用正則化的迴歸方法(LASSO、Ridge 和 Elastic-Net)所代替。正則化其實就是一種對過多回歸係數採取懲罰以減少過擬合風險的技術。當然,我們還得確定懲罰強度以讓模型在欠擬合和過擬合之間達到平衡。
-
優點:線性迴歸的理解與解釋都十分直觀,並且還能通過正則化來降低過擬合的風險。另外,線性模型很容易使用隨機梯度下降和新資料更新模型權重。
-
缺點:線性迴歸在變數是非線性關係的時候表現很差。並且其也不夠靈活以捕捉更復雜的模式,新增正確的互動項或使用多項式很困難並需要大量時間。
-
Python 實現:http://scikit-learn.org/stable/modules/linear_model.html
-
R 實現:https://cran.r-project.org/web/packages/glmnet/index.html
1.2 迴歸樹(整合方法)
迴歸樹(決策樹的一種)通過將資料集重複分割為不同的分支而實現分層學習,分割的標準是最大化每一次分離的資訊增益。這種分支結構讓迴歸樹很自然地學習到非線性關係。
整合方法,如隨機森林(RF)或梯度提升樹(GBM)則組合了許多獨立訓練的樹。這種演算法的主要思想就是組合多個弱學習演算法而成為一種強學習演算法,不過這裡並不會具體地展開。在實踐中 RF 通常很容易有出色的表現,而 GBM 則更難調參,不過通常梯度提升樹具有更高的效能上限。
-
優點:決策樹能學習非線性關係,對異常值也具有很強的魯棒性。整合學習在實踐中表現非常好,其經常贏得許多經典的(非深度學習)機器學習競賽。
-
缺點:無約束的,單棵樹很容易過擬合,因為單棵樹可以保留分支(不剪枝),並直到其記住了訓練資料。整合方法可以削弱這一缺點的影響。
-
隨機森林 Python 實現:http://scikit-learn.org/stable/modules/ensemble.html#random-forests
-
隨機森林 R 實現:https://cran.r-project.org/web/packages/randomForest/index.html
-
梯度提升樹 Python 實現:http://scikit-learn.org/stable/modules/ensemble.html#classification
-
梯度提升樹 R 實現:https://cran.r-project.org/web/packages/gbm/index.html
1.3 深度學習
深度學習是指能學習極其複雜模式的多層神經網路。該演算法使用在輸入層和輸出層之間的隱藏層對資料的中間表徵建模,這也是其他演算法很難學到的部分。
深度學習還有其他幾個重要的機制,如卷積和 drop-out 等,這些機制令該演算法能有效地學習到高維資料。然而深度學習相對於其他演算法需要更多的資料,因為其有更大數量級的引數需要估計。
-
優點:深度學習是目前某些領域最先進的技術,如計算機視覺和語音識別等。深度神經網路在影象、音訊和文字等資料上表現優異,並且該演算法也很容易對新資料使用反向傳播演算法更新模型引數。它們的架構(即層級的數量和結構)能夠適應於多種問題,並且隱藏層也減少了演算法對特徵工程的依賴。
-
缺點:深度學習演算法通常不適合作為通用目的的演算法,因為其需要大量的資料。實際上,深度學習通常在經典機器學習問題上並沒有整合方法表現得好。另外,其在訓練上是計算密集型的,所以這就需要更富經驗的人進行調參(即設定架構和超引數)以減少訓練時間。
-
Python 資源:https://keras.io/
-
R 資源:http://mxnet.io/
1.4 最近鄰演算法
最近鄰演算法是「基於例項的」,這就意味著其需要保留每一個訓練樣本觀察值。最近鄰演算法通過搜尋最相似的訓練樣本來預測新觀察樣本的值。
而這種演算法是記憶體密集型,對高維資料的處理效果並不是很好,並且還需要高效的距離函式來度量和計算相似度。在實踐中,基本上使用正則化的迴歸或樹型整合方法是最好的選擇。
2、分類方法
分類方法是一種對離散型隨機變數建模或預測的監督學習演算法。使用案例包括郵件過濾、金融欺詐和預測僱員異動等輸出為類別的任務。
許多回歸演算法都有與其相對應的分類演算法,分類演算法通常適用於預測一個類別(或類別的概率)而不是連續的數值。
2.1 Logistic 迴歸(正則化)
Logistic 迴歸是與線性迴歸相對應的一種分類方法,且該演算法的基本概念由線性迴歸推導而出。Logistic 迴歸通過 Logistic 函式(即 Sigmoid 函式)將預測對映到 0 到 1 中間,因此預測值就可以看成某個類別的概率。
該模型仍然還是「線性」的,所以只有在資料是線性可分(即資料可被一個超平面完全分離)時,演算法才能有優秀的表現。同樣 Logistic 模型能懲罰模型係數而進行正則化。
-
優點:輸出有很好的概率解釋,並且演算法也能正則化而避免過擬合。Logistic 模型很容易使用隨機梯度下降和新資料更新模型權重。
-
缺點:Logistic 迴歸在多條或非線性決策邊界時效能比較差。
-
Python 實現:http://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
-
R 實現:https://cran.r-project.org/web/packages/glmnet/index.html
2.2 分類樹(整合方法)
與迴歸樹相對應的分類演算法是分類樹。它們通常都是指決策樹,或更嚴謹一點地稱之為「分類迴歸樹(CART)」,這也就是非常著名的 CART 的演算法。
簡單的隨機森林
-
優點:同迴歸方法一樣,分類樹的整合方法在實踐中同樣表現十分優良。它們通常對異常資料具有相當的魯棒性和可擴充套件性。因為它的層級結構,分類樹的整合方法能很自然地對非線性決策邊界建模。
-
缺點:不可約束,單棵樹趨向於過擬合,使用整合方法可以削弱這一方面的影響。
-
隨機森林 Python 實現:http://scikit-learn.org/stable/modules/ensemble.html#regression
-
隨機森林 R 實現:https://cran.r-project.org/web/packages/randomForest/index.html
-
梯度提升樹 Python 實現:http://scikit-learn.org/stable/modules/ensemble.html#classification
-
梯度提升樹 R 實現:https://cran.r-project.org/web/packages/gbm/index.html
2.3 深度學習
深度學習同樣很容易適應於分類問題。實際上,深度學習應用地更多的是分類任務,如影象分類等。
-
優點:深度學習非常適用於分類音訊、文字和影象資料。
-
缺點:和迴歸問題一樣,深度神經網路需要大量的資料進行訓練,所以其也不是一個通用目的的演算法。
-
Python 資源:https://keras.io/
-
R 資源:http://mxnet.io/
2.4 支援向量機
支援向量機(SVM)可以使用一個稱之為核函式的技巧擴充套件到非線性分類問題,而該演算法本質上就是計算兩個稱之為支援向量的觀測資料之間的距離。SVM 演算法尋找的決策邊界即最大化其與樣本間隔的邊界,因此支援向量機又稱為大間距分類器。
支援向量機中的核函式採用非線性變換,將非線性問題變換為線性問題
例如,SVM 使用線性核函式就能得到類似於 logistic 迴歸的結果,只不過支援向量機因為最大化了間隔而更具魯棒性。因此,在實踐中,SVM 最大的優點就是可以使用非線性核函式對非線性決策邊界建模。
-
優點:SVM 能對非線性決策邊界建模,並且有許多可選的核函式形式。SVM 同樣面對過擬合有相當大的魯棒性,這一點在高維空間中尤其突出。
-
缺點:然而,SVM 是記憶體密集型演算法,由於選擇正確的核函式是很重要的,所以其很難調參,也不能擴充套件到較大的資料集中。目前在工業界中,隨機森林通常優於支援向量機演算法。
-
Python 實現:http://scikit-learn.org/stable/modules/svm.html#classification
-
R 實現:https://cran.r-project.org/web/packages/kernlab/index.html
2.5 樸素貝葉斯
樸素貝葉斯(NB)是一種基於貝葉斯定理和特徵條件獨立假設的分類方法。本質上樸素貝葉斯模型就是一個概率表,其通過訓練資料更新這張表中的概率。為了預測一個新的觀察值,樸素貝葉斯演算法就是根據樣本的特徵值在概率表中尋找最大概率的那個類別。
之所以稱之為「樸素」,是因為該演算法的核心就是特徵條件獨立性假設(每一個特徵之間相互獨立),而這一假設在現實世界中基本是不現實的。
-
優點:即使條件獨立性假設很難成立,但樸素貝葉斯演算法在實踐中表現出乎意料地好。該演算法很容易實現並能隨資料集的更新而擴充套件。
-
缺點:因為樸素貝葉斯演算法太簡單了,所以其也經常被以上列出的分類演算法所替代。
-
Python 實現:http://scikit-learn.org/stable/modules/naive_bayes.html
-
R 實現:https://cran.r-project.org/web/packages/naivebayes/index.html
3、聚類
聚類是一種無監督學習任務,該演算法基於資料的內部結構尋找觀察樣本的自然族群(即叢集)。使用案例包括細分客戶、新聞聚類、文章推薦等。
因為聚類是一種無監督學習(即資料沒有標註),並且通常使用資料視覺化評價結果。如果存在「正確的回答」(即在訓練集中存在預標註的叢集),那麼分類演算法可能更加合適。
3.1 K 均值聚類
K 均值聚類是一種通用目的的演算法,聚類的度量基於樣本點之間的幾何距離(即在座標平面中的距離)。叢集是圍繞在聚類中心的族群,而叢集呈現出類球狀並具有相似的大小。聚類演算法是我們推薦給初學者的演算法,因為該演算法不僅十分簡單,而且還足夠靈活以面對大多數問題都能給出合理的結果。
-
優點:K 均值聚類是最流行的聚類演算法,因為該演算法足夠快速、簡單,並且如果你的預處理資料和特徵工程十分有效,那麼該聚類演算法將擁有令人驚歎的靈活性。
-
缺點:該演算法需要指定叢集的數量,而 K 值的選擇通常都不是那麼容易確定的。另外,如果訓練資料中的真實叢集並不是類球狀的,那麼 K 均值聚類會得出一些比較差的叢集。
-
Python 實現:http://scikit-learn.org/stable/modules/clustering.html#k-means
-
R 實現:https://stat.ethz.ch/R-manual/R-devel/library/stats/html/kmeans.html
3.2 Affinity Propagation 聚類
AP 聚類演算法是一種相對較新的聚類演算法,該聚類演算法基於兩個樣本點之間的圖形距離(graph distances)確定叢集。採用該聚類方法的叢集擁有更小和不相等的大小。
-
優點:該演算法不需要指出明確的叢集數量(但是需要指定「sample preference」和「damping」等超引數)。
-
缺點:AP 聚類演算法主要的缺點就是訓練速度比較慢,並需要大量記憶體,因此也就很難擴充套件到大資料集中。另外,該演算法同樣假定潛在的叢集是類球狀的。
-
Python 實現:http://scikit-learn.org/stable/modules/clustering.html#affinity-propagation
-
R 實現:https://cran.r-project.org/web/packages/apcluster/index.html
3.3 層次聚類(Hierarchical / Agglomerative)
層次聚類是一系列基於以下概念的聚類演算法:
-
最開始由一個數據點作為一個叢集
-
對於每個叢集,基於相同的標準合併叢集
-
重複這一過程直到只留下一個叢集,因此就得到了叢集的層次結構。
-
優點:層次聚類最主要的優點是叢集不再需要假設為類球形。另外其也可以擴充套件到大資料集。
-
缺點:有點像 K 均值聚類,該演算法需要設定叢集的數量(即在演算法完成後需要保留的層次)。
-
Python 實現:http://scikit-learn.org/stable/modules/clustering.html#hierarchical-clustering
-
R 實現:https://stat.ethz.ch/R-manual/R-devel/library/stats/html/hclust.html
3.4 DBSCAN
DBSCAN 是一個基於密度的演算法,它將樣本點的密集區域組成一個叢集。最近還有一項被稱為 HDBSCAN 的新進展,它允許改變密度叢集。
-
優點:DBSCAN 不需要假設叢集為球狀,並且它的效能是可擴充套件的。此外,它不需要每個點都被分配到一個叢集中,這降低了叢集的異常資料。
-
缺點:使用者必須要調整「epsilon」和「min_sample」這兩個定義了叢集密度的超引數。DBSCAN 對這些超引數非常敏感。
-
Python 實現:http://scikit-learn.org/stable/modules/clustering.html#dbscan
-
R 實現:https://cran.r-project.org/web/packages/dbscan/index.html
結語
本文從迴歸問題、分類問題和聚類問題三個角度下初步瞭解了各個演算法的優缺點,也基本瞭解了那些演算法到底是什麼。但以上每一個演算法都有更多的概念和細節沒有展現出來,我們不能知道它們的損失函式是什麼、訓練目標是什麼、權重更新策略是什麼等等一些列問題。因此我們希望能從機器之心歷來文章中搜尋一些,為有興趣的讀者提供這些演算法的具體細節。
線性迴歸:
決策樹(整合方法):
支援向量機:
深度學習:
聚類演算法:
最後,不論是基本概念還是具體演算法,最重要的就是實踐。不實踐這些演算法就永遠不能發現哪些地方沒有掌握,因此希望本文能有助於各位讀者實踐自己的演算法。