決策樹基本原理概述

沒錯,就是倒著的

舉例簡述決策樹的工作原理

決策樹可以實現(xiàn)二分類等問題,舉個例子:

一大批志愿者100人,
目標:判斷某一個人是否具有“A病”
志愿者屬性:年齡;性別;生活地區(qū)經(jīng)緯度;家中長輩是否有A病;本人是否有A病

我們可以通過構(gòu)建一大堆的ifelse來對數(shù)據(jù)進行切割,假如數(shù)據(jù)構(gòu)成里,是如下結(jié)構(gòu):

if 家中是否遺傳{
  #70人
  if 長輩里有得病的{
    #30人
    if 生活經(jīng)緯度是重工業(yè)污染區(qū){
      #25人
      if 是否大于40歲 {
        #20人
        if 男人{
          有病人群?。。?!
        }else{
          10人沒病
        }
      }else{
      5人沒病
      }
    }else{
    5人沒病
    }
  }else{
    40人無病
  }
}else{
  10人無病
}

以上我們看到了一批混沌的數(shù)據(jù),根據(jù)屬性的限制而不斷的分裂,從100人的群體逐漸找到了10個病患的特征。
即:家中長輩遺傳A病+長輩有病+生活在重工業(yè)污染區(qū)+40歲以上的+男性會得A病
通過以上例子,我們會發(fā)現(xiàn):

  • 所有的數(shù)據(jù)最終都會走向葉子節(jié)點
  • 沿用以上思路,我們既可以進行邏輯回歸,也可以進行線性回歸。(如本例中的是否有病,或者預(yù)測房屋價格等)

決策樹特點和構(gòu)建原則

  • 每個決策的判斷先后順序?qū)Y(jié)果的影響非常大
  • 海選階段就應(yīng)該有很強的區(qū)分效果,之后的決策可以慢慢細化分裂
  • 決策樹模型的目的就是通過計算機計算出合理的決策判斷內(nèi)容以及先后順序
  • 決策樹應(yīng)用廣泛,可以擴展出各種森林,也可通用于邏輯回歸和線性回歸

構(gòu)建算法

那么問題來了,在海選階段如何找到區(qū)分能力強的決策標準?首先引入概念:
“熵”和“Gini系數(shù)”

理科的同學(xué)們應(yīng)該印象深刻一點吧,說白了就是描述某事物的混亂程度,電影《信條》也蹭了一波熱度。
H(x)= - \sum_{i=1}^{n} {P_{i} \cdot \ln P_{i}}
??:有的科學(xué)計算庫用的log,有的ln,其實差不多。
公式簡單解析:

  • P為決策一次后產(chǎn)生某一結(jié)果的概率,因此值在0~1之間。
  • 因此lnx為單調(diào)增函數(shù),在(0,1]區(qū)間時y值從-∞到0,而P取值恰巧是[0,1]區(qū)間。
  • 公式前面添加負號,圖像翻轉(zhuǎn)。即(0,1]區(qū)間時y值從+∞到0的單調(diào)減函數(shù),正好對應(yīng)了概率越大時值越小,熵不就是越規(guī)矩(概率越大),熵越小嘛...
  • 每一個i代表一個類別,把每個類別熵計算出來后再累加,就能得到最終的熵。

我們可以通過判斷熵的大小計算一次分裂過后某棵子樹的混亂程度,以此來評估決策標準的好壞。

信息增益(ID3)

假設(shè)場景(和上述數(shù)據(jù)無關(guān)):
14個人,9人有病,5人無病
A:早上只吃<菜>的人里:2人有病,3人無病
B:早上只吃<肉>的人里:有四個人全有病
C:早上只喝<水>的人里:三人有病,兩人無病
A的熵為:H(A) = (- \frac{2}{5} \ln \frac{2}{5})+(- \frac{3}{5} \ln \frac{3}{5}) = 0.971
B的熵為:H(B)=0
C的熵為:H(C) = (- \frac{3}{5}\ln \frac{3}{5})+(- \frac{2}{5}\ln \frac{2}{5}) = 0.971
所以“早上吃飯”這個屬性所帶來的熵的計算為:
H(x) = \frac{5}{14} \cdot 0.971+ \frac{4}{14} \cdot 0 + \frac {5}{14} \cdot 0.971 =0.693
而在數(shù)據(jù)未進行決策時的熵為:
H(z) = - \frac{9}{14}+(- \frac{5}{14}) = 0.94
那么信息增益(熵下降)為:
Gain = H(x)-H(z) = 0.693-0.94=0.247
以上是在有一個屬性作為決策條件的時候算出的信息增益,如果有多個屬性,那么分別算出所有屬性的信息增益,然后比大小,哪個屬性信息增益大,誰先決策。

信息增益率(C4.5)

