1. 程式人生 > >skiti-learn決策樹演算法庫

skiti-learn決策樹演算法庫

skiti-learn內部實現的是調優過的CART決策樹。既可以做分類,也可以做迴歸。分類決策樹採用的類是DecisionTreeClassifier,迴歸則是DecisionTreeRegressor。

  1. DecisionTreeClassifier and DecisionTreeRegressor重要引數調參
    1).特徵選擇標準criterion:
    DecisionTreeClassifier:可以使用‘gini’(基尼指數),或者‘entropy’(資訊增益),一般使用預設的基尼指數‘gini’,(CART演算法)。
    DecisionTreeRegressor:可以使用‘mse’(均方差),或者‘mae’(和均值之差的絕對值之和),推薦使用預設的‘mse’。一般來說‘mse’比‘mae’更精確。
    2).特徵劃分點選擇標準splitter:
    可以使用‘best’(在所有劃分點中找出最優劃分點),或者‘random’(隨機部分劃分點中找到區域性最優劃分點)。預設的‘best’適合樣本量不大時,樣本量非常大時,推薦‘random’
    3).劃分時考慮的最大特徵數max_features:
    預設的‘None’,意味著劃分時考慮所有特徵數;‘log2’意味劃分最多考慮log2N個特徵;‘sqrt’或者‘auto’劃分時最多考慮√N個特徵;如果是整數,代表考慮特徵的絕對數;如果是浮點數,代表考慮特徵的百分比,即考慮百分比*N取整後的特徵值。特徵數不多,比如小於50,可以採用預設的‘None’,如果特徵數特別多,可以靈活採用其他引數來控制劃分時考慮最大特徵數,以控制決策樹生成的時間。
    4).決策樹最大深max_depth:
    決策樹的最大深度,預設可以不輸入。資料少或者特徵少的情況下,不去管這個值。如果樣本和特徵數量都多的情況下,推薦限制這個深度,具體取值取決於資料的分佈,常用取值10-100之間。
    5).內部結點再劃分所需的最小樣本數min_simples_split:
    這個值限制了子樹繼續劃分的條件,如果某結點的樣本數少於min_simples_split則不會繼續選擇最優特徵進行劃分。預設為2,如果樣本量不大,不需管這個值。樣本數量非常大則推薦增大這個值。
    6).葉子節點最少的樣本數min_simples_leaf:
    這個值限制了葉子節點最少的樣本數,如果葉子節點數目小於樣本數,則會和兄弟節點一起被剪枝。預設是1,可以輸入最少的樣本數的整數,或者最少樣本數佔樣本總數的百分比。如果樣本量不大,不需要管這個值。如果樣本量數量級非常大,則推薦增大這個值。
    7).葉子節點最小的樣本權重和min_weight_fraction_leaf:
    這個值限制了葉子節點所有樣本權重和的最小值,如果小於這個值,則會和兄弟節點一起被剪枝。 預設是0,就是不考慮權重問題。一般來說,如果我們有較多樣本有缺失值,或者分類樹樣本的分佈類別偏差很大,就會引入樣本權重,這時我們就要注意這個值了。
    8).最大葉子節點數max_leaf_nodes:
    通過限制最大葉子節點數,可以防止過擬合,預設是"None”,即不限制最大的葉子節點數。如果加了限制,演算法會建立在最大葉子節點數內最優的決策樹。如果特徵不多,可以不考慮這個值,但是如果特徵分成多的話,可以加以限制,具體的值可以通過交叉驗證得到。
    9).型別權重class_weight:
    DecisionTreeClassifier:指定樣本各類別的權重,防止訓練集某些樣本過多,導致訓練的決策樹過於偏向於這些類別。我們可以指定類別的權重,或者用‘balance’(自動計算樣本的權重,樣本少的權重會高),如果樣本沒有明顯的偏倚,可以不管這個引數,選擇預設的‘None’。
    DecisionTreeRegressor:不適用於迴歸樹。
    10).節點劃分最小不純度 min_impurity_split:
    這個值限制了決策樹的增長,當某節點的不純度(基尼指數,資訊增益,均方差,絕對差)小於某個閾值,則不再生成子節點。
    11).資料是否預排序presort:
    這個值是布林值,預設是False不排序。一般來說,如果樣本量少或者限制了一個深度很小的決策樹,設定為true可以讓劃分點選擇更加快,決策樹建立的更加快。如果樣本量太大的話,反而沒有什麼好處。問題是樣本量少的時候,速度本來就不慢。
  2. 調參注意點:
    1)當樣本少數量但是樣本特徵非常多的時候,決策樹很容易過擬合,一般來說,樣本數比特徵數多一些會比較容易建立健壯的模型
    2)如果樣本數量少但是樣本特徵非常多,在擬合決策樹模型前,推薦先做維度規約,比如主成分分析(PCA),特徵選擇(Losso)或者獨立成分分析(ICA)。這樣特徵的維度會大大減小。再來擬合決策樹模型效果會好。
    3)推薦多用決策樹的視覺化,同時先限制決策樹的深度(比如最多3層),這樣可以先觀察下生成的決策樹裡資料的初步擬合情況,然後再決定是否要增加深度。
    4)在訓練模型先,注意觀察樣本的類別情況(主要指分類樹),如果類別分佈非常不均勻,就要考慮用class_weight來限制模型過於偏向樣本多的類別。
    5)決策樹的陣列使用的是numpy的float32型別,如果訓練資料不是這樣的格式,演算法會先做copy再執行。
    6)如果輸入的樣本矩陣是稀疏的,推薦在擬合前呼叫csc_matrix稀疏化,在預測前呼叫csr_matrix稀疏化。
  3. 決策樹結果的視覺化
    skiti-learn決策樹的視覺化一般需要安裝graphviz。
    視覺化的三種方法:
    第一種是用graphviz的dot命令生成決策樹的視覺化檔案,敲完這個命令後當前目錄就可以看到決策樹的視覺化檔案iris.pdf.開啟可以看到決策樹的模型圖。
