機器學習:決策樹(使用基尼系數划分節點數據集)


一、基礎理解

  1. 決策樹結構中,每個節點處的數據集划分到最后,得到的數據集中一定只包含一種類型的樣本;

 1)公式

  1. k:數據集中樣本類型數量;
  2. Pi:第 i 類樣本的數量占總樣本數量的比例

 

 2)實例計算基尼系數

  • 3 種情況計算基尼系數:
  • 基尼系數的性質與信息熵一樣:度量隨機變量的不確定度的大小
  1. G 越大,數據的不確定性越高;
  2. G 越小,數據的不確定性越低;
  3. G = 0,數據集中的所有樣本都是同一類別;

 

 3)只有兩種類別的數據集

  1. x:兩類樣本中,其中一類樣本數量所占全部樣本的比例;
  2. 當 x = 0.5,兩類樣本數量相等時,數據集的確定性最低;

 

 

二、使用基尼系數划分節點數據集

 1)格式

  • from sklearn.tree import DecisionTreeClassifier
    
    dt_clf = DecisionTreeClassifier(max_depth=2, criterion='gini')
    dt_clf.fit(X, y)
  1. criterion='gini'使用 “基尼系數” 方式划分節點數據集;
  2. criterion='entropy'使用 “信息熵” 方式划分節點數據集;

 

 2)代碼實現

  • 導入數據集
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn import datasets
    
    iris = datasets.load_iris()
    X = iris.data
    y = iris.target

     

  • 封裝函數:

  1. split():划分數據集;
  2. gini():計算數據集的基尼系數;
  3. try_split():尋找最佳的特征、特征值、基尼系數;
    from collections import Counter
    from math import log
    
    def split(X, y, d, value):
        index_a = (X[:, d] <= value)
        index_b = (X[:, d] > value)
        return X[index_a], X[index_b], y[index_a], y[index_b]
    
    def gini(y):
        counter = Counter(y)
        res = 1.0
        for num in counter.values():
            p = num / len(y)
            res += -p**2
        return res
    
    def try_split(X, y):
        
        best_g = float('inf')
        best_d, best_v = -1, -1
        for d in range(X.shape[1]):
            sorted_index = np.argsort(X[:,d])
            for i in range(1, len(X)):
                if X[sorted_index[i-1], d] != X[sorted_index[i], d]:
                    v = (X[sorted_index[i-1], d] + X[sorted_index[i], d]) / 2
                    x_l, x_r, y_l, y_r = split(X, y, d, v)
                    g = gini(y_l) + gini(y_r)
                    if g < best_g:
                        best_g, best_d, best_v = g, d, v
                        
        return best_g, best_d, best_v

     

  • 第一次划分

    best_g, best_d, best_v = try_split(X, y)
    X1_l, X1_r, y1_l, y1_r = split(X, y, best_d, best_v)
    
    gini(y1_l)
    # 數據集 X1_l 的基尼系數:0.0
    
    gini(y1_r)
    # 數據集 X1_r 的基尼系數:0.5

    # 判斷:數據集 X1_l 的基尼系數等於 0,不需要再進行划分,;數據集 X1_r 需要再次進行划分;

 

  • 第二次划分

    best_g2, best_d2, best_v2 = try_split(X1_r, y1_r)
    X2_l, X2_r, y2_l, y2_r = split(X1_r, y1_r, best_d2, best_v2)
    
    gini(y2_l)
    # 數據集 X2_l 的基尼系數:0.1680384087791495
    
    gini(y2_r)
    # 數據集 X2_l 的基尼系數:0.04253308128544431

    # 判斷:數據集 X2_l 和 X2_r 的基尼系數不為 0,都需要再次進行划分;

 

 

三、信息熵  VS  基尼系數

  • 信息熵的計算比基尼系數慢
  1. 原因:計算信息熵 H 時,需要計算一個 log(P),而基尼系數只需要計算 P2
  2. 因此,scikit-learn 中的  DecisionTreeClassifier()  類中,參數  criterion = 'gini',默認選擇基尼系數的方式進行划分節點數據集;
  • 大多數時候,二者沒有特別的效果優劣;

 


免責聲明!

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



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