scikit-learn 中文文檔-決策樹-監督學習|ApacheCN

中文文檔: http://sklearn.apachecn.org/cn/stable/modules/tree.html

英文文檔: http://sklearn.apachecn.org/en/stable/modules/tree.html

官方文檔: http://scikit-learn.org/stable/

GitHub: https://github.com/apachecn/scikit-learn-doc-zh(覺得不錯麻煩給個 Star,我們一直在努力)

貢獻者: https://github.com/apachecn/scikit-learn-doc-zh#貢獻者

關於我們: http://www.apachecn.org/organization/209.html




1.10. 決策樹

Decision Trees (DTs) 是一種用來 classification 和 regression 的無參監督學習方法。其目的是創建一種模型從數據特徵中學習簡單的決策規則來預測一個目標變量的值。

例如,在下面的圖片中,決策樹通過if-then-else的決策規則來學習數據從而估測數一個正弦圖像。決策樹越深入,決策規則就越複雜並且對數據的擬合越好。

../_images/sphx_glr_plot_tree_regression_0011.png

決策樹的優勢:

  • 便於理解和解釋。樹的結構可以可視化出來。
  • 訓練需要的數據少。其他機器學習模型通常需要數據規範化,比如構建虛擬變量和移除缺失值,不過請注意,這種模型不支持缺失值。
  • 由於訓練決策樹的數據點的數量導致了決策樹的使用開銷呈指數分佈(訓練樹模型的時間複雜度是參與訓練數據點的對數值)。
  • 能夠處理數值型數據和分類數據。其他的技術通常只能用來專門分析某一種變量類型的數據集。詳情請參閱算法。
  • 能夠處理多路輸出的問題。
  • 使用白盒模型。如果某種給定的情況在該模型中是可以觀察的,那麼就可以輕易的通過布爾邏輯來解釋這種情況。相比之下,在黑盒模型中的結果就是很難說明清 楚地。
  • 可以通過數值統計測試來驗證該模型。這對事解釋驗證該模型的可靠性成爲可能。
  • 即使該模型假設的結果與真實模型所提供的數據有些違反,其表現依舊良好。

決策樹的缺點包括:

  • 決策樹模型容易產生一個過於複雜的模型,這樣的模型對數據的泛化性能會很差。這就是所謂的過擬合.一些策略像剪枝、設置葉節點所需的最小樣本數或設置數的最大深度是避免出現 該問題最爲有效地方法。
  • 決策樹可能是不穩定的,因爲數據中的微小變化可能會導致完全不同的樹生成。這個問題可以通過決策樹的集成來得到緩解
  • 在多方面性能最優和簡單化概念的要求下,學習一棵最優決策樹通常是一個NP難問題。因此,實際的決策樹學習算法是基於啓發式算法,例如在每個節點進 行局部最優決策的貪心算法。這樣的算法不能保證返回全局最優決策樹。這個問題可以通過集成學習來訓練多棵決策樹來緩解,這多棵決策樹一般通過對特徵和樣本有放回的隨機採樣來生成。
  • 有些概念很難被決策樹學習到,因爲決策樹很難清楚的表述這些概念。例如XOR,奇偶或者複用器的問題。
  • 如果某些類在問題中占主導地位會使得創建的決策樹有偏差。因此,我們建議在擬合前先對數據集進行平衡。

1.10.1. 分類

DecisionTreeClassifier 是能夠在數據集上執行多分類的類,與其他分類器一樣,DecisionTreeClassifier 採用輸入兩個數組:數組X,用 [n_samples, n_features] 的方式來存放訓練樣本。整數值數組Y,用 [n_samples] 來保存訓練樣本的類標籤:

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

執行通過之後,可以使用該模型來預測樣本類別:

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

另外,也可以預測每個類的概率,這個概率是葉中相同類的訓練樣本的分數:

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

DecisionTreeClassifier 既能用於二分類(其中標籤爲[-1,1])也能用於多分類(其中標籤爲[0,…,k-1])。使用Lris數據集,我們可以構造一個決策樹,如下所示:

>>>
>>> from sklearn.datasets import load_iris
>>> from sklearn import tree
>>> iris = load_iris()
>>> clf = tree.DecisionTreeClassifier()
>>> clf = clf.fit(iris.data, iris.target)

