Scikit-learn中的決策樹

寫在之前

想看程序參數(shù)說明的請到:

正文部分

決策樹是一個非參數(shù)的監(jiān)督式學(xué)習(xí)方法,主要用于分類和回歸饲齐。算法的目標(biāo)是通過推斷數(shù)據(jù)特征诫隅,學(xué)習(xí)決策規(guī)則從而創(chuàng)建一個預(yù)測目標(biāo)變量的模型腐魂。如下如所示,決策樹通過一系列if-then-else 決策規(guī)則 近似估計一個正弦曲線逐纬。

../_images/sphx_glr_plot_tree_regression_0011.png

決策樹優(yōu)勢:

  • 簡單易懂蛔屹,原理清晰,決策樹可以實現(xiàn)可視化
  • 數(shù)據(jù)準(zhǔn)備簡單豁生。其他的方法需要實現(xiàn)數(shù)據(jù)歸一化兔毒,創(chuàng)建虛擬變量,刪除空白變量甸箱。(注意:這個模塊不支持缺失值)
  • 使用決策樹的代價是數(shù)據(jù)點的對數(shù)級別育叁。
  • 能夠處理數(shù)值和分類數(shù)據(jù)
  • 能夠處理多路輸出問題
  • 使用白盒子模型(內(nèi)部結(jié)構(gòu)可以直接觀測的模型)。一個給定的情況是可以觀測的摇肌,那么就可以用布爾邏輯解釋這個結(jié)果擂红。相反,如果在一個黑盒模型(ANN)围小,結(jié)果可能很難解釋
  • 可以通過統(tǒng)計學(xué)檢驗驗證模型昵骤。這也使得模型的可靠性計算變得可能
  • 即使模型假設(shè)違反產(chǎn)生數(shù)據(jù)的真實模型,表現(xiàn)性能依舊很好肯适。

決策樹劣勢:

  • 可能會建立過于復(fù)雜的規(guī)則变秦,即過擬合。為避免這個問題框舔,剪枝蹦玫、設(shè)置葉節(jié)點的最小樣本數(shù)量、設(shè)置決策樹的最大深度有時候是必要的刘绣。
  • 決策樹有時候是不穩(wěn)定的樱溉,因為數(shù)據(jù)微小的變動,可能生成完全不同的決策樹纬凤。 可以通過總體平均(ensemble)減緩這個問題福贞。應(yīng)該指的是多次實驗。
  • 學(xué)習(xí)最優(yōu)決策樹是一個NP完全問題停士。所以挖帘,實際決策樹學(xué)習(xí)算法是基于試探性算法完丽,例如在每個節(jié)點實現(xiàn)局部最優(yōu)值的貪心算法。這樣的算法是無法保證返回一個全局最優(yōu)的決策樹拇舀÷咦澹可以通過隨機(jī)選擇特征和樣本訓(xùn)練多個決策樹來緩解這個問題。
  • 有些問題學(xué)習(xí)起來非常難骄崩,因為決策樹很難表達(dá)聘鳞。如:異或問題、奇偶校驗或多路復(fù)用器問題
  • 如果有些因素占據(jù)支配地位要拂,決策樹是有偏的搁痛。因此建議在擬合決策樹之前先平衡數(shù)據(jù)的影響因子。

分類

DecisionTreeClassifier 能夠?qū)崿F(xiàn)多類別的分類宇弛。輸入兩個向量:向量X,大小為[n_samples,n_features]源请,用于記錄訓(xùn)練樣本枪芒;向量Y,大小為[n_samples]谁尸,用于存儲訓(xùn)練樣本的類標(biāo)簽舅踪。

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

clf.predict([[2., 2.]])
clf.predict_proba([[2., 2.]])       #計算屬于每個類的概率

能夠?qū)崿F(xiàn)二進(jìn)制分類和多分類。使用Isis數(shù)據(jù)集良蛮,有:

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

# export the tree in Graphviz format using the export_graphviz exporter
with open("iris.dot", 'w') as f:
    f = tree.export_graphviz(clf, out_file=f)
    
# predict the class of samples
clf.predict(iris.data[:1, :])
# the probability of each class
clf.predict_proba(iris.data[:1, :])

安裝Graphviz將其添加到環(huán)境變量抽碌,使用dot創(chuàng)建一個PDF文件。dot -Tpdf iris.dot -o iris.pdf

# 刪除dot文件
import os
os.unlink('iris.dot')

如果安裝了pydotplus决瞳,也可以在Python中直接生成:

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

可以根據(jù)不同的類別輸出不同的顏色货徙,也可以指定類別名字。

from IPython.display import Image  
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()) 
../_images/iris.svg
../_images/iris.svg

更多地可以看到分類的效果:

../_images/sphx_glr_plot_iris_0013.png

回歸

和分類不同的是向量y可以是浮點數(shù)皮胡。

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]])

本文前面提到的例子:http://scikit-learn.org/stable/auto_examples/tree/plot_tree_regression.html#sphx-glr-auto-examples-tree-plot-tree-regression-py

