簡介
基於樹的學習算法被認爲是最優秀的,也是使用最普遍的監督型學習方法。基於樹的算法賦予預測模型高精度、穩定性和易解釋性。與線性模型不一樣,它們能很好地映射非線性關係。它們善於解決手頭上的任何問題,包括分類和迴歸。node
例如Decision Trees,Random Forest,Gradient Boosting等方法,在各類數據科學問題中獲得了普遍的應用。所以,對於每個分析師來講,學會這些算法並使用它們進行建模是很重要的。算法
目錄
- 什麼是決策樹,以及它是如何工做的?
- 迴歸樹Vs分類樹
- 決策樹是如何決定分割點的?
- 模型創建的關鍵參數是什麼?如何避免決策樹的過擬合?
- 基於樹的模型優於線性模型嗎?
- 在R和Python中使用決策樹。
- 基於樹的模型的集成方法(Ensemble Methods)是什麼?
- 什麼是裝袋(Bagging)?它是如何工做的?
- 什麼是隨機森林?它是如何工做的?
- 什麼是Boosting?它是如何工做的?
- GBM和Xgboost哪一個更強大?
- 在R和Python中使用GBM。
- 在R和Python中使用Xgboost。
1. 什麼是決策樹,以及它是如何工做的?
決策樹是在分類問題中常用到的一種監督型學習算法。它適用於分類型以及連續性輸入和輸出變量。在這個方法中,咱們根據輸入變量中最顯著的分裂點將整體或樣本劃分爲兩類或多類。dom

例子:ide
假若有30個同窗,已知他們的性別(Gender:Boy/Girl),班級(Class:IX/X)和身高(Hight:5-6 ft)。其中15個同窗在業餘時間打板球(cricket)。如今,我想創建一個模型預測誰在業餘時間打板球?在這個問題中,咱們須要根據高度顯著的輸入變量來區分在業餘時間中打板球的同窗。函數
決策樹可以幫助咱們,它根據三個變量的全部值劃分學生,並識別哪一個變量的劃分效果最好。在下圖中,你能夠看到與其它兩個變量相比,性別(Gender)的劃分效果最好。工具

如上所述,決策樹識別出最顯著的變量以及取值,並給出效果最好的劃分結果。那麼,如今的問題是:它如何識別最顯著的變量,以及如何進行分裂?爲此,決策樹使用了各類算法,咱們將在下面的章節中討論。性能
決策樹類型
決策樹的類型取決於咱們的目標變量的類型。共分爲兩類:學習
- 分類型變量決策樹:目標變量爲分類型的決策樹,稱爲分類型變量決策樹。例如上面的「學生是否在業餘時間打板球」。
- 連續型變量決策樹:目標變量爲連續型的決策樹,稱爲連續型變量決策樹。
例子:假如咱們要預測一個客戶是否會向保險公司支付續期保險費(是/否)。在這裏,咱們知道客戶的收入是一個顯著性變量,但保險公司沒有全部客戶的收入狀況。但是,咱們能夠基於客戶的職業,所買產品以及其它變量創建一個決策樹模型去預測客戶的收入。在這個例子中,咱們預測的是連續變量的值。spa
決策樹相關重要術語
讓咱們看看與決策樹相關的一些基本術語:3d
- 根節點(Root Node):表明整個整體或樣本。
- 分裂(Splitting):將一個節點分紅兩個或多個子節點的過程。
- 決策節點(Decision Node):當一個子節點(sub-node)進一步分紅子節點時,咱們稱這個節點爲決策節點。
- 葉子/終端節點(Leaf/Terminal Node):再也不分裂的節點稱爲葉子或終端節點。

