谷歌、百度或許搜到了很多關(guān)于決策樹(shù)的文章(回歸又可以分類(lèi)的)凛虽。好吧死遭,不喜歡看那些公式的朋友請(qǐng)看這里:
這就是一個(gè)決策樹(shù),一顆可以根據(jù)策略將數(shù)據(jù)集分成類(lèi)別的樹(shù)凯旋。呀潭。钉迷。。钠署。糠聪。(這個(gè)解釋是low點(diǎn)哈)
附上一個(gè)簡(jiǎn)單實(shí)例的代碼實(shí)現(xiàn):
from sklearn.datasets import load_iris,load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
import pydotplus
iris = load_iris( )
clf = DecisionTreeClassifier( )
clf_iris = clf.fit(iris.data,iris.target)
dot_Data = export_graphviz(clf_iris,out_file=None)
graph_iris = pydotplus.graph_from_dot_data(dot_Data)
graph_iris.write_pdf("./load_iris.pdf")
結(jié)果如下:
決策樹(shù)比較官方的解釋是:決策樹(shù)是廣泛用于分類(lèi)和回歸任務(wù)的模型。本質(zhì)上谐鼎,它從一層層的if/else問(wèn)題中進(jìn)行學(xué)習(xí)舰蟆,并得出結(jié)論。決策樹(shù)有兩個(gè)優(yōu)點(diǎn):一是得到的模型很容易可視化狸棍,非專(zhuān)家也很容易理解(至少對(duì)于較小的樹(shù)而言)身害。二是算法完全不受數(shù)據(jù)縮放的影響。由于每個(gè)特征被單獨(dú)處理草戈,而且數(shù)據(jù)的劃分也不依賴于縮放塌鸯,因此決策樹(shù)算法不需要特征預(yù)處理,比如歸一化或標(biāo)準(zhǔn)化唐片。特別是特征的尺度完全不一樣時(shí)或者二元特征和連續(xù)特征同時(shí)存在時(shí)丙猬,決策樹(shù)的效果很好。決策樹(shù)的主要缺點(diǎn)在于费韭,即使做了預(yù)剪枝淮悼,它也經(jīng)常會(huì)過(guò)擬合,泛化性能很差揽思。因此袜腥,在大多數(shù)應(yīng)用中,往往使用集成方法來(lái)替代單棵決策樹(shù)钉汗。下面解釋過(guò)擬合和預(yù)剪枝羹令。
過(guò)擬合:通俗的理解就是生成的決策樹(shù)(模型)對(duì)訓(xùn)練數(shù)據(jù)集的依賴性很高,當(dāng)這樣一個(gè)完全針對(duì)某一訓(xùn)練集而生成的模型面對(duì)訓(xùn)練數(shù)據(jù)時(shí)的準(zhǔn)確度是完全可以達(dá)到100%的损痰,但是如果面對(duì)其他測(cè)試集可能錯(cuò)誤率也會(huì)很高福侈,比如下圖:
上面的模型確實(shí)可以非常完美的將圓形和三角形完全的分開(kāi)(模型其實(shí)就是那些直線),但是這種模型很顯然是對(duì)訓(xùn)練數(shù)據(jù)依賴性很高的卢未。再看另外一幅圖片肪凛。
很顯然這個(gè)模型并沒(méi)有把所有的數(shù)據(jù)完美的區(qū)分開(kāi),但是對(duì)于其它測(cè)試數(shù)據(jù)而言辽社,錯(cuò)誤率可能要比第一個(gè)模型要小很多了伟墙,也就是說(shuō)第二個(gè)模型泛化能力更好。
那么我們?cè)鮽兡芨玫淖屇P偷姆夯芰Ω鼜?qiáng)呢滴铅?答案是預(yù)剪枝戳葵。預(yù)剪枝的限制條件可能包括限制樹(shù)的最大深度、限制葉結(jié)點(diǎn)的最大數(shù)目汉匙, 或者規(guī)定一個(gè)結(jié)點(diǎn)中數(shù)據(jù)點(diǎn)的最小數(shù)目來(lái)防止繼續(xù)劃分等拱烁,這些在DecisionTreeClassifier的參數(shù)中就可以選擇生蚁。下面就是介紹DecisionTreeClassifier參數(shù)嘍~
在sklearn的官網(wǎng)中有給出,如下:
class?sklearn.tree.DecisionTreeClassifier(criterion='gini',?splitter='best',?max_depth=None,?min_samples_split=2,min_samples_leaf =1,?min_weight_fraction_leaf=0.0,?max_features=None,?random_state=None,?max_leaf_nodes=None,class_weight=None,?presort=False)
特征選擇標(biāo)準(zhǔn)criterion:string類(lèi)型戏自,可以使用"gini"或者"entropy"邦投,前者代表基尼系數(shù),后者代表信息增益擅笔。一般說(shuō)使用默認(rèn)的基尼系數(shù)"gini"就可以了尼摹,即CART算法。除非你更喜歡類(lèi)似ID3, C4.5的最優(yōu)特征選擇方法剂娄。
特征劃分點(diǎn)選擇標(biāo)準(zhǔn)splitter:string類(lèi)型蠢涝,可以使用"best"或者"random"。前者在特征的所有劃分點(diǎn)中找出最優(yōu)的劃分點(diǎn)阅懦。后者是隨機(jī)的在部分劃分點(diǎn)中找局部最優(yōu)的劃分點(diǎn)和二。默認(rèn)的"best"適合樣本量不大的時(shí)候,而如果樣本數(shù)據(jù)量非常大耳胎,此時(shí)決策樹(shù)構(gòu)建推薦"random"?
劃分時(shí)考慮的最大特征數(shù)max_features:int,float,string or None惯吕。可以使用很多種類(lèi)型的值怕午,默認(rèn)是"None"意味著劃分時(shí)考慮所有的特征數(shù)废登;如果是"log2"意味著劃分時(shí)最多考慮log2N個(gè)特征;如果是"sqrt"或者"auto"意味著劃分時(shí)最多考慮N^(1/2)個(gè)特征郁惜。如果是整數(shù)堡距,代表考慮的特征絕對(duì)數(shù)。如果是浮點(diǎn)數(shù)兆蕉,代表考慮特征百分比羽戒,即考慮(百分比xN)取整后的特征數(shù)。其中N為樣本總特征數(shù)虎韵。一般來(lái)說(shuō)易稠,如果樣本特征數(shù)不多,比如小于50包蓝,我們用默認(rèn)的"None"就可以了锥腻,如果特征數(shù)非常多别威,我們可以靈活使用剛才描述的其他取值來(lái)控制劃分時(shí)考慮的最大特征數(shù)俄周,以控制決策樹(shù)的生成時(shí)間沪铭。
??? 1.如果是int,在每次分類(lèi)是都要考慮max_features個(gè)特征绳泉。
??? 2.如果是float,那么max_features是一個(gè)百分率并且分類(lèi)時(shí)需要考慮的特征數(shù)是int(max_features*n_features,其中n_features是訓(xùn)練完成時(shí)發(fā)特征數(shù))逊抡。
??? 3.如果是auto,max_features=auto(n_features)
??? 4.如果是sqrt,max_features=sqrt(n_features)
??? 5.如果是log2,max_features=log2(n_features)
??? 6.如果是None,max_features=n_features
決策樹(shù)最大深max_depth:int or None零酪。決策樹(shù)的最大深度冒嫡,默認(rèn)可以不輸入,如果不輸入的話四苇,決策樹(shù)在建立子樹(shù)的時(shí)候不會(huì)限制子樹(shù)的深度孝凌。一般來(lái)說(shuō),數(shù)據(jù)少或者特征少的時(shí)候可以不管這個(gè)值月腋。如果模型樣本量多蟀架,特征也多的情況下,推薦限制這個(gè)最大深度榆骚,具體的取值取決于數(shù)據(jù)的分布片拍。常用的可以取值50-100之間。
內(nèi)部節(jié)點(diǎn)再劃分所需最小樣本數(shù)min_samples_spli:int,float妓肢。這個(gè)值限制了子樹(shù)繼續(xù)劃分的條件捌省,如果某節(jié)點(diǎn)的樣本數(shù)少于min_samples_split,則不會(huì)繼續(xù)再嘗試選擇最優(yōu)特征來(lái)進(jìn)行劃分碉钠。?默認(rèn)是2.如果樣本量不大纲缓,不需要管這個(gè)值。如果樣本量數(shù)量級(jí)非常大喊废,則推薦增大這個(gè)值祝高。我之前的一個(gè)項(xiàng)目例子,有大概10萬(wàn)樣本污筷,建立決策樹(shù)時(shí)工闺,可以選擇min_samples_split=10。
葉子節(jié)點(diǎn)最少樣本數(shù)min_samples_leaf:int,float瓣蛀。這個(gè)值限制了葉子節(jié)點(diǎn)最少的樣本數(shù)斤寂,如果某葉子節(jié)點(diǎn)數(shù)目小于樣本數(shù),則會(huì)和兄弟節(jié)點(diǎn)一起被剪枝揪惦。?默認(rèn)是1,可以輸入最少的樣本數(shù)的整數(shù)遍搞,或者最少樣本數(shù)占樣本總數(shù)的百分比。如果樣本量不大器腋,不需要管這個(gè)值溪猿。如果樣本量數(shù)量級(jí)非常大,則推薦增大這個(gè)值纫塌。之前的10萬(wàn)樣本項(xiàng)目使用min_samples_leaf的值為5诊县。
葉子節(jié)點(diǎn)最小的樣本權(quán)重和min_weight_fraction_lea:float。這個(gè)值限制了葉子節(jié)點(diǎn)所有樣本權(quán)重和的最小值措左,如果小于這個(gè)值依痊,則會(huì)和兄弟節(jié)點(diǎn)一起被剪枝。?默認(rèn)是0,就是不考慮權(quán)重問(wèn)題胸嘁。一般來(lái)說(shuō)瓶摆,如果我們有較多樣本有缺失值,或者分類(lèi)樹(shù)樣本的分布類(lèi)別偏差很大性宏,就會(huì)引入樣本權(quán)重群井,這時(shí)我們就要注意這個(gè)值。
最大葉子節(jié)點(diǎn)數(shù)max_leaf_nodes:int,None毫胜。通過(guò)限制最大葉子節(jié)點(diǎn)數(shù),可以防止過(guò)擬合荐吉,默認(rèn)是"None”,即不限制最大的葉子節(jié)點(diǎn)數(shù)瞧哟。如果加了限制,算法會(huì)建立在最大葉子節(jié)點(diǎn)數(shù)內(nèi)最優(yōu)的決策樹(shù)陨亡。如果特征不多,可以不考慮這個(gè)值遮糖,但是如果特征分成多的話欲账,可以加以限制,具體的值可以通過(guò)交叉驗(yàn)證得到踢故。
類(lèi)別權(quán)重class_weight:dict,list of dicts,"Banlanced" or None耸峭。指定樣本各類(lèi)別的的權(quán)重抓艳,主要是為了防止訓(xùn)練集某些類(lèi)別的樣本過(guò)多,導(dǎo)致訓(xùn)練的決策樹(shù)過(guò)于偏向這些類(lèi)別。這里可以自己指定各個(gè)樣本的權(quán)重产场,或者用“balanced”,如果使用“balanced”确徙,則算法會(huì)自己計(jì)算權(quán)重,樣本量少的類(lèi)別所對(duì)應(yīng)的樣本權(quán)重會(huì)高。當(dāng)然错蝴,如果你的樣本類(lèi)別分布沒(méi)有明顯的偏倚,則可以不管這個(gè)參數(shù)馍惹,選擇默認(rèn)的"None"
節(jié)點(diǎn)劃分最小不純度min_impurity_split:這個(gè)值限制了決策樹(shù)的增長(zhǎng)悼吱,如果某節(jié)點(diǎn)的不純度(基尼系數(shù),信息增益,均方差粱檀,絕對(duì)差)小于這個(gè)閾值,則該節(jié)點(diǎn)不再生成子節(jié)點(diǎn),即為葉子節(jié)點(diǎn)?皱碘。
數(shù)據(jù)是否預(yù)排序presort:這個(gè)值是布爾值缓醋,默認(rèn)是False不排序送粱。一般來(lái)說(shuō)脆丁,如果樣本量少或者限制了一個(gè)深度很小的決策樹(shù),設(shè)置為true可以讓劃分點(diǎn)選擇更加快震蒋,決策樹(shù)建立的更加快。如果樣本量太大的話,反而沒(méi)有什么好處直砂。問(wèn)題是樣本量少的時(shí)候瘦锹,我速度本來(lái)就不慢泪掀。所以這個(gè)值不處理就可以了椅挣。
除了這些參數(shù)要注意以外靠抑,其他在調(diào)參時(shí)的注意點(diǎn)有:
1)當(dāng)樣本少數(shù)量但是樣本特征非常多的時(shí)候,決策樹(shù)很容易過(guò)擬合,一般來(lái)說(shuō)川队,樣本數(shù)比特征數(shù)多一些會(huì)比較容易建立健壯的模型
2)如果樣本數(shù)量少但是樣本特征非常多,在擬合決策樹(shù)模型前瑟捣,推薦先做維度規(guī)約捐祠,比如主成分分析(PCA),特征選擇(Losso)或者獨(dú)立成分分析(ICA)桑李。這樣特征的維度會(huì)大大減小踱蛀。再來(lái)擬合決策樹(shù)模型效果會(huì)好。
3)推薦多用決策樹(shù)的可視化贵白,同時(shí)先限制決策樹(shù)的深度率拒,這樣可以先觀察下生成的決策樹(shù)里數(shù)據(jù)的初步擬合情況,然后再?zèng)Q定是否要增加深度禁荒。
4)在訓(xùn)練模型先猬膨,注意觀察樣本的類(lèi)別情況(主要指分類(lèi)樹(shù)),如果類(lèi)別分布非常不均勻呛伴,就要考慮用class_weight來(lái)限制模型過(guò)于偏向樣本多的類(lèi)別勃痴。
5)決策樹(shù)的數(shù)組使用的是numpy的float32類(lèi)型,如果訓(xùn)練數(shù)據(jù)不是這樣的格式热康,算法會(huì)先做copy再運(yùn)行沛申。
6)如果輸入的樣本矩陣是稀疏的,推薦在擬合前調(diào)用csc_matrix稀疏化褐隆,在預(yù)測(cè)前調(diào)用csr_matrix稀疏化污它。
下面以乳腺癌數(shù)據(jù)集寫(xiě)一個(gè)簡(jiǎn)單的實(shí)例并每個(gè)特征的重要程度以及模型打印成pdf:
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris,load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
import numpy as np
import matplotlib.pyplot as plt
import pydotplus
import graphviz
iris = load_iris()
cancer = load_breast_cancer()
clf = DecisionTreeClassifier(max_depth=7)
clf_iris = clf.fit(iris.data,iris.target)
clf_cancer = clf.fit(cancer.data,cancer.target)
#print("cancer.keys(): \n{}".format(cancer.keys()))
#print(cancer.target)
#print("{}".format({n:v for n,v in zip(cancer.target_names,np.bincount(cancer.target))}))
x_train,x_test,y_train,y_test = train_test_split(cancer.data,cancer.target,test_size=0.3,random_state=1)
clf_DT??= clf.fit(x_train,y_train)
print("{:.3f}".format(clf_DT.score(x_train,y_train)))
print("{:.3f}".format(clf_DT.score(x_test,y_test)))
export_graphviz(clf_DT,out_file="./DT.dot",class_names=['malignant','benign'],feature_names=cancer.feature_names,impurity=False,filled=True)
print("{}".format(clf_DT.feature_importances_))
print(cancer.data.shape[0])
def polt_feature_importances_cancer(model):
????feature_count = cancer.data.shape[1]
????plt.barh(range(feature_count),model.feature_importances_,align='center')
????plt.yticks(np.arange(feature_count),cancer.feature_names)
????plt.xlabel("Feature importance")
????plt.ylabel("Feature")
????plt.show()
polt_feature_importances_cancer(clf_DT)
結(jié)果如下:
可以看出來(lái)第22個(gè)特征worst perimeter的劃分能力最強(qiáng),模型中第一個(gè)用到的也是x[22]庶弃。