
舉例簡述決策樹的工作原理
決策樹可以實(shí)現(xiàn)二分類等問題,舉個(gè)例子:
一大批志愿者100人,
目標(biāo):判斷某一個(gè)人是否具有“A病”
志愿者屬性:年齡;性別;生活地區(qū)經(jīng)緯度;家中長輩是否有A??;本人是否有A病
我們可以通過構(gòu)建一大堆的ifelse來對(duì)數(shù)據(jù)進(jìn)行切割,假如數(shù)據(jù)構(gòu)成里,是如下結(jié)構(gòu):
if 家中是否遺傳{
#70人
if 長輩里有得病的{
#30人
if 生活經(jīng)緯度是重工業(yè)污染區(qū){
#25人
if 是否大于40歲 {
#20人
if 男人{(lán)
有病人群?。。。? }else{
10人沒病
}
}else{
5人沒病
}
}else{
5人沒病
}
}else{
40人無病
}
}else{
10人無病
}
以上我們看到了一批混沌的數(shù)據(jù),根據(jù)屬性的限制而不斷的分裂,從100人的群體逐漸找到了10個(gè)病患的特征。
即:家中長輩遺傳A病+長輩有病+生活在重工業(yè)污染區(qū)+40歲以上的+男性會(huì)得A病
通過以上例子,我們會(huì)發(fā)現(xiàn):
- 所有的數(shù)據(jù)最終都會(huì)走向葉子節(jié)點(diǎn)
- 沿用以上思路,我們既可以進(jìn)行
邏輯回歸,也可以進(jìn)行線性回歸。(如本例中的是否有病,或者預(yù)測(cè)房屋價(jià)格等)
決策樹特點(diǎn)和構(gòu)建原則
- 每個(gè)決策的判斷先后順序?qū)Y(jié)果的影響非常大
- 海選階段就應(yīng)該有很強(qiáng)的區(qū)分效果,之后的決策可以慢慢細(xì)化分裂
- 決策樹模型的目的就是通過計(jì)算機(jī)計(jì)算出合理的決策判斷內(nèi)容以及先后順序
- 決策樹應(yīng)用廣泛,可以擴(kuò)展出各種森林,也可通用于邏輯回歸和線性回歸
構(gòu)建算法
那么問題來了,在海選階段如何找到區(qū)分能力強(qiáng)的決策標(biāo)準(zhǔn)?首先引入概念:
“熵”和“Gini系數(shù)”
熵
理科的同學(xué)們應(yīng)該印象深刻一點(diǎn)吧,說白了就是描述某事物的混亂程度,電影《信條》也蹭了一波熱度。
??:有的科學(xué)計(jì)算庫用的log,有的ln,其實(shí)差不多。
公式簡單解析:
- P為決策一次后產(chǎn)生某一結(jié)果的概率,因此值在0~1之間。
- 因此lnx為單調(diào)增函數(shù),在(0,1]區(qū)間時(shí)y值從-∞到0,而P取值恰巧是[0,1]區(qū)間。
- 公式前面添加負(fù)號(hào),圖像翻轉(zhuǎn)。即(0,1]區(qū)間時(shí)y值從+∞到0的單調(diào)減函數(shù),正好對(duì)應(yīng)了概率越大時(shí)值越小,熵不就是越規(guī)矩(概率越大),熵越小嘛...
- 每一個(gè)i代表一個(gè)類別,把每個(gè)類別熵計(jì)算出來后再累加,就能得到最終的熵。
我們可以通過判斷熵的大小計(jì)算一次分裂過后某棵子樹的混亂程度,以此來評(píng)估決策標(biāo)準(zhǔn)的好壞。
信息增益(ID3)
假設(shè)場(chǎng)景(和上述數(shù)據(jù)無關(guān)):
14個(gè)人,9人有病,5人無病
A:早上只吃<菜>的人里:2人有病,3人無病
B:早上只吃<肉>的人里:有四個(gè)人全有病
C:早上只喝<水>的人里:三人有病,兩人無病
A的熵為:
B的熵為:
C的熵為:
所以“早上吃飯”這個(gè)屬性所帶來的熵的計(jì)算為:
而在數(shù)據(jù)未進(jìn)行決策時(shí)的熵為:
那么信息增益(熵下降)為:
以上是在有一個(gè)屬性作為決策條件的時(shí)候算出的信息增益,如果有多個(gè)屬性,那么分別算出所有屬性的信息增益,然后比大小,哪個(gè)屬性信息增益大,誰先決策。
信息增益率(C4.5)
假設(shè)在信息增益模塊所介紹的數(shù)據(jù)場(chǎng)景里,有一個(gè)屬性,14個(gè)人,每個(gè)人都不一樣或特征及其稀疏(如個(gè)人身份證號(hào)碼),以此屬性決策時(shí)會(huì)出現(xiàn)一課子節(jié)點(diǎn)非常多的子樹,并且此子樹的熵為0,那么按照上述邏輯,身份證的信息增益應(yīng)該是最大的,然而在實(shí)際情況中,身份證號(hào)碼對(duì)于決策一個(gè)人是否生病沒什么卵用!此時(shí)利用信息增益決定決策的先后順序就會(huì)出現(xiàn)問題,因此提出信息增益率來進(jìn)行算法改進(jìn)。
首先算一下此屬性自身熵(假設(shè)是身份證號(hào)碼)為:
信息增益率為:,可以看出,一個(gè)給定的數(shù)除以無窮,那么他是很小很小很小的......。
GINI系數(shù)標(biāo)準(zhǔn)(CART)
由此可知,概率越大,Gini越接近0
連續(xù)型隨機(jī)變量該如何進(jìn)行決策?
現(xiàn)將連續(xù)數(shù)值排序,將值劈開!如分成age<=20和age>20兩大塊,分別計(jì)算出信息增益,然后再去別的段去劈,直到找到最大的信息增益。
決策樹剪枝
決策樹在構(gòu)建過程中,經(jīng)常遇到過擬合的情況
- 預(yù)剪枝:(推薦)建立決策樹的同時(shí)完成剪枝操作。
- 后剪枝:當(dāng)建立完決策樹之后進(jìn)行剪枝操作。
預(yù)剪枝的方式:限制深度,葉子節(jié)點(diǎn)個(gè)數(shù),葉子節(jié)點(diǎn)樣本數(shù),信息增益量
后剪枝衡量標(biāo)準(zhǔn):,值越大,越不好!
??注意:
- 如果希望數(shù)據(jù)不用太精確,那么也不會(huì)容易過擬合,可以把a(bǔ)設(shè)置大一些。
- 如果想要精確數(shù)據(jù),可以把a(bǔ)設(shè)置小一些,但是有過擬合風(fēng)險(xiǎn)!
加利福尼亞房價(jià)數(shù)據(jù)集決策樹分析示例
這里只使用經(jīng)度緯度使用決策樹簡單分析
from sklearn import tree
import pydotplus
from IPython.display import Image
from sklearn.datasets.california_housing import fetch_california_housing
housing = fetch_california_housing()
print(housing.DESCR)
print(housing.data.shape)
'''參數(shù)說明
1.criterion gini or entropy
2.splitter best or random 前者是在所有特征中找最好的切分點(diǎn) 后者是在部分特征中(數(shù)據(jù)量大的時(shí)候)
3.max_features None(所有),log2,sqrt,N 特征小于50的時(shí)候一般使用所有的
4.max_depth 數(shù)據(jù)少或者特征少的時(shí)候可以不管這個(gè)值,如果模型樣本量多,特征也多的情況下,可以嘗試限制下
5.min_samples_split 如果某節(jié)點(diǎn)的樣本數(shù)少于min_samples_split,則不會(huì)繼續(xù)再嘗試選擇最優(yōu)特征來進(jìn)行劃分如果樣本量不大,不需要管這個(gè)值。如果樣本量數(shù)量級(jí)非常大,則推薦增大這個(gè)值。
6.min_samples_leaf 這個(gè)值限制了葉子節(jié)點(diǎn)最少的樣本數(shù),如果某葉子節(jié)點(diǎn)數(shù)目小于樣本數(shù),則會(huì)和兄弟節(jié)點(diǎn)一起被剪枝,如果樣本量不大,不需要管這個(gè)值,大些如10W可是嘗試下5
7.min_weight_fraction_leaf 這個(gè)值限制了葉子節(jié)點(diǎn)所有樣本權(quán)重和的最小值,如果小于這個(gè)值,則會(huì)和兄弟節(jié)點(diǎn)一起被剪枝默認(rèn)是0,就是不考慮權(quán)重問題。一般來說,如果我們有較多樣本有缺失值,或者分類樹樣本的分布類別偏差很大,就會(huì)引入樣本權(quán)重,這時(shí)我們就要注意這個(gè)值了。
8.max_leaf_nodes 通過限制最大葉子節(jié)點(diǎn)數(shù),可以防止過擬合,默認(rèn)是"None”,即不限制最大的葉子節(jié)點(diǎn)數(shù)。如果加了限制,算法會(huì)建立在最大葉子節(jié)點(diǎn)數(shù)內(nèi)最優(yōu)的決策樹。如果特征不多,可以不考慮這個(gè)值,但是如果特征分成多的話,可以加以限制具體的值可以通過交叉驗(yàn)證得到。
9.class_weight 指定樣本各類別的的權(quán)重,主要是為了防止訓(xùn)練集某些類別的樣本過多導(dǎo)致訓(xùn)練的決策樹過于偏向這些類別。這里可以自己指定各個(gè)樣本的權(quán)重如果使用“balanced”,則算法會(huì)自己計(jì)算權(quán)重,樣本量少的類別所對(duì)應(yīng)的樣本權(quán)重會(huì)高。
10.min_impurity_split 這個(gè)值限制了決策樹的增長,如果某節(jié)點(diǎn)的不純度(基尼系數(shù),信息增益,均方差,絕對(duì)差)小于這個(gè)閾值則該節(jié)點(diǎn)不再生成子節(jié)點(diǎn)。即為葉子節(jié)點(diǎn) 。
n_estimators:要建立樹的個(gè)數(shù)
'''
dtr = tree.DecisionTreeRegressor(max_depth = 2) #設(shè)置決策樹最大深度是2
dtr.fit(housing.data[:, [6, 7]], housing.target) #處理所有數(shù)據(jù),每條數(shù)據(jù)只處理第6和7列
#安裝 graphviz 工具,可以將導(dǎo)出的決策樹數(shù)據(jù)展示成圖片
dot_data = \
tree.export_graphviz(
dtr,
out_file = None,
feature_names = housing.feature_names[6:8],
filled = True,
impurity = False,
rounded = True
)
graph = pydotplus.graph_from_dot_data(dot_data)#讀入決策樹數(shù)據(jù)
graph.get_nodes()[7].set_fillcolor("#FFF2DD")
Image(graph.create_png()) #導(dǎo)出圖片
graph.write_png("dtr_white_background.png")
#超參數(shù)選擇
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestRegressor
data_train, data_test, target_train, target_test = \
train_test_split(housing.data, housing.target, test_size = 0.9, random_state = 42)
tree_param_grid = { 'min_samples_split': list((3,6,9)),'n_estimators':list((10,50,100))}#這里設(shè)置超參數(shù)待選項(xiàng)
grid = GridSearchCV(RandomForestRegressor(),param_grid=tree_param_grid, cv=2)#cv=5為交叉驗(yàn)證輪數(shù)
grid.fit(data_train, target_train)
'''
means = grid_result.cv_results_['mean_test_score']
params = grid_result.cv_results_['params']
'''
print(grid.cv_results_)
print("=======")
print(grid.best_params_)
print("=======")
print(grid.best_score_)