- 剪枝(Pruning):咱們把移除一個決策節點的子節點的過程稱爲剪枝。也能夠稱之爲和分裂相反的處理過程。
- 分支/子樹(Branch/Sub-Tree):整棵樹的一個子部分叫作分支或子樹。
- 父節點和子節點(Parent and Child Node):被分裂爲sub-nodes的節點稱爲sub-nodes的父節點,而這些sub-nodes稱爲這個節點的子節點。
這些是決策樹經常使用的術語。咱們知道每種算法都有優缺點,下面是咱們應該瞭解的關於決策樹的一些優缺點:
優勢
- 易於理解:決策樹的輸出易於理解,即便是沒有分析背景的人也很容易解釋。它不須要任何統計知識來閱讀和解釋它們。它的圖形表示很是直觀,用戶能夠很容易地將它們的假設聯繫起來。
- 在數據探索過程當中頗有用:決策樹是識別最顯著變量以及兩個或多個變量之間關係的最快速的方法之一。在決策樹的幫助下,咱們能夠建立新的變量/特徵,以便可以更好地預測目標變量。它也能夠在數據探索階段發揮做用。例如:如今咱們有100個變量的信息,決策樹能夠幫助咱們識別出最顯著的變量。
- 須要少許的數據清洗工做:與其它模型相比,決策樹只須要少許的數據清洗工做。它不受離羣值和缺失值對公平度的影響。
- 數據類型沒有限制:它能夠處理數值型以及分類型變量。
- 無參方法:決策樹是一種無參方法。這意味着決策樹對空間分佈以及分類器結構沒有任何假設。
缺點
- 過擬合:過擬合是決策樹模型中最爲困難的問題之一。能夠經過設置模型參數和修剪來解決這個問題。
- 不適合連續性變量:處理連續數值型變量問題上,當決策樹將變量劃分爲不一樣類別時,將會致使信息的丟失。
2.迴歸樹Vs分類樹
咱們知道終端節點(葉子節點)位於決策樹的最底部。這意味着決策樹是一棵顛倒的樹,葉子在下面,根在上面,以下圖所示:

這兩種樹的工做原理幾乎相同,讓咱們看看分類和迴歸樹之間的主要區別和類似之處:
- 當因變量爲連續型變量時,使用迴歸樹;當因變量爲分類型變量時,使用分類樹。
- 在迴歸樹中,訓練數據中葉子節點獲得的值是該區域內觀測值的平均響應值。所以,若是一個數據觀測值落在那個區域(葉子節點),咱們將用這個區域內全部觀測值的平均值做爲它的預測值。
- 在分類樹中,訓練數據中葉子節點獲得的值(類別)是該區域內的觀測模式。所以,若是一個數據觀測落在那個區域,咱們將用這個區域內的模型做爲它的預測類別。
- 這兩種樹將預測空間(自變量)分紅不一樣的和不重疊的區域。爲了簡單起見,能夠將這些區域視爲高維空間中的一個個不重疊的空間。
- 兩種樹都遵循一種自上而下的稱爲遞歸二進制分裂的貪婪方法。之因此稱之爲「自上而下」是由於:它從樹頂開始,並不斷地將預測空間分割爲兩個新的分支。之因此稱之爲「貪婪」是由於:該算法每次都尋找最佳分割變量,只考慮當前的最優分裂,並不關心如何在總體上獲得一個最好的分裂。
- 分裂過程一直持續進行,直到用戶定義中止條件爲止。例如:當節點的觀察數小於50時,咱們能夠告訴算法中止分裂。
- 這兩種狀況下,持續地分裂將會致使徹底成熟的樹,直到達到中止條件。可是,徹底長大的樹極有可能致使過擬合,使得模型的泛化能力較弱。這就產生了「剪枝」的概念。剪枝是一種解決過擬合的技術。咱們將在下面的章節中進一步瞭解它。
3.決策樹是如何決定分割點的?
分割的方式嚴重影響着樹的準確性。分類樹和迴歸樹的分割斷定準則有所不一樣。
決策樹使用多種算法來決定把一個節點分裂成兩個或更多的子節點。子節點的生成使得分裂後的各個子節點的純度增長。決策樹在全部可用變量上進行分裂,而後選擇使得分裂後節點的純度最高的分裂方式。
算法的選擇基於目標變量的數據類型。讓咱們來看一下決策樹中最經常使用的四種算法:
基尼係數(Gini Index)
基尼係數指出:咱們從整體中隨機挑選兩個樣本,若是整體是純的,那麼這兩個樣本是同類別的機率爲1。
- 用於處理分類型目標變量「Success」或者「Failure」。
- 它只做用於二進制分裂。
- 基尼係數越大,純度越高。
- CART(分類和迴歸樹)使用Gini方法建立二進制分裂。
如何計算一個分裂的基尼係數?
- 計算各個子節點的基尼係數:計算Success和Failure的機率的平方和:$p^2 + q^2$。
- 計算分裂的基尼係數:計算各個子節點基尼係數的加權平均值。
例子:引用上面的例子,咱們想要根據目標變量(是否打板球),對學生進行劃分。以下圖:咱們使用兩個輸入變量Gender和Class對整體進行分割。如今,我想用基尼係數來肯定哪一個分裂可以產生更均勻(純)的子節點。

