理解CART決策樹


CART算法

原理

CART全稱為Classification and Regression Tree。

回歸樹

相比ID3,CART遍歷所有的特征和特征值,然后使用二元切分法划分數據子集,也就是每個節點都只會分裂2個分支。接着計算數據子集的總方差來度量數據子集的混亂程度,總方差越小數據子集越純,最后選擇總方差最小的划分方式對應的特征和特征值,而二元切分的依據就是將小於等於這個特征值和大於這個特征值的數據划分為兩塊。這里說的總方差一般就是通過數據子集的樣本輸出值的均方差 * 數據子集的樣本個數來計算。最后的輸出結果是取各葉子節點數據的中位數或均值。

分類樹

相比ID3,CART一般選擇基尼不純度來代替信息增益的方式度量數據子集的不純度。基尼不純度越小,數據純度越高。相比回歸樹,分類樹對於離散或者連續特征的處理都是采用二元切分的方式,但是在數據子集的混亂程度的計算上,是用基尼不純度替代總方差的方式。

基尼不純度的定義:從一個數據集中隨機選取子項,度量其被錯誤的划分到其他組里的概率。

先不着急理解這句話,先看下面對基尼不純度的表達式的解釋。

  • 假設一個數據集中有K個類別,第k個類別的概率為p_k, 則基尼系數的表達式為:

    上面的公式中,p_k表示第k個類別出現的概率,那么1-p_k顯然就是當前數據集中,除了第k個類別以外的其他所有類別出現的概率,所以兩者相乘就是當前數據集中,第k個類別和其他所有類別都出現的概率,這個概率越高,數據集越不純。
    現在再看上面的定義,應該就好理解了吧。
  • 對於個給定的樣本D,假設有K個類別, 第k個類別的數量為CkCk,則樣本D的基尼系數表達式為:
  • 對於樣本D,如果根據特征A的某個值a,把D分成D1和D2兩部分,則在特征A的條件下,D的基尼系數表達式為:

算法庫調用

在scikit-learn庫中的決策樹算法是使用了調優過的CART算法,既可以做分類,又可以做回歸。

代碼

分類樹對應DecisionTreeClassifier,回歸樹對應DecisionTreeRegressor。代碼示例和參數說明如下:

from sklearn.tree import DecisionTreeClassifier
clf_dt = DecisionTreeClassifier()
clf_dt.fit(train_X, train_y)
predictions_dt = clf_dt.predict(test_X)[:,None]

參數