# Import the necessary modules and libraries
import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt

# Create a random dataset
rng = np.random.RandomState(1)
X = np.sort(5 * rng.rand(80, 1), axis=0)
y = np.sin(X).ravel()
y[::5] += 3 * (0.5 - rng.rand(16))

# Fit regression model
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)

# Predict
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)

# Plot the results
plt.figure()
plt.scatter(X, y, c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue", label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()

多輸出問題

多輸出問題時需要預(yù)測多個輸出的監(jiān)督式學(xué)習(xí)問題痴颊。即Y是一個2d的向量,大小為[n_samples, n_outputs]屡贺。

當(dāng)輸出之間不相關(guān)時蠢棱,一個簡單的解決辦法是建立n個獨立模型。對于每一個輸出甩栈,使用這些模型獨立預(yù)測這每個輸出泻仙。由于輸出是和相同的輸入相關(guān)的,所以一個更好的辦法是建立一個能夠持續(xù)預(yù)測所有輸出的單一模型量没。首先玉转,系統(tǒng)需要的訓(xùn)練時間更少了,因為只建立了一個模型允蜈。其次準(zhǔn)確性也會得到提高冤吨。

決策樹的策略需要修改以支持多分類問題蒿柳。

  • 葉子上存儲n個輸出變量
  • 使用不同的標(biāo)準(zhǔn)計算所有n輸出的平均減少

這一節(jié)是關(guān)于 DecisionTreeClassifierDecisionTreeRegressor的一些知識點。如果一個決策樹的輸出向量Y大小為[n_samples, n_outputs]漩蟆,預(yù)測量有:

  • predict:輸出n個預(yù)測值
  • predict_proba:輸出有n個輸出的向量組成的列表垒探。

多輸出的回歸的例子:輸入X是一個單一的值,輸出Y是輸入X的Sine和Cosine怠李。

Multi-output Decision Tree Regression

../_images/sphx_glr_plot_tree_regression_multioutput_0011.png

多輸出的分類的例子:Face completion with a multi-output estimators

輸入X是上半臉的像素圾叼,輸出Y是下半臉的像素。

../_images/sphx_glr_plot_multioutput_face_completion_0011.png

參考文獻(xiàn):

復(fù)雜度

通常生成一個二進(jìn)制樹運(yùn)行時間為

查詢時間為
雖然構(gòu)建的算法意圖建立一個均衡的樹捺癞,但是不總是均衡的夷蚊。假設(shè)子樹保持均衡,每個節(jié)點的消耗為
以查找使熵最大減少的特征髓介。每個節(jié)點的消耗為

惕鼓,使得整個樹的消耗為

Scikit-learn提供了建立決策樹的一種更加高效的實現(xiàn)。簡單的實現(xiàn)唐础,在每次劃分時箱歧,將會重新計算類標(biāo)簽的直方圖(分類)或者均值(回歸)。將所有相關(guān)樣本特征預(yù)分類保留標(biāo)簽計數(shù)一膨,將每個節(jié)點的復(fù)雜度減少為

呀邢,同時將整體復(fù)雜度減少為
。默認(rèn)是開啟的豹绪,一般來說會使得訓(xùn)練更快价淌,但是如果關(guān)閉,則訓(xùn)練深層決策樹的時候訓(xùn)練會變慢瞒津。

使用小貼士

  • 如果數(shù)據(jù)量大蝉衣,決策樹容易過擬合。樣本和特征的比例非常重要仲智。如果決策樹樣本少买乃,特征多,非车隽荆可能過擬合剪验。
  • 可以考慮事先做維度約減(PCA,ICA)前联,以產(chǎn)生一個特征之間區(qū)別性大的決策樹
  • 通過export將你的訓(xùn)練的決策樹可視化功戚,使用max_depth =3作為一個初始的樹的深度,有一個數(shù)據(jù)擬合決策樹模型的大概感覺似嗤,然后逐漸增加深度
  • 數(shù)據(jù)的樣本量的增加將加深決策樹的深度啸臀,使用max_depth控制決策樹的尺寸以防止過擬合
  • 使用min_samples_split 或者 min_samples_leaf來控制葉節(jié)點的樣本數(shù)量。一個非常小的數(shù)量往往意味著過擬合,而一個較大的數(shù)可以防止過擬合乘粒⊥阕ⅲ可以將min_samples_leaf=5作為一個初始值。如果樣本數(shù)據(jù)變化巨大灯萍,可以采用一個浮點數(shù)轧铁。兩者的區(qū)別在于min_samples_leaf保證了葉節(jié)點最小的數(shù)量,min_samples_split能夠建立任意數(shù)量的葉子節(jié)點旦棉,在文學(xué)上用到也更多
  • 如果樣本是有權(quán)重的齿风,可以使用min_weight_fraction_leaf來實現(xiàn)基于權(quán)重的預(yù)修剪規(guī)則來優(yōu)化決策樹結(jié)構(gòu)
  • 決策樹內(nèi)部使用np.float32向量,如果樣本不是這個形式的绑洛,將產(chǎn)生一個數(shù)據(jù)集的樣本
  • 如果數(shù)據(jù)矩陣X是非常稀疏的剂娄,建議在擬合和預(yù)測之前轉(zhuǎn)換為稀疏矩陣csc_matrix甸鸟。稀疏矩陣將比稠密矩陣快數(shù)量級的速度

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

ID3是由Ross Quinlan在1985年建立的。這個方法建立多路決策樹幼苛,并找到最大的信息增益废登。當(dāng)樹長到最大的尺寸咽弦,經(jīng)常應(yīng)用剪枝來提高決策樹對未知數(shù)據(jù)的一般化势木。

C4.5是ID3的進(jìn)一步延伸易猫,通過將連續(xù)屬性離散化,去除了特征的限制晾匠。C4.5將訓(xùn)練樹轉(zhuǎn)換為一系列if-then的語法規(guī)則√莞眨可確定這些規(guī)則的準(zhǔn)確性凉馆,從而決定哪些應(yīng)該被采用。如果去掉某項規(guī)則亡资,準(zhǔn)確性能提高澜共,則應(yīng)該實行修剪。

C5.0較C4.5使用更小的內(nèi)存锥腻,建立更小的決策規(guī)則嗦董,更加準(zhǔn)確。

CART和C4.5很相似瘦黑,但是它支持?jǐn)?shù)值的目標(biāo)變量(回歸)且不產(chǎn)生決策規(guī)則京革。CART使用特征和閾值在每個節(jié)點獲得最大的信息增益來構(gòu)建決策樹。