基於Gender進行分裂:
- 計算子節點Female的基尼係數:(0.2)×(0.2)+(0.8)×(0.8)=0.68
- 計算子節點Male的基尼係數:(0.65)×(0.65)+(0.35)×(0.35)=0.55
- 計算Gender分裂的基尼係數:(10/30)×0.68+(20/30)×0.55=0.59
基於Class進行分裂:
- 計算子節點Class IX的基尼係數:(0.43)×(0.43)+(0.57)×(0.57)=0.51
- 計算子節點Class X的基尼係數:(0.56)×(0.56)+(0.44)×(0.44)=0.51
- 計算Class分裂的基尼係數:(14/30)×0.51+(16/30)×0.51=0.51
能夠看出,基於Gender分裂的基尼係數要高於基於Class分裂的基尼係數。所以,節點將基於Gender進行分裂。
卡方(Chi-Square)
它能夠用來衡量子節點和父節點之間是否存在顯著性差別。咱們用目標變量的觀測頻率和指望頻率之間的標準離差的平方和來計算卡方值。
- 它用於處理分類型目標變量「Success」或「Failure」。
- 它能夠計算兩個或多個分裂。
- 卡方越高,子節點與父節點之間的差別越顯著。
- Chi-square = ((Actual – Expected)^2 / Expected)^1/2
- 它生成的樹稱爲:CHAID (Chi-square Automatic Interaction Detector)
如何計算一個分裂的卡方:
- 經過計算Success和Failure的誤差來計算單個節點的卡方。
- 經過計算每一個節點的Success和Failure的全部卡方總和計算一個分裂的卡方。
例子:仍然採用上述的例子。
基於Gender分裂:
- 首先,咱們統計節點Female中「Play Cricket"和」Not Play Cricket「的學生數,分別爲2和8。
- 計算「Play Cricket"和」Not Play Cricket「的指望值,都是10 × 50% = 5。由於父節點中「Play Cricket"和」Not Play Cricket「的比例都是50%。
- 計算離差值Actual - Expected。「Play Cricket」:2-5=-3;「Not Play Cricket」:8-5=3。
- 計算節點「Play Cricket"和」Not Play Cricket「的卡方值:Chi-square = ((Actual – Expected)^2 / Expected)^1/2。都是1.34。
- 和上述一樣的方法計算Male節點的卡方值。
- 將全部節點的卡方值求和,計算一個分割的卡方值。

基於Class分裂:
和上述計算過程類似,計算結果以下:

能夠看出,基於Gender的分裂比基於Class的分裂更顯著。
信息增益(Information Gain)
觀察下面的圖像,想一下哪一個節點描述起來更加容易。答案必定是C,由於C圖中的全部的值都是類似的,須要較少的信息去解釋。相比較,B和A須要更多的信息去描述。用純度描述,就是:Pure(C) > Pure(B) > Pure(A)。

純度越高的節點,就會須要更少的信息去描述它;相反,不純度越高,就會須要更多的信息。信息論用熵來定義系統的混亂程度。若是樣本中的個體是徹底相同類別的,那麼系統的熵爲0;若是樣本是等劃分的(50%-50%),那麼系統的熵爲1。
熵的計算公式爲:Entropy = -p×log(p) - q×log(q), 其中log以2爲底。以下圖,當p=0.5時,熵最大,爲1。

這裏的p和q分別是節點中Success和Failure的機率。熵也用於分類型目標變量。它選擇與父節點和其餘分裂相比,擁有最低熵的分裂。熵越小越好。
如何計算一個分裂的熵?
- 計算父節點的熵。
- 計算分裂的每個節點的熵,而後計算分裂下的全部子節點的加權平均熵。
例子:用信息熵的方法在學生打板球案例中挑選出最好的分裂。
- 父節點的熵 = -(15/30)log2(15/30)-(15/30)log2(15/30) = 1。這裏的1表示它是一個非純節點。
- Female節點的熵 = -(2/10)log2(2/10)-(8/10)log2(8/10)=0.72;Male節點的熵 = -(13/20)log2(13/20)-(7/20)log2(7/20)=0.93。
- 基於Gender的分裂熵 = 全部子節點熵的加權平均 = (10/30)×0.72+(20/30)×0.93=0.86。
- CLass IX節點的熵 = -(6/14)log2(6/14)-(8/14)log2(8/14)=0.99;Class X節點的熵 = -(9/16)log2(9/16)-(7/16)log2(7/16)=0.99。
- 基於Class的分裂熵 = (14/30)×0.99+(16/30)×0.99=0.99。
能夠看出,基於Gender分裂的熵更小。因此樹將基於Gender進行分裂。咱們能夠計算信息增益爲:1-Entropy。
方差削減(Reduction in Variance)
至此,咱們已經討論了不少關於分類型目標變量的算法。方差削減是用於連續型目標變量的算法(迴歸問題)。它使用方差公式去挑選最優分裂。方差最小的分裂將會做爲分割整體的準則。