參數 DecisionTreeClassifier DecisionTreeRegressor
criterion 特征選擇標准。可以使用"gini"或者"entropy",前者代表基尼系數,后者代表信息增益。一般說使用默認的基尼系數"gini"就可以了,即CART算法。除非你更喜歡類似ID3, C4.5的最優特征選擇方法。 可以使用"mse"或者"mae",前者是均方差,后者是和均值之差的絕對值之和。推薦使用默認的"mse"。一般來說"mse"比"mae"更加精確。除非你想比較二個參數的效果的不同之處。
splitter 特征划分點選擇標准。可以使用"best"或者"random"。前者在特征的所有划分點中找出最優的划分點。后者是隨機的在部分划分點中找局部最優的划分點。默認的"best"適合樣本量不大的時候,而如果樣本數據量非常大,此時決策樹構建推薦"random" 同左。
max_features 划分時考慮的最大特征數。 可以使用很多種類型的值,默認是"None",意味着划分時考慮所有的特征數;如果是"log2"意味着划分時最多考慮log2Nlog2N個特征;如果是"sqrt"或者"auto"意味着划分時最多考慮N−−√N個特征。如果是整數,代表考慮的特征絕對數。如果是浮點數,代表考慮特征百分比,即考慮(百分比xN)取整后的特征數。其中N為樣本總特征數。一般來說,如果樣本特征數不多,比如小於50,我們用默認的"None"就可以了,如果特征數非常多,我們可以靈活使用剛才描述的其他取值來控制划分時考慮的最大特征數,以控制決策樹的生成時間。 同左。
max_depth 決策樹的最大深度。默認可以不輸入,如果不輸入的話,決策樹在建立子樹的時候不會限制子樹的深度。一般來說,數據少或者特征少的時候可以不管這個值。如果模型樣本量多,特征也多的情況下,推薦限制這個最大深度,具體的取值取決於數據的分布。常用的可以取值10-100之間。 同左。
min_samples_split 內部節點再划分所需最小樣本數。這個值限制了子樹繼續划分的條件,如果某節點的樣本數少於min_samples_split,則不會繼續再嘗試選擇最優特征來進行划分。 默認是2.如果樣本量不大,不需要管這個值。如果樣本量數量級非常大,則推薦增大這個值。我之前的一個項目例子,有大概10萬樣本,建立決策樹時,我選擇了min_samples_split=10。可以作為參考。 同左。
min_samples_leaf 葉子節點最少樣本數。 這個值限制了葉子節點最少的樣本數,如果某葉子節點數目小於樣本數,則會和兄弟節點一起被剪枝。 默認是1,可以輸入最少的樣本數的整數,或者最少樣本數占樣本總數的百分比。如果樣本量不大,不需要管這個值。如果樣本量數量級非常大,則推薦增大這個值。之前的10萬樣本項目使用min_samples_leaf的值為5,僅供參考。
min_weight_fraction_leaf 葉子節點最小的樣本權重和。這個值限制了葉子節點所有樣本權重和的最小值,如果小於這個值,則會和兄弟節點一起被剪枝。 默認是0,就是不考慮權重問題。一般來說,如果我們有較多樣本有缺失值,或者分類樹樣本的分布類別偏差很大,就會引入樣本權重,這時我們就要注意這個值了。 同左。
max_leaf_nodes 最大葉子節點數。通過限制最大葉子節點數,可以防止過擬合,默認是"None”,即不限制最大的葉子節點數。如果加了限制,算法會建立在最大葉子節點數內最優的決策樹。如果特征不多,可以不考慮這個值,但是如果特征分成多的話,可以加以限制,具體的值可以通過交叉驗證得到。 同左。
class_weight 指定樣本各類別的的權重,主要是為了防止訓練集某些類別的樣本過多,導致訓練的決策樹過於偏向這些類別。這里可以自己指定各個樣本的權重,或者用“balanced”,如果使用“balanced”,則算法會自己計算權重,樣本量少的類別所對應的樣本權重會高。當然,如果你的樣本類別分布沒有明顯的偏倚,則可以不管這個參數,選擇默認的"None" 不適用於回歸樹。
min_impurity_split 節點划分最小不純度。這個值限制了決策樹的增長,如果某節點的不純度(基尼系數,信息增益,均方差,絕對差)小於這個閾值,則該節點不再生成子節點。即為葉子節點 。 同左。
presort 數據是否預排序。這個值是布爾值,默認是False不排序。一般來說,如果樣本量少或者限制了一個深度很小的決策樹,設置為true可以讓划分點選擇更加快,決策樹建立的更加快。如果樣本量太大的話,反而沒有什么好處。問題是樣本量少的時候,我速度本來就不慢。所以這個值一般懶得理它就可以了。 同左。

決策樹可視化

安裝graphviz

可視化需要先安裝graphviz,這是一個開源的圖形可視化軟件,官網:https://graphviz.gitlab.io,下載適合自己操作系統的文件即可。

如果是windows操作系統,可以點此下載安裝包。安裝完成記得設置一下環境變量將 xxx/Graphviz2.38/bin/加入PATH

安裝python插件:

pip install graphviz
pip install pydotplus

代碼示例

from sklearn.datasets import load_iris
from sklearn import tree
import pydotplus
import os
# 如果執行程序總是找不到Graphviz命令,可以加入下面這行代碼,注意修改路徑為你的正確的Graphviz/bin目錄的路徑
os.environ["PATH"] += os.pathsep + 'H:/program_files/Graphviz2.38/bin'
# 訓練模型
iris = load_iris()
clf = tree.DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)
# 用pydotplus生成iris.pdf
dot_data = tree.export_graphviz(clf, out_file=None,
								feature_names=iris.feature_names,
								class_names=iris.target_names,
								filled=True, rounded=True,
								special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
graph.write_pdf("iris.pdf")

查看pdf文件

參考資料

https://www.cnblogs.com/pinard/p/6056319.html

https://blog.csdn.net/JJBOOM425/article/details/79997440

https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/tree/_tree.pyx

ok,本篇就這么多內容啦~,感謝閱讀O(∩_∩)O。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM