基于樹的學(xué)習(xí)算法被認為是最好的和最常用的監(jiān)督學(xué)習(xí)(supervised learning)方法之一?;跇涞姆椒ㄙx予預(yù)測模型高精度,穩(wěn)定性和易于解釋的能力。 與線性模型不同,它們非常好地映射非線性關(guān)系。 它們適應(yīng)于解決手頭的任何問題(分類或回歸)。
決策樹,隨機森林,梯度提升等方法被廣泛用于各種數(shù)據(jù)科學(xué)問題。 因此,對于每個分析師(新手也是一樣)來說,重要的是學(xué)習(xí)這些算法并將其用于建模。
本教程旨在幫助初學(xué)者從頭開始學(xué)習(xí)基于樹的建模。 成功完成本教程之后,人們期望熟練使用基于樹的算法和構(gòu)建預(yù)測模型。
注意:本教程不需要機器學(xué)習(xí)的先驗知識。 然而,R或Python的基本知識將是有幫助的。 在開始本教程前你可以從頭開始學(xué)習(xí)Python或者R語言。
1. 什么是決策樹? 它是如何工作的 ?
決策樹是一種主要用于分類問題的監(jiān)督學(xué)習(xí)算法(具有預(yù)先定義的目標(biāo)變量)。 它適用于分類變量和連續(xù)型的輸入輸出變量。 在這種技術(shù)中,我們基于輸入變量中最重要的分割器/微分器將總體或樣本分成兩個或更多個同質(zhì)集合(或子集群)。

例子:
假設(shè)我們有30個學(xué)生的樣本,有三個變量:性別(boy/girl),班級(IX / X)和身高(5到6英尺)。 30名孩子中間有15個在業(yè)余時間打板球。 現(xiàn)在,我想創(chuàng)建一個模型來預(yù)測誰將在業(yè)余時間玩板球? 在這個問題中,我們需要根據(jù)所有三個中最重要的輸入變量來區(qū)分在休閑時間玩板球的學(xué)生。
這是決策樹最有用的地方,它將基于三個變量的所有值劃分學(xué)生,并識別變量,這創(chuàng)建了最好的同質(zhì)學(xué)生集合(彼此是異質(zhì)的)。 在下面的截圖中,您可以看到變量Gender與其他兩個變量相比能夠最好的識別同類集。

如上所述,決策樹識別最重要的變量,它是給出最佳同質(zhì)集合的值。 現(xiàn)在的問題是,它如何識別變量和分裂? 為此,決策樹使用了各種算法,我們將在下一節(jié)中討論。
決策樹的類型
決策樹的類型是由我們所擁有的目標(biāo)變量的類型決定的。它可以有兩種類型:
- 分類變量決策樹:目標(biāo)變量是分類變量的決策樹被稱為分類變量決策樹。示例: 在上述的學(xué)生問題當(dāng)中,目標(biāo)變量是“學(xué)生將打板球”,即YES或NO。
- 連續(xù)變量決策樹:決策樹具有連續(xù)型的目標(biāo)變量,則稱為連續(xù)變量決策樹。假設(shè)我們有一個問題來預(yù)測客戶是否會向保險公司支付續(xù)保費(是/否)。 在這里,我們知道客戶的收入是一個重要的變量,但保險公司沒有所有客戶的收入明細。 現(xiàn)在,我們知道這是一個重要的變量,那么我們可以構(gòu)建一個決策樹,根據(jù)職業(yè),產(chǎn)品和各種其他變量來預(yù)測客戶收入。 在這種情況下,我們預(yù)測連續(xù)變量的值。
與決策樹相關(guān)的重要術(shù)語(important terminology)
讓我們來看看決策樹使用的基本術(shù)語:
- 根節(jié)點(root node):它代表整個群體或樣本,并且會進一步被劃分為兩個或更多個同質(zhì)集合。
- 分裂(splitting):這是將節(jié)點劃分為兩個或更多個子節(jié)點的過程。
- 決策節(jié)點(decision node):當(dāng)子節(jié)點拆分為更多的子節(jié)點時,稱為決策節(jié)點。
- 葉/終端節(jié)點(leaf/terminal node):節(jié)點不分裂稱為葉節(jié)點或終端節(jié)點。
- 修剪(prunning):當(dāng)我們刪除決策節(jié)點的子節(jié)點時,這個過程稱為修剪。 你可以說分裂的相反過程。
- 分支/子樹(branch/sub-tree):整個樹的子部分稱為分支或子樹。
- 父子節(jié)點(parent and child node):被劃分為子節(jié)點的節(jié)點被稱為子節(jié)點的父節(jié)點,其中子節(jié)點是父節(jié)點的子節(jié)點。

以上這些都是通常用于決策樹的術(shù)語。我們知道每個算法都有優(yōu)缺點,下面是我們應(yīng)該知道的重要因素。
優(yōu)點
- 容易理解(Easy to Understand):決策樹輸出非常容易理解,即使對于非分析背景的人。它不需要任何統(tǒng)計知識來閱讀和解釋它們。它的圖形表示非常直觀,用戶可以很容易聯(lián)系到他們的假設(shè)。
- 在數(shù)據(jù)探索中有用(Useful in Data Exploration):決策樹是識別最重要變量和兩個或更多變量之間關(guān)系的最快方法之一。在決策樹的幫助下,我們可以創(chuàng)建具有更好的預(yù)測目標(biāo)變量的能力的新變量/特征。你可以參考這篇文章(Trick to enhance power of Regression model)。它也可以用于數(shù)據(jù)探索階段。例如,我們正在處理一個問題,其中我們有數(shù)百個變量,決策樹將有助于識別出其中最重要的變量。
- 更少的數(shù)據(jù)清理(Less data cleaning required):與其他一些建模技術(shù)相比,它需要更少的數(shù)據(jù)清理。它一定程度上不受異常值和錯誤值的影響。
- 數(shù)據(jù)類型不是約束(Data type is not a constraint):它可以處理數(shù)值和分類變量。
- 非參數(shù)方法(Non Parametric Method):決策樹被認為是一個非參數(shù)方法。這意味著決策樹沒有關(guān)于空間分布和分類器結(jié)構(gòu)的假設(shè)。
缺點
- 過擬合(Over fitting):過擬合是決策樹模型最實際的困難之一。 通過設(shè)置模型參數(shù)和修剪的約束(下面將詳細討論)解決這個問題。
- 不適合連續(xù)變量(Not fit for continuous variables):當(dāng)使用連續(xù)數(shù)值變量時,決策樹在將變量分類到不同類別時會丟失信息。
2.回歸樹和分類樹
我們都知道終端節(jié)點(或葉)位于決策樹的底部。 這意味著決策樹通常被倒置地繪制,使得葉子是底部和根部是頂部(如下所示)。