如何計算方差?
- 計算每個節點的方差。
- 計算每個節點方差的加權平均,做爲一個分裂的方差。
例子:仍然使用打板球的例子。這裏,咱們將「Play Cricket」標記爲1,「Not Play Cricket」標記爲0。下面,利用方差的算法挑選出最優的分裂:
- 根節點的方差。這裏均值爲:(15×1 + 15×0)/30 = 0.5。方差爲:(15×(1-0.5)^2 + 15×(0-0.5)^2)/30=0.25。
- Female節點的均值爲:(2×1+8×0)/10=0.2。方差爲:(2×(1-0.2)^2+8×(0-0.2)^2)/10=0.16。
- Male節點的均值爲:(13×1+7×0)/20=0.65。方差爲:(13×(1-0.65)^2+7×(0-0.65)^2)/20=0.23。
- 基於Gender分裂的方差爲:(10/30)×0.16+(20/30)×0.23=0.21。
- Class IX節點的均值爲:(6×1+8×0)/14=0.43。方差爲:(6×(1-0.43)^2+8×(0-0.43)^2)/14=0.24。
- Class X節點的均值爲;(9×1+7×0)/16=0.56。方差爲:(9×(1-0.56)^2+7×(0-0.56)^2)/16=0.25。
- 基於Class分裂的方差爲:(14/30)×0.24+(16/30)×0.25=0.25。
能夠看出,基於Gender分裂的方差更低,因此樹將會選擇Gender變量進行分裂。
至此,咱們已經瞭解了決策樹的一些基礎知識,以及決策樹如何選擇最優變量進行分裂,創建樹模型的。決策樹能夠處理迴歸以及分類問題,下面讓咱們詳細瞭解這些方面。
4.模型創建的關鍵參數是什麼?如何避免決策樹的過擬合?
過擬合是創建決策樹模型時面臨的重要挑戰之一。若是一個決策樹沒有限制條件,那麼它會在訓練集上給你100%的準確率。由於在決策樹底部,每個觀察值都將會成爲一個葉子節點。所以,創建決策樹模型的時候防止過擬合相當重要。咱們能夠經過一下2種方式防止過擬合:
- 限制樹的大小。
- 剪枝。
限制樹的大小
能夠經過定義樹的各類參數,限制樹的大小。首先,讓咱們看下決策樹的通常結構:

用於定義樹的參數在下面進一步解釋。下面描述的參數與工具無關。理解參數在創建樹模型中的做用是很重要的。固然,這些參數在R和Python中均可以設置。
-
節點分裂的最小樣本(Minimum samples for a node split)
- 定義一個節點進行分裂要知足的最小樣本量。
- 用於控制過擬合。較高的值能夠組織模型繼續學習關係,這些關係可能只存在於一些特定的樣本中。
- 若是最小樣本設置的太高,可能致使欠擬合。須要用CV進行調整。
-
葉子節點的最小樣本(Minimum samples for a terminal node (leaf))
- 定義葉子節點中,最小的樣本量。
- 和節點分裂的最小樣本相似,用於控制過擬合。
- 通常來講,在不平衡分類問題中應該選擇較低的值,由於少類別的點落入的區域樣本數將會更少。
-
樹的最大深度(Maximum depth of tree)
- 一棵樹的最大深度。
- 用於控制過擬合。由於決策樹越深就會致使模型學習與特定樣本具備強相關的關係,使得泛化能力變弱。
- 須要用CV進行調整。
-
葉子結點的最大數量(Maximum number of terminal nodes)
- 決策樹中,葉子節點數量的最大值。
- 能夠代替樹的最大深度(max_depth)。由於二叉樹中,深度爲'n'的樹將最多生成2^n個葉子。
-
分裂所考慮的最大特徵數(Maximum features to consider for split)
- 搜索最優分裂時所考慮的最大特徵數。這些特徵變量都是隨機挑選的。
- 根據經驗法則,總特徵數的平方根效果最佳。可是,咱們應該檢查高達30%-40%的總特徵。
- 較高的值可能致使過擬合,可是取決於實際案例。
剪枝(Tree Pruning)
如前所述,設置約束的技術是一種貪婪方法。換句話說,它將檢查目前狀態下的最優分裂並繼續分裂,直到達到指定的終止條件。讓咱們考慮一下下面「當你正在開車的時候」的場景:

