一、信息論基礎
樹具有天然的分支結構。對於分類問題而言,決策樹的思想是用節點代表樣本集合,通過某些判定條件來對節點內的樣本進行分配,將它們划分到該節點下的子節點,並且要求各個子節點中類別的純度之和應高於該節點中的類別純度,從而起到分類效果。
節點純度反映的是節點樣本標簽的不確定性。當一個節點的純度較低時,說明每種類別都傾向於比較均勻的頻率出現,從而我們比較難在這個節點上得到關於樣本標簽的具體信息,其不確定性較高。當一個節點的純度很高時,說明有些類別傾向於比較高的頻率出現,從而我們能夠更有信心把握這個節點樣本標簽的具體信息,即確定性較高。
信息熵:熵是衡量信息量大小的一個數值,信息熵描述的是一個隨機變量的不確定程度,不確定性越大熵值越大。即 對隨機事件的信息量求期望。
聯合熵:兩個隨機變量的X、Y的聯合分布,可以稱為聯合熵,H(X,Y)。
條件熵:H(X,Y) - H(Y) 表示(X,Y)發生所包含的熵減去Y單獨發生所包含的熵:在Y發生的前提下,X發生新帶來的熵。
信息增益:即節點分裂之后帶來了多少不確定性的降低或純度的提高。
參考:https://www.cnblogs.com/little-YTMM/p/5582271.html
二、分類樹的節點分裂
對每個節點進行分裂決策時,會抽出max_features個特征進行遍歷以比較信息增益的大小。特征的類別可以分為三種情況討論:類別特征、數值特征和含缺失值的特征。對類別特征而言,給定一個閾值,樹的每一個節點會選擇最大信息增益對應的特征進行分裂,直到所有節點的相對最大信息增益小於閾值,這種生成算法為ID3算法。在sklearn中,min_impurity_decrease即為閾值。
C4.5算法在ID3算法的基礎上作出了改進,包括但不限於:處理數值特征、處理含缺失值的特征、使用信息增益比代替信息增益以及給出樹的剪枝策略。
在處理節點數值特征時,可以用兩種方法來將數值特征通過分隔轉化為類別,它們分別是最佳分隔法和隨機分隔法,分別對應sklearn中的splitter參數的best和random.
C4.5算法處理缺失數據的思想非常簡單,樣本的缺失值占比越大,那么對信息增益的懲罰就越大,因為缺失值本身就是一種不確定性成分。
前面所說的都是單個節點如何選取特征進行分裂,但沒有涉及到樹節點的分裂順序。在sklearn中提供了兩種生長模式,它們分別被稱為深度優先生長和最佳增益生長,當參數max_leaf_nodes使用默認none時使用前者,當它被賦予某個數值時使用后者。
深度優先生長采用深度優先搜索的方法:若當前節點存在未搜索過的子節點,則當前節點跳轉到子節點進行分裂決策;若當前節點為葉節點,則跳轉到上一層節點,直到根節點不存在未搜索過的子節點為止。當決策樹使用最佳增益生長時,每次總是選擇會帶來最大相對信息增益的節點進行分裂,直到葉節點的最大數量達到max_left_nodes.
三、CART決策樹
cart(classification and regression tree)是一棵二叉樹,既能處理分類問題,又能處理回歸問題。但是在sklearn中沒有實現處理類別特征和處理缺失值的問題,前者是因為多個類別的特征會產生多叉樹,后者因為sklearn認為用戶應該自己決定缺失值的處理而不是交給模型來決定。
對於回歸樹而言,每個葉節點輸出的不再是類別而是數值,其輸出值為該葉節點所有樣本標簽的均值。在每次分裂時,我們希望不同的子節點之間的差異較大,但每個子節點內部的差異較小。此時,分割策略仍然可以采用隨機分割法或者最佳分隔法,只是現在不再以熵來評價子節點的純度,而是使用均方誤差或平均絕對誤差來替換熵和條件熵的位置,從而引出基尼系數的信息增益。
常見問題整理:
(1)假設需要處理一個分類問題,請問對輸入特征進行歸一化會對樹模型的類別輸出產生影響嗎?請解釋原因
不會產生影響,理由如下:
使用歸一化的目的是因為各個特征之間數值大小不同使得它們對某些模型(通過梯度下降法求解的模型通常是需要歸一化的),比如神經網絡的輸出和損失計算的影響不同,這樣反向傳播時會偏向於數值比較大的特征,這樣是不合理的。 因為在沒有任何先驗知識的情況下,各個特征應該一視同仁。但是,樹模型是直接利用數據的信息熵來建立的,不需要計算損失函數並反向傳播,因此各個特征之間數值的大小不同不會影響 它的建模過程。換句話說,神經網絡里數據的數值會直接和權重相乘,進行計算,樹模型不會直接使用數值本身,而是使用它出現的概率。
(2)C4.5算法中,如果將信息增益的系數替換為(1-r^2),請問對缺失值時增強了還是削弱了懲罰?
將系數替換為1-r^2后削弱了對缺失值的懲罰,因為缺失值的比例r<=1, 平方之后缺失比例變小了,樣本的不確定性變小了。
(3)決策樹的生長策略假如由深度優先生長改成廣度優先生長,其他參數保持不變的情況下,兩個模型對應的結果輸出一樣嗎?
不一樣,
(4)在一般的機器學習問題中,總是會通過一組參數來定義模型的損失函數,並且在訓練集上以最小化該損失函數為目標進行優化,那么對於決策樹而言,模型優化的目標是什么?
優化的目標是提升度,類似於提升節點的純度,提升度越高越好。
(5)決策樹三種算法的有何異同?

