決策樹分類及實例


本文介紹機器學習中最基礎最簡單的決策樹分類
參考:

一. 理論

1.決策樹的介紹

決策樹算法是最流行的機器學習算法之一。它使用樹狀結構及其可能的組合來解決特定的問題。它屬於監督學習算法的一類,可以用於分類和回歸目的。
決策樹是一種包含根節點、分支和葉節點的結構。每個內部節點表示對一個屬性的測試,每個分支表示測試的結果,每個葉節點保存一個類標簽。樹中最頂端的節點是根節點。

2.分類和回歸樹(CART)

CART是一個二叉樹,也是回歸樹,同時也是分類樹,CART的構成簡單明了。CART只能將一個父節點分為2個子節點。CART用GINI指數來決定如何分裂。
回歸解析用來決定分布是否終止。理想地說每一個葉節點里都只有一個類別時分類應該停止,但是很多數據並不容易完全划分,或者完全划分需要很多次分裂,必然造成很長的運行時間,所以CART可以對每個葉節點里的數據分析其均值方差,當方差小於一定值可以終止分裂,以換取計算成本的降低。

3.熵增和基尼系數

熵度量給定數據集中的雜質。在物理學和數學中,熵指的是隨機變量x的隨機性或不確定性。在信息論中,熵指的是一組例子中的雜質。信息增益是熵的減少。信息增益是根據給定的屬性值計算數據集分割前的熵值與分割后的平均熵值的差值。

c是類的個數pi是第i類的概率。
ID3 (Iterative Dichotomiser)決策樹算法使用熵來計算信息增益。因此,通過計算每個屬性的熵減,我們可以計算出它們的信息增益。選擇信息增益最高的屬性作為節點的分割屬性。

基尼系數


c是類的個數pi是第i類的概率。

基尼指數表示,如果我們從總體中隨機選擇兩項,它們必須屬於同一類如果總體是純的,概率為1。
它與分類目標變量“成功”或“失敗”一起工作。它只執行二進制分割。基尼系數越高,同質性越高。CART (Classification and Regression Tree)使用基尼方法創建二進制分割。

計算分割Gini的步驟

  1. 計算子節點的Gini,使用公式成功和失敗概率的平方和(p2 + q2)。
  2. 使用該分割的每個節點的加權基尼值計算分割的基尼值。
  3. 對於離散值屬性,給出所選屬性的最小基尼指數的子集被選為分割屬性。對於連續值屬性,該策略是選擇每一對相鄰值作為可能的分割點,並選擇基尼指數較小的點作為分割點。選擇基尼指數最小的屬性作為分割屬性。

4.過擬合

在建立決策樹模型時,過擬合是一個實際問題。當算法不斷深入以減少訓練集誤差而導致測試集誤差增大時,考慮過擬合問題。因此,我們模型的預測精度下降了。當我們由於數據中的異常值和不規則性而構建許多分支時,通常會發生這種情況。
有兩種方法可以用來避免過擬合:

  • Pre-Pruning
    在Pre-Pruning中,我們提前一點停止樹的構造。如果節點的優度度量值低於閾值,我們不希望拆分節點。但是很難選擇一個合適的停靠點。

  • Post-Pruning
    在Post-Pruning中,我們在樹中越走越深,以構建一個完整的樹。如果樹顯示過擬合問題,那么剪枝作為后剪枝步驟進行。我們使用交叉驗證數據來檢查修剪的效果。使用交叉驗證數據,我們測試擴展一個節點是否會導致改進。如果它顯示了改進,那么我們可以繼續擴展該節點。但如果它顯示了准確性的下降,那么它就不應該擴大。因此,節點應該被轉換為葉節點。

二. 實踐

數據預覽
本例所用數據為汽車的分類。輸入features如下,輸出分為acc, noacc, good 3個等級

這里的doors和persons並不一定是數字,有5more和more代表車具有更多的車門和座位

本例通過sklearn來做決策樹
導入庫和數據:

import pandas as pd
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
import matplotlib.pyplot as plt

df = pd.read_csv('car_evaluation.csv')

預處理(編碼):

FEATURES_NEED_ENCODE = ['buying', 'maint', 'doors', 'persons','lug_boot', 'safety', 'class']

for feature in FEATURES_NEED_ENCODE:
    le = preprocessing.LabelEncoder()
    le.fit(df[feature].unique())
    df[feature] = le.transform(df[feature])

X = df.drop(['class'], axis=1)

y = df['class']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 42)

訓練:

clf_gini = DecisionTreeClassifier(criterion='gini', max_depth=3, random_state=0)
clf_gini.fit(X_train, y_train)
print('Prediction Accuracy:', (clf_gini.score(X_test, y_test) * 100), '%')

畫出決策樹:

tree.plot_tree(clf_gini)
plt.show()


如果用熵增來做:

clf_en = DecisionTreeClassifier(criterion='entropy', max_depth=3, random_state=0)
clf_en.fit(X_train, y_train)
print('Prediction Accuracy:', (clf_en.score(X_test, y_test) * 100), '%')

tree.plot_tree(clf_gini)
plt.show()

關於DecisionTreeClassifier的參數詳見:
https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM