機器學習:決策樹(使用信息熵尋找最優划分)


  • 老師強調作為計算機工程師,傳統的算法和數據結構是最基礎的內容,要掌握。

一、節點數據集的划分

 1)決策樹算法的思想

  • 解決分類問題時,決策樹算法的任務是構造決策樹模型,對未知的樣本進行分類;
  • 決策樹算法利用了信息熵和決策樹思維:
  1. 信息熵越小的數據集,樣本的確定性越高,當數據集的信息熵為 0 時,該數據集中只有一種類型的樣本;
  2. 訓練數據集中有很多類型的樣本,通過對數據集信息熵的判斷,逐層划分數據集,最終將每一類樣本單獨划分出來;
  3. 划分數據集的方式有很多種,只有當按樣本類別划分數據集時(也就是兩部分數據集中不會同時存在相同類型的樣本),划分后的兩部分數據集的整體的信息熵最小;反相推斷,當兩部分數據集的整體的信息熵最小時,則兩部分數據集中不會同時存在相同類型的樣本;

 

 2)划分步驟

  • 划分點:某一特征的某一個數值;(根據該特征值對數據集樣本進行划分)
  • 數據集中樣本的排序:根據特征的數值大小進行排序;
  1. (一般不直接打亂原始數據集中樣本的排列順序,而是使用 np.argsorted( 特征向量 ),返回特征向量中元素排序后對應的 index)

 

  • 選取划分點:要沒有遺漏的迭代所有情況的划分點對應的划分情況;
  1. 將特征值排序后,從 0 號開始,選取相鄰的但不相等的兩個特征值的平均數作為一個划分點;按此方式迭代找出一組特質向量中的所有划分點;

 

 4)划分結果

  1. 兩種數據集:X_left、X_right 機器對應的 y;
  2. 特征類型,及其最優的划分點的特征值;

 

 5)代碼實現划分過程

  • 划分根節點的數據集
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn import datasets
    
    iris = datasets.load_iris()
    X = iris.data[:, 2:]
    y = iris.target

     

  • 划分函數:返回數據集 X1、X2、y1、y2
    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]
  1. d:特征;
  2. value:特征值;
  • 信息熵計算函數
    from collections import Counter
    from math import log
    
    def entropy(y):
        counter = Counter(y)
        res = 0.0
        for num in counter.values():
            p = num / len(y)
            res += -p * log(p)
        return res
  1. counter = Counter(y):將向量 y 做成一個字典;
  2. counter 的 key:y 中各種數據;
  3. counter 的value:key 對應的數據在 y 中的個數;
  4. Counter(list/tuple/str/array等序列):以字典的形式返回 序列中所有元素及其數量;(可以起到去重的作用)
  • 尋找最優的特征 d 及其對應的特征值 value、最小信息熵 entropy
    def try_split(X, y):
    
        best_entropy = 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)
                    e = entropy(y_l) + entropy(y_r)
                    if e < best_entropy:
                        best_entropy, best_d, best_v = e, d, v
                        
        return best_entropy, best_d, best_v
  1. float('inf'):'inf'表示正無窮的值;
  2. np.argsort(X[:, d]):返回數據集 X 在第 d 列的排序的 index,並沒有打亂數據集 X 的樣本排列順序;
  • 第一次划分
    best_entropy, best_d, best_v = try_split(X, y)
    
    x1_l, x1_r, y1_l, y1_r = split(X, y, best_d, best_v)

     

  • 第二次划分數據集
  1. 判斷數據集的信息熵是否為 0,如果等於 0,說明該數據集中只有一種類型的樣本,不需要再進行划分;反之則需要再次進行划分;
  2. 划分方法與第一次划分的過程一樣;

 


免責聲明!

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



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