查看原文
其他

第8.6节 连续型特征变量下决策树实现

空字符 月来客栈 2024-01-21

各位朋友大家好,欢迎来到月来客栈,我是掌柜空字符。

本期推送内容目录如下,如果本期内容对你有所帮助,欢迎点赞、转发支持掌柜!

  • 8.6 连续型特征变量下决策树实现
    • 8.6.1 特征离散化实现
    • 8.6.2 信息熵与条件熵实现
    • 8.6.3 决策树构建实现
    • 8.6.4 样本预测实现
    • 8.6.5 使用示例
    • 8.6.6 小结
    • 引用

8.6 连续型特征变量下决策树实现

上一节内容中,笔者详细介绍了如何基于ID3与C4.5的原理来一步一步从零开始实现决策树模型,不过由于原始的决策树模型均是针对离散型的特征变量,因此并不能对连续型的特征变量进行建模处理。在这节内容中笔者将采用sklearn库中的做法来对连续型特征进行离散化处理,并以此来实现ID3与C4.5的建模过程。值得一提的是,在sklearn中不管输入的是离散型变量还是连续型变量,都会先对其以同样的方式来进行离散化处理,下面笔者也将采用同样的做法来进行处理。

8.6.1 特征离散化实现

由于在第8.5节内容中笔者已经详细介绍了对于离散型特征输入的ID3与C4.5的决策树实现过程,因此接下来只需要以之前的代码框架为基础,对其中部分判断逻辑进行修改即可。在实现这部分内容之前,笔者先来介绍如何对特征进行离散化。本节所有实现代码可参见Book/Chapter08/C14_id3_continuous.py文件。

根据第8.2.5节内容可知,连续型特征变量的离散化过程可以先对原始特征进行排序处理,然后取所有连续两个值的均值来离散化整个连续型特征变量。在清楚上述特征离散化的原理后,便可以来进一步对其编码实现,实现代码如下所示:

 1     def _get_feature_values(self, data):
 2         n_features = data.shape[1]
 3         feature_values = {}
 4         for i in range(n_features):
 5             x_feature = sorted(set(data[:, i]))  # 去重与排序
 6             tmp_values = [x_feature[0]]  # 左边插入最小值
 7             for j in range(1, len(x_feature)):
 8                 tmp_values.append(round((x_feature[j - 1] + x_feature[j]) / 24))
 9             tmp_values.append(x_feature[-1])  # 右边插入最大值
10             feature_values[i] = tmp_values
11         return feature_values

在上述代码中,第2行是得到特征的维度数量;第4~5行是遍历每一列特征维度并进行排序以及去重处理;第7~8行是计算得到两两相邻的特征值之间的平均值作为离散特征;第6、9行是为了方便后续决策树的实现,所以在离散化特征的两边分别加入了原始特征中的最小值和最大值。

最终,通过上述方法便可以得到离散化后的数据特征。例如对于如下测试数据来说

1 x = np.array([[34567],
2               [22358],
3               [33889.]])
4 x = _get_feature_values(x)
5 print(x)
6 {0: [2.02.53.0], 1: [2.02.53.54.0], 2: [3.04.06.58.0],
7  3: [5.05.57.08.0], 4: [7.07.58.59.0]}

在上述结果中,第6~7行便是原始输入特征离散化后的结果,其中key表示特征维度的ID,value表示该特征维度对应的离散化特征取值。

8.6.2 信息熵与条件熵实现

在完成特征离散化的编码工作后,下一步便可以开始对第8.5.2中实现的代码进行修改以满足离散化特征的需求。信息熵的计算代码修改如下所示:

1     def _compute_entropy(self, y_class):
2         y_unique = np.unique(y_class)
3         if y_unique.shape[0] == 1:  # 只有一个类别
4             return 0.  # 熵为0
5         ety = 0.
6         for i in range(len(y_unique)):  # 取每个类别
7             p = np.sum(np.abs(y_class - y_unique[i]) < 0.0001) / len(y_class)
8             ety += p * np.log2(p)
9         return -ety

在上述代码中,第1行是定义一个方法来计算信息熵,主要用于ID3和C4.5中计算样本的信息熵,以及C4.5中特征的信息熵;第2行是计算得到当前输入有多少重类别(或特征取值);第3~4行则是判断如果只有一个类别则信息熵为0;第6~8行是分别遍历么一个类别,然后计算信息熵。值得注意的是,因为同时要计算特征维度的信息熵,而特征是浮点型所以一般不会用==来判断两者是否相等。

为你认可的知识付费,欢迎订阅本专栏阅读更多优质内容!

继续滑动看下一个

第8.6节 连续型特征变量下决策树实现

空字符 月来客栈
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存