看到一篇關於決策樹比較好的文章,轉錄過來,內容如下:
決策樹
決策樹里面最重要的就是節點和分裂條件,直接決定了一棵樹的好壞。用一個簡單的例子先說明一下:
來一段情景對話:
母親:女兒,你也不小了,還沒對象!媽很揪心啊,這不托人給你找了個對象,明兒去見個面吧!
女兒:年紀多大了?
母親:25
女兒:長的帥不帥?
母親:挺帥的!
女兒:收入高不高?有沒有上進心?
母親:收入還行,蠻有上進心!
就這樣女兒建立了一棵決策樹:

這種簡單的決策樹,處處可見。女兒一步步選擇重要特征(年齡、長相、收入等)並構建特征分割方式(年紀大小、長相帥不帥、收入高不高),讓自己進行最優的決策。
- 決策樹的構建過程
很顯然,由上面的例子可以看到構建一個決策樹需要如下步驟:
1、收集樣本
沒有要決策的對象,一切都是扯淡。就是例子中母親托人找對象的過程。
2、選擇特征-----構建節點
根據特征的重要度,來構建子節點,越重要的特征越靠近根節點。也就是女兒覺得那些條件最重要,當最重要的條件不滿足,就沒必要繼續了。
3、特征的分裂方式-----分裂節點
根據特征的分裂方式,來划分數據集,也就是根據條件區別對待。就是年紀太大的壓根就不予考慮,年齡合適的才進一步考察。
其實在實際構建樹模型的時候,2和3是通過遍歷的方式同時進行的。
上面的例子是主觀的分裂節點,那么如何科學的構建節點分裂呢?下面來說明:
我們覺得什么樣才算好,通俗來說就是通過越少的分裂,達到更好的區分度。用術語說就是當選擇了這個條件之后,系統的不確定度下降最多。這個特征就是我們要重視的feature!在這里就不得不引入信息論中的一些知識了,主要是信息熵和不純度,詳情請參考我在語雀中總結的一一篇文檔。
主要是通過以下幾種算法來實現最優分裂的效果:
ID3算法
系統的信息熵是,分別計算每個特征的條件熵
,然后得到每個條件的信息增益
。通過判斷每個特征的
的大小來決定特征的重要度。所以ID3算法是基於信息增益,信息增益大,則越適合用來分類。在具體的特征分裂的時候,每個條件的分裂是遍歷了所有的可能(離散值有多少個就有多少個可能),這是一種貪心算法。所以這個算法不支持連續特征,也是缺點之一。
C4.5算法
與ID3算法的思路基本相同,只是解決了ID3算法中的一些缺點,比如將連續值離散化從而支持連續型特征,采用信息增益比來代替ID3算法的信息增益,解決了信息增益偏向分支過多的特征。也補充了剪枝和補全缺失值的操作。
CART算法
簡單來說,CART算法是不斷的生成二叉樹,能分類也能回歸,因此也叫分類回歸樹。在生成分類樹時,采用的是基尼系數,也叫不純度。生成回歸樹則采用的是節點樣本的方差
來做分裂標准。這些過程,3種算法都差不多,有區別的是CART算法如何生成二叉樹?
CART對連續型屬性的處理與C4.5差不多,也是先離散化。而對於離散型屬性,理論上有多少個離散值就應該分裂成多少個節點。但CART是一棵二叉樹,每一次分裂只會產生兩個節點,怎么辦呢?很簡單,只要將其中一個離散值獨立作為一個節點,其他的離散值生成另外一個節點即可。這種分裂方案有多少個離散值就有多少種划分的方法,舉一個簡單的例子:如果某離散屬性一個有三個離散值x,y,z,則該屬性的分裂方法有【x、(y,z)】,【y、(z,x)】,【z,(x,y)】,分別計算每種划分方法的基尼值或者樣本方差確定最優的方法。原則就是通過一個條件將樣本空間一分為二。
決策樹的評價
分類樹:
假定某個樣本空間有類,對於生成好的一棵決策樹的某葉子結點,假定該葉結點含有樣本數目為
,可以分別統計該葉子節點下每個分類的頻數
。每個類別的概率
,於是這個葉子節點的信息熵就是
。信息熵越小,系統的區分度越明顯。所以最終對於一棵分類樹的評價可以用下面的公式來評判(
葉子節點的權重,可以更具樣本數目來決定):
對於不同的算法,並不完全都是用信息熵,也可以采用基尼系數來代替信息熵。
回歸樹:
假定某個樣本空間,對於生成好的一棵決策樹的某葉子結點,假定該葉結點含有樣本數目為,計算這個葉子節點的方差
。所以最終對於一棵回歸樹的評價可以用下面的公式來評判(
葉子節點的權重,可以更具樣本數目來決定):
決策樹的剪枝
決策樹對訓練屬於有很好的分類能力,但是對於未知的測試集未必有好的分類能力,泛化能力弱,即可能發生過擬合現象。為防止過擬合,我們需要進行剪枝。三種決策樹的剪枝過程算法相同,區別是對於當前樹的評價標准不同。
剪枝分為預剪枝和后剪枝:
預剪枝:
在樹還沒有完全分裂完成的時候,設定閾值,停止分裂,比如:
(1)每一個結點所包含的最小樣本數目,例如10,則該結點總樣本數小於10時,則不再分;
(2)指定樹的高度或者深度,例如樹的最大深度為6;
(3)指定結點的熵小於某個值,不再划分。
后剪枝:
在樹已經完全分裂之后,進行剪枝:
由完全樹開始,剪枝部分結點(葉子節點,或者子節點)得到
,再次剪枝部分結點得到
...,直到剩下樹根的樹(就是根節點)
;在驗證數據集上對這
個樹分別評價,選擇損失函數最小的樹
。
C4.5采用悲觀剪枝方法(PEP)
悲觀剪枝認為如果決策樹的精度在剪枝前后沒有影響的話,則進行剪枝。怎樣才算是沒有影響?如果剪枝后的誤差小於剪枝前經度的上限,則說明剪枝后的效果更佳,此時需要子樹進行剪枝操作。
CART采用代價復雜度剪枝方法(CCP)
代價復雜度選擇節點表面誤差率增益值最小的非葉子節點,刪除該非葉子節點的左右子節點,若有多個非葉子節點的表面誤差率增益值相同小,則選擇非葉子節點中子節點數最多的非葉子節點進行剪枝。
- 決策好的一棵樹,除去葉子節點后有
- 計算每個子節點剪枝后的表面誤差率增益
剪枝后的損失函數
剪枝前的損失函數
剪枝前T節點下面的葉子節點數
-
= Min(
),剪枝最小的子節點
。
隨機森林----一片決策樹森林
這個可以當作是決策樹解決過擬合的一種方式。隨機的采用樣本的某些特征構建多棵簡單的決策樹,然后預測結果是這么多棵決策樹預測結果的綜合。用於分類就多數表決,用於回歸就是取平均值。不想多說。
決策樹單獨作為一個算法的效果不是特別好,更多的是在集成算法種充當內核。比如xgboost、adboost之類的。
code
基於sklearn.tree
模塊
分類樹:
from sklearn import datasets from sklearn.tree import DecisionTreeClassifier # 使用自帶的iris數據 iris = datasets.load_iris() X = iris.data[:, [0, 2]] y = iris.target # 創建模型 ''' 常用參數說明: criterion="gini" ---- 'entropy'-->信息熵,'gini'-->基尼系數 splitter="best" ---- 'best'-->全局最優分裂,'random'-->隨機選擇局部最優點 max_depth=None ---- 設定樹深度 min_samples_split=2 ---- 內部節點停止分裂的最小樣本數 min_samples_leaf=1 ---- 葉子節點的最小樣本數,如果實際值小於它,則會和兄弟節點一起被剪枝 max_features=None, ---- 分裂的時候要考慮的樣本特征比例 max_leaf_nodes=None,---- 最大葉子節點數 ''' clf = DecisionTreeClassifier(max_depth=4) # 訓練模型 clf.fit(X, y)
回歸樹:
from sklearn.datasets.california_housing import fetch_california_housing from sklearn.tree import DecisionTreeRegressor # 使用波士頓房價數據 housing = fetch_california_housing() X = housing.data[:, [6, 7]] y = housing.target ''' criterion="mse" ---- 和分類樹一樣,評價指標,'mse'是均方誤差,'mae'是絕對值誤差 ''' # 創建模型 dtr = tree.DecisionTreeRegressor(max_depth = 2) # 訓練模型 dtr.fit(x, y)
隨機森林:
from sklearn.ensemble import RandomForestClassifier from sklearn import datasets # 使用自帶的iris數據 iris = datasets.load_iris() X = iris.data y = iris.target ''' 樹的基本參數設定和分類樹差不多 n_estimators=10, ---- 建立多少棵樹 bootstrap=True, ---- 是統計學中的一種重采樣技術,可以簡單理解成是有放回地抽樣 oob_score=False, ---- 是否使用帶外樣本進行模型驗證 n_jobs=1, ---- 並行job個數,1:CPU有多少core,就啟動多少job warm_start=False, ---- 熱啟動,決定是否使用上次調用該類的結果然后增加新的。 ''' rftcl = RandomForestClassifier() rftcl.fit(x,y)
原文鏈接:
作者:Zimix
鏈接:https://www.jianshu.com/p/d7820021efe2