天天看點

【sklearn】1.分類決策樹前言決策樹簡介sklearn中的決策樹sklearn的基本模組化流程分類樹 DecisionTreeClassifier

前言

決策樹是機器學習中的一種常用算法。相關數學理論我也曾在數學模組化專欄中數學模組化學習筆記(二十五)決策樹

介紹過,本篇博文不注重相關數學原理,主要注重使用sklearn實作分類樹的效果。

參考課程見【2020機器學習全集】菜菜的sklearn完整版

決策樹簡介

決策樹(Decision Tree)是一種非參數的有監督學習方法,它能夠從一系列有特征和标簽的資料中總結出決策規則,并用樹狀圖的結構來呈現這些規則,以解決分類和回歸問題。

sklearn中的決策樹

  • 子產品sklearn.tree
樹類型 庫表示
分類樹 tree.DecisionTreeClassifier
回歸樹 tree.DecisionTreeRegressor
生成的決策樹導出為DOT格式,畫圖專用 tree.export_graphviz
高随機版本的分類樹 tree.ExtraTreeClassifier
高随機版本的回歸樹 tree.ExtraTreeRegressor

sklearn的基本模組化流程

【sklearn】1.分類決策樹前言決策樹簡介sklearn中的決策樹sklearn的基本模組化流程分類樹 DecisionTreeClassifier

對應python代碼

from sklearn import tree #導入需要的子產品

clf = tree.DecisionTreeClassifier()     #執行個體化
clf = clf.fit(X_train,y_train) #用訓練集資料訓練模型
result = clf.score(X_test,y_test) #導入測試集,從接口中調用需要的資訊
           

分類樹 DecisionTreeClassifier

重要參數

criterion 決定不純度的計算方法

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

通俗了解:為了将一群混在一起的複雜樣本分開,用不純度來進行衡量,沒分之前,也就是根節點,不純度最高,之後越往下面不純度越低,到葉子節點,就完全分離開,不純度最低,得到的結果最“純淨”!

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

1)輸入”entropy“,使用資訊熵(Entropy)

2)輸入”gini“,使用基尼系數(Gini Impurity)

【sklearn】1.分類決策樹前言決策樹簡介sklearn中的決策樹sklearn的基本模組化流程分類樹 DecisionTreeClassifier

不填寫,預設的是gini。

sklearn實際計算的是基于資訊熵的資訊增益(Information Gain),即父節點的資訊熵和子節點的資訊熵之差。

選取規則:

通常就使用基尼系數

資料次元很大,噪音很大時使用基尼系數

次元低,資料比較清晰的時候,資訊熵和基尼系數沒差別

當決策樹的拟合程度不夠的時候,使用資訊熵

兩個都試試,不好就換另外一個

建立分類樹步驟

1.導入需要的算法庫和子產品

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

2.檢視資料

這裡使用的是sklearn自帶的wine資料集。

wine = load_wine()
print(wine.data.shape)

print(pd.concat([pd.DataFrame(wine.data), pd.DataFrame(wine.target)], axis=1))
print(wine.feature_names)
print(wine.target_names)
           
【sklearn】1.分類決策樹前言決策樹簡介sklearn中的決策樹sklearn的基本模組化流程分類樹 DecisionTreeClassifier

總共178條資料,3分類問題。

3.劃分訓練集和測試集

Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data,wine.target,test_size=0.3)
print(Xtrain.shape)
print(Xtest.shape)
           

test_size=0.3表示測試集占樣本數量的30%

劃分之後,訓練集為124條資料,測試集為54條資料。

4.模型建立

clf = tree.DecisionTreeClassifier(criterion="entropy")
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest) # 傳回預測的準确度
print(score)
           

這裡選用資訊熵entropy作為計算方法。

score代表準确度

由于決策樹的建立包含随機變量,每次運作結果都不一樣。

這裡我運作幾次大緻結果準确率在90%以上。

5.決策樹可視化

feature_name = ['酒精','蘋果酸','灰','灰的堿性','鎂','總酚','類黃酮','非黃烷類酚類','花青素','顔色強度','色調','od280/od315稀釋葡萄酒','脯氨酸']

dot_data = tree.export_graphviz(clf
                               ,feature_names= feature_name
                               ,class_names=["類型一","類型二","類型三"]
                               ,filled=True  #控制顔色填充
                               ,rounded=True  #控制圖檔為圓角
                               )
graph = graphviz.Source(dot_data.replace('helvetica','"Microsoft YaHei"'), encoding='utf-8')
graph.view()
           

這裡直接運作會報錯,問題是雖然安裝了graphviz庫,但仍需安裝graphviz插件才能顯示圖檔。

插件下載下傳位址https://graphviz.gitlab.io/download/

windows選擇:

【sklearn】1.分類決策樹前言決策樹簡介sklearn中的決策樹sklearn的基本模組化流程分類樹 DecisionTreeClassifier

在安裝時,勾選将graphviz添加到環境變量

【sklearn】1.分類決策樹前言決策樹簡介sklearn中的決策樹sklearn的基本模組化流程分類樹 DecisionTreeClassifier

replace(‘helvetica’,’“Microsoft YaHei”’), encoding='utf-8’目的是防止中文亂碼,使用utf-8進行重新編碼。

運作之後,會直接打開一張pdf圖檔。

【sklearn】1.分類決策樹前言決策樹簡介sklearn中的決策樹sklearn的基本模組化流程分類樹 DecisionTreeClassifier

這就是分類決策樹,每一個分支節點上第一行代表分支的依據。

