同步更新在個(gè)人網(wǎng)站:http://www.wangpengcufe.com/machinelearning/pythonml-pythonml4/
一棒卷、決策樹的原理
決策樹思想的來(lái)源非常樸素蒙袍,程序設(shè)計(jì)中的條件分支結(jié)構(gòu)就是if-then結(jié)構(gòu),最早的決策樹就是利用這類結(jié)構(gòu)分割數(shù)據(jù)的一種分類學(xué)習(xí)方法 。
二、決策樹的現(xiàn)實(shí)案例
相親
女兒:多大年紀(jì)了粱栖?
母親:26。
女兒:長(zhǎng)的帥不帥脏毯?
母親:挺帥的闹究。
女兒:收入高不?
母親:不算很高食店,中等情況渣淤。
女兒:是公務(wù)員不赏寇?
母親:是,在稅務(wù)局上班呢价认。
女兒:那好嗅定,我去見(jiàn)見(jiàn)。
銀行是否發(fā)放貸款
行長(zhǎng):是否有自己的房子用踩?
職員:有渠退。
行長(zhǎng):可以考慮放貸。
職員:如果沒(méi)有自己的房子呢脐彩?
行長(zhǎng):是否有穩(wěn)定工作碎乃?
職員:有。
行長(zhǎng):可以考慮放貸惠奸。
職員:那如果沒(méi)有呢梅誓?
行長(zhǎng):既沒(méi)有自己的房子,也沒(méi)有穩(wěn)定工作佛南,那咱還放啥貸款梗掰?
職員:懂了。
預(yù)測(cè)足球隊(duì)是否奪冠
三共虑、信息論基礎(chǔ)
信息熵:
假如我們競(jìng)猜32只足球隊(duì)誰(shuí)是冠軍愧怜?我可以把球編上號(hào),從1到32妈拌,然后提問(wèn):冠 軍在1-16號(hào)嗎?依次進(jìn)行二分法詢問(wèn)蓬蝶,只需要五次尘分,就可以知道結(jié)果。
32支球隊(duì)丸氛,問(wèn)詢了5次培愁,信息量定義為5比特,log32=5比特缓窜。比特就是表示信息的單位定续。
假如有64支球隊(duì)的話,那么我們需要二分法問(wèn)詢6次禾锤,信息量就是6比特私股,log64=6比特。
問(wèn)詢了多少次恩掷,專業(yè)術(shù)語(yǔ)稱之為信息熵倡鲸,單位為比特。
公式為:
信息熵的作用:
決策樹生成的過(guò)程中黄娘,信息熵大的作為根節(jié)點(diǎn)峭状,信息熵小的作為葉子節(jié)點(diǎn)克滴,按照信息熵的從大到小原則,生成決策樹优床。
條件熵:
條件熵H(D|A)表示在已知隨機(jī)變量A的條件下隨機(jī)變量D的不確定性劝赔。
公式為:
通俗來(lái)講就是,知道A情況下胆敞,D的信息量着帽。
信息增益:
特征A對(duì)訓(xùn)練數(shù)據(jù)集D的信息增益g(D,A),定義為集合D的信息熵H(D)與特征A給定條件下D的信息條件熵H(D|A)之差。
公式為:
怎么理解信息增益呢竿秆?信息增益表示得知特征X的信息而使得類Y的信息的不確定性減少的程度启摄。簡(jiǎn)單講,就是知道的增多幽钢,使得不知道的(不確定的)就減少歉备。
四、 決策樹API
決策樹:
sklearn.tree.DecisionTreeClassifier
class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
決策樹分類器
criterion:默認(rèn)是’gini’系數(shù)匪燕,也可以選擇信息增益的熵’entropy’
max_depth:樹的深度大小
random_state:隨機(jī)數(shù)種子
method:
dec.fit(X,y): 根據(jù)數(shù)據(jù)集(X,y)建立決策樹分類器
dec.apply(X): 返回每個(gè)樣本被預(yù)測(cè)為的葉子的索引蕾羊。
dec.cost_complexity_pruning_path(X,y): 在最小成本復(fù)雜性修剪期間計(jì)算修剪路徑。
dec.decision_path(X): 返回樹中的決策路徑
dec.get_depth(): 返回樹的深度
dec.get_n_leaves(): 返回決策樹的葉子節(jié)點(diǎn)
dec.get_params(): 返回評(píng)估器的參數(shù)
dec.predict(X): 預(yù)測(cè)X的類或回歸值
dec.predict_log_proba(X): 預(yù)測(cè)X的類的log值
dec.predict_proba(X): 預(yù)測(cè)X分類的概率值
dec.score(X,y): 測(cè)試數(shù)據(jù)X和標(biāo)簽值y之間的平均準(zhǔn)確率
dec.set_params(min_samples_split=3): 設(shè)置評(píng)估器的參數(shù)
X 表示訓(xùn)練集帽驯,y表示特征值
決策樹的生成與本地保存:
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
li = load_iris()
dec = DecisionTreeClassifier()
# 根據(jù)訓(xùn)練集(X,y)建立決策樹分類器
dec.fit(li.data,li.target)
# 預(yù)測(cè)X的類或回歸值
dec.predict(li.data)
# 測(cè)試數(shù)據(jù)X和標(biāo)簽值y之間的平均準(zhǔn)確率
dec.score(li.data,li.target)
# 保存樹文件 tree.dot
tree.export_graphviz(dec,out_file='tree.dot')
tree.dot 保存結(jié)果:
digraph Tree {
node [shape=box] ;
0 [label="X[2] <= 2.45\ngini = 0.667\nsamples = 150\nvalue = [50, 50, 50]"] ;
1 [label="gini = 0.0\nsamples = 50\nvalue = [50, 0, 0]"] ;
.....
五龟再、實(shí)現(xiàn)案例
1、導(dǎo)入數(shù)據(jù)尼变,劃分測(cè)試集利凑,訓(xùn)練集
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
import graphviz
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
import pylab as mpl #導(dǎo)入中文字體,避免顯示亂碼
mpl.rcParams['font.sans-serif']=['SimHei'] #設(shè)置為黑體字
data = load_wine()
dataFrame = pd.concat([pd.DataFrame(X_train),pd.DataFrame(y_train)],axis=1)
print(dataFrame)
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.3, random_state=30)
2嫌术、模型實(shí)例化
clf = tree.DecisionTreeClassifier(criterion='gini'
,max_depth=None
,min_samples_leaf=1
,min_samples_split=2
,random_state=0
,splitter='best'
)
3哀澈、數(shù)據(jù)代入訓(xùn)練
clf = clf.fit(X_train,y_train)
4、測(cè)試集導(dǎo)入打分
score = clf.score(X_test,y_test)
5度气、graphviz畫出決策樹
feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚','類黃酮','非黃烷類酚類','花青素','顏色強(qiáng)度','色調(diào)','od280/od315稀釋葡萄酒','脯氨酸']
dot_data = tree.export_graphviz(clf
,out_file=None
,feature_names=feature_name
,class_names=["紅酒","白酒","葡萄酒"] #別名
,filled=True
,rounded=True
)
graph = graphviz.Source(dot_data)
6割按、參數(shù)的重要性討論
clf.feature_importances_
[*zip(feature_name,clf.feature_importances_)]
[('酒精', 0.0),
('蘋果酸', 0.0),
('灰', 0.023800041266200594),
('灰的堿性', 0.0),
('鎂', 0.0),
('總酚', 0.0),
('類黃酮', 0.14796731056604398),
('非黃烷類酚類', 0.0),
('花青素', 0.023717402234026283),
('顏色強(qiáng)度', 0.3324466124446747),
('色調(diào)', 0.021345662010623646),
('od280/od315稀釋葡萄酒', 0.0),
('脯氨酸', 0.45072297147843077)]
將重要性排序:
df = pd.DataFrame([*zip(features, clf.feature_importances_)])
df.columns = ['features','importances']
df = df.sort_values(by='importances',ascending=False)
df.index = range(df.shape[0])
df
將重要性可視化:
plt.figure(figsize=(10,5))
plt.barh(df['features'],df['importances'])
plt.title('特征重要性排序')
plt.show()
7、參數(shù)的穩(wěn)定性和隨機(jī)性
問(wèn)題:為什么大家對(duì)同一份數(shù)據(jù)進(jìn)行執(zhí)行磷籍,結(jié)果分?jǐn)?shù)會(huì)不一樣呢?同一個(gè)人執(zhí)行同一份數(shù)據(jù)适荣,每次的分?jǐn)?shù)結(jié)果也會(huì)不一樣?
答:是因?yàn)橛?xùn)練數(shù)據(jù)集在模型里每次都是隨機(jī)劃分的院领,所以執(zhí)行的結(jié)果會(huì)不穩(wěn)定弛矛,那么要怎么才會(huì)穩(wěn)定呢?參數(shù)random_state就是用來(lái)干這個(gè)事情的栅盲,只要給random_state設(shè)置了值汪诉,那么每次執(zhí)行的結(jié)果就都會(huì)是一樣的了。具體設(shè)置多少呢?是不一定的扒寄,從0到n可以自己嘗試,哪個(gè)值得到的score高就用哪個(gè)鱼鼓。
clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30)
clf = clf.fit(X_train, y_train)
score = clf.score(X_test, y_test) #返回預(yù)測(cè)的準(zhǔn)確度
8、剪枝參數(shù)調(diào)優(yōu)
為什么要剪枝该编?
剪枝參數(shù)的默認(rèn)值會(huì)讓樹無(wú)限增長(zhǎng)迄本,這些樹在某些數(shù)據(jù)集中可能非常巨大,非常消耗內(nèi)存课竣。其次嘉赎,決策樹的無(wú)限增長(zhǎng)會(huì)造成過(guò)擬合線性,導(dǎo)致模型在訓(xùn)練集中表現(xiàn)很好于樟,但是在測(cè)試集中表現(xiàn)一般公条。之所以在訓(xùn)練集中表現(xiàn)很好,是包括了訓(xùn)練集中的噪音在里面迂曲,造成了過(guò)擬合現(xiàn)象靶橱。所以,我們要對(duì)決策樹進(jìn)行剪枝參數(shù)調(diào)優(yōu)路捧。
常用的參數(shù)主要有:
min_samples_leaf: 葉子的最小樣本量关霸,如果少于設(shè)定的值,則停止分枝杰扫;太小引起過(guò)擬合队寇,太大阻止模型學(xué)習(xí)數(shù)據(jù);建議從5開始章姓;
min_samples_split: 分枝節(jié)點(diǎn)的樣本量佳遣,如果少于設(shè)定的值,那么就停止分枝凡伊。
max_depth:樹的深度苍日,超過(guò)深度的樹枝會(huì)被剪掉,建議從3開始窗声,看效果決定是否要增加深度;如果3的準(zhǔn)確率只有50%辜纲,那增加深度笨觅,如果3的準(zhǔn)確率80%,90%耕腾,那考慮限定深度见剩,不用再增加深度了,節(jié)省計(jì)算空間扫俺。
clf = tree.DecisionTreeClassifier(min_samples_leaf=10
, min_samples_split=20
, max_depth=3)
clf.fit(X_train, y_train)
dot_data = tree.export_graphviz(clf
,feature_names=feature_name
,class_names=["紅酒","白酒","葡萄酒"] #別名
,filled=True
,rounded=True)
graphviz.Source(dot_data)
9苍苞、確定最優(yōu)剪枝參數(shù)
import matplotlib.pyplot as plt
score_list = []
for i in range(1,11):
clf = tree.DecisionTreeClassifier(max_depth=i
,criterion="entropy"
,random_state=30
,splitter="random")
clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
score_list.append(score)
plt.plot(range(1,11),score_list,color="red",label="max_depth",linewidth=2)
plt.legend()
plt.show()
可以看到,max_depth在=3的時(shí)候,score已經(jīng)達(dá)到了最高羹呵,再增加深度骂际,則會(huì)增加過(guò)擬合的風(fēng)險(xiǎn)。
六冈欢、 決策樹的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 簡(jiǎn)單的理解和解釋歉铝,樹木可視化。
- 需要很少的數(shù)據(jù)準(zhǔn)備凑耻,其他技術(shù)通常需要數(shù)據(jù)歸一化太示。
缺點(diǎn)
- 決策樹學(xué)習(xí)者可以創(chuàng)建不能很好地推廣數(shù)據(jù)的過(guò)于復(fù)雜的樹,被稱為過(guò)擬合香浩。
- 決策樹可能不穩(wěn)定类缤,因?yàn)閿?shù)據(jù)的小變化可能會(huì)導(dǎo)致完全不同的樹
被生成。
改進(jìn)
- 減枝cart算法
- 隨機(jī)森林
撰寫記錄
2020.02.19-00:11:01-第一次撰寫
2020.04.03-16:06:06-第二次撰寫
2020.04.07-16:36:09-第三次撰寫
2020.06.12-23:53:08-第四次撰寫