兩個樹的工作模式幾乎相似,讓我們看看分類樹和回歸樹之間的主要差異和相似性:
- 當(dāng)因變量(dependent variables)是連續(xù)變量時,使用回歸樹。當(dāng)因變量是分類變量時,使用分類樹。
- 在回歸樹的情況下,由訓(xùn)練數(shù)據(jù)中的終端節(jié)點獲得的值是落在該區(qū)域中的觀測值的平均響應(yīng)。因此,如果一個不可見的數(shù)據(jù)觀測值屬于該區(qū)域,我們將用平均值進行預(yù)測。
- 在分類樹的情況下,終端節(jié)點在訓(xùn)練數(shù)據(jù)中獲得的值(類)是落在該區(qū)域中的眾數(shù)。因此,如果一個不可見的數(shù)據(jù)觀測值落在該區(qū)域,我們將使用眾數(shù)值進行預(yù)測。
- 這兩棵樹將預(yù)測變量空間(自變量)劃分為不同的和非重疊的區(qū)域。為了簡單起見,您可以將這些區(qū)域視為高維盒子或箱子。
- 兩個樹都遵循稱為遞歸二進制分裂的自上而下的貪婪方法。我們將其稱為“自上而下”,因為當(dāng)所有觀察結(jié)果在單個區(qū)域中可用時,它從樹的頂部開始,并且連續(xù)地將預(yù)測器空間分割成樹中的兩個新分支。它被稱為“貪婪”,因為,算法僅僅關(guān)心(尋找最佳可用變量)關(guān)于當(dāng)前的分裂,而不是關(guān)于未來分裂(而這將導(dǎo)致更好的樹)。
- 該分裂過程繼續(xù),直到達到用戶定義的停止標(biāo)準。例如:一旦每個節(jié)點的觀測數(shù)量小于50,我們就可以告訴算法停止。
- 在這兩種情況下,分裂過程導(dǎo)致完全生長的樹,直到達到停止標(biāo)準。但是,完全生長的樹可能過度擬合數(shù)據(jù),導(dǎo)致未知數(shù)據(jù)的準確性差。這帶來了“修剪”。修剪是使用滑輪過度配合的技術(shù)之一。我們將在下一節(jié)中詳細了解它。
3.樹如何決定在哪里分裂?
樹的分裂策略嚴重影響樹的準確性。分類樹和回歸樹的決策標(biāo)準是不同的。
決策樹使用多個算法來決定將一個節(jié)點分裂成兩個或更多個子節(jié)點。子節(jié)點的創(chuàng)建增加了所得到的子節(jié)點的同質(zhì)性。 換句話說,我們可以說,節(jié)點的純度相對于目標(biāo)變量增加。 決策樹分裂所有可用變量上的節(jié)點,然后選擇導(dǎo)致最一致子節(jié)點的分裂。
算法選擇也基于目標(biāo)變量的類型。 讓我們來看看決策樹中最常用的四種算法:
吉尼指數(shù)(Gini Index)
吉尼指數(shù)指出,如果我們從一個群體中隨機選擇兩個項目,而且它們必須是相同的類別,如果群體是單一的,那么概率為1。
- 它的分類目標(biāo)變量只能是“成功”或“失敗”
- 它只執(zhí)行二進制拆分
- Gini的值越高,同質(zhì)性越高。
- CART(分類和回歸樹)使用Gini方法創(chuàng)建二進制拆分。
計算分裂的Gini指數(shù)的步驟:
- 計算子節(jié)點的吉尼指數(shù)(成功和失敗概率的平方和,$$p2+q2$$)
- 使用該分割的每個節(jié)點的加權(quán)Gini分數(shù)計算分割的Gini指數(shù)
例子
參考上面使用的示例,其中我們想基于目標(biāo)變量(玩或不玩板球)來劃分學(xué)生。 在下面的快照中,我們使用兩個輸入變量Gender和Class來拆分總體。 現(xiàn)在,我想確定哪個拆分使用Gini指數(shù)能夠生成更均勻的子節(jié)點。

