簡介
決策樹是廣泛用於分類和回歸任務的監督模型。 在本文中,我們將討論決策樹分類器以及如何動態可視化它們。 這些分類器在訓練數據上構建一系列簡單的if / else規則,通過它們預測目標值。
在本演示中,我們將使用sklearn_wine數據集,使用sklearn export_graphviz函數,我們可以在Jupyter中顯示樹。
from sklearn.tree import DecisionTreeClassifier, export_graphviz from sklearn import tree from sklearn.datasets import load_wine from IPython.display import SVG from graphviz import Source from IPython.display import display # load dataset data = load_wine() # feature matrix X = data.data # target vector y = data.target # class labels labels = data.feature_names # print dataset description print(data.DESCR) estimator = DecisionTreeClassifier() estimator.fit(X, y) graph = Source(tree.export_graphviz(estimator, out_file=None , feature_names=labels, class_names=['0', '1', '2'] , filled = True)) display(SVG(graph.pipe(format='svg')))
在樹形圖中,每個節點包含分割數據的條件(if / else規則)以及節點的一系列其他度量。基尼是指基尼雜質,它是節點雜質的量度,即節點內樣品的均勻程度。我們說當一個節點的所有樣本屬於同一個類時它是純粹的。在這種情況下,不需要進一步拆分,這個節點稱為葉子。 Samples是節點中的實例數,而value數組顯示每個類的這些實例的分布。在底部,我們看到節點的多數類。當export_graphviz的填充選項設置為True時,每個節點將根據多數類進行着色。
雖然易於理解,但通過構建復雜模型,決策樹往往會過度擬合數據。過度擬合的模型很可能不會在“看不見的”數據中很好地概括。防止過度擬合的兩種主要方法是修剪前和修剪后。預修剪意味着在創建之前限制樹的深度,而后修剪是在樹構建之后移除非信息節點。
Sklearn學習決策樹分類器僅實現預修剪。可以通過若干參數來控制預修剪,例如樹的最大深度,節點保持分裂所需的最小樣本數以及葉所需的最小實例數。下面,我們在相同的數據上繪制決策樹,這次設置max_depth = 3。
這個模型不太深,因此比我們最初訓練和繪制的模型簡單。
除了預修剪參數之外,決策樹還有一系列其他參數,我們在構建分類模型時嘗試優化這些參數。 我們通常通過查看准確度指標來評估這些參數的影響。 為了掌握參數的變化如何影響樹的結構,我們可以再次在每個階段可視化樹。 我們可以使用Jupyter Widgets(ipywidgets)來構建我們樹的交互式繪圖,而不是每次進行更改時都繪制樹。
Jupyter小部件是交互式元素,允許我們在筆記本中呈現控件。 通過pip和conda安裝ipywidgets有兩種選擇。
用pip安裝
pip install ipywidgets
jupyter nbextension enable --py widgetsnbextension
用conda安裝
conda install -c conda-forge ipywidgets
對於此應用程序,我們將使用交互式功能。 首先,我們定義一個訓練和繪制決策樹的函數。 然后,我們將此函數與針對交互式函數感興趣的每個參數的一組值一起傳遞。 后者返回我們用display顯示的Widget實例。
from sklearn.tree import DecisionTreeClassifier, export_graphviz from sklearn import tree from sklearn.datasets import load_wine from IPython.display import SVG from graphviz import Source from IPython.display import display from ipywidgets import interactive # load dataset data = load_wine() # feature matrix X = data.data # target vector y = data.target # class labels labels = data.feature_names def plot_tree(crit, split, depth, min_split, min_leaf=0.2): estimator = DecisionTreeClassifier(random_state = 0 , criterion = crit , splitter = split , max_depth = depth , min_samples_split=min_split , min_samples_leaf=min_leaf) estimator.fit(X, y) graph = Source(tree.export_graphviz(estimator , out_file=None , feature_names=labels , class_names=['0', '1', '2'] , filled = True)) display(SVG(graph.pipe(format='svg'))) return estimator inter=interactive(plot_tree , crit = ["gini", "entropy"] , split = ["best", "random"] , depth=[1,2,3,4] , min_split=(0.1,1) , min_leaf=(0.1,0.5)) display(inter)
在此示例中,我們公開以下參數:
- criterion:衡量節點分裂質量的標准
- splitter:每個節點的拆分策略
- max_depth:樹的最大深度
- min_samples_split:節點中所需的最小實例數
- min_samples_leaf:葉節點上所需的最小實例數
最后兩個參數可以設置為整數或浮點數。 浮點數被解釋為實例總數的百分比。 有關參數的更多詳細信息,請閱讀sklearn類文檔。