顔色代表不純度,顔色越深代表代表不純度越小,葉子節點不純度為0。

6.特征重要性顯示

上圖的決策樹分支是根據特征重要性(資訊增益)來進行分支,通過下面的程式可以列印出各個特征的重要性。

print([*zip(feature_name,clf.feature_importances_)])
           

得到結果:

[('酒精', 0.0), ('蘋果酸', 0.0), ('灰', 0.0), ('灰的堿性', 0.03448006546085971), ('鎂', 0.0), ('總酚', 0.0), ('類黃酮', 0.4207777417026953), ('非黃烷類酚類', 0.0), ('花青素', 0.0), ('顔色強度', 0.1444829682905809), ('色調', 0.03408453152321241), ('od280/od315稀釋葡萄酒', 0.0), ('脯氨酸', 0.3661746930226517)]
           

有些特征的重要性為0,說明這些名額在決策樹中沒有被利用。

随機參數 random_state & splitter

在上面的例子中,每次運作結果都會有些不同,原因在于使用sklearn自帶的決策樹時,它會預設“栽種”好幾棵不同的決策樹,從中傳回出效果最好的那一棵。

random_state用來設定分枝中的随機模式的參數,預設None,輸入任意整數,會一直長出同一棵樹,讓模型穩定下來。

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

  • 輸入”best",決策樹在分枝時雖然随機,但是還是會優先選擇更重要的特征進行分枝(重要性可以通過屬性feature_importances_檢視)
  • 輸入“random",決策樹在分枝時會更加随機,樹會因為含有更多的不必要資訊而更深更大,并因這些不必要資訊而降低對訓練集的拟合。這也是防止過拟合的一種方式。
clf = tree.DecisionTreeClassifier(criterion="entropy"
                                 ,random_state=30
                                 ,splitter="random"
                                 )
           

設定随機參數可以讓決策樹穩定或者更随機,效果不确定,一切以最後的score為主。

剪枝政策 max_depth

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

策樹多生長一層,對樣本量的需求會增加一倍。

實際使用時,建議從=3開始嘗試,看看拟合的效果再決定是否增加設定深度。

剪枝政策 min_samples_leaf & min_samples_split

min_samples_leaf限定,一個節點在分枝後的每個子節點都必須包含至少min_samples_leaf個訓練樣本,否則分

枝就不會發生,一般來說,建議從=5開始使用。

min_samples_split限定,一個節點必須要包含至少min_samples_split個訓練樣本,這個節點才允許被分枝,否則

分枝就不會發生。

clf = tree.DecisionTreeClassifier(criterion="entropy"
                                 ,random_state=30
                                 ,splitter="random"
                                 ,max_depth=3
                                 ,min_samples_leaf=10
                                 ,min_samples_split=10
                                 )
           

剪枝政策max_features & min_impurity_decrease

max_features限制分枝時考慮的特征個數,超過限制個數的特征都會被舍棄。

min_impurity_decrease限制資訊增益的大小,資訊增益小于設定數值的分枝不會發生。

确認最優的剪枝參數

通過程式設計循環,控制其它量不變,一個量循環改變,畫圖顯示,可以顯示出這個量的最優值。

下面以max_depth為例:

import matplotlib.pyplot as plt

test = []
for i in range(10):
    clf = tree.DecisionTreeClassifier(max_depth=i+1
                                     ,criterion="entropy"
                                     ,random_state=30
                                     ,splitter="random"
                                     )
    clf = clf.fit(Xtrain, Ytrain)
    score = clf.score(Xtest, Ytest)
    test.append(score)
plt.plot(range(1,11),test,color="red",label="max_depth")
plt.legend()
plt.show()
           

繪制結果如圖所示

【sklearn】1.分類決策樹前言決策樹簡介sklearn中的決策樹sklearn的基本模組化流程分類樹 DecisionTreeClassifier

說明max_depth取4時,效果最好。

目标權重參數class_weight & min_weight_fraction_leaf

想象這種情況:在銀行要判斷“一個辦了信用卡的人是否會違約”,就是 是vs否(1%:99%)的比例,在這種情況下,出現了樣本不平衡,這個時候就需要調整其目标權重參數。

使用class_weight參數對樣本标簽進行一定的均衡,給少量的标簽更多的權重,讓模型更偏向少數類,向捕獲少數類的方向模組化。該參數預設None,此模式表示自動給與資料集中的所有标簽相同的權重。

有了權重之後,樣本量就不再是單純地記錄數目,而是受輸入的權重影響了,是以這時候剪枝,就需要搭配min_weight_fraction_leaf這個基于權重的剪枝參數來使用。

重要屬性和接口

1.(上面提到過)feature_importances_

能夠檢視各個特征對模型的重要性

注意後面的下劃線_不能省略

2.apply

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

clf.apply(Xtest)
           

3.predict傳回每個測試樣本的分類/回歸結果

clf.predict(Xtest)
           

其它内容補充

分類樹天生不擅長環形資料,最擅長月亮型資料的是最近鄰算法,RBF支援向量機和高斯過程;最擅長環形資料的是最近鄰算法和高斯過程;最擅長對半分的資料的是樸素貝葉斯,神經網絡和随機森林。

【sklearn】1.分類決策樹前言決策樹簡介sklearn中的決策樹sklearn的基本模組化流程分類樹 DecisionTreeClassifier

上面是分類樹的結果,環形資料可以看到左側出現一塊白色,說明分類效果不好。

繼續閱讀