1.10. Decision Trees
決策樹(Decision Trees ,DTs)是一種無監督的學習方法,用於分類和回歸。它對數據中蘊含的決策規則建模,以預測目標變量的值。
某些情況,例如下面的例子,決策樹通過學習模擬一個包含一系列是否判斷的正弦曲線。樹越深,決策樹的規則和擬合越復雜。
決策樹的一些優點:
- 易於理解和解釋。數可以可視化。
- 幾乎不需要數據預處理。其他方法經常需要數據標准化,創建虛擬變量和刪除缺失值。決策樹還不支持缺失值。
- 使用樹的花費(例如預測數據)是訓練數據點(data points)數量的對數。
- 可以同時處理數值變量和分類變量。其他方法大都適用於分析一種變量的集合。
- 可以處理多值輸出變量問題。
- 使用白盒模型。如果一個情況被觀察到,使用邏輯判斷容易表示這種規則。相反,如果是黑盒模型(例如人工神經網絡),結果會非常難解釋。
- 可以使用統計檢驗檢驗模型。這樣做被認為是提高模型的可行度。
- 即使對真實模型來說,假設無效的情況下,也可以較好的適用。
決策樹的一些缺點:
- 決策樹學習可能創建一個過於復雜的樹,並不能很好的預測數據。也就是過擬合。修剪機制(現在不支持),設置一個葉子節點需要的最小樣本數量,或者數的最大深度,可以避免過擬合。
- 決策樹可能是不穩定的,因為即使非常小的變異,可能會產生一顆完全不同的樹。這個問題通過decision trees with an ensemble來緩解。
- 學習一顆最優的決策樹是一個NP-完全問題under several aspects of optimality and even for simple concepts。因此,傳統決策樹算法基於啟發式算法,例如貪婪算法,即每個節點創建最優決策。這些算法不能產生一個全家最優的決策樹。對樣本和特征隨機抽樣可以降低整體效果偏差。
- 概念難以學習,因為決策樹沒有很好的解釋他們,例如,XOR, parity or multiplexer problems.
- 如果某些分類占優勢,決策樹將會創建一棵有偏差的樹。因此,建議在訓練之前,先抽樣使樣本均衡。
1.10.1. Classification
DecisionTreeClassifier 能夠對數據進行多分類的類。
和其他分類器一樣,DecisionTreeClassifier 有兩個向量輸入:X,稀疏或密集,大小為[n_sample,n_fearure],存放訓練樣本; Y,值為整型,大小為[n_sample],存放訓練樣本的分類標簽:
>>> 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,1,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 格式。下面是導出 iris 數據集訓練樹的例子。
>>> from sklearn.externals.six import StringIO >>> with open("iris.dot", 'w') as f: ... f = tree.export_graphviz(clf, out_file=f)
然后用 Graphviz的 dot 工具創建PDF文件(或者其他支持的文件格式):dot -Tpdf iris.dot -o iris.pdf.
>>> import os >>> os.unlink('iris.dot')
或者,如果安裝了pydot 模塊,可以直接用Python創建PDF文件(或者其他支持文件):
>>> from sklearn.externals.six import StringIO >>> import pydot >>> dot_data = StringIO() >>> tree.export_graphviz(clf, out_file=dot_data) >>> graph = pydot.graph_from_dot_data(dot_data.getvalue()) >>> graph.write_pdf("iris.pdf")
export_graphviz 也支持很多美觀選項,包括根據節點的分類(或者擬合的值)着色和根據需要描述變量和分類。 IPython notebooks can also render these plots inline using the Image() function:
>>> from IPython.display import Image >>> dot_data = StringIO() >>> tree.export_graphviz(clf, out_file=dot_data, feature_names=iris.feature_names, class_names=iris.target_names, filled=True, rounded=True, special_characters=True) >>> graph = pydot.graph_from_dot_data(dot_data.getvalue()) >>> Image(graph.create_png())
擬合之后,模型可以用來樣本分類:
>>> clf.predict(iris.data[:1, :])
array([0])
或者,每個分類的概率能被預測,即某個葉子中,該分類樣本的占比。
>>> clf.predict_proba(iris.data[:1, :])
array([[ 1., 0., 0.]])
Examples:
1.10.2. Regression
決策樹也可用來解決回歸問題,使用 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])
Examples:
1.10.3. Multi-output problems
多輸出問題是預測多個輸出的監督學習過程,也就是說,y是大小為[n_sample, n_output]的二維向量。
當輸出變量之間不相關是,一個非常簡單的解決辦法是
啊啊啊啊