信息增益和信息增益率是决策树算法中用于特征选择的核心指标,二者都基于信息熵的概念衍生而来,通过计算特征对数据集纯度的提升程度,判断特征的重要程度。信息增益直接衡量特征带来的熵减少量,而信息增益率则在此基础上加入了特征本身的固有值惩罚,避免偏向取值较多的特征。

基础概念与计算原理
信息熵
信息熵是衡量数据集混乱程度的指标,熵值越高说明数据集的类别分布越均匀,纯度越低。对于数据集D,其信息熵的计算公式为:
H(D) = -∑_{k=1}^{|y|} p_k log_2(p_k)
其中|y|是数据集的类别总数,p_k是第k类样本在数据集D中的占比。
信息增益
信息增益表示使用特征A对数据集D进行划分后,熵的减少量,计算公式为:
Gain(D, A) = H(D) - ∑_{v=1}^{V} frac{|D^v|}{|D|} H(D^v)
其中V是特征A的取值个数,D^v是特征A取第v个值的样本子集,|D^v|和|D|分别是对应子集和总数据集的样本数。
信息增益率
信息增益率是信息增益与特征A的固有值(IV)的比值,固有值衡量特征本身的取值分散程度,计算公式为:
Gain_ratio(D, A) = frac{Gain(D, A)}{IV(A)}
其中IV(A) = -∑_{v=1}^{V} frac{|D^v|}{|D|} log_2(frac{|D^v|}{|D|})。
Python实现步骤
1. 计算信息熵
首先实现信息熵的计算函数,输入为数据集的标签列表,输出对应的熵值。
import math
from collections import Counter
def calc_entropy(labels):
# 统计每个类别的样本数量
label_counts = Counter(labels)
total = len(labels)
entropy = 0.0
# 遍历每个类别计算熵
for count in label_counts.values():
prob = count / total
entropy -= prob * math.log2(prob)
return entropy
2. 计算信息增益
实现信息增益的计算,需要输入总数据集的标签、特征对应的取值列表,以及特征取值对应的子集标签。
def calc_information_gain(all_labels, feature_values, feature_subsets):
# 计算总数据集的熵
total_entropy = calc_entropy(all_labels)
total = len(all_labels)
# 计算划分后的加权熵
weighted_entropy = 0.0
for subset_labels in feature_subsets:
subset_prob = len(subset_labels) / total
weighted_entropy += subset_prob * calc_entropy(subset_labels)
# 信息增益 = 总熵 - 加权熵
return total_entropy - weighted_entropy
3. 计算信息增益率
信息增益率需要先计算特征的固有值,再用信息增益除以固有值得到结果。
def calc_information_gain_ratio(all_labels, feature_values, feature_subsets):
# 先计算信息增益
gain = calc_information_gain(all_labels, feature_values, feature_subsets)
total = len(all_labels)
# 计算固有值IV
iv = 0.0
for subset_labels in feature_subsets:
subset_prob = len(subset_labels) / total
iv -= subset_prob * math.log2(subset_prob)
# 避免除零错误,若IV为0则增益率设为0
if iv == 0:
return 0.0
return gain / iv
完整示例演示
下面用一个简单的天气数据集演示两个指标的计算过程,数据集包含4个样本,特征为是否有风,标签为是否适合打球。
# 总数据集标签:1表示适合打球,0表示不适合
all_labels = [1, 1, 0, 0]
# 特征"是否有风"的取值:1表示有风,0表示无风
feature_values = [1, 0]
# 特征取值对应的子集标签:有风的样本标签为[1,0],无风的样本标签为[1,0]
feature_subsets = [[1, 0], [1, 0]]
# 计算信息增益
gain = calc_information_gain(all_labels, feature_values, feature_subsets)
print("信息增益:", gain)
# 计算信息增益率
gain_ratio = calc_information_gain_ratio(all_labels, feature_values, feature_subsets)
print("信息增益率:", gain_ratio)
运行上述代码后,输出结果为:
信息增益: 0.0 信息增益率: 0.0
这是因为该特征划分后的子集熵和总熵相同,没有带来纯度提升,所以两个指标都为0。
二者的差异与适用场景
- 信息增益偏向于选择取值数量多的特征,比如ID类特征取值极多,信息增益会很高但实际没有分类价值。
- 信息增益率通过固有值惩罚了取值多的特征,更适合处理取值分布不均的特征,但可能对取值少的特征有偏好。
- 实际使用中,C4.5算法会先筛选出信息增益高于平均水平的特征,再从中选择信息增益率最高的特征,平衡二者的缺点。