基于性別分裂:
- 子節(jié)點Female的Gini指數(shù) =(0.2)*(0.2)+(0.8)*(0.8)= 0.68
- 子節(jié)點Male的Gini指數(shù) =(0.65)*(0.65)+(0.35)*(0.35)= 0.55
- 計算基于性別分裂的加權(quán)Gini指數(shù)=(10/30)* 0.68 +(20/30)* 0.55 = 0.59
相似地,基于年級的分裂:
- 子節(jié)點類IX的Gini指數(shù) =(0.43)*(0.43)+(0.57)*(0.57)= 0.51
- 子節(jié)點類X的Gini指數(shù)=(0.56)*(0.56)+(0.44)*(0.44)= 0.51
- 計算基于年級分裂的加權(quán)Gini指數(shù)=(14/30)* 0.51 +(16/30)* 0.51 = 0.51
在上面,您可以看到,“Gender”的Gini分數(shù)高于“Class”的分數(shù),因此,節(jié)點拆分將在“Gender”上進行。
卡方(Chi-Square)
它是一種計算子節(jié)點和父節(jié)點之間的差異的統(tǒng)計顯著性的算法。 我們通過目標(biāo)變量的觀測頻率和預(yù)期頻率之間的標(biāo)準差的平方和來測量。
- 它的分類目標(biāo)變量只能是“成功”或“失敗”
- 它可以執(zhí)行兩個或多個拆分。
- Chi-Square的值越高,子節(jié)點和父節(jié)點之間的差異的統(tǒng)計顯著性就越高。
- 每個節(jié)點的卡方使用公式計算 $$ \xi = \sqrt[]{(Actual – Expected)^2 \over Expected} $$
- 它產(chǎn)生的樹稱為CHAID(卡方自動交互檢測器)
計算分裂的卡方值的步驟:
- 通過計算成功和失敗的偏差計算個體節(jié)點的卡方
- 使用分割的每個節(jié)點的成功和失敗的所有卡方的和計算分裂的卡方值
例子
我們依然使用上面計算吉尼指數(shù)的例子
基于性別的分裂:
- 首先我們填寫節(jié)點Female的值,填入“Play Cricket”和“Not Play Cricket”的實際值,這里分別是2和8。
- 計算“Play Cricket”和“Not Play Cricket”的期望值,因為父節(jié)點具有50%的概率,我們對女性計數(shù)(10)應(yīng)用相同的概率。
- 使用公式計算偏差,$$Actual - expected$$。 它們分別是“Play Cricket”(2 - 5 = -3)和“Not Play Cricket”(8 - 5 = 3)。
- 使用公式 $$\xi = \sqrt[]{(Actual – Expected)^2 \over Expected}$$計算“Play Cricket”和“Not Play Cricket”的節(jié)點的卡方值。 您可以參考下表進行計算。
- 按照類似的步驟計算Male節(jié)點的卡方值。
- 最后將所有的卡方值加起來計算出基于性別節(jié)點分裂的卡方值。

基于年級的分裂
步驟類似于上面基于性別的分類,詳見下表

上面,你可以看到,卡方值也識別出性別分裂比類別更顯著。
信息增益(Information Gain)
觀察下面的圖像,并指出哪個節(jié)點可以很容易地描述。 我相信,你的答案是C,因為它需要較少的信息,因為所有的值都是類似的。 另一方面,B需要更多的信息來描述它,A需要最大的信息。 換句話說,我們可以說C是一個純節(jié)點,B是不純,A是更不純。

現(xiàn)在,我們可以得出一個結(jié)論,一個樣本擁有越少的不純節(jié)點,描述這個樣本所需的信息越少。而更多的不純節(jié)點則需要更多的信息來描述。 信息論(Information Theory)采用“熵(Entropy)”來衡量一個系統(tǒng)的紊亂程度。如果樣本完全均勻,則熵為零,如果樣本是等分的(50%-50%),則熵為1。
熵的計算公式:
$$Entropy = p\log_2p-q\log_2q$$
這里p和q分別是該節(jié)點的成功和失敗的概率。 熵也與分類目標(biāo)變量一起使用。 它選擇與父節(jié)點和其他分裂相比具有最低熵的分裂。 熵越小,它越好。
計算分割的熵的步驟:
- 計算父節(jié)點的熵
- 計算分割的每個單獨節(jié)點的熵,并計算分割中可用的所有子節(jié)點的加權(quán)平均值。
例子
讓我們使用這個方法來識別學(xué)生示例的最佳分裂。
- 父節(jié)點的熵= $${15\over30}\log_2{15\over30} - {15\over30}\log_2{15\over30}= 1$$.這里1示出它是不純節(jié)點。
- Female節(jié)點的熵為$${2\over10}\log_2{2\over10} - {8\over10}\log_2{8\over10}= 0.72$$,
- 對于Male節(jié)點, $${13\over20}\log_2{13\over20} – {7\over20}\log_2 {7\over20} = 0.93$$
- 基于性別分割的熵=子節(jié)點的加權(quán)熵=$$(10/30)* 0.72 +(20/30)* 0.93 = 0.86$$
- "Class IX"節(jié)點的熵$${6\over14}\log_2{6\over14} - {8\over14}\log_2{8\over14}= 0.99$$,
- 對于"Class X"節(jié)點,$${9\over16}\log_2{9\over16} - {7\over16}\log_2{7\over16}= 0.99$$。
- 基于年級分裂的熵=子節(jié)點的加權(quán)熵=$$(14/30)* 0.99 +(16/30)* 0.99 = 0.99$$
上面,你可以看到,在性別上分割的熵是最低的,所以樹將在性別上分裂。 我們可以從熵中獲取信息增益為1-熵。
方差縮減(Reduction in Variance)
到目前為止,我們已經(jīng)討論了分類目標(biāo)變量的算法。 方差的減少是用于連續(xù)目標(biāo)變量(回歸問題)的算法。 該算法使用標(biāo)準方差公式選擇最佳分割。 選擇具有較低方差的分割作為分割總體的標(biāo)準:
方差公式
$$
s2={\frac1n}\sum_{i=1}n(x_i-\overline{x})^2
$$
計算方差的步驟:
- 計算每個節(jié)點的方差。
- 每個節(jié)點方差的加權(quán)平均值作為分裂的方差值。
例子
我們把打板球賦值為1,不打板球賦值為0。 現(xiàn)在按照步驟確定正確的分割:
- 根節(jié)點的方差,這里的平均值是$$(15 * 1 + 15 * 0)/ 30 = 0.5$$,我們有15個和15個零?,F(xiàn)在方差將是$$((1-0.5)^ 2 +(1-0.5)^ 2 + ... .15倍+(0-0.5)^ 2 +(0-0.5)^ 2 + ... 15倍)/ 30$$, 被寫為$$(15 *(1-0.5)^ 2 + 15 *(0-0.5)^ 2)/ 30 = 0.25$$
- 女性節(jié)點的平均值為$$(2 * 1 + 8 * 0)/10=0.2$$,方差為$$(2 *(1-0.2)^ 2 + 8 *(0-0.2)^ 2)/ 10 = 0.16$$
- 男性節(jié)點的均值為$$(13 * 1 + 7 * 0)/20=0.65$$,方差為$$(13 *(1-0.65)^ 2 + 7 *(0-0.65)^ 2)/ 20 = 0.23$$
- 基于性別分裂的方差=子節(jié)點的加權(quán)方差=$$(10/30)* 0.16 +(20/30)* 0.23 = 0.21$$
- 年級IX節(jié)點的平均值為$$(6 * 1 + 8 * 0)/14=0.43$$,方差為$$(6 *(1-0.43)^ 2 + 8 *(0-0.43)^ 2)/ 14 = 0.24$$
- 年級X節(jié)點的均值為$$(9 * 1 + 7 * 0)/16=0.56$$且方差為$$(9 *(1-0.56)^ 2 + 7 *(0-0.56)^ 2)/ 16 = 0.25$$
- 基于年級分裂的方差為$$(14/30)* 0.24 +(16/30)* 0.25 = 0.25$$
上面,您可以看到,與父節(jié)點相比,性別拆分具有更低的方差,因此拆分將在Gender變量上進行。
在此之前,我們了解了決策樹的基礎(chǔ)知識,以及決策過程涉及在構(gòu)建樹模型中選擇最佳分割。 正如我所說,決策樹可以應(yīng)用于回歸和分類問題。 讓我們來詳細了解這些方面。
4.樹模型的關(guān)鍵參數(shù)是什么?我們?nèi)绾伪苊膺^度擬合的決策樹?
過度擬合是決策樹建模時面臨的關(guān)鍵挑戰(zhàn)之一。 如果沒有決策樹的限制集,它將給你100%的訓(xùn)練集精度,因為在最壞的情況下,它將最終為每個觀察生成1個葉子節(jié)點。 因此,防止過擬合在對決策樹建模時是關(guān)鍵的,并且可以以兩種方式來完成:
- 設(shè)置樹大小的約束
- 樹修剪
讓我們簡要討論這兩個。
在樹的大小上設(shè)置約束
這可以通過使用用于定義樹的各種參數(shù)來完成。 首先,讓我們看看決策樹的一般結(jié)構(gòu):

