scikit-learn 決策樹

2023-02-20 13:43 更新

決策樹(DTs)是一種用于分類回歸的非參數(shù)有監(jiān)督學(xué)習(xí)方法。其目標(biāo)是創(chuàng)建一個(gè)模型,通過學(xué)習(xí)從數(shù)據(jù)特性中推斷出的簡單決策規(guī)則來預(yù)測(cè)目標(biāo)變量的值。

例如,在下面的示例中,決策樹從數(shù)據(jù)中學(xué)習(xí),用一組if-then-else的決策規(guī)則來逼近正弦曲線。樹越深,決策規(guī)則越復(fù)雜,模型越適合。


決策樹的一些優(yōu)點(diǎn):

  • 易于理解和解釋。樹可以被可視化。
  • 幾乎不需要數(shù)據(jù)準(zhǔn)備。其他算法通常需要數(shù)據(jù)標(biāo)準(zhǔn)化,需要?jiǎng)?chuàng)建虛擬變量并刪除缺失值。但是,請(qǐng)注意,此模塊不支持缺失值。
  • 使用樹的成本(即預(yù)測(cè)數(shù)據(jù))是用于訓(xùn)練樹的數(shù)據(jù)點(diǎn)數(shù)的對(duì)數(shù)。
  • 能夠處理數(shù)值型和分類型數(shù)據(jù)。其他技術(shù)通常專門分析只有一種類型變量的數(shù)據(jù)集。有關(guān)更多信息,請(qǐng)參見algorithms 。
  • 能夠處理多輸出問題。
  • 使用白盒模型。如果給定的情況在模型中是可以觀察到的,那么對(duì)條件的解釋就很容易用布爾邏輯來解釋。相反,在黑箱模型中(例如,在人工神經(jīng)網(wǎng)絡(luò)中),結(jié)果可能很難解釋。
  • 可以使用統(tǒng)計(jì)測(cè)試驗(yàn)證模型。這樣就有可能對(duì)模型的可靠性作出解釋。
  • 即使它的假設(shè)在某種程度上被生成數(shù)據(jù)的真實(shí)模型所違背,它也表現(xiàn)得很好。

決策樹的缺點(diǎn)包括:

  • 決策樹學(xué)習(xí)器可以創(chuàng)建過于復(fù)雜的樹,不能很好地概括數(shù)據(jù)。這就是所謂的過擬合。為了避免這個(gè)問題,必須設(shè)置剪枝、設(shè)置葉節(jié)點(diǎn)所需的最小樣本數(shù)或設(shè)置樹的最大深度等機(jī)制。

  • 決策樹可能是不穩(wěn)定的,因?yàn)閿?shù)據(jù)中的小變化可能導(dǎo)致生成完全不同的樹。通過集成決策樹來緩解這個(gè)問題。

  • 學(xué)習(xí)最優(yōu)決策樹的問題在最優(yōu)性的幾個(gè)方面都是NP-complete的,甚至對(duì)于簡單的概念也是如此。因此,實(shí)際的決策樹學(xué)習(xí)算法是基于啟發(fā)式算法,如貪婪算法,在每個(gè)節(jié)點(diǎn)上進(jìn)行局部最優(yōu)決策。這種算法不能保證返回全局最優(yōu)決策樹。這可以通過訓(xùn)練多棵樹再集成一個(gè)學(xué)習(xí)器來緩解,其中特征和樣本被隨機(jī)抽取并替換。

  • 有些概念很難學(xué)習(xí),因?yàn)闆Q策樹不能很容易地表達(dá)它們,例如異或、奇偶校驗(yàn)或多路復(fù)用器問題。

  • 如果某些類占主導(dǎo)地位,則決策樹學(xué)習(xí)者會(huì)創(chuàng)建有偏見的樹。因此,建議在擬合決策樹之前平衡數(shù)據(jù)集。

1.10.1 分類

DecisionTreeClassifier 是一個(gè)能夠在數(shù)據(jù)集上執(zhí)行多類分類的類。

與其他分類器一樣,DecisionTreeClassifier使用兩個(gè)數(shù)組作為輸入:形狀為[n_samples, n_features]的數(shù)組(稀疏或稠密),以及整數(shù)值數(shù)組,形狀[n_samples],保存訓(xùn)練樣本的類標(biāo)簽:

>>> from sklearn import tree
>>> X = [[0, 0], [1, 1]]
>>> Y = [0, 1]
>>> clf = tree.DecisionTreeClassifier()
>>> clf = clf.fit(X, Y)

經(jīng)擬合后,該模型可用于預(yù)測(cè)其他樣本的類別:

>>> clf.predict([[2., 2.]])
array([1])

或者,可以預(yù)測(cè)屬于每一類別的概率,即同一類的訓(xùn)練樣本在一片葉子中的分?jǐn)?shù):

>>> clf.predict_proba([[2., 2.]])
array([[0., 1.]])

DecisionTreeClassifier 既能夠進(jìn)行二分類(其中標(biāo)簽為[-1,1]),也能夠進(jìn)行多類分類(其中標(biāo)簽為[0,…K-1])分類。

使用Iris數(shù)據(jù)集,我們可以構(gòu)建如下樹:

>>> from sklearn.datasets import load_iris
>>> from sklearn import tree
>>> X, y = load_iris(return_X_y=True)
>>> clf = tree.DecisionTreeClassifier()
>>> clf = clf.fit(X, y)

一旦經(jīng)過訓(xùn)練,就可以用 plot_tree函數(shù)繪制樹:

>>> tree.plot_tree(clf) 


我們還可以使用 export_graphviz導(dǎo)出器以 Graphviz 格式導(dǎo)出樹。如果使用 conda包管理器,則可以使用 conda install python-graphviz安裝Graphviz二進(jìn)制文件和python包。

另外,還可以從Graphviz項(xiàng)目主頁下載用于Graphviz的二進(jìn)制文件,并從pypi使用 pip install graphviz安裝Python包裝器并安裝Graphviz。

下面是對(duì)整個(gè) iris 數(shù)據(jù)集進(jìn)行訓(xùn)練的樹的圖形輸出示例;結(jié)果保存在一個(gè)輸出文件iris.pdf中:

>>> import graphviz 
>>> dot_data = tree.export_graphviz(clf, out_file=None) 
>>> graph = graphviz.Source(dot_data) 
>>> graph.render("iris") 

export_graphviz 還支持各種美化,包括通過他們的類著色節(jié)點(diǎn)(或回歸值),如果需要,還能使用顯式變量和類名。Jupyter notebook也可以自動(dòng)內(nèi)聯(lián)式渲染這些繪制節(jié)點(diǎn):

>>> 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 = graphviz.Source(dot_data)  
>>> graph 



或者,還可以使用函數(shù) export_text以文本格式導(dǎo)出樹。此方法不需要安裝外部庫,而且更緊湊:

>>> from sklearn.datasets import load_iris
>>> from sklearn.tree import DecisionTreeClassifier
>>> from sklearn.tree import export_text
>>> iris = load_iris()
>>> decision_tree = DecisionTreeClassifier(random_state=0, max_depth=2)
>>> decision_tree = decision_tree.fit(iris.data, iris.target)
>>> r = export_text(decision_tree, feature_names=iris['feature_names'])
>>> print(r)
|--- petal width (cm) <= 0.80
|   |--- class: 0
|--- petal width (cm) >  0.80
|   |--- petal width (cm) <= 1.75
|   |   |--- class: 1
|   |--- petal width (cm) >  1.75
|   |   |--- class: 2
<BLANKLINE>
示例
在iris數(shù)據(jù)集中繪制決策樹的決策面
理解決策樹結(jié)構(gòu)

1.10.2 回歸


決策樹也可以應(yīng)用于回歸問題,使用DecisionTreeRegressor 類。

與分類的設(shè)置一樣,fit方法需要參數(shù)數(shù)組X和y,只是在這種情況下,y可以有浮點(diǎn)數(shù)值,而不是整數(shù)值:

>>> from sklearn import tree
>>> X = [[0, 0], [2, 2]]
>>> y = [0.5, 2.5]
>>> clf = tree.DecisionTreeRegressor()
>>> clf = clf.fit(X, y)
>>> clf.predict([[1, 1]])
array([0.5])
示例
決策樹回歸

1.10.3 多輸出問題

多輸出問題是一個(gè)具有多個(gè)輸出預(yù)測(cè)的有監(jiān)督學(xué)習(xí)問題,即 Y 是一個(gè)大小為二維的數(shù)組[n_samples, n_outputs]。

當(dāng)輸出之間沒有相關(guān)性時(shí),解決這類問題的一個(gè)非常簡單的方法是建立n個(gè)獨(dú)立的模型,即對(duì)于每個(gè)輸出,利用這些模型獨(dú)立地預(yù)測(cè)n個(gè)輸出的每一個(gè)。但是,由于可能由于輸出的值與同樣的輸入本身是相關(guān)的,所以通常更好的方法是建立一個(gè)能夠同時(shí)預(yù)測(cè)所有n個(gè)輸出的單一模型。首先,它需要較低的訓(xùn)練時(shí)間,因?yàn)橹恍枰⒁粋€(gè)簡單的估計(jì)器。其次,估計(jì)結(jié)果的泛化精度往往會(huì)提高。

對(duì)于決策樹,這種策略可以很容易地用于支持多輸出問題。這需要進(jìn)行以下更改:

  • 將n個(gè)輸出值存儲(chǔ)在葉子中,而不是1;
  • 通過計(jì)算所有n個(gè)輸出的平均減少量來作為分裂標(biāo)準(zhǔn)。

該模塊通過在 DecisionTreeClassifierDecisionTreeRegressor 中實(shí)現(xiàn)該策略來支持多輸出問題。如果一個(gè)決策樹在形狀為 [n_samples, n_outputs] 的輸出數(shù)組Y上進(jìn)行擬合,則得到的估計(jì)器:

  • predict輸出的是 n_output 的值;
  • predict_proba上輸出類概率數(shù)組n_output的列表。

多輸出決策樹回歸中說明了多輸出樹在回歸上的應(yīng)用。 在該示例中,輸入X是單個(gè)實(shí)數(shù)值,并且輸出Y是X的正弦和余弦。


使用多輸出估算器完成人臉繪制中演示了多輸出樹的分類的使用。在這個(gè)例子中,輸入X是人臉的上半部分的像素,輸出Y是這些人臉的下半部的像素。


示例
多輸出決策樹回歸
使用多輸出估算器完成人臉繪制

參考

M. Dumont et al, Fast multi-class image annotation with random subwindows and multiple output randomized trees, International Conference on Computer Vision Theory and Applications 2009

1.10.4 復(fù)雜度

通常,構(gòu)建平衡二叉樹的運(yùn)行時(shí)間代價(jià)是和查詢時(shí)間是。雖然樹構(gòu)造算法試圖生成平衡樹,但它們并不總是平衡的。假設(shè)子樹保持近似平衡,每個(gè)節(jié)點(diǎn)的代價(jià)成本是通過搜索找到熵減少最大的特征。這在每個(gè)節(jié)點(diǎn)上的成本為,導(dǎo)致整個(gè)樹的總成本(通過將每個(gè)節(jié)點(diǎn)的成本求和)是。

1.10.5 實(shí)用技巧

  • 對(duì)于擁有大量特征的數(shù)據(jù)決策樹會(huì)趨向于過擬合。獲得一個(gè)合適的樣本與特征的比例十分重要,因?yàn)榫哂懈呔S空間中只有少量的樣本的, 那樹是十分容易過擬合的。

  • 考慮在此之前進(jìn)行降維((PCA, ICA, 或者 Feature selection) ),以便給您的樹更好的機(jī)會(huì)找到更有區(qū)分度的特征。

  • 通過 export 功能可以可視化您的決策樹。使用 max_depth=3 作為初始樹深度,讓決策樹知道如何適應(yīng)您的數(shù)據(jù),然后再增加樹的深度。

  • 了解決策樹結(jié)構(gòu)理解決策樹的結(jié)構(gòu) 將有助于更深入地了解決策樹是如何進(jìn)行預(yù)測(cè)的,這對(duì)于理解數(shù)據(jù)中的重要特性非常重要。

  • 通過 export 功能可以可視化您的決策樹。使用 max_depth=3 作為初始樹深度,讓決策樹知道如何適應(yīng)您的數(shù)據(jù),然后再增加樹的深度。

  • 通過使用 min_samples_splitmin_samples_leaf 確保多個(gè)樣本通知樹中的每個(gè)決策, 方法是控制將考慮哪些分割。當(dāng)這個(gè)值很小時(shí)意味著生成的決策樹將會(huì)過擬合,然而當(dāng)這個(gè)值很大時(shí)將會(huì)不利于決策樹的對(duì)樣本進(jìn)行學(xué)習(xí)。嘗試 min_samples_leaf=5 作為初始值。如果樣本的變化量很大,可以使用浮點(diǎn)數(shù)作為這兩個(gè)參數(shù)中的百分比。當(dāng)min_samples_split 可以產(chǎn)生任意小的葉子時(shí),, min_samples_leaf保證每個(gè)葉子都有最小的大小,避免了回歸問題中的低方差、過擬合的葉節(jié)點(diǎn)。對(duì)于少數(shù)類的分類,min_samples_leaf=1通常是最好的選擇。

  • 在訓(xùn)練前平衡數(shù)據(jù)集,以防止樹偏向于占主導(dǎo)地位的類。類平衡可以通過從每個(gè)類中抽取相同數(shù)量的樣本來實(shí)現(xiàn),或者最好通過將每個(gè)類的樣本權(quán)重(sample_weight)之和歸一化為相同的值來實(shí)現(xiàn)。還要注意的是,基于權(quán)重的預(yù)剪枝準(zhǔn)則(如 min_weight_fraction_leaf)將比不知道樣本權(quán)重的標(biāo)準(zhǔn)(如min_samples_leaf)更傾向于優(yōu)勢(shì)類。

  • 如果樣本是加權(quán)的,則使用基于權(quán)重的預(yù)剪枝準(zhǔn)則(如min_weight_fraction_leaf)來優(yōu)化樹結(jié)構(gòu),這樣可以確保葉節(jié)點(diǎn)至少包含樣本權(quán)重的總和的一部分。

  • 所有決策樹都在內(nèi)部使用np.float32數(shù)組。如果訓(xùn)練數(shù)據(jù)不是這種格式,則將復(fù)制數(shù)據(jù)集。

  • 如果輸入矩陣X非常稀疏,則建議在調(diào)用fit方法之前將其轉(zhuǎn)換為稀疏 csc_matrix,在調(diào)用predict之前將其轉(zhuǎn)換為稀疏csr_matrix。當(dāng)大多數(shù)樣本的特征值為零時(shí),輸入的稀疏矩陣訓(xùn)練時(shí)間比密集矩陣的訓(xùn)練時(shí)間快幾個(gè)數(shù)量級(jí)。

1.10.6 樹算法:ID3、C4.5、C5.0和CART

各種決策樹算法是什么?它們之間有何不同?哪一種是在scikit-learn中實(shí)現(xiàn)的?

ID3(迭代分離 3)是由Ross Quinlan于1986年開發(fā)的。該算法建立了一個(gè)多路樹,為每個(gè)節(jié)點(diǎn)(即貪婪地)尋找分類特征,從而為分類目標(biāo)提供最大的信息增益。樹生長到它們的最大尺寸,然后,通常采取一個(gè)剪枝步驟,以提高樹的對(duì)位置數(shù)據(jù)的泛化能力。

c4.5是ID3的繼承者,并且通過動(dòng)態(tài)定義將連續(xù)屬性值分割成一組離散間隔的離散屬性(基于數(shù)字變量),從而消除了特征必須是分類的限制。c4.5將經(jīng)過訓(xùn)練的樹(即ID3算法的輸出)轉(zhuǎn)換成一組if-then規(guī)則的集合。然后對(duì)每條規(guī)則的這些準(zhǔn)確性進(jìn)行評(píng)估,以確定應(yīng)用它們的順序。如果規(guī)則的準(zhǔn)確性沒有提高的話,則需要決策樹的樹枝來解決。

c5.0是Quinlan在專有許可下發(fā)布的最新版本。與C4.5相比,它使用更少的內(nèi)存和構(gòu)建更小的規(guī)則集,同時(shí)更精確。