經過訓練,我們可以使用 export_graphviz 導出器以 Graphviz 格式導出決策樹. 如果你是用 conda 來管理包,那麼安裝 graphviz 二進制文件和 python 包可以用以下指令安裝

conda install python-graphviz

或者,可以從 graphviz 項目主頁下載 graphviz 的二進制文件,並從 pypi 安裝 Python 包裝器,並安裝 pip install graphviz .以下是在整個 iris 數據集上訓練的上述樹的 graphviz 導出示例; 其結果被保存在 iris.pdf 中:

   >>> import graphviz # doctest: +SKIP
   >>> dot_data = tree.export_graphviz(clf, out_file=None) # doctest: +SKIP
   >>> graph = graphviz.Source(dot_data) # doctest: +SKIP
   >>> graph.render("iris") # doctest: +SKIP

:func:`export_graphviz` 出導出還支持各種美化,包括通過他們的類着色節點(或迴歸值),如果需要,使用顯式變量和類名。Jupyter notebook也可以自動找出相同的模塊::

   >>> dot_data = tree.export_graphviz(clf, out_file=None, # doctest: +SKIP
                            feature_names=iris.feature_names,  # doctest: +SKIP
                            class_names=iris.target_names,  # doctest: +SKIP
                            filled=True, rounded=True,  # doctest: +SKIP
                            special_characters=True)  # doctest: +SKIP
   >>> graph = graphviz.Source(dot_data)  # doctest: +SKIP
   >>> graph # doctest: +SKIP
../_images/iris.svg

執行通過之後,可以使用該模型預測樣品類別:

>>>
>>> clf.predict(iris.data[:1, :])
array([0])

或者,可以根據決策樹葉子樹裏訓練樣本中的相同類的分數,使得類預測成爲可能:

>>>
>>> clf.predict_proba(iris.data[:1, :])
array([[ 1.,  0.,  0.]])
../_images/sphx_glr_plot_iris_0013.png

1.10.2. 迴歸

../_images/sphx_glr_plot_tree_regression_0011.png

決策樹通過使用 DecisionTreeRegressor 類也可以用來解決迴歸問題。如在分類設置中,擬合方法將數組X和數組y作爲參數,只有在這種情況下,y數組預期纔是浮點值:

>>>
>>> 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. 多值輸出問題

一個多值輸出問題是一個類似當 Y 是大小爲當 Y 是大小爲 [n_samples, n_outputs] 的2d數組時,有多個輸出值需要預測的監督學習問題。

當輸出值之間沒有關聯時,一個很簡單的處理該類型的方法是建立一個n獨立模型,即每個模型對應一個輸出,然後使用這些模型來獨立地預測n個輸出中的每一個。然而,由於可能與相同輸入相關的輸出值本身是相關的,所以通常更好的方法是構建能夠同時預測所有n個輸出的單個模型。首先,因爲僅僅是建立了一個模型所以訓練時間會更短。第二,最終模型的泛化性能也會有所提升。對於決策樹,這一策略可以很容易地用於多輸出問題。 這需要以下更改:

  • 在葉中存儲n個輸出值,而不是一個;
  • 通過計算所有n個輸出的平均減少量來作爲分裂標準.

該模塊通過在 DecisionTreeClassifier `和 :class:`DecisionTreeRegressor 中實現該策略來支持多輸出問題。如果決策樹與大小爲 [n_samples, n_outputs] 的輸出數組Y向匹配,則得到的估計器將:

* ``predict`` 是輸出n_output的值

* 在 ``predict_proba`` 上輸出 n_output 數組列表

用多輸出決策樹進行迴歸分析 Multi-output Decision Tree Regression 。 在該示例中,輸入X是單個實數值,並且輸出Y是X的正弦和餘弦。

../_images/sphx_glr_plot_tree_regression_multioutput_0011.png

使用多輸出樹進行分類,在 Face completion with a multi-output estimators 中進行了演示。 在該示例中,輸入X是面的上半部分的像素,並且輸出Y是這些面的下半部分的像素。

modules/../auto_examples/images/sphx_glr_plot_multioutput_face_completion_001.png

參考:

1.10.4. 複雜度分析