下面進一步解釋用于定義樹的參數(shù)。 以下描述的參數(shù)與工具無關(guān)。 重要的是要了解樹模型中使用的參數(shù)的作用。 這些參數(shù)在R&Python中可用。
1. 節(jié)點分割的最小樣本(Minimum samples for a node split)
- 定義在要考慮分裂的節(jié)點中需要的樣本(或觀測)的最小數(shù)量。
- 用于控制過度擬合。較高的值會阻止模型學(xué)習(xí)可能對于為樹選擇的特定樣本高度特別明確的關(guān)系。
- 太高的值可能導(dǎo)致欠擬合,因此應(yīng)使用CV(變異系數(shù))進行調(diào)整。
2. 終端節(jié)點(葉)的最小樣本(Minimum samples for a terminal node (leaf))
- 定義終端節(jié)點或葉子所需的最小樣本(或觀測值)。
- 用于控制過擬合,類似于min_samples_split。
- 通常,對于不平衡類問題應(yīng)選擇較低的值,因為其中少數(shù)類將在大多數(shù)地區(qū)將是非常小的。
3. 樹的最大深度(垂直深度)(Maximum depth of tree (vertical depth))
- 樹的最大深度。
- 用于控制過擬合,因為較高的深度將允許模型學(xué)習(xí)對于特定樣品的特定關(guān)系。
- 應(yīng)使用CV調(diào)整。
4. 終端節(jié)點的最大數(shù)量(Maximum number of terminal nodes)
- 樹中的終端節(jié)點或葉子節(jié)點的最大數(shù)量。
- 可以定義為代替max_depth。由于創(chuàng)建了二叉樹,因此深度“n”將產(chǎn)生最多$$2 ^ n$$個葉。
5. 要考慮拆分的最大特征數(shù)(Maximum features to consider for split)
- 在搜索最佳分割時要考慮的要素數(shù)。這些將隨機選擇。
- 作為拇指規(guī)則,特征總數(shù)的平方根很好,但我們應(yīng)該檢查到特征總數(shù)的30-40%。
- 較高的值可能導(dǎo)致過擬合,但取決于具體情況。
樹的修剪
如前所述,設(shè)置約束的技術(shù)是貪婪方法。 換句話說,它將立即檢查最佳分離并向前移動,直到達到指定的停止條件之一。 讓我們考慮以下情況當(dāng)你開車:

