天天看點

【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹

文章目錄

  • DecisionTreeClassifier 分類樹
    • ① 重要參數:criterion 不純度的計算
      • ♦ 基本概念
      • ♦ 選擇方式
      • ♦ 基本計算流程
      • ♦ 案例
    • ② 重要參數:random_state & splitter
    • ③ 剪枝參數
      • ▶ max_depth
      • ▶ min_samples_leaf & min_samples_split
      • ▶ max_features & min_impurity_decrease
      • ▶ 确認最優剪枝參數
      • ▶ 目标權重參數:class_weight & min_weight_fraction_leaf
    • ④ 重要屬性和接口
    • 總結

DecisionTreeClassifier 分類樹

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, min_impurity_decrease=0.0, min_impurity_split=None,
class_weight=None, presort=False)
           

① 重要參數:criterion 不純度的計算

♦ 基本概念

為了要将表格轉化為一棵樹,決策樹需要找出最佳節點和最佳的分枝方法,對分類樹來說,衡量這個“最佳”的名額叫做“不純度”。通常來說,

不純度越低,決策樹對訓練集的拟合越好

。現在使用的決策樹算法在分枝方法上的核心,大多是圍繞在對某個不純度相關名額的最優化上。

不純度基于節點來計算,樹中的每個節點都會有一個不純度,并且子節點的不純度一定是低于父節點的,也就是說,在同一棵決策樹上,葉子節點的不純度一定是最低的。

Criterion參數

正是用來決定不純度的計算方法的。sklearn提供了兩種選擇:

  • 輸入”

    entropy

    “,使用

    資訊熵(Entropy)

  • 輸入”

    gini

    “,使用

    基尼系數(Gini Impurity)

    【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹

其中t代表給定的節點,i代表标簽的任意分類, p ( i ∣ t ) p(i|t) p(i∣t)代表标簽分類i在節點t上所占的比例。

注意:當使用資訊熵時,sklearn實際計算的是基于資訊熵的資訊增益(Information Gain),即

父節點的資訊熵和子節點的資訊熵之差

。比起基尼系數,

資訊熵對不純度更加敏感,對不純度的懲罰最強

。但是在實際使用中,資訊熵和基尼系數的效果基本相同。資訊熵的計算比基尼系數緩慢一些,因為基尼系數的計算不涉及對數。另外,因為資訊熵對不純度更加敏感,是以

資訊熵作為名額時,決策樹的生長會更加“精細”,是以對于高維資料或者噪音很多的資料,資訊熵很容易過拟合

,基尼系數在這種情況下效果往往比較好。

對于資訊熵的了解參見大佬博文~

傳回頂部

♦ 選擇方式

【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹

傳回頂部

♦ 基本計算流程

【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹
  • 直到沒有更多的特征可用,或整體的不純度名額已經最優,決策樹就會停止生長。

傳回頂部

♦ 案例

import pandas  as  pd
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

# 擷取資料集
wine_data = load_wine()
x = pd.DataFrame(wine_data.data)
y = wine_data.target
feature = wine_data.feature_names
x.columns = feature

# 劃分測試集、訓練集
xtrain, xtest, ytrain, ytest = train_test_split(x, y, test_size=0.3, random_state=420)

# 模組化
clf = DecisionTreeClassifier(criterion="entropy").fit(xtrain, ytrain)
# 傳回預測的準确度 accuracy
score = clf.score(xtest, ytest)  # 0.9629629629629629

feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚','類黃酮','非黃烷類酚類','花青素','顔色強度','色調','od280/od315稀釋葡萄酒','脯氨酸']
import graphviz
dot_data = tree.export_graphviz(clf
                                ,feature_names= feature_name
                                ,class_names=["琴酒","雪莉","貝爾摩德"]
                                ,filled=True
                                ,rounded=True
                                )
graph = graphviz.Source(dot_data)
print(graph)
           
  • filled=True

    按照所分的類别進行顔色填充
  • rounded=True

    顯示的方框是否為圓角
  • 通過繪制出的決策樹模型可以看到其中的

    entropy

    就是之前提到的資訊熵不純度計算方式的結果,越往後其值越小,驗證了:

    不純度基于節點來計算,樹中的每個節點都會有一個不純度,并且子節點的不純度一定是低于父節點的

    【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹
  • 檢視特征重要性,并比對。(類似于回歸模型中的回歸系數)