CART (分類和回歸樹)與C4.5非常相似,但它的不同之處在于它支持?jǐn)?shù)值目標(biāo)變量(回歸),不計(jì)算規(guī)則集。CART使用特征和閾值構(gòu)造二叉樹,在每個(gè)節(jié)點(diǎn)上獲得最大的信息增益。

scikit-learn使用 CART算法的優(yōu)化版本;但是目前,scikit-learn實(shí)現(xiàn)不支持分類變量。

1.10.7 數(shù)學(xué)公式

給定訓(xùn)練向量 I和標(biāo)簽向量,決策樹遞歸地劃分空間,使得具有相同標(biāo)簽的樣本被分到一樣的組。

讓節(jié)點(diǎn)處的數(shù)據(jù)集用表示,對(duì)于一個(gè)由特征和閾值組成的候選劃分?jǐn)?shù)據(jù)集,將數(shù)據(jù)劃分為兩個(gè)子集。

節(jié)點(diǎn)處的不存度用不存度函數(shù)計(jì)算,其選擇取決于正在解決的任務(wù)(分類或回歸)。

選擇使不存度最小化的參數(shù)

對(duì)子集進(jìn)行遞歸,直到達(dá)到最大允許的深度,。

1.10.7.1 分類標(biāo)準(zhǔn)

如果目標(biāo)是變量的值0,1,…K-1的分類結(jié)果,對(duì)于節(jié)點(diǎn),表示具有個(gè)觀測(cè)值的區(qū)域,令:

表示的是節(jié)點(diǎn)中k類觀測(cè)的比例。

常見的不存度度量的方法是 Gini

熵(Entropy)

和錯(cuò)誤分類(Misclassification)

其中是節(jié)點(diǎn)中的訓(xùn)練數(shù)據(jù)。

1.10.7.2 回歸標(biāo)準(zhǔn)

如果目標(biāo)是連續(xù)性的值,那么對(duì)于節(jié)點(diǎn) ,表示具有 個(gè)觀測(cè)值的區(qū)域 ,對(duì)于以后的分裂節(jié)點(diǎn)的位置的決定常用的最小化標(biāo)準(zhǔn)是均方誤差和平均絕對(duì)誤差,前者使用終端節(jié)點(diǎn)處的平均值來最小化L2誤差,后者使用終端節(jié)點(diǎn)處的中值來最小化 L1 誤差。

均方誤差:

平均絕對(duì)誤差:

其中是節(jié)點(diǎn)中的訓(xùn)練數(shù)據(jù)。

1.10.8 最小成本復(fù)雜度剪枝

最小代價(jià)復(fù)雜度剪枝是一種用于修剪樹以避免過擬合的算法,在[BRE]第3章中描述了這種算法。該算法由作為復(fù)雜度參數(shù)進(jìn)行參數(shù)化。復(fù)雜度參數(shù)用于定義給定樹的成本復(fù)雜度度量

其中,中的終端節(jié)點(diǎn)數(shù),傳統(tǒng)上定義為終端節(jié)點(diǎn)的總誤分類率?;蛘?,scikit-learn使用終端節(jié)點(diǎn)的總樣本加權(quán)不存度作為。如上所述,節(jié)點(diǎn)的不存度取決于標(biāo)準(zhǔn)(criterion)。最小成本-復(fù)雜度剪枝找到的子樹,使最小化。

單節(jié)點(diǎn)的代價(jià)復(fù)雜度度量為 被定義為一棵樹,其中分支節(jié)點(diǎn)是它的根。一般而言,節(jié)點(diǎn)的不存度大于其葉子節(jié)點(diǎn)的不存度之和,。然而,節(jié)點(diǎn)及其分支 的成本復(fù)雜度度量取決于。我們定義了一個(gè)節(jié)點(diǎn)的有效為與它們相等的值, 或者。一個(gè)非葉子節(jié)點(diǎn),其最小的是最弱的連接(weakest link),并將被修剪。當(dāng)被剪枝的樹的最小的ccp_alpha參數(shù)大時(shí),此過程將停止。

示例
具有成本復(fù)雜度的后剪枝決策樹

參考

[BRE] L. Breiman, J. Friedman, R. Olshen, and C. Stone. Classification and Regression Trees. Wadsworth, Belmont, CA, 1984.


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)