from sklearn.datasets import load_iris
from sklearn import tree
import sys
import os
os.environ["PATH"]+=os.pathsep+'C:/Program Files (x86)/Graphviz2.38/bin/'


iris=load_iris()
clf=tree.DecisionTreeClassifier()
clf=clf.fit(iris.data,iris.target)

with open("iris.dot",'w') as f:
	f=tree.export_graphviz(clf,out_file=f)


#注意,這個命令在命令列執行
dot -Tpdf iris.dot -o iris.pdf

第二種方法是用pydotplus生成iris.pdf

import pydotplus
dot_data=tree.export_graphviz(clf,out_file-None)
graph=pydotplus.graph_from_dot_data(dot_data)
graph.write_pdf("iris.pdf")

第三種辦法是個人比較推薦的做法,因為這樣可以直接把圖產生在ipython的notebook。

from  Ipython.display import Image
dot_data=tree.export_graphviz(clf, out_file=None,
				feature_names=iris.feature_names,
				class_name=iris.target_names,
				filled=True,rounded=True,
				special_characters=True)
graph=pydotplus.graph_from_dot_data(dot_data)
Image(graph.create_png())

DecisionTreeClassifier例項

from itertools import product

import numpy as np
import matplotlib.pyplot as plt

from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier


# 仍然使用自帶的iris資料
iris = datasets.load_iris()
X = iris.data[:, [0, 2]]
y = iris.target

# 訓練模型,限制樹的最大深度4
clf = DecisionTreeClassifier(max_depth=4)
#擬合模型
clf.fit(X, y)


# 畫圖
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1),
                     np.arange(y_min, y_max, 0.1))

Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8)
plt.show()



#視覺化我們的決策樹,使用了第三種方法
from IPython.display import Image  
from sklearn import tree
import pydotplus 
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 = pydotplus.graph_from_dot_data(dot_data)  
Image(graph.create_png())