#特征重要性
feature_im = clf.feature_importances_
match = [*zip(feature_name,clf.feature_importances_)]
           
【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹

傳回頂部

② 重要參數:random_state & splitter

random_state用來設定分枝中的随機模式的參數

,預設None,在高次元時随機性會表現更明顯,低次元的資料(比如鸢尾花資料集),随機性幾乎不會顯現。輸入任意整數,會一直長出同一棵樹,讓模型穩定下來。

splitter也是用來控制決策樹中的随機選項的,有兩種輸入值

輸入”best"

,決策樹在分枝時雖然随機,但是還是會優先選擇更重要的特征進行分枝(重要性可以通過屬性feature_importances_檢視),

輸入“random"

,決策樹在分枝時會更加随機,樹會因為含有更多的不必要資訊而更深更大,并因這些不必要資訊而降低對訓練集的拟合。這也是防止過拟合的一種方式。當你預測到你的模型會過拟合,用這兩個參數來幫助你降低樹建成之後過拟合的可能性。當然,樹一旦建成,我們依然是使用剪枝參數來防止過拟合。

clf = tree.DecisionTreeClassifier(criterion="entropy"
                                 ,random_state=30
                                 ,splitter="random"
                                 )
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
score
import graphviz
dot_data = tree.export_graphviz(clf
                               ,feature_names= feature_name
                               ,class_names=["琴酒","雪莉","貝爾摩德"]
                               ,filled=True
                               ,rounded=True
                               )  
graph = graphviz.Source(dot_data)
graph
           
  • 顯然當設定splitter參數為random的時候,拟合出來的樹模型深度要比best的深(由于圖檔較大沒有截取完整的)。
    【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹
    傳回頂部

③ 剪枝參數

在不加限制的情況下,一棵決策樹會生長到衡量不純度的名額最優,或者沒有更多的特征可用為止。這樣的決策樹往往會過拟合,這就是說,它會在訓練集上表現很好,在測試集上卻表現糟糕。我們收集的樣本資料不可能和整體的狀況完全一緻,是以當一棵決策樹對訓練資料有了過于優秀的解釋性,它找出的規則必然包含了訓練樣本中的噪聲,并使它對未知資料的拟合程度不足。(

沒有絕對的完美,就是說對于模型對于訓練集的拟合越是完美,細節過于到位,其局限性就越高,或許拟合出來的模型對于新資料集的适應能力反而較差

)

為了讓決策樹有更好的泛化性,我們要對決策樹進行剪枝。

剪枝政策對決策樹的影響巨大,正确的剪枝政策是優化決策樹算法的核心

。sklearn為我們提供了不同的剪枝政策:

▶ max_depth

max_depth限制樹的最大深度

,超過設定深度的樹枝全部剪掉。這是用得最廣泛的剪枝參數,在高次元低樣本量時非常有效。決策樹多生長一層,對樣本量的需求會增加一倍,是以限制樹深度能夠有效地限制過拟合。在內建算法中也非常實用。實際使用時,建議從3開始嘗試,看看拟合的效果再決定是否增加設定深度。

【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹

▶ min_samples_leaf & min_samples_split

  • min_samples_leaf限定

    ,一個節點在分枝後的每個子節點都必須包含至少min_samples_leaf個訓練樣本,否則分枝就不會發生,或者,分枝會朝着滿足每個子節點都包含min_samples_leaf個樣本的方向去發生。一般搭配max_depth使用,在回歸樹中有神奇的效果,可以讓模型變得更加平滑。這個參數的數量設定得太小會引起過拟合,設定得太大就會阻止模型學習資料。一般來說,建議從5開始使用。如果葉節點中含有的樣本量變化很大,建議輸入浮點數作為樣本量的百分比來使用。同時,這個參數可以保證每個葉子的最小尺寸,可以在回歸問題中避免低方差,過拟合的葉子節點出現。對于類别不多的分類問題,1通常就是最佳選擇。
    【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹
  • min_samples_split限定

    ,一個節點必須要包含至少min_samples_split個訓練樣本,這個節點才允許被分枝,否則分枝就不會發生。
    【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹

▶ max_features & min_impurity_decrease

  • 一般max_depth使用,用作樹的”精修“。
  • max_features

    限制分枝時考慮的特征個數,超過限制個數的特征都會被舍棄。和max_depth異曲同工,max_features是用來限制高次元資料的過拟合的剪枝參數,但其方法比較暴力,是直接限制可以使用的特征數量而強行使決策樹停下的參數,在不知道決策樹中的各個特征的重要性的情況下,強行設定這個參數可能會導緻模型學習不足。如果希望通過降維的方式防止過拟合,建議使用PCA,ICA或者特征選擇子產品中的降維算法。
  • min_impurity_decrease

    限制資訊增益的大小,資訊增益小于設定數值的分枝不會發生。sklearn實際計算的是基于資訊熵的資訊增益(Information Gain),即

    父節點的資訊熵和子節點的資訊熵之差

    。也就是說當父節點與子節點之間的的entroy差越大,就說明該層對于整棵樹的拟合效果貢獻越大

▶ 确認最優剪枝參數

  • 那具體怎麼來确定每個參數填寫什麼值呢?這時候,我們就要使用确定超參數的曲線來進行判斷了,繼續使用我們

    已經訓練好的決策樹模型clf。

    超參數的學習曲線,是一條以超參數的取值為橫坐标,模型的度量名額為縱坐标的曲 線,它是用來衡量不同超參數取值下模型的表現的線

    。在我們建好的決策樹裡,我們的模型度量名額就是score。
import matplotlib.pyplot as plt

scores = []
for i in range(10):
    clf = tree.DecisionTreeClassifier(criterion="entropy"
                                     ,random_state=30
                                     ,splitter="random"
                                     ,max_depth=i+1
                                     ).fit(xtrain, ytrain)
    score = clf.score(xtest, ytest)
    scores.append(score)
fig = plt.figure(figsize=(10,6))
plt.plot(range(1,11),scores)
plt.show()
           

這裡我們使用不同的max_depth參數來進行學習曲線的繪制,通過圖像可以看出,在樹的深度為5的時候,模型精确度達到了最大,為6的時候有所下降,并且之後保持不變,說明6之後的樹深度對于模型的影響幾乎沒有。

【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹

▶ 目标權重參數:class_weight & min_weight_fraction_leaf

  • 完成樣本标簽平衡的參數

    。樣本不平衡是指在一組資料集中,标簽的一類天生占有很大的比例。比如說,在銀行要判斷“一個辦了信用卡的人是否會違約”,就是是vs否(1%:99%)的比例。這種分類狀況下,即便模型什麼也不做,全把結果預測成“否”,正确率也能有99%。是以我們要使用class_weight參數對樣本标簽進行一定的均衡,給少量的标簽更多的權重,讓模型更偏向少數類,向捕獲少數類的方向模組化。

    該參數預設None,此模式表示自動給與資料集中的所有标簽相同的權重

  • 有了權重之後,樣本量就不再是單純地記錄數目,而是受輸入的權重影響了,是以這時候剪枝,就需要搭配min_weight_fraction_leaf這個基于權重的剪枝參數來使用。另請注意,基于權重的剪枝參數(例如min_weight_fraction_leaf)将比不知道樣本權重的标準(比如min_samples_leaf)更少偏向主導類。如果樣本是權重的,則使用基于權重的預修剪标準來更容易優化樹結構,這確定葉節點至少包含樣本權重的總和的一小部分。

傳回頂部

④ 重要屬性和接口

屬性是在模型訓練之後,能夠調用檢視的模型的各種性質。

對決策樹來說,最重要的是feature_importances_,能夠檢視各個特征對模型的重要性

。sklearn中許多算法的接口都是相似的,比如說我們之前已經用到的

fit

score

,幾乎對每個算法都可以使用。除了這兩個接口之外,決策樹最常用的接口還有

apply

predict

apply中輸入測試集傳回每個測試樣本所在的葉子節點的索引

predict輸入測試集傳回每個測試樣本的标簽

【skLearn 分類、回歸算法】DecisionTreeClassifier 分類樹DecisionTreeClassifier 分類樹

傳回頂部

總結

七個參數:

  • Criterion

    不純度計算
  • 兩個随機性相關的參數(

    random_state

    splitter

  • 四個剪枝參數(

    max_depth

    ,

    min_sample_leaf

    max_feature

    min_impurity_decrease

一個屬性:

feature_importances_

四個接口:

fit

score

apply

predict

繼續閱讀