機器學習-演算法-細談決策樹分類樹(DecisionTreeClassifier)

Introduction

  • 一種非參數監督學習(有目標值)的演算法
    • 非參數:不限制數據的結構與類型
      • 任何數據皆適用
  • 只要是決策樹的葉子節點(有進邊,沒有出邊),都是一個類別的標籤
  • 決策樹演算法的核心是要解決兩個問題
    • 如何從數據中找出最佳節點最佳分枝
    • 如何讓決策樹停止生長,防止過擬合

sklearn中的決策樹

  • sklearn中關於決策樹的類(不包含集成演算法)都在sklearn.tree這個模塊下,共包含五個類
    • tree.DecisionTreeClassifier:分類樹
    • tree.DecisionTreeRegressor:回歸樹
    • tree.export_graphviz:將生成的決策樹導出為DOT格式,畫圖專用
    • tree.ExtraTreeClassifier高隨機版本的分類樹
    • tree.ExtraTreeRegressor高隨機版本的回歸樹

DecisionTreeClassifier

1
2
3
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

對分類樹來說,找出最佳節點及分枝的指標為"不純度",不純度越低,決策樹對訓練集得的擬合越好
決策樹就是追求不純度相關指標的最優化

  • 樹中的每個節點都會有一個不純度
    • 子節點的不純度定低於父節點
    • 葉子節點的不純度是最低的
  • "entropy": 使用信息熵
    • 信息熵對不純度叫基尼係數強(對不純度懲罰最強)
      • 容易過擬合
    • 實際使用中兩者效果基本一樣
  • "gini":使用基尼係數
    • 適用於數據維度大,噪音很大的數據

隨機性參數

random_state

設置分枝中隨機模式的參數,預設為None
使用同一批訓練集(Xtrain)進行訓練,得到的準確度仍有差異,原因決策樹本身就具有隨機性
輸入任意整數,會針對特定模型選定的feature,長出同一顆樹讓模型穩定下來(固定隨機性)

  • 調參優化時通常會固定random_state

splitter

用作控制決策樹的隨機性

  • "best":
    • 決策樹雖然本身就具有隨機性,但會優先選擇更重要的特徵進行分枝
  • "random:
    • 決策樹在分枝時會更為隨機
      • 樹深度更深
      • 對訓練集的擬合會降低(防止過擬合的一種方式)

剪枝參數

決策樹會生長到衡量不純度最優,或者沒有更多特徵可用為止

  • 這樣決策樹往往會過擬合
  • 會在訓練集上表現很好,測試集卻很糟糕
  • 為了決策樹有更好的泛化性,須對決策樹進行剪枝
    • 剪枝策略對決策樹的影響巨大,正確的剪枝策略是優化決策樹算法的核心

max_depth

限制樹的最大深度,超過設定深度的樹枝全部剪掉

  • 用的最廣泛的剪枝參數
  • 高維度、低樣本量時非常有效
  • 在集成算法中也非常實用
  • 建議從 = 3開始嘗試

min_samples_leaf

一個節點在分枝後每個子節點都必須包含至少min_samples_leaf訓練樣本
分枝會朝著滿足每個子節點都包含min_samples_leaf個樣本的方向去發展

  • 一般搭配max_depth使用
  • 一般建議從= 5開始使用
  • 如果葉節點中含有的樣本量變化很大,建議輸入浮點樹作為樣本量的百分比使用

min_samples_split

一個中間節點必須包含至少min_samples_split個訓練樣本,這個節點在允許被分枝,否則分枝不會發生

max_features

限制分枝時考慮的特徵個數,超過限制個數的特徵都會被捨棄
max_depth異曲同工

  • 在不知道決策樹中的各個特徵的重要性情況下,設定這個參數會導致學習不足

min_impurity_decrease

限制信息增益的大小
信息增益小於設定數值的分枝不會發生

利用matplotlib畫出學習曲線來確認最優的剪枝參數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import matplotlib.pyplot as plt
y_eff = []
for i in range(10): # 測試的條件數
tree_clf = tree.DecisionTreeClassifier(criterion="entropy"
,random_state = 30
,splitter = "random"
,max_depth = i+1 #測試條件
)
tree_clf = tree_clf.fit(Xtrain,ytrain)
score = tree_clf.score(Xtest,ytest)
y_eff.append(score)
plt.plot(range(1,11),y_eff,color="red",label="max_depth")
plt.legend()
plt.show()

目標權重參數

控制目標權重的參數

class_weight

樣本不平衡是指在一組數據集中,某個標籤天生佔有很大的比例
完成樣本標籤平衡的參數,對樣本標籤進行一定的均衡

  • 給少量的標籤更多的權重
  • 讓模型更偏向少數類,向捕獲少數類的方向建模
  • 該參數默認為None
    • 自動給予數據集中的所有標籤相同的權重

min_weight_fraction_leaf

有了權重之後,樣本量就不再是單純記錄樹目,而是受輸入權重影響
此時剪枝須搭配min_weight_fraction_leaf這個基於權重的剪枝參數使用

重要屬性和接口

所有接口中要求輸入X_train,X_test的部分,輸入的特徵矩陣必須至少是一個二維的矩陣

  • sklearn不接受任何一維矩陣作為特徵矩陣被輸入
    • 如果數據確實只有一個特徵的data
      • 必須用reshape(-1,1)來給矩陣增維
    • 如果數據只有一個特徵和一個樣本(one-sample)
      • 必須用reshape(1,-1)來給數據增維

estimator.apply(Xtest)

返回每個測試樣本所在的葉子節點的索引

  • 只輸入測試集,返回預測的結果

estimator.predict(Xtest)

返回每個測試樣本分類/回歸的結果

  • 只輸入測試集,返回預測的結果

結論

分類樹(DecisionTreeClassifier)天生不擅長環形數據,每個模型都有自己決策的上限

  • 一個怎樣調整參數都無法提升的表現的可能性仍存在

Reference

  1. http://www.peixun.net/view/1281.html