這里2個車道:
- 汽車以80公里/小時的速度行駛
- 卡車以30公里/小時的速度行駛的車道
在這個時刻,你是黃色的車,你有兩個選擇:
- 左轉(zhuǎn),快速超過其他2輛車
- 繼續(xù)在當(dāng)前車道移動
讓我們分析這些選擇。 在前一種選擇中,您將立即超車,然后到達卡車后面,以30公里/小時的速度開始移動,尋找機會向右移動。 原來在你身后的所有車輛同時向前移動。 這將是最佳的選擇,如果你的目標(biāo)是在下一個10秒覆蓋最大的距離。 在后面一個 選擇中,你以相同的速度前行,趕上卡車,然后超過,可能取決于前面的情況。 你好貪心!
這正是正常決策樹和修剪之間的區(qū)別。具有約束的決策樹將不會看到前面的卡車,并采取貪婪的方法左轉(zhuǎn)。 另一方面,如果我們使用修剪,我們實際上會看前面幾步,并做出選擇。
所以我們知道修剪是更好的。 但是如何在決策樹中實現(xiàn)它呢? 這個想法很簡單。
- 我們首先將決策樹做得很深。
- 然后我們從底部開始,并開始刪除那些和頂部相比給我們負回報的葉子。
- 假設(shè)一次分裂給我們一個增益-10(損失10),然后下一個分裂給我們一個增益20.一個簡單的決策樹將停止在步驟1,但在修剪,我們將看到整體 增益是+10并保留兩個葉。
注意sklearn的決策樹分類器目前不支持修剪。 高級包像xgboost在它們的功能中已經(jīng)采用了樹修剪。 但是R中rpart包,提供了一個修剪的函數(shù)。 對于R用戶自然是極好的!
5. 基于樹的模型是否比線性模型好?
“如果我可以對分類問題使用邏輯回歸和對回歸問題使用線性回歸,為什么要使用樹”? 我們許多人都有這個問題。 而且,這也是一個有效的問題。
實際上,你可以使用任何算法。 它取決于你解決的問題的類型。 讓我們來看看一些關(guān)鍵因素,它們將幫助你決定使用哪種算法:
- 如果因變量和自變量之間的關(guān)系通過線性模型很好地近似,則線性回歸將優(yōu)于基于樹的模型。
- 如果因變量和自變量之間存在高的非線性和復(fù)雜關(guān)系,則樹模型將優(yōu)于經(jīng)典的回歸方法。
- 如果你需要構(gòu)建一個易于向人們解釋的模型,那么決策樹模型將總是比線性模型更好。 決策樹模型甚至比線性回歸更容易解釋!
6. 在R和Python中實現(xiàn)決策樹算法
對于R用戶和Python用戶,決策樹很容易實現(xiàn)。 讓我們快速看看可以讓你開始使用這個算法的代碼集。 為了便于使用,我共享了標(biāo)準代碼,您需要替換您的數(shù)據(jù)集名稱和變量以開始使用。
對于R用戶,有多個包可用于實現(xiàn)決策樹,如ctree,rpart,tree等。
> library(rpart)
> x <- cbind(x_train,y_train)
# grow tree
> fit <- rpart(y_train ~ ., data = x,method="class")
> summary(fit)
#Predict Output
> predicted= predict(fit,x_test)
在上面的代碼中:
- y_train - 表示因變量。
- x_train - 表示自變量
- x - 表示訓(xùn)練數(shù)據(jù)。
對于Python用戶,下面是代碼:
#Import Library
#Import other necessary libraries like pandas, numpy...
from sklearn import tree
#Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset
# Create tree object
model = tree.DecisionTreeClassifier(criterion='gini') # for classification, here you can change the algorithm as gini or entropy (information gain) by default it is gini
# model = tree.DecisionTreeRegressor() for regression
# Train the model using the training sets and check score
model.fit(X, y)
model.score(X, y)
#Predict Output
predicted= model.predict(x_test)
7. 什么是基于樹建模的集成方法(Ensemble methods)?
詞語“ensemble”的文學(xué)意義是群體。 集成方法涉及預(yù)測模型組,以實現(xiàn)更好的準確性和模型穩(wěn)定性。 已知集成方法對基于樹的模型賦予了極大的提升。
像所有其他模型一樣,基于樹的模型也遭受偏差和方差的影響。 偏差意味著“預(yù)測值與實際值存在多大程度的差異”。方差意味著,如果不同的樣本是從同一個總體中獲取的,模型的預(yù)測值與總體存在多大差異。
你建立一個小樹,你會得到一個低方差和高偏差的模型。 你如何設(shè)法找到偏差和方差之間的折衷方案?
通常,當(dāng)您增加模型的復(fù)雜性時,由于模型中的偏差較小,您將看到預(yù)測誤差的減少。 隨著你繼續(xù)讓你的模型更復(fù)雜,你最終會過度擬合你的模型,你的模型將開始遭受高方差。
一個冠軍模型應(yīng)該保持這兩種類型的錯誤之間的平衡。 這被稱為偏差方差誤差的權(quán)衡管理。 集成學(xué)習(xí)是執(zhí)行這種權(quán)衡分析的一種方式。

一些常用的集成方法包括:裝袋,拉動和堆積(Bagging, Boosting and Stacking)。 在本教程中,我們將詳細介紹Bagging和Boosting。
8. 什么是Bagging? 它是如何工作的?
Bagging是一種用于通過組合對相同數(shù)據(jù)集的不同子樣本建模的多個分類器的結(jié)果來減少我們的預(yù)測的方差的技術(shù)。 下圖將使其更清楚:

裝袋中的步驟是:
- 創(chuàng)建多個DataSet:
- 通過對原始數(shù)據(jù)進行替換來完成采樣,并形成新的數(shù)據(jù)集。
- 新數(shù)據(jù)集可以具有列的一部分列以及行,其在裝袋模型中通常是超參數(shù)
- 取的行和列的級分小于1有助于使可靠的模型,不易發(fā)生過度擬合
- 構(gòu)建多個分類器:
- 分類器建立在每個數(shù)據(jù)集上。
- 通常,對每個數(shù)據(jù)集建模相同的分類器,并進行預(yù)測。
- 組合分類器:
- 所有的分類器的預(yù)測是根據(jù)手頭問題使用的均值,中位數(shù)或眾數(shù)值相結(jié)合。
- 組合值通常比單個模型更魯棒。
注意,這里建立的模型數(shù)量不是超參數(shù)。 較高數(shù)量的模型總是更好,或者可以給出與較低數(shù)字類似的性能。 在理論上可以表明,在某些假設(shè)下,組合預(yù)測的方差減小到原始方差的1 / n(n:分類器的數(shù)量)。
裝袋模型有各種實現(xiàn)。 隨機森林是其中之一,我們將在下面討論它。
9. 什么是隨機森林? 它是如何工作的?
隨機森林被認為是所有數(shù)據(jù)科學(xué)問題的靈丹妙藥。 在一個有趣的信條,當(dāng)你想不出任何算法(不論任何情況),使用隨機森林!
隨機森林是一種多功能機器學(xué)習(xí)方法,能夠執(zhí)行回歸和分類任務(wù)。 它還采用降維方法,處理缺失值,異常值和數(shù)據(jù)探索的其他必要步驟,并且做得相當(dāng)不錯。 它是一種集成學(xué)習(xí)方法,一組弱模型組合形成一個強大的模型。
它是如何工作的
在隨機森林中,我們在CART模型中生成多棵樹,而不是單棵樹(參見CART和Random Forest之間的比較,第1部分和第2部分)。 為了基于屬性對新對象進行分類,每個樹給出一個分類,并且我們說給該樹的“投票”。 森林選擇具有最多票數(shù)(在森林中的所有樹上)的分類,并且在回歸的情況下,它取不同樹的輸出的平均值。
它以以下方式工作。 每棵樹種植和種植如下:
- 假設(shè)在訓(xùn)練集中樣本的數(shù)量為N.然后,這N個樣本中下,隨機取樣(可放回)。 該樣本將是用于生長樹的訓(xùn)練集。
- 如果存在M個輸入變量,則指定數(shù)目m <M,使得在每個節(jié)點處,從M中隨機選擇m個變量。m個變量中最佳的分裂將用于分裂節(jié)點。當(dāng)森林成長時,m的值保持不變。
- 如果存在M個輸入變量,則指定數(shù)目m <M,使得在每個節(jié)點處,從M中隨機選擇m個變量。m個變量中最佳的分裂將用于分裂節(jié)點。當(dāng)森林成長時,m的值保持不變。
- 每棵樹都生長到盡可能最大的程度,沒有修剪。
- 通過聚合n棵樹的預(yù)測值(即,用于分類的多數(shù)票,平均值用于回歸)來預(yù)測新數(shù)據(jù)。