(6)什么是信息增益,衡量了什么指標,有什么缺陷?
信息增益:即節點分裂之后帶來了多少不確定性的降低或純度的提高。
一般來說,通過一種划分方式帶來的純度提升越大,信息增益就越高。ID3算法以信息增益為准則來選擇決策樹划分屬性。值多的屬性更有可能會帶來更高的純度提升,所以信息增益的比較偏向選擇取值多的屬性。
可能會帶來一個不好的結果,如果選擇唯一ID作為划分屬性,那么會得到n個類別,每個類別都只包含一個樣本,每個節點的純度都是最高的,純度提升也是最大的,帶來的信息增益也是最高的。但是這樣的划分是沒有意義的。
(7)sklearn 決策樹中的random_state參數控制了哪些步驟的隨機性?
random_state參數主要是為了保證每次都分割一樣的訓練集和測試集,大小可以是任意一個整數,在調參緩解,只要保證其值一致即可。
因為同一算法模型在不同的訓練集和測試集的會得到不同的准確率,無法調參。所以在sklearn 中可以通過添加random_state,通過固定random_state的值,每次可以分割得到同樣訓練集和測試集。
(8)決策樹如何處理連續變量和缺失變量?
處理連續型屬性(例如西瓜的成熟度、學生成績)時,需要將其離散化,將連續型屬性的值划分到不同的區間(類似於二叉排序樹),比較各個分裂點的Gain值的大小。
在C4.5決策樹算法中,采用二分法處理連續型屬性。
當屬性值有缺失時主要解決兩個問題:
在有屬性值有缺失的情況下,如何選擇最優屬性?這時候需要重新定義信息增益計算方式來選擇最優屬性;
給定划分屬性后,訓練集中屬性值含有缺失值,如何划分樣本?
若樣本屬性已知,則將樣本划分到與其取值相同的子節點中,權值w不變
若樣本屬性缺失,則將該樣本同時划分到所有子節點,樣本權值也要相應的調整;
(9)基尼系數是什么?為什么要在cart中引入它?
基尼值 Gini(D) 反映了從數據集中隨機抽取兩個樣本,其類別標記不一致的概率。當數據集的純度越高,每次抽到不同類別標記的概率越小。打個比方,在一個袋子里裝100個乒乓球,其中有99個白球,1個黃球,那么當我們隨機抽取兩個球的時候,很大概率是抽到兩個白球。所以數據集D的純度可以用基尼值來度量,基尼指數是針對於屬性定義的,其反映的是,使用屬性a進行划分后,所有分支中(使用基尼值度量的)純度的加權和。
在ID3算法中我們使用了信息增益來選擇特征,信息增益大的優先選擇。在C4.5算法中,采用了信息增益比來選擇特征,以減少信息增益容易選擇特征值多的特征的問題。但是無論是ID3還是C4.5,都是基於信息論的熵模型的,這里面會涉及大量的對數運算。所以為了簡化模型的同時也不至於完全丟失熵模型,CART分類樹算法使用基尼系數來代替信息增益比,基尼系數代表了模型的不純度,基尼系數越小,則不純度越低,特征越好。這和信息增益(比)是相反的。
(10)什么是樹的預剪枝和后剪枝,具體是如何操作的?
樹的剪枝就是剪掉樹的一些枝葉,考慮大決策樹的枝代表着邏輯判斷,也代表着分類后的子集。決策樹的剪枝就是刪掉一些不必要的邏輯判斷,並且將子集合並。這樣確實會造成在訓練集上子集不純的現象,但是因為我們最終目標是模型在測試集上的效果,所以犧牲在訓練集上的效果換取解決測試集的過擬合問題這樣的做法也是值得的。決策樹剪枝可以分為兩類,預剪枝(Pre-Pruning)和后剪枝(Post-Pruning)。
PrePrune:預剪枝,及早的停止樹增長;PostPrune:后剪枝,在已生成過擬合決策樹上進行剪枝,可以得到簡化版的剪枝決策樹。
預剪枝:就是在生成決策樹的同時進行剪枝。正常決策樹的生成是只要有信息增益就要進行分支,換句話可以說所有決策樹的構建方法,都是在無法進一步降低熵的情況下才會停止創建分支的過程,為了避免過擬合,可以設定一個閾值,熵減小的數量小於這個閾值,即使還可以繼續降低熵,也停止繼續創建分支。預剪枝就是設定一個閾值,比如只有在信息增益大於這個閾值的時候(也即是在分類后的信息混亂程度減小程度大於一定標准的時候)才進行分類。如果在信息增益過小的情況下,即使存在信息增益的現象,也不會對其進行分支。預剪枝的思想比較簡單,但在實際應用中,預剪枝的表現並不是很好。所以,目前我們基本都是使用后剪枝方法。
預剪枝依據:
- 作為葉結點或作為根結點需要含的最少樣本個數
- 決策樹的層數
- 結點的經驗熵小於某個閾值才停止
后剪枝:就是在決策樹構造完成后進行剪枝。剪枝的過程是對擁有相同父節點的一組節點進行檢查,如果將其合並,熵增小於某一閾值,那么這一組節點可以合並一個節點。如果將其合並后熵增大於這個閾值,那么說明將其分枝是合理的。后剪枝就是刪除一些子樹,然后用其葉節點代替。這個葉節點代表的子集不一定都是“純”的。那么,這個葉子節點所標識的類別通過大多數原則確定。大多數原則就是指這個葉節點所代表的子集中大多數的類別來表示這個葉節點。剪枝的過程是對擁有同樣父節點的一組節點進行檢查,判斷如果將其合並,熵的增加量是否小於某一閾值。如果確實小,則這一組節點可以合並一個節點,其中包含了所有可能的結果。后剪枝是目前最普遍的做法。
常用的后剪枝算法有五種,REP、PEP、MEP、CCP算法和后規則修剪方法。如果訓練數據較少,PEP算法表現出良好的預測精度,隨着數據規模的增大,使用REP和CCP剪枝方法得到的決策樹的分類性能和預測精度明顯提高。
參考:https://www.cnblogs.com/bonheur/p/12469858.html
四、決策樹相關python相關方法總結
1、sklearn.tree.DecisionTreeClassifier 決策樹分類器
class sklearn.tree.DecisionTreeClassifier(*, criterion='gini', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, class_weight=None, ccp_alpha=0.0)
(1)參數解析
criterion{“gini”, “entropy”}, default=”gini”
這個函數是來衡量分裂的質量,支持基尼系數(基尼純度)和熵(信息增益);
splitter{“best”, “random”}, default=”best”
這個方法主要是用來選擇節點分裂,分別對應最佳分隔法和隨機分隔法;
max_depth: int, default=None
表示樹的最大深度,默認none時,節點將會擴展到所有的葉子都是純的或所有的葉子包含少於min_samples_split個樣本.
min_samples_split :int or float, default=2
分裂一個內部節點所需的最小樣本數。
min_samples_leaf:int or float, default=1
葉節點所需的最小樣本數。 任何深度的分裂點只有在左右分支中至少留下 min_samples_leaf 訓練樣本時才會被考慮。 這可能具有平滑模型的效果,尤其是在回歸中;
https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