scikit-learn使用一個最佳的CART算法

數(shù)學(xué)公式

訓(xùn)練向量

i=1,...和標(biāo)簽向量
幸斥,決策樹遞歸地劃分空間匹摇,以使得相同標(biāo)簽的樣本被分到一起。用Q表示在節(jié)點m的數(shù)據(jù)甲葬,對于每一個候選劃分
由特征j和閾值

廊勃,將數(shù)據(jù)劃分為
兩個子集

m節(jié)點的不純度用函數(shù)H()計算,

選擇參數(shù)是的不純度最芯选:

遞歸以上坡垫,直至達(dá)到最大可允許的深度梭灿,

或者

分類標(biāo)準(zhǔn)

類k在節(jié)點m的比例:

Gini不純度:

交叉熵:

誤分類:

回歸標(biāo)準(zhǔn)

函數(shù) 函數(shù)功能
apply(X[, check_input]) 返回每個樣本的葉節(jié)點的預(yù)測序號
decision_path(X[, check_input]) 返回決策樹的決策路徑 [n_samples, n_nodes]
fit(X, y[, sample_weight, check_input, ...]) 從訓(xùn)練數(shù)據(jù)建立決策樹,返回一個對象
fit_transform(X[, y]) 將數(shù)據(jù)X轉(zhuǎn)換[n_samples, n_features_new]
get_params([deep]) 得到估計量的參數(shù)冰悠,返回一個映射
predict(X[, check_input]) 預(yù)測X的分類或者回歸堡妒,返回[n_samples]
predict_log_proba(X) 預(yù)測輸入樣本的對數(shù)概率,返回[n_samples, n_classes]
predict_proba(X[, check_input]) 預(yù)測輸入樣本的屬于各個類的概率[n_samples, n_classes]
score(X, y[, sample_weight]) 返回對于測試數(shù)據(jù)的平均準(zhǔn)確率
set_params(**params) 設(shè)置估計量的參數(shù)
transform(*args, **kwargs) 將輸入?yún)?shù)X減少的最重要的特征屿脐,返回[n_samples, n_selected_features]

參考文獻(xiàn)
-http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涕蚤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子的诵,更是在濱河造成了極大的恐慌万栅,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件西疤,死亡現(xiàn)場離奇詭異烦粒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)代赁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門扰她,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人芭碍,你說我怎么就攤上這事徒役。” “怎么了窖壕?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵忧勿,是天一觀的道長。 經(jīng)常有香客問我瞻讽,道長鸳吸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任速勇,我火速辦了婚禮晌砾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烦磁。我一直安慰自己养匈,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布都伪。 她就那樣靜靜地躺著乖寒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪院溺。 梳的紋絲不亂的頭發(fā)上楣嘁,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼逐虚。 笑死聋溜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叭爱。 我是一名探鬼主播撮躁,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼买雾!你這毒婦竟也來了把曼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤漓穿,失蹤者是張志新(化名)和其女友劉穎嗤军,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晃危,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡叙赚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了僚饭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片震叮。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鳍鸵,靈堂內(nèi)的尸體忽然破棺而出苇瓣,到底是詐尸還是另有隱情,我是刑警寧澤偿乖,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布钓简,位于F島的核電站,受9級特大地震影響汹想,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜撤蚊,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一古掏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧侦啸,春花似錦槽唾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至忘闻,卻和暖如春钝计,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工私恬, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留债沮,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓本鸣,卻偏偏與公主長得像疫衩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子荣德,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容