要了解更多關(guān)于此算法使用案例研究,請閱讀這篇文章隨機森林簡介 - 簡化。
隨機森林的優(yōu)點
- 這種算法可以解決兩種類型的問題,即分類和回歸,并在兩個方面做出合理的估計。
- 隨機森林一個這讓我興奮的好處就是,具有較高的維度設(shè)置處理大量數(shù)據(jù)的能力。它可以處理數(shù)千個輸入變量并識別最重要的變量,因此它被認為是降維方法之一。 此外,模型輸出變量的重要性,其可以是非常方便的特征(在一些隨機數(shù)據(jù)集上)。
- 它具有估計丟失數(shù)據(jù)的有效方法,并且當(dāng)大部分數(shù)據(jù)丟失時保持精度。
- 它具有用于平衡類不平衡的數(shù)據(jù)集中的錯誤的方法。
- 上述的能力可以擴展到未標(biāo)記的數(shù)據(jù),導(dǎo)致無監(jiān)督的聚類,數(shù)據(jù)視圖和異常值檢測。
- 隨機森林涉及對輸入數(shù)據(jù)的采樣,稱為自舉采樣。 這里三分之一的數(shù)據(jù)不用于訓(xùn)練,可用于測試。 這些稱為袋外取樣。 對這些出袋樣本估計的誤差被稱為出袋誤差。 通過Out of bag進行誤差估計的研究,證明了out-of-bag估計與使用與訓(xùn)練集相同大小的測試集是準確的。 因此,使用袋外誤差估計消除了對預(yù)留測試集的需要。

