信息熵是衡量樣本純度的一種指標,嘉定當前樣本集合D中第k類樣本所佔的比例爲pk(k=1,2,...,|y|),則D的信息熵定義爲node
Ent(D)的值越小,則D的純度越高。算法
通常而言,信息增益越大,則意味着使用屬性a來進行劃分所得到的「純度提高」越大。其中ID3決策樹就是以信息增益爲準則來選擇劃分屬性。函數
實際上,信息增益準則對可取值數目較多的屬性有所偏好,爲減小這種偏好可能帶來的不利影響。C4.5決策樹算法不直接使用信息增益,而是使用「增益率」來選擇最優劃分屬性,增益率定義爲性能
屬性a的可能取值數目越多(即V越大),則IV(a)的值一般會越大。須要注意的是,增益率準則對可取值數目較少的屬性有所偏好,所以C4.5算法並非直接選擇增益率最大的候選劃分屬性,而是使用了一個啓發性:先從候選劃分屬性中找出信息增益高於平均水平的屬性,再從中選擇增益率最高的。學習
CART決策樹選擇劃分屬性。數據集D的純度能夠用基尼指數來度量測試
所以,Gini(D)越小,則數據集D的純度越高spa
剪枝是決策樹學習算法對付「過擬合」的主要手段。在決策樹學習中,爲了儘量正確分類樣本,節點劃分過程不斷重複,有時會形成決策樹分支過多,這時有時候把自身特色當作全部數據都具備的通常性質而致使過擬合,所以,能夠經過主動去掉一些分支來下降過擬合的風險命令行
基本策略有預剪枝和後剪枝,預剪枝是指在決策樹生成過程當中,對每一個節點在劃分前先進行估計,若當前節點的劃分不能帶來決策樹泛化性能的提高,則中止劃分當前節點標記爲葉節點;後剪枝則是先從訓練集生成一顆完整的決策樹,而後自底向上地對非葉節點進行考察,若將該節點對應的字數替換爲葉節點能帶來決策樹泛化性能提高,則將該子樹替換爲葉節點。3d
另外,決策樹所造成的分類邊界有一個明顯的特色:軸平行,即它的分類邊界有若干個與座標軸平行的分段組成。code
下面的代碼就是在咱們熟知的鳶尾花數據集上進行一個決策樹分類器的訓練
決策樹的衆多特性之一就是, 它不須要太多的數據預處理, 尤爲是不須要進行特徵的縮放或者歸一化。
from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier iris = load_iris() X = iris.data[:, 2:] # petal length and width y = iris.target tree_clf = DecisionTreeClassifier(max_depth=2) tree_clf.fit(X, y)
你能夠經過使用export_graphviz()方法,經過生成一個叫作iris_tree.dot的圖形定義文件將一個訓練好的決策樹模型可視化
from sklearn.tree import export_graphviz export_graphviz( tree_clf, out_file=image_path("iris_tree.dot"), feature_names=iris.feature_names[2:], class_names=iris.target_names, rounded=True, filled=True )
而後,咱們能夠利用graphviz package 中的dot命令行,將.dot文件轉換成 PDF 或 PNG 等多種數據格式。例如,使用命令行將.dot文件轉換成.png文件的命令以下:
Graphviz是一款開源圖形可視化軟件包, http://www.graphviz.org/
$ dot -Tpng iris_tree.dot -o iris_tree.png
咱們的第一個決策樹如圖
節點的samples屬性統計出它應用於多少個訓練樣本實例,例如,咱們有一百個訓練實例是花瓣長度大於 2.45 裏面的(深度爲 1, 右側),在這 100 個樣例中又有 54 個花瓣寬度小於 1.75cm(深度爲 2,左側);節點的value屬性告訴你這個節點對於每個類別的樣例有多少個,例如:右下角的節點中包含 0 個 Iris-Setosa,1 個 Iris-Versicolor 和 45 個 Iris-Virginica;最後,節點的Gini屬性用於測量它的純度:若是一個節點包含的全部訓練樣例全都是同一類別的,咱們就說這個節點是純的(Gini=0)
下面公式顯示了訓練算法如何計算第i個節點的 gini 分數 。例如, 深度爲 2 的左側節點基尼指數爲:
$$G_i=\sum_{k=1}^nP_{i,k}^2$$
$p_{i,k}$ 是第i個節點中訓練實例爲的k類實例的比例
Scikit-Learn 用的是 CART 算法, CART 算法僅產生二叉樹:每個非葉節點老是隻有兩個子節點(只有是或否兩個結果)。然而,像 ID3 這樣的算法能夠產生超過兩個子節點的決策樹模型
下圖顯示了決策樹的決策邊界。粗的垂直線表明根節點(深度爲 0)的決定邊界:花瓣長度爲 2.45 釐米。因爲左側區域是純的(只有 Iris-Setosa),因此不能再進一步分裂。然而,右邊的區域是不純的,因此深度爲 1 的右邊節點在花瓣寬度爲 1.75 釐米處分裂(用虛線表示)。又因爲max_depth設置爲 2,決策樹在那裏停了下來。可是,若是將max_depth設置爲 3,兩個深度爲 2 的節點,每一個都將會添加另外一個決策邊界(用虛線表示)
決策樹還能夠估計某個實例屬於特定類k的機率:首先遍歷樹來查找此實例的葉節點,而後它返回此節點中類k的訓練實例的比例。
例如,假設你發現了一個花瓣長 5 釐米,寬 1.5 釐米的花朵。相應的葉節點是深度爲 2 的左節點,所以決策樹應該輸出如下機率:Iris-Setosa 爲 0%(0/54),Iris-Versicolor 爲 90.7%(49/54),Iris-Virginica 爲 9.3%(5/54)。固然,若是你要求它預測具體的類,它應該輸出 Iris-Versicolor(類別 1),由於它具備最高的機率。咱們了測試一下
>>> tree_clf.predict_proba([[5, 1.5]]) array([[ 0. , 0.90740741, 0.09259259]]) >>> tree_clf.predict([[5, 1.5]]) array([1])
Scikit-Learn 用分裂迴歸樹(Classification And Regression Tree,簡稱 CART)算法訓練決策樹(也叫「增加樹」)。這種算法思想真的很是簡單:
首先使用單個特徵k和閾值$t_k$ (例如,「花瓣長度≤2.45cm」)將訓練集分紅兩個子集。它如何選擇k和$t_k$ 呢?它尋找到可以產生最純粹的子集一對(k,$t_k$) ,而後經過子集大小加權計算.
算法會嘗試最小化成本函數。方法如公式
當它成功的將訓練集分紅兩部分以後, 它將會繼續使用相同的遞歸式邏輯繼續的分割子集,而後是子集的子集。當達到預約的最大深度以後將會中止分裂(由max_depth超參數決定),或者是它找不到能夠繼續下降不純度的分裂方法的時候。幾個其餘超參數(以後介紹)控制了其餘的中止生長條件(min_samples_split,min_samples_leaf,min_weight_fraction_leaf,max_leaf_nodes)。
正如您所看到的,CART 算法是一種貪婪算法:它貪婪地搜索最高級別的最佳分割方式,而後在每一個深度重複該過程。 它不檢查分割是否可以在幾個級別中的所有分割可能中找到最佳方法。貪婪算法一般會產生一個至關好的解決方法,但它不保證這是全局中的最佳解決方案
在創建好決策樹模型後, 作出預測須要遍歷決策樹, 從根節點一直到葉節點。決策樹一般近似左右平衡,所以遍歷決策樹須要經歷大體 O(log_2^m) 個節點。因爲每一個節點只須要檢查一個特徵的值,所以整體預測複雜度僅爲O(log_2^m) ,與特徵的數量無關。 因此即便在處理大型訓練集時,預測速度也很是快.
然而,訓練算法的時候(訓練和預測不一樣)須要比較全部特徵(若是設置了max_features會更少一些)
在每一個節點的全部樣本上。就有了O(nmlog_2^m) 的訓練複雜度。對於小型訓練集(少於幾千例),Scikit-Learn 能夠經過預先設置數據(presort = True)來加速訓練,可是這對於較大訓練集來講會顯着減慢訓練速度。
一般,算法使用 Gini 不純度來進行檢測, 可是你也能夠經過將標準超參數設置爲"entropy"來使用熵不純度進行檢測。這裏熵的概念是源於熱力學中分子混亂程度的概念,當分子井井有理的時候,熵值接近於 0
那麼咱們到底應該使用 Gini 指數仍是熵(ID3,C4.5決策樹)呢? 事實上大部分狀況都沒有多大的差異:他們會生成相似的決策樹。 基尼指數計算稍微快一點,因此這是一個很好的默認值。可是,也有的時候它們會產生不一樣的樹,基尼指數會趨於在樹的分支中將最多的類隔離出來,而熵指數趨向於產生略微平衡一些的決策樹模型。
決策樹幾乎不對訓練數據作任何假設(於此相反的是線性迴歸等模型,這類模型一般會假設數據是符合線性關係的)。
若是不添加約束,樹結構模型一般將根據訓練數據調整本身,使自身可以很好的擬合數據,而這種狀況下大多數會致使模型過擬合。
這一類的模型一般會被稱爲非參數模型,這不是由於它沒有任何參數(一般也有不少),而是由於在訓練以前沒有肯定參數的具體數量,因此模型結構能夠根據數據的特性自由生長。
DecisionTreeClassifier類還有一些其餘的參數用於限制樹模型的形狀:
min_samples_split(節點在被分裂以前必須具備的最小樣本數),min_samples_leaf(葉節點必須具備的最小樣本數),min_weight_fraction_leaf(和min_samples_leaf相同,但表示爲加權總數的一小部分實例),max_leaf_nodes(葉節點的最大數量)和max_features(在每一個節點被評估是否分裂的時候,具備的最大特徵數量)。增長min_ hyperparameters或者減小max_ hyperparameters會使模型正則化預剪枝與後剪枝
下圖顯示了對moons數據集進行訓練生成的兩個決策樹模型,左側的圖形對應的決策樹使用默認超參數生成(沒有限制生長條件),右邊的決策樹模型設置爲min_samples_leaf=4。很明顯,左邊的模型過擬合了,而右邊的模型泛用性更好。
決策樹也可以執行迴歸任務,讓咱們使用 Scikit-Learn 的DecisionTreeRegressor類構建一個迴歸樹,讓咱們用max_depth = 2在具備噪聲的二次項數據集上進行訓練。
from sklearn.tree import DecisionTreeRegressor tree_reg = DecisionTreeRegressor(max_depth=2) tree_reg.fit(X, y)
結果如圖:
這棵樹看起來很是相似於你以前創建的分類樹,它的主要區別在於,它不是預測每一個節點中的樣本所屬的分類,而是預測一個具體的數值。例如,假設您想對 的新實例進行預測。從根開始遍歷樹,最終到達預測值等於 0.1106 的葉節點。該預測僅僅是與該葉節點相關的 110 個訓練實例的平均目標值。而這個預測結果在對應的 110 個實例上的均方偏差(MSE)等於 0.0151
下圖的左側顯示的是模型的預測結果,若是你將max_depth=3設置爲 3,模型就會如 6-5 圖右側顯示的那樣.注意每一個區域的預測值老是該區域中實例的平均目標值。算法以一種使大多數訓練實例儘量接近該預測值的方式分割每一個區域。
譯者注:圖裏面的紅線就是訓練實例的平均目標值,對應上圖中的value
CART 算法的工做方式與以前處理分類模型基本同樣,不一樣之處在於,如今再也不以最小化不純度的方式分割訓練集,而是試圖以最小化 MSE 的方式分割訓練集
下面公式顯示了成本函數,該算法試圖最小化這個成本函數。
和處理分類任務時同樣,決策樹在處理迴歸問題的時候也容易過擬合。若是不添加任何正則化(默認的超參數),你就會獲得圖 6-6 左側的預測結果,顯然,過分擬合的程度很是嚴重。而當咱們設置了min_samples_leaf = 10,相對就會產生一個更加合適的模型了,就如圖 6-6 所示的那樣
它很容易理解和解釋,易於使用且功能豐富而強大。然而,它也有一些限制,首先,你可能已經注意到了,決策樹很喜歡設定正交化的決策邊界,(全部邊界都是和某一個軸相垂直的),這使得它對訓練數據集的旋轉很敏感,例如圖 6-7 顯示了一個簡單的線性可分數據集。在左圖中,決策樹能夠輕易的將數據分隔開,可是在右圖中,當咱們把數據旋轉了 45° 以後,決策樹的邊界看起來變的格外複雜。儘管兩個決策樹都完美的擬合了訓練數據,右邊模型的泛化能力極可能很是差。
解決這個難題的一種方式是使用 PCA 主成分分析,這樣一般能使訓練結果變得更好一些。
更加通俗的講,決策時的主要問題是它對訓練數據的微小變化很是敏感,舉例來講,咱們僅僅從鳶尾花訓練數據中將最寬的 Iris-Versicolor 拿掉(花瓣長 4.8 釐米,寬 1.8 釐米),而後從新訓練決策樹模型,你可能就會獲得圖 6-8 中的模型。正如咱們看到的那樣,決策樹有了很是大的變化(原來的如圖 6-2),事實上,因爲 Scikit-Learn 的訓練算法是很是隨機的,即便是相同的訓練數據你也可能獲得差異很大的模型(除非你設置了隨機數種子)