機器學習A-Z~決策樹與隨機森林
決策樹
有的人可能聽過一個詞:CART,這個代表的意思是Classification And Regression Tree。它是一個分類和迴歸的決策樹。它被分為兩類,一類是分類決策樹(Classification Trees),另一個類是迴歸決策樹(Regression Trees)。也就是我們要用這個決策樹解決兩類問題,一個分類問題一個迴歸問題。

決策樹
對於分類決策樹,一般來說用於一些分類離散的資料,比如說人的性別是男或者女,水果的種類有蘋果梨子等等都是離散的。反之迴歸決策樹,那麼對應的場景就是連續的資料,比如人的年齡或者室外的溫度。當我們進行分類問題時,分類的組之間是無序的。這裡首先介紹下什麼是有序,可以舉個例子比如年齡,又年齡大或者年齡小。那麼對於性別問題,男或女,它是沒有順序的。本文要講的是分類問題在決策樹上的應用。
來看個例子,在一個二維平面上有兩個顏色分組的資料,我們要用決策樹演算法來構建分類器。這裡的決策樹演算法要做的事情就是不斷用水平和豎直的線不斷對平面進行分隔,直到某一個區域類只有紅類或者綠類。如圖所示,我們畫出幾條線對平面進行分隔。

image
這樣圖中的紅組和藍組的資料點就被這些資料分隔開來了,但這組資料是為了方便展示而特地畫成這個樣子的,實際情況並不一定會出現這種比較清晰的分割線。那我們先看看第一條分割線,將其分割成了上下兩塊區域,雖然兩邊都是既有紅色又有藍色,但我們可以說分類的結果還是比較純的。用複雜點的數學語言來說就是,我們正在尋找一條分隔線,可以是水平的也可以是豎直的,我們想要做一個優化的問題,需要最小化分隔後的基尼不純度。什麼叫純,指的是分隔後的一邊如果只有紅點或者綠點,那麼可以說這個分隔的結果是非常純的,那麼如果兩邊既有紅也有藍,那麼就是不純的。我們希望當我們新增一條分割線後,想要將兩邊的純度和最小化。那麼每一條的分割線的尋找實際上就是在做一個優化的問題,那麼優化的物件可以是基尼不純度,也可以是資訊學中的熵。這裡不做過多解釋,只是展示下決策樹是如果運作的。
畫出第一條分隔線後如圖可以得到兩組分類結果,一個是x2小於或者不小於60,再然後我們畫出第二條分割線,看出x1<50是綠組,否則就是紅組,接著再畫出第三條分割線,x1<70都是紅組,再對x1>70分隔,得出紅組和綠組資料。

image
如圖其實就是上述所說的工作流程,我們得到的每一片葉子都是比較純的結果,如果在實際實際生活中,資料可能非常複雜,那麼我們的樹可能就非常非常大,枝節非常非常多。那麼有的時候,有的枝節不一定非要到最後知道yes or no,也許可能在前面某個枝節就停止了。比如對於x2<20這裡不再繼續分割,假設有個新的資料點落在了這個區域,它落在綠色的區域的概率比落在紅色的概率要大,那麼我們就可以把這一部分都劃分到綠色組中,也就是說可以剪掉多餘的枝節,也許它對於訓練集是有意義的,但對於更多其他的資料來說,它可能就是個噪音,我們不需要知道這麼詳細的資訊。那最終就沒有這兩片葉子,到前面一步就結束了。
決策樹演算法是個很經典的機器學習演算法,很多年以前是比較流行的。但到了20世紀初已經逐漸被其他演算法所取代。直到最近又發現這個演算法中一些新的精妙的東西,比如說隨機森林,就是以決策樹為根本來展開的。還有提升梯度(Gradient Boosting)等等都是在決策樹演算法之上我們加上了一些新的元素。
程式碼實現
由於這次決策樹演算法,我們沒有使用歐式距離,也就是說可以不用進行特徵縮放。但最終畫影象時之前模版中定義的步距可能就過大或者過小,所以這裡就妥協一下保留特徵縮放的程式碼。分類器改成決策樹演算法的DecisionTreeClassifier。這個方法的引數criterion指的就是標準,預設gini,即基尼指數或者說基尼不純度。它和熵都是表示分類時劃分質量的好壞。這裡我們使用熵。其他的引數暫時用不到,random_state依然只是用來大家如果想得到相同的結果時就設定為相同的值即可。
from sklearn.tree import DecisionTreeClassifier classifier = DecisionTreeClassifier(criterion='entropy',random_state=) classifier.fit(X_train, y_train)
隨機森林
在開始講隨機森林之前我們先講一個更為廣義的概念: Ensemble Learning,整合學習。它的意思是我們使用多個分類器對我們的結果進行預測,最後再對分類結果進行一個組合,以達到最終的結果。這個組合的方式有很多種,比如平均,加權平均或者投票等等。這個整合學習的作用就是,我們覺得任何一個單獨的分類器去分類結果回感覺有誤差,這時可以用成百上千個分類器都進行預測,然後再對結果進行一個組合,可以減少預測結果的浮動率。下面來看看隨機森林演算法的步驟。
首先,隨機採用訓練集合中的資料,相當於裝袋的過程,構建自己新的訓練集;然後用這些資料訓練決策樹分類器;再然後實際上就是重複第一第二步,但每一次得到的結果是不同的,因為在第一步中我們取得的資料都是隨機的。對於一個新的資料點,我們用已經訓練好的多個訓練器分別對這個新資料的分類進行預測,最後進行一個投票,擁有最大投票數量的分類結果勝出就使用這個分類結果。

隨機森林
前文講述瞭如何構建一棵決策樹,現在擁有成百上千棵決策樹來幫助我們解決分類問題。這個分類演算法還有不少數學上的一些細節問題,比如Boosting(提升),還有當我們有高維度的情況時,我們每次選取資料時可能只選取部分維度,這樣可以避免個別維度比其他維度大的多情況。
程式碼實現
這裡依然開始先套用分類的模版,然後換成隨機森林分類器,這裡的引數n_estimators指的是決策樹的數量,這裡暫時設定成10 criterion依然設定為entropy。
from sklearn.ensemble import RandomForestClassifier classifier = RandomForestClassifier(n_estimators=10, criterion='entropy', random_state=0) classifier.fit(X_train, y_train)
通過結果觀察,這裡使用隨機森林分類器是會出現過擬合的情況。對比這幾篇文章中的分類器,實際上最適合的是核svm和樸素貝葉斯,線性分類器準確度不夠,隨機森林分類器會出現過擬合,而這兩者它們保證了擬合的準確率,並且也不會出現過擬合的問題。
以上,就是關於決策樹和隨機森林相關的基礎知識。