總體來說,用來構建平衡二叉樹的運行時間爲 O(n_{samples}n_{features}\log(n_{samples})) 查詢時間爲 O(\log(n_{samples})) 。儘管樹的構造算法嘗試生成平衡樹,但它們並不總能保持平衡。假設子樹能大概保持平衡,每個節點的成本包括通過 O(n_{features}) 時間複雜度來搜索找到提供熵減小最大的特徵。每個節點的花費爲 O(n_{features}n_{samples}\log(n_{samples})) ,從而使得整個決策樹的構造成本爲 O(n_{features}n_{samples}^{2}\log(n_{samples})) 。

Scikit-learn提供了更多有效的方法來創建決策樹。初始實現(如上所述)將重新計算沿着給定特徵的每個新分割點的類標籤直方圖(用於分類)或平均值(用於迴歸)。與分類所有的樣本特徵,然後再次訓練時運行標籤計數,可將每個節點的複雜度降低爲 O(n_{features}\log(n_{samples})) ,則總的成本花費爲 O(n_{features}n_{samples}\log(n_{samples})) 。這是一種對所有基於樹的算法的改進選項。默認情況下,對於梯度提升模型該算法是打開的,一般來說它會讓訓練速度更快。但對於所有其他算法默認是關閉的,當訓練深度很深的樹時往往會減慢訓練速度。

