机器学习:决策树(使用信息熵寻找最优划分)

  • 老师强调作为计算机工程师,传统的算法和数据结构是最基础的内容,要掌握。

一、节点数据集的划分

 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. 划分方法与第一次划分的过程一样;
原文地址:https://www.cnblogs.com/volcao/p/9477776.html