有兩個車道:
- 一個車道上的汽車以80km/h行駛。
- 另外一個車道上的卡車以30km/h行駛。
此時,你是黃色的車,你想超過前面兩輛汽車,你將會有2個選擇:
- 從左側迅速超過前面兩輛汽車。
- 繼續在當前車道上行駛。
讓咱們來分析一下上面兩種選擇。在第一種選擇中,你將會當即超過前面的兩輛汽車到達卡車的後方,接下來以30km/h的速度行駛,而後等待機會回到右側車道。但此時,本來在你後面的車將會你前方行駛。在第二種選擇中,你將保持當前速度繼續行駛,先超過卡車,而後視狀況超越前面的車。
這正是正常決策樹與剪枝之間的區別。帶有約束的決策樹不會看到前方的卡車,而是選擇貪婪的方式,直接從左側超車。相反,若是咱們採起剪枝,將會先看看前面的幾步,而後再進行有效的選擇。
所以,咱們知道了剪枝的效果將會更好。可是如何在決策樹中實現剪枝呢?其實思想很簡單。
- 首先,咱們先生成一個比較深的決策樹。
- 而後,從樹的底部開始,移除和頂部相比增益爲負的葉子。
- 假如一個分裂的增益爲-10,而後下一步分裂的增益爲20。普通的決策樹將會在步驟1時中止分裂。可是在剪枝中,將會保留這兩個分裂,由於在總體上實現了+10的增益。
注意,sklearn中的決策樹分類器目前不支持剪枝。比較先進的包,例如xgboost中採用了剪枝算法。可是在R的rpart包中,提供了剪枝的函數。恭喜R的用戶們!
5.基於樹的模型優於線性模型嗎?
「若是我可以用邏輯迴歸處理分類問題,用線性迴歸處理迴歸問題,還有必要使用樹模型嗎?」咱們中的不少人都會有這樣的疑問。
事實上,你可使用任何算法。它取決於你所處理的問題類型。讓咱們看看一些關鍵因素,這些因素將幫助您決定使用哪一種算法:
- 若是自變量和因變量可以很好地用線性模型近似,那麼線性迴歸的性能將優於基於樹的模型。
- 若是自變量與因變量之間存在高度的非線性以及複雜的關係,那麼基於樹的模型性能將優於傳統的迴歸算法。
- 若是你想創建一個結果易於解釋的模型,那麼決策樹將會作得更好。決策樹模型比線性迴歸模型更易於解釋。
6.在R和Python中使用決策樹
對於R以及Pythn用戶來講,很容易實現一個決策樹模型。爲了便於使用,我已經共享了標準代碼,您只須要替換您的數據集名稱和變量就可使用了。
對於R用戶,你可使用不少包來實現決策樹算法,例如ctree, rpart, tree等。
library(rpart)
x <- bind(x_train, y_train)
# 生成樹
fit <- rpart(y_train ~ ., data = x, method='class')
summary(fit)
# 預測
predicted <- predict(fit, x_test)
在上面的代碼中:
- y_train - 表示因變量。
- x_train - 表示自變量。
- x - 表示訓練數據。
對Python用戶,代碼以下:
# 加載你可以用到的包,例如pandas, bumpy
from sklearn import tree
# 假設你已經準備好了X,y,以及x_test
# 建立樹對象
model = tree.DecisionTreeClassifier(criterion='gini') #分類
# model = tree.DecisionTreeRegressor() #迴歸
# 訓練模型
model.fit(X, y)
model.score(X, y)
# 預測
predicted = model.predict(x_test)
7.基於樹的模型的集成方法(Ensemble Methods)是什麼?
"集成「的就是」羣「,」組「,」集合「的意思。集成算法將一組預測模型組合起來,以達到更精確,更穩定的預測效果。集成算法能夠顯著提升基於樹模型的性能。與其餘模型同樣,基於樹的模型也遭受着偏倚和方差的困擾。偏倚是指:預測值和觀測值的平均差別。方差是指: