ID3算法熵计算中log2(0)问题及代码实现解析
ID3算法中log2(0)问题解析与NumPy熵计算代码拆解
一、ID3算法里log2(0)的处理方案
做ID3决策树的时候,你肯定会碰到这个糟心的问题:当某个类别的样本占比为0时,计算熵的公式里就会出现log2(0)——这玩意儿是负无穷,直接导致熵的计算结果彻底失效。
那怎么解决呢?其实从数学角度看,0 * log2(0)的极限是0,所以我们完全可以把这类项直接当作0来处理。实际代码里有两种常用的处理方式:
- 条件判断法:先检查概率是否大于0,只有当概率不为0时才计算对应的熵项,否则跳过。
- NumPy数组过滤法:把所有大于0的概率筛选出来,只对这些值计算熵,自动忽略概率为0的项。
举个例子,用NumPy优化后的熵计算代码可以写成这样:
p = np.array([negative_probability, positive_probability]) # 只保留大于0的概率值 p_valid = p[p > 0] entropy = -np.sum(p_valid * np.log2(p_valid))
这样就完美避开了log2(0)的坑。
二、NumPy熵计算与属性划分代码逐行解析
咱们先把完整代码贴出来,再逐行拆解:
import numpy as np udacity_set = np.array( [[1,1,1,0], [1,0,1,0], [0,1,0,1], [1,0,0,1]]) label = udacity_set[:,udacity_set.shape[1]-1] fx = label.size positive = label[label == 1].shape[0] positive_probability = positive/fx negative = label[label == 0].shape[0] negative_probability = negative/fx entropy = -negative_probability*np.log2(negative_probability) - positive_probability*np.log2(positive_probability) atribute = 0 V = 1 attribute_set = udacity_set[np.where(udacity_set[:,atribute] == 1)]
import numpy as np:导入NumPy库,这是处理数组和数值计算的利器,没有它咱们没法高效操作数据集。udacity_set = np.array(...):创建一个4行4列的样本数据集,每一行是一个样本,最后一列是分类标签(0代表负例,1代表正例)。label = udacity_set[:,udacity_set.shape[1]-1]:提取数据集的最后一列作为标签列——udacity_set.shape[1]是列数,减1就是最后一列的索引,[:,索引]表示取所有行的这一列。fx = label.size:统计样本总数,这里label有4个元素,所以fx=4。positive = label[label == 1].shape[0]:筛选出标签为1的样本,然后统计数量,这里有2个正例。positive_probability = positive/fx:计算正例的占比,2/4=0.5。negative = label[label == 0].shape[0]:统计负例的数量,这里也是2个。negative_probability = negative/fx:负例占比同样是0.5。entropy = ...:根据熵的公式计算整个数据集的熵。这里正负概率都是0.5,所以熵是-0.5*log2(0.5) -0.5*log2(0.5) = 1,这是熵的最大值,说明当前数据集最混乱。atribute = 0:指定要划分的属性是第0列(也就是数据集的第一列)。V = 1:我们要筛选出该属性值为1的样本子集。attribute_set = udacity_set[np.where(udacity_set[:,atribute] == 1)]:用np.where找到第0列值为1的所有行的索引,然后提取这些行,最终得到的子集是[[1,1,1,0], [1,0,1,0], [1,0,0,1]]。
内容的提问来源于stack exchange,提问作者Kamil Septio Trojnar
相关产品推荐
相关产品推荐