假設(shè)在信息增益模塊所介紹的數(shù)據(jù)場景里,有一個屬性,14個人,每個人都不一樣或特征及其稀疏(如個人身份證號碼),以此屬性決策時會出現(xiàn)一課子節(jié)點非常多的子樹,并且此子樹的熵為0,那么按照上述邏輯,身份證的信息增益應(yīng)該是最大的,然而在實際情況中,身份證號碼對于決策一個人是否生病沒什么卵用!此時利用信息增益決定決策的先后順序就會出現(xiàn)問題,因此提出信息增益率來進行算法改進。
首先算一下此屬性自身熵(假設(shè)是身份證號碼)為:
H( m) = (- \frac{1}{14} \ln \frac{1}{14} ) \cdot 14 \approx \infty
信息增益率為:\frac{Gain}{H(m)},可以看出,一個給定的數(shù)除以無窮,那么他是很小很小很小的......。

GINI系數(shù)標準(CART)

Gini(p) = \sum_{k=1}^{K}p_{k}(1-p_{k}) = 1-\sum_{k=1}^{K}{P_{k}}^{2}
由此可知,概率越大,Gini越接近0

連續(xù)型隨機變量該如何進行決策?

現(xiàn)將連續(xù)數(shù)值排序,將值劈開!如分成age<=20和age>20兩大塊,分別計算出信息增益,然后再去別的段去劈,直到找到最大的信息增益。

決策樹剪枝

決策樹在構(gòu)建過程中,經(jīng)常遇到過擬合的情況

  • 預(yù)剪枝:(推薦)建立決策樹的同時完成剪枝操作。
  • 后剪枝:當(dāng)建立完決策樹之后進行剪枝操作。

預(yù)剪枝的方式:限制深度,葉子節(jié)點個數(shù),葉子節(jié)點樣本數(shù),信息增益量
后剪枝衡量標準:C_{a}(T)=C(T)+\alpha \cdot \left | T_{leaf} \right |,值越大,越不好!
??注意:

  • 如果希望數(shù)據(jù)不用太精確,那么也不會容易過擬合,可以把a設(shè)置大一些。
  • 如果想要精確數(shù)據(jù),可以把a設(shè)置小一些,但是有過擬合風(fēng)險!

加利福尼亞房價數(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 前者是在所有特征中找最好的切分點 后者是在部分特征中(數(shù)據(jù)量大的時候)

3.max_features None(所有),log2,sqrt,N 特征小于50的時候一般使用所有的

4.max_depth 數(shù)據(jù)少或者特征少的時候可以不管這個值,如果模型樣本量多,特征也多的情況下,可以嘗試限制下

5.min_samples_split 如果某節(jié)點的樣本數(shù)少于min_samples_split,則不會繼續(xù)再嘗試選擇最優(yōu)特征來進行劃分如果樣本量不大,不需要管這個值。如果樣本量數(shù)量級非常大,則推薦增大這個值。

6.min_samples_leaf 這個值限制了葉子節(jié)點最少的樣本數(shù),如果某葉子節(jié)點數(shù)目小于樣本數(shù),則會和兄弟節(jié)點一起被剪枝,如果樣本量不大,不需要管這個值,大些如10W可是嘗試下5

7.min_weight_fraction_leaf 這個值限制了葉子節(jié)點所有樣本權(quán)重和的最小值,如果小于這個值,則會和兄弟節(jié)點一起被剪枝默認是0,就是不考慮權(quán)重問題。一般來說,如果我們有較多樣本有缺失值,或者分類樹樣本的分布類別偏差很大,就會引入樣本權(quán)重,這時我們就要注意這個值了。

8.max_leaf_nodes 通過限制最大葉子節(jié)點數(shù),可以防止過擬合,默認是"None”,即不限制最大的葉子節(jié)點數(shù)。如果加了限制,算法會建立在最大葉子節(jié)點數(shù)內(nèi)最優(yōu)的決策樹。如果特征不多,可以不考慮這個值,但是如果特征分成多的話,可以加以限制具體的值可以通過交叉驗證得到。

9.class_weight 指定樣本各類別的的權(quán)重,主要是為了防止訓(xùn)練集某些類別的樣本過多導(dǎo)致訓(xùn)練的決策樹過于偏向這些類別。這里可以自己指定各個樣本的權(quán)重如果使用“balanced”,則算法會自己計算權(quán)重,樣本量少的類別所對應(yīng)的樣本權(quán)重會高。

10.min_impurity_split 這個值限制了決策樹的增長,如果某節(jié)點的不純度(基尼系數(shù),信息增益,均方差,絕對差)小于這個閾值則該節(jié)點不再生成子節(jié)點。即為葉子節(jié)點 。

n_estimators:要建立樹的個數(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ù)待選項
grid = GridSearchCV(RandomForestRegressor(),param_grid=tree_param_grid, cv=2)#cv=5為交叉驗證輪數(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_)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容