隨機森林的缺點
- 它確實在分類方面做得很好,但不如回歸問題好,因為它不提供精確的連續(xù)自然預(yù)測。 在回歸的情況下,它不預(yù)測超出在訓(xùn)練數(shù)據(jù)的范圍內(nèi)的數(shù)據(jù),并且它們會對噪聲特別大的數(shù)據(jù)集產(chǎn)生過擬合。
- 隨機森林可以覺得自己像一個黑盒子的方法進行統(tǒng)計建模 - 您對模型做什么很難控制。 你最好能 - 嘗試不同的參數(shù)和隨機種子!
Python&R實現(xiàn)
隨機森林通常在R包和Python scikit-learn中的實現(xiàn)。 讓我們看看下面的R和Python中加載隨機森林模型的代碼:
Python
#Import Library
from sklearn.ensemble import RandomForestClassifier #use RandomForestRegressor for regression problem
#Assumed you have, X (predictor) and Y (target) for training data set and x_test(predictor) of test_dataset
# Create Random Forest object
model= RandomForestClassifier(n_estimators=1000)
# Train the model using the training sets and check score
model.fit(X, y)
#Predict Output
predicted= model.predict(x_test)
R Code
> library(randomForest)
> x <- cbind(x_train,y_train)
# Fitting model
> fit <- randomForest(Species ~ ., x,ntree=500)
> summary(fit)
#Predict Output
> predicted= predict(fit,x_test)
10.什么是Boosting? 它是如何工作的?
定義:術(shù)語“Boosting”是指將弱學(xué)習(xí)者轉(zhuǎn)化為強大學(xué)習(xí)者的算法家族。
讓我們通過解決垃圾郵件識別問題來詳細了解這個定義:
您如何將電子郵件分類為垃圾郵件? 和其他人一樣,我們的初始方法是使用以下標(biāo)準來識別“垃圾郵件”和“非垃圾郵件”電子郵件。 如果:
- 電子郵件只有一個圖片文件(促銷圖片),這是一個垃圾郵件
- 電子郵件只有鏈接,這是一個垃圾郵件
- 電子郵件正文包括“你贏得$ xxxxxx的獎金”這句話,這是一個垃圾郵件
- 電子郵件從我們的官方域“Analyticsvidhya.com”,而不是垃圾郵件
- 電子郵件來自已知來源,不是垃圾郵件
以上,我們定義了多個規(guī)則,將電子郵件分為“垃圾郵件”或“非垃圾郵件”。 但是,你認為這些規(guī)則是否足夠強大以成功分類電子郵件? 沒有。
個別地,這些規(guī)則不足以將電子郵件分類為“垃圾郵件”或“非垃圾郵件”。 因此,這些規(guī)則被稱為弱學(xué)習(xí)者。
為了將弱學(xué)習(xí)者轉(zhuǎn)換為強學(xué)習(xí)者,我們將使用以下方法來組合每個弱學(xué)習(xí)者的預(yù)測:
- 使用平均/加權(quán)平均
- 考慮有更高投票的預(yù)測
例如:上面,我們定義了5個弱學(xué)習(xí)者。 在這5個中,3個被表決為“垃圾郵件”,2個被表決為“不是垃圾郵件”。 在這種情況下,默認情況下,我們會將電子郵件視為垃圾郵件,因為我們對“垃圾郵件”投票較高(3)。
它是如何工作的?
現(xiàn)在我們知道,"Boosting"結(jié)合弱學(xué)習(xí)者和基礎(chǔ)學(xué)習(xí)者形成一個強大的規(guī)則。 在你心目中應(yīng)該浮現(xiàn)的一個直接的問題是,“Boosting是如何識別弱規(guī)則的?"
為了找到弱規(guī)則,我們應(yīng)用具有不同分布的基礎(chǔ)學(xué)習(xí)(ML)算法。每應(yīng)用一次基礎(chǔ)學(xué)習(xí)算法,它就會生成新的弱預(yù)測規(guī)則。 這是一個迭代過程。 在許多迭代之后,增強算法將這些弱規(guī)則組合成單個強預(yù)測規(guī)則。
另一個可能困擾你的問題是,"我們?nèi)绾螢槊枯嗊x擇不同的分布?"
為了選擇正確的分布,請執(zhí)行以下步驟:
- 步驟1:基礎(chǔ)學(xué)習(xí)者獲取所有分布,并給每個觀察分配相等的權(quán)重或關(guān)注。
- 步驟2:如果存在由第一個基礎(chǔ)學(xué)習(xí)算法引起的任何預(yù)測誤差,則我們更加注意具有預(yù)測誤差的觀測。 然后,我們應(yīng)用下一個基本學(xué)習(xí)算法。
- 步驟3:迭代步驟2,直到達到基礎(chǔ)學(xué)習(xí)算法的極限或達到更高的精度。
最后,它結(jié)合了弱學(xué)習(xí)者的輸出,并創(chuàng)建了一個強大的學(xué)習(xí)者,最終提高了模型的預(yù)測能力。 Boosting通過前面的弱規(guī)則更加關(guān)注錯誤分類或具有更高錯誤的示例。
有許多增強算法給予模型的精度額外的提升。 在本教程中,我們將了解兩種最常用的算法,即Gradient Boosting(GBM)和XGboost。
11. 哪個更強大:GBM或Xgboost?
我一直很欣賞的xgboost算法增強能力。有時,我發(fā)現(xiàn)它比起GBM實現(xiàn)了較好的效果,但有時,你可能會發(fā)現(xiàn),收益只是微不足道的。 當(dāng)我探索更多關(guān)于它的性能和科學(xué)背后的高精確度后,我發(fā)現(xiàn)了Xgboost相比GBM的更多優(yōu)點:
- 正則化:
- 標(biāo)準的GBM算法沒有像XGBoost那樣實現(xiàn)正則化,因此其也有助于減少過度擬合。
- 事實上,XGBoost也被稱為“正則化提升”技術(shù)。
- 并行處理:
- XGBoost能夠?qū)崿F(xiàn)并行處理,并且比GBM快得多。
- 但需要強調(diào)的是,我們知道,Boosting是一個連續(xù)的過程,那么怎么才能實現(xiàn)并行呢? 我們知道每個樹只能在前一個樹之后才能構(gòu)建,所以是什么阻止了我們使用所有的核心生成樹?我希望你能得到我來自的地方。 檢查此鏈接,進一步探索。
- XGBoost還支持在Hadoop上實現(xiàn)。
- 高靈活性
- XGBoost允許用戶定義自定義優(yōu)化目標(biāo)和評估標(biāo)準。
- 這為模型增加了一個全新的維度,我們可以做的沒有限制。
- 處理缺少的值
- XGBoost有一個內(nèi)置的程序來處理缺失值。
- 用戶需要提供與其他觀測值不同的值,并將其作為參數(shù)傳遞。 XGBoost嘗試不同的東西,因為它遇到每個節(jié)點上的缺失值,并了解將來丟失值采用哪個路徑。
- 修剪樹:
- 當(dāng)分裂中遇到負損失時,GBM將停止分裂節(jié)點。 因此,它更多是貪婪算法。
- 另一方面,XGBoost將秩序分裂直到達到max_depth,然后開始向后修剪樹,并刪除沒有正增益的分裂。
- 另一個優(yōu)點是有時負損失為-2的分裂可能跟隨著正損失為+10的分裂。 GBM將在遇到-2時停止。 但XGBoost會更深入,因為它會看到兩者的組合效果產(chǎn)生的+8的分裂。
- 內(nèi)置交叉驗證
- XGBoost允許用戶在Boosting過程的每次迭代時運行交叉驗證,因此很容易在單次運行中獲得精確的最佳Boosting迭代次數(shù)。
- 這不像GBM,我們必須運行網(wǎng)格搜索,只有有限的值可以測試。
- 在現(xiàn)有模型上繼續(xù)運行
- 用戶可以從上次運行的最后一次迭代開始訓(xùn)練XGBoost模型。 這在某些特定應(yīng)用中會是特別顯著的優(yōu)點。
- sklearn中的GBM實現(xiàn)了這個功能,所以在這一點上他們是相同的。
12. 在R和Python中使用GBM
在我們開始工作之前,讓我們快速了解這個算法的重要參數(shù)和工作原理。 這將有助于R和Python用戶。 下面是GBM算法的2個類的總體偽代碼:
1. Initialize the outcome
2. Iterate from 1 to total number of trees
2.1 Update the weights for targets based on previous run (higher for the ones mis-classified)
2.2 Fit the model on selected subsample of data
2.3 Make predictions on the full set of observations
2.4 Update the output with current results taking into account the learning rate
3. Return the final output.
這是一個非常簡化(可能天真)的GBM的工作原理的解釋。 但是,它將幫助每個初學(xué)者了解這種算法。
讓我們考慮用來改進Python中模型性能的重要GBM參數(shù):
- learning_rate
- 這決定了每棵樹對最終結(jié)果的影響(步驟2.4)。 GBM從使用每個樹的輸出更新的初始估計開始工作。 學(xué)習(xí)參數(shù)控制估計中的這種變化的大小。
- 較低的值通常是優(yōu)選的,因為它們使模型穩(wěn)健樹的具體特征,從而允許它概括很好。
- 較低的值將需要較大數(shù)量的樹來建模所有關(guān)系,并且計算上將是昂貴的。
- n_estimators
- 要建模的順序樹的數(shù)量(步驟2)
- 雖然GBM在較高數(shù)量的樹木是相當(dāng)健壯,但它仍然可以在一個點過度擬合。 因此,這應(yīng)該使用CV對特定的學(xué)習(xí)率進行調(diào)整。
- subsample
- 要為每個樹選擇的觀測值的分數(shù)。 通過隨機抽樣進行選擇。
- 小于1的值通過減少方差使模型魯棒。
- 典型值?0.8通常工作正常,但可以進一步微調(diào)。
除此之外,還有一些影響整體功能的雜項參數(shù):
- loss
- 它指的是在每個分裂中最小化的損失函數(shù)。
- 它可以具有用于分類和回歸情況的各種值。一般默認值工作正常。只有在您了解其對模型的影響時,才應(yīng)選擇其他值。
- init
- 這會影響輸出的初始化。
- 如果我們制定了另一個模型,其結(jié)果將被用作GBM的初始估計,則可以使用該模型。
- random_state
- 隨機數(shù)種子,使得每次都生成相同的隨機數(shù)。
- 這對于參數(shù)調(diào)整很重要。如果我們不固定隨機數(shù),則對于相同參數(shù)的后續(xù)運行時,我們將會看到不同的結(jié)果,使得模型變得難以比較。
- 它可能潛在地使一個所選擇的特定隨機樣本產(chǎn)生過擬合。我們可以嘗試運行不同隨機樣本的模型,這是計算昂貴的,通常不使用。
- verbose
- 當(dāng)模型擬合時要打印的輸出類型。不同的值可以是:
- 0:無輸出生成(默認)
- 1:以一定間隔為樹生成的輸出
- > 1:為所有樹生成輸出
- warm_start
- 這個參數(shù)有一個有趣的應(yīng)用程序,可以幫助很多,如果使用得當(dāng)。
- 使用這個,我們可以在模型的先前擬合中擬合額外的樹。它可以節(jié)省大量的時間,你應(yīng)該為高級應(yīng)用程序探索這個選項
- presort
- 選擇是否預(yù)分類數(shù)據(jù)以實現(xiàn)更快的分割。
- 默認情況下會自動進行選擇,但如果需要可以更改。
我知道它的一個長列表的參數(shù),但我已經(jīng)簡化了它在一個excel文件,你可以從這個GitHub存儲庫下載。
對于R用戶,使用caret包,有3個主要調(diào)整參數(shù):
- n.trees
- 它指的是迭代次數(shù),即將用來生長樹的樹
- interaction.depth
- 它確定樹的復(fù)雜性,即它必須在樹上執(zhí)行的分割的總數(shù)(從單個節(jié)點開始)
- shrinkage
- 指學(xué)習(xí)率。這類似于python中的learning_rate(如上所示)。
- n.minobsinnode
- 它指的是節(jié)點執(zhí)行拆分所需的訓(xùn)練樣本的最小數(shù)量
R中的GBM(帶交叉驗證)
我已經(jīng)共享了R和Python中的標(biāo)準代碼。 最后,您需要更改下面代碼中使用的因變量和數(shù)據(jù)集名稱的值。 考慮到在R中實現(xiàn)GBM的容易性,可以容易地執(zhí)行諸如交叉驗證和網(wǎng)格搜索這樣的任務(wù)。
> library(caret)
> fitControl <- trainControl(method = "cv",
number = 10, #5folds)
> tune_Grid <- expand.grid(interaction.depth = 2,
n.trees = 500,
shrinkage = 0.1,
n.minobsinnode = 10)
> set.seed(825)
> fit <- train(y_train ~ ., data = train,
method = "gbm",
trControl = fitControl,
verbose = FALSE,
tuneGrid = gbmGrid)
> predicted= predict(fit,test,type= "prob")[,2]
GBM in Python
#import libraries
from sklearn.ensemble import GradientBoostingClassifier #For Classification
from sklearn.ensemble import GradientBoostingRegressor #For Regression
#use GBM function
clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0, max_depth=1)
clf.fit(X_train, y_train)
13. 在R和Python中使用XGBoost
XGBoost(eXtreme Gradient Boosting)是梯度提升算法的高級實現(xiàn)。 它的功能是實現(xiàn)并行計算,使其至少比現(xiàn)有的梯度提升實現(xiàn)快10倍。 它支持多種目標(biāo)函數(shù),包括回歸,分類和排名。
R教程:對于R用戶,這是一個完整的教程XGboost,解釋參數(shù)和代碼在R.檢查教程。
Python教程:對于Python用戶,這是一個關(guān)于XGBoost的綜合教程,很好地幫助您入門。 檢查教程。
14.在哪里練習(xí)?
實踐是掌握任何概念的一個真正的方法。 因此,如果你想掌握這些算法,你需要開始練習(xí)。
到這里,你已經(jīng)獲得了有關(guān)樹基模型的重要知識以及這些實際實現(xiàn)。 現(xiàn)在是時候開始工作。 這里是開放的練習(xí)問題,你可以參加和檢查您的排行榜上的實時排名:
回歸:大市場銷售預(yù)測
分類:貸款預(yù)測
結(jié)束注釋
基于樹的算法對于每個數(shù)據(jù)科學(xué)家都很重要。 事實上,已知樹模型在整個機器學(xué)習(xí)算法族中提供最好的模型性能。 在本教程中,我們學(xué)會了直到GBM和XGBoost。 有了這個,我們來到本教程的結(jié)尾。
我們討論了從頭開始的基于樹的建模。 我們學(xué)習(xí)了決策樹的重要性,以及如何使用這種簡單化的概念來提升算法。 為了更好地理解,我建議你繼續(xù)實踐這些算法。 此外,請記住與提升算法相關(guān)的參數(shù)。 我希望這個教程將豐富你有關(guān)樹基建模的完整知識。
您覺得本教程很有用嗎? 如果你有經(jīng)驗,你使用樹的模型最好的技巧是什么? 請隨時在下面的評論部分分享您的技巧,建議和意見。