1.10.5. 實際使用技巧

  • 對於擁有大量特徵的數據決策樹會出現過擬合的現象。獲得一個合適的樣本比例和特徵數量十分重要,因爲在高維空間中只有少量的樣本的樹是十分容易過擬合的。
  • 考慮事先進行降維( PCA , ICA ,使您的樹更好地找到具有分辨性的特徵。
  • 通過 export 功能可以可視化您的決策樹。使用 max_depth=3 作爲初始樹深度,讓決策樹知道如何適應您的數據,然後再增加樹的深度。
  • 請記住,填充樹的樣本數量會增加樹的每個附加級別。使用 max_depth 來控制輸的大小防止過擬合。
  • 通過使用 min_samples_split 和 min_samples_leaf 來控制葉節點上的樣本數量。當這個值很小時意味着生成的決策樹將會過擬合,然而當這個值很大時將會不利於決策樹的對樣本的學習。所以嘗試 min_samples_leaf=5 作爲初始值。如果樣本的變化量很大,可以使用浮點數作爲這兩個參數中的百分比。兩者之間的主要區別在於 min_samples_leaf 保證葉結點中最少的採樣數,而 min_samples_split 可以創建任意小的葉子,儘管在文獻中 min_samples_split 更常見。
  • 在訓練之前平衡您的數據集,以防止決策樹偏向於主導類.可以通過從每個類中抽取相等數量的樣本來進行類平衡,或者優選地通過將每個類的樣本權重 (sample_weight) 的和歸一化爲相同的值。還要注意的是,基於權重的預修剪標準 (min_weight_fraction_leaf) 對於顯性類別的偏倚偏小,而不是不瞭解樣本權重的標準,如 min_samples_leaf 。
  • 如果樣本被加權,則使用基於權重的預修剪標準 min_weight_fraction_leaf 來優化樹結構將更容易,這確保葉節點包含樣本權重的總和的至少一部分。
  • 所有的決策樹內部使用 np.float32 數組 ,如果訓練數據不是這種格式,將會複製數據集。
  • 如果輸入的矩陣X爲稀疏矩陣,建議您在調用fit之前將矩陣X轉換爲稀疏的``csc_matrix`` ,在調用predict之前將 csr_matrix 稀疏。當特徵在大多數樣本中具有零值時,與密集矩陣相比,稀疏矩陣輸入的訓練時間可以快幾個數量級。

1.10.6. 決策樹算法: ID3, C4.5, C5.0 和 CART

所有種類的決策樹算法有哪些以及它們之間的區別?scikit-learn 中實現何種算法呢?

ID3(Iterative Dichotomiser 3)由 Ross Quinlan 在1986年提出。該算法創建一個多路樹,找到每個節點(即以貪心的方式)分類特徵,這將產生分類目標的最大信息增益。決策樹發展到其最大尺寸,然後通常利用剪枝來提高樹對未知數據的泛華能力。

C4.5 是 ID3 的後繼者,並且通過動態定義將連續屬性值分割成一組離散間隔的離散屬性(基於數字變量),消除了特徵必須被明確分類的限制。C4.5 將訓練的樹(即,ID3算法的輸出)轉換成 if-then 規則的集合。然後評估每個規則的這些準確性,以確定應用它們的順序。如果規則的準確性沒有改變,則需要決策樹的樹枝來解決。

C5.0 是 Quinlan 根據專有許可證發佈的最新版本。它使用更少的內存,並建立比 C4.5 更小的規則集,同時更準確。

CART(Classification and Regression Trees (分類和迴歸樹))與 C4.5 非常相似,但它不同之處在於它支持數值目標變量(迴歸),並且不計算規則集。CART 使用在每個節點產生最大信息增益的特徵和閾值來構造二叉樹。

scikit-learn 使用 CART 算法的優化版本。

1.10.7. 數學表達

給定訓練向量 x_i \in R^n, i=1,…, l 和標籤向量 y \in R^l。決策樹遞歸地分割空間,例如將有相同標籤的樣本歸爲一組。

將 m 節點上的數據用 Q 來表示。每一個候選組 \theta = (j, t_m) 包含一個特徵 j 和閾值 t_m 將,數據分成 Q_{left}(\theta) 和 Q_{right}(\theta) 子集。

Q_{left}(\theta) = {(x, y) | x_j <= t_m}Q_{right}(\theta) = Q \setminus Q_{left}(\theta)

使用不純度函數 H() 計算 m 處的不純度,其選擇取決於正在解決的任務(分類或迴歸)

G(Q, \theta) = \frac{n_{left}}{N_m} H(Q_{left}(\theta))+ \frac{n_{right}}{N_m} H(Q_{right}(\theta))

選擇使不純度最小化的參數

\theta^* = \operatorname{argmin}_\theta  G(Q, \theta)

重新計算子集 Q_{left}(\theta^*) 和 Q_{right}(\theta^*) ,直到達到最大允許深度,N_m < \min_{samples} 或 N_m = 1

1.10.7.1. 分類標準

對於節點 m ,表示具有 N_m 個觀測值的區域 R_m ,如果分類結果採用值是 0,1,…,K-1 的值,讓

p_{mk} = 1/ N_m \sum_{x_i \in R_m} I(y_i = k)

是節點 m 中k類觀測的比例通常用來處理雜質的方法是Gini

H(X_m) = \sum_k p_{mk} (1 - p_{mk})

Cross-Entropy (交叉熵)

H(X_m) = - \sum_k p_{mk} \log(p_{mk})

和 Misclassification (錯誤分類)

H(X_m) = 1 - \max(p_{mk})

在 X_m 訓練 m 節點上的數據時。

1.10.7.2. 迴歸標準

如果目標是連續性的值,那麼對於節點 m ,表示具有 N_m 個觀測值的區域 R_m ,對於以後的分裂節點的位置的決定常用的最小化標準是均方差和平均絕對誤差,前者使用終端節點處的平均值來最小化L2誤差,後者使用終端節點處的中值來最小化 L1 誤差。

Mean Squared Error (均方誤差):

c_m = \frac{1}{N_m} \sum_{i \in N_m} y_iH(X_m) = \frac{1}{N_m} \sum_{i \in N_m} (y_i - c_m)^2

Mean Absolute Error(平均絕對誤差):

\bar{y_m} = \frac{1}{N_m} \sum_{i \in N_m} y_iH(X_m) = \frac{1}{N_m} \sum_{i \in N_m} |y_i - \bar{y_m}|

在 X_m 訓練 m 節點上的數據時。

示例:




中文文檔: http://sklearn.apachecn.org/cn/stable/modules/tree.html

英文文檔: http://sklearn.apachecn.org/en/stable/modules/tree.html

官方文檔: http://scikit-learn.org/stable/

GitHub: https://github.com/apachecn/scikit-learn-doc-zh(覺得不錯麻煩給個 Star,我們一直在努力)

貢獻者: https://github.com/apachecn/scikit-learn-doc-zh#貢獻者

關於我們: http://www.apachecn.org/organization/209.html

有興趣的們也可以和我們一起來維護,持續更新中 。。。

機器學習交流羣: 629470233

發佈了1 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章