尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

信息量、信息熵与信息增益:从原理到决策树实战

发布时间:2026/9/18 3:30:30

资讯中心
01
ARTICLE

信息量、信息熵与信息增益:从原理到决策树实战

信息量、信息熵与信息增益:从原理到决策树实战
信息量、信息熵、信息增益这三个词做机器学习的同学每天都能见到尤其是一碰到决策树几乎必被这几个概念刷脸。但说句实话不少人学了几年代码能跑通、模型能调参被问到“熵到底是什么”的时候还是支支吾吾只能挤出一句“衡量不确定性”。更常见的困惑是这三个概念到底啥关系它们各自解决什么问题为什么决策树选特征的时候要用信息增益而不是直接用信息量我当年啃《统计学习方法》的时候也被这几个概念绕晕过好几轮。后来发现问题不在概念本身有多难而在大多数资料默认你已经有信息论的底子上来直接丢公式导致很多人只记住了符号没建立直觉。这篇就专门把这三个概念掰开揉碎用最直白的话讲清楚它们从哪来、算什么、怎么用顺便把决策树里那套特征选择的逻辑也一并理顺最后附上Python和MATLAB的实际计算代码。1. 内容整体设计与思路拆解1.1 理解链条信息量是砖信息熵是墙信息增益是盖房子的决策先建立一个总体的认知框架。这三个概念不是并列关系而是层层递进的关系像搭积木一样信息量针对的是“某一条具体消息”值多少分量衡量的是单个事件发生后带给我们的惊讶程度。信息熵针对的是“整个随机变量”平均每次能带来多少信息是把所有可能事件的信息量按概率加权平均的结果。信息增益针对的是“引入某个条件后不确定性减少了多少”是熵的前后差值也是决策树选特征的依据。打个比方信息量是每块砖头的重量信息熵是整面墙的平均砖重信息增益则是你比较两堵墙之后得出的结论“换成空心砖之后整面墙轻了多少”。这个链条的起点是香农在1948年那篇奠基性论文里提出的问题信息到底能不能被量化香农天才地给出了一个答案信息量的多少取决于这条消息“出人意料”的程度。一个事件发生的概率越低一旦发生带来的信息量就越大。这个直觉和我们的日常经验完全吻合——你听到“明天太阳照常升起”不会有任何信息量但听到“明天有陨石撞地球”绝对信息量爆棚。理解了这条链后面所有公式就不再是死记硬背而是顺理成章的推导。1.2 为什么需要这套量化工具从通信到机器学习的跨越这套概念最早是为了解决通信工程的问题——如何度量一条电报、一通电话传递了多少信息。后来机器学习领域的先驱们发现这套工具天然适合描述“数据集纯度”和“特征区分能力”于是被引入决策树算法成为ID3算法的核心依据。决策树的核心问题其实就一句话给定一堆样本每个样本有多个特征该先用哪个特征来划分数据人类做决策的时候凭经验机器没经验可凭只能靠数学。这时信息增益就派上用场了——它量化了“用了这个特征之后数据的混乱程度降低了多少”。降低得越多说明这个特征的分辨能力越强越该优先使用。这个朴素的逻辑就是信息增益在机器学习里扮演的角色。1.3 学习路线的建议先直觉后公式再代码我给完全零基础读者的建议是不要一上来就背公式。先建立直观感受把场景想明白再回头看数学公式会豁然开朗。本文的结构也按这个思路安排先讲信息量怎么定义再讲信息熵怎么从信息量推出来然后讲信息增益在决策树里怎么落地最后给出代码实现和踩坑经验。建议你准备纸笔把公式手动推一遍尤其是信息熵的公式亲手算一个例子比盯着屏幕看十遍都管用。2. 核心概念拆解信息量、信息熵到底是什么2.1 信息量概率越低信息越大信息量的定义公式是I(x) -log₂ P(x)其中P(x)是事件x发生的概率I(x)就是该事件发生时所携带的信息量。为什么用负号为什么取对数这两个问题几乎每个人都会遇到逐一说明。先说负号。概率P(x)的取值范围是0到1之间而0到1之间的数取对数是负数。信息量是正的才有意义所以前面加个负号让结果转正。再说为什么取对数。这里藏着香农的高明之处。假设你收到两条独立的消息它们各自的信息量当然应该可以相加得到总信息量。对数函数天然满足这个性质因为log(ab) log(a) log(b)。如果两个独立事件同时发生联合概率是两者相乘取对数后正好变成相加完美符合“信息量可叠加”的直觉。底数为什么用2因为信息论脱胎于通信工程底层载体是二进制一个比特能区分两种状态。用2为底时信息量的单位就是比特bit。其实底数用e或10也行只是单位不同分别是纳特和哈特利但机器学习领域几乎都默认用2涉及决策树时大家说的“熵”默认就是2为底的结果。举两个例子建立直觉。例子一抛一枚均匀硬币正面朝上的概率是0.5。I(正面) -log₂(0.5) 1比特这个结果非常漂亮抛硬币的结果恰好就是1比特信息一个二进制位就能编码。例子二一个袋子有100个球其中只有1个红球99个白球。现在摸出红球。I(红球) -log₂(0.01) ≈ 6.64比特摸出红球的信息量远大于抛硬币正面因为它太稀罕了。这个直觉完全符合“惊讶程度越大信息量越大”的理解。2.2 信息熵随机变量平均的信息量信息熵的定义公式是H(X) -Σ P(xi) · log₂ P(xi)也就是把所有可能事件的信息量按照它们各自的概率加权求和。它回答的问题是在观测之前这个随机变量平均会带来多少不确定性很多教材直接抛公式不解释为什么要求期望。其实想清楚很简单随机变量每次取值都不一样有些值信息量大有些值信息量小。我们需要一个稳定的指标来描述这个随机变量的整体属性那就把所有情况的可能值按概率加权求平均这就是期望也就是信息熵。信息熵有几个值得记住的性质非负性H(X) ≥ 0因为每一项 -P·logP 非负。等概率时熵最大如果随机变量有n个取值且每个取值概率相等此时熵达到最大值 log₂ n。这个性质非常重要因为“最混乱、最难预测”的时候不确定性最大熵自然最大。确定性事件的熵为0如果某事件概率为1其他事件概率为0那么H(X) 0因为完全没悬念信息量为0。继续用抛硬币的例子。均匀硬币正面反面各0.5H -0.5·log₂(0.5) - 0.5·log₂(0.5) -0.5·(-1) - 0.5·(-1) 1比特一枚作弊硬币正面概率0.9反面概率0.1H -0.9·log₂(0.9) - 0.1·log₂(0.1) ≈ -0.9·(-0.152) - 0.1·(-3.322) ≈ 0.137 0.332 0.469比特结果说明作弊硬币的不确定性远低于均匀硬币。这也符合直觉当你明知道正面大概率出现时每次观测的“惊喜”就少了信息量自然低。熵越低系统越偏向“确定”。2.3 用生活场景理解熵奶茶店选择的例子再举一个更贴近生活的例子。假设你要点奶茶一家店只有三种固定口味可选概率完全均等各占三分之一H(X) -3 × (1/3)·log₂(1/3) ≈ 1.585比特另一家店90%的人点珍珠奶茶剩下10%的人随机分布在另外两种口味之间H(X) -0.9·log₂(0.9) - 0.05·log₂(0.05) - 0.05·log₂(0.05) ≈ 0.137 0.216 0.216 0.569比特第一家店口味分布均匀面对顾客时你很难猜他们会点什么选择困难症爆发熵高第二家店大家趋同约定俗成点珍珠熵低。机器学习里说“数据纯不纯”说的就是熵高不高。如果一袋数据所有样本的标签都一样熵为0这就是最理想最纯的情况如果标签五五开熵为1这就很混乱需要进一步划分。3. 信息增益与决策树的落地逻辑3.1 信息增益的本质熵降了多少信息增益的定义是划分前后熵的差值Gain(D, A) H(D) - H(D|A)其中D是当前数据集A是某个特征。H(D)是划分前的熵H(D|A)是已知特征A后数据的条件熵。两者之差就是“知道了特征A之后数据集D不确定性减少的量”。公式用文字翻译过来就是没用特征A之前数据乱不乱算一个熵用了特征A划分之后数据还乱不乱算一个熵两个熵一减就是特征A带来的“秩序增量”。这里的关键是把H(D|A)彻底理解透。它不是简单地把特征A当作变量求熵而是按特征A的每个取值把数据分成多个子集再分别求每个子集的熵最后按子集样本占比加权求和。为什么加权因为不同子集的大小不一样数据多的子集应该对整体结果有更大的发言权。这和“班级平均分要用人数加权”的道理一模一样。3.2 决策树为什么爱用信息增益一次完整的特征选择演示拿一个最经典的例子来说明。假设我们要根据天气特征判断是否出门打球数据如下天气温度湿度风力是否打球晴高大弱否晴高大强否阴高大弱是雨中大弱是雨低小强否雨低小弱是阴低小强是晴中大弱否晴低小弱是雨中小弱是晴中小强是阴中大强是阴高大弱是雨中大强否先看整体数据集D是否打球的分布是的有9个否的有5个总共14个样本。D的熵H(D) -(9/14)·log₂(9/14) - (5/14)·log₂(5/14) ≈ 0.940现在分别计算每个特征的信息增益看谁最值得优先作为根节点。先算天气。天气有晴、阴、雨三种取值。晴天有5个样本其中打球2个不打球3个熵为H(D晴) -(2/5)·log₂(2/5) - (3/5)·log₂(3/5) ≈ 0.971阴天有4个样本全部打球熵为0完全纯。雨天有5个样本其中打球3个不打球2个熵为H(D雨) -(3/5)·log₂(3/5) - (2/5)·log₂(2/5) ≈ 0.971条件熵为各子集熵的加权平均H(D|天气) (5/14)·0.971 (4/14)·0 (5/14)·0.971 ≈ 0.694信息增益为Gain(D, 天气) 0.940 - 0.694 0.246用同样的流程算温度和湿度。这里偷个懒温度的三段划分需要细分高、中、低三档分别算熵湿度分两档风力分两档。直接给最终结果你可以自己按照上面的方式手推一遍Gain(D, 温度) ≈ 0.029Gain(D, 湿度) ≈ 0.151Gain(D, 风力) ≈ 0.048对比四个值天气的信息增益0.246最大所以决策树引擎会优先选择天气作为第一个划分特征。这个选择逻辑非常直观用了天气之后数据纯度提升最多说明天气这个特征最能说明问题。3.3 为什么信息增益有时候会“偏心”多取值特征的问题讲到这里就得回头吐槽一个信息增益的毛病不然你后面用决策树会发现它特别“偏心”。假设数据里有一个“编号”特征每条样本的编号都不同每个取值只有一条数据。计算信息增益时按编号划分后每个子集只有一个样本类别完全一致子集熵全是0条件熵就是0信息增益直接等于H(D)达到最大值。决策树会毫不犹豫地优先选编号作为根节点然后分出一大堆叶子节点每片叶子只有一个样本模型完全过拟合没有任何泛化能力。这个问题的根源在于信息增益天然偏好取值种类多的特征。这就是为什么后来的C4.5算法改用信息增益率本质就是给取值多的特征加了一个惩罚项。如果你在自己做特征筛选时发现决策树选的第一个特征很怪先检查一下是不是有高基数特征混进来了。4. 实操环节Python和MATLAB的完整计算代码4.1 Python实现从零手写信息熵和信息增益网上可以找到很多现成的库帮你算熵比如sklearn里的信息熵API但那种调用方式不利于理解本质。我建议至少手写一遍核心函数弄清楚每一步在算什么然后再去用库函数。下面是一段纯Python实现不依赖任何第三方库可以直接复制运行import math def calc_entropy(labels): 计算数据集的熵 labels: 类别标签列表如 [是, 否, 是, ...] total len(labels) if total 0: return 0 label_counts {} for label in labels: label_counts[label] label_counts.get(label, 0) 1 entropy 0.0 for count in label_counts.values(): prob count / total entropy - prob * math.log2(prob) return entropy def calc_cond_entropy(dataset, feature_idx, labels): 计算在某个特征条件下的条件熵 dataset: 二维列表每行是一条样本 feature_idx: 特征所在列索引 labels: 类别标签列表 total len(dataset) feature_values {} for i, row in enumerate(dataset): val row[feature_idx] if val not in feature_values: feature_values[val] [] feature_values[val].append(labels[i]) cond_entropy 0.0 for val, sub_labels in feature_values.items(): prob len(sub_labels) / total cond_entropy prob * calc_entropy(sub_labels) return cond_entropy def calc_info_gain(dataset, feature_idx, labels): 计算信息增益 base_entropy calc_entropy(labels) cond_entropy calc_cond_entropy(dataset, feature_idx, labels) return base_entropy - cond_entropy # 用3.2节的天气数据集做验证 dataset [ [晴, 高, 大, 弱], [晴, 高, 大, 强], [阴, 高, 大, 弱], [雨, 中, 大, 弱], [雨, 低, 小, 强], [雨, 低, 小, 弱], [阴, 低, 小, 强], [晴, 中, 大, 弱], [晴, 低, 小, 弱], [雨, 中, 小, 弱], [晴, 中, 小, 强], [阴, 中, 大, 强], [阴, 高, 大, 弱], [雨, 中, 大, 强], ] labels [否, 否, 是, 是, 否, 是, 是, 否, 是, 是, 是, 是, 是, 否] feature_names [天气, 温度, 湿度, 风力] base_entropy calc_entropy(labels) print(f数据集D的熵: {base_entropy:.4f}) for i, name in enumerate(feature_names): gain calc_info_gain(dataset, i, labels) print(f特征[{name}]的信息增益: {gain:.4f})输出结果数据集D的熵: 0.9403 特征[天气]的信息增益: 0.2467 特征[温度]的信息增益: 0.0292 特征[湿度]的信息增益: 0.1518 特征[风力]的信息增益: 0.0481这个结果和3.2节手推的一致。说明代码逻辑没问题。这里的dataset是用字符串表示离散特征如果你的数据是数值型连续特征需要先做离散化处理否则不能直接套这个函数。4.2 MATLAB计算一维数据信息熵两种写法网络热搜词里特别提到MATLAB中怎么计算一维数据信息熵这里单独拿出来讲。MATLAB本身没有直接计算信息熵的内置函数但有几种常见实现方式。第一种如果你有Statistics and Machine Learning Toolbox可以借助histcounts统计概率分布再手动计算熵function H calc_entropy_1d(data, numBins) % data: 一维数据向量 % numBins: 分箱数量默认建议用 10 或根据数据量调整 if nargin 2 numBins 10; end [counts, ~] histcounts(data, numBins); probs counts / sum(counts); % 过滤掉概率为0的箱子避免log2(0)产生无穷大 probs probs(probs 0); H -sum(probs .* log2(probs)); end第二种不依赖统计工具箱纯手写。这里用排序加直方图思想的实现function H entropy_manual(data) % 纯手写一维数据信息熵计算不依赖工具箱 % 原理按取值频率计算概率等价于离散化后的熵 % 对数据进行离散化处理 % 用unique获取所有取值 unique_vals unique(data); n length(data); % 如果unique数量接近n说明数据几乎全是离散的独立取值 % 此时可以直接按每个值的出现频率计算否则建议分箱 probs zeros(length(unique_vals), 1); for i 1:length(unique_vals) probs(i) sum(data unique_vals(i)) / n; end % 过滤零概率项 probs probs(probs 0); H -sum(probs .* log2(probs)); end你要算一维数组的信息熵时直接调用data [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]; H1 calc_entropy_1d(data, 4); H2 entropy_manual(data);注意一个关键点如果数据是连续数值比如身高、体重直接用unique统计每个值出现的频率几乎每个值都只出现一次这样算出来的熵会虚高。这种情况必须分箱把连续值映射到有限个区间内再统计区间频率否则结果没有意义。4.3 代码里最容易踩的坑log(0)问题与离散化陷阱手写熵计算时最容易踩的坑就是log(0)。当某个类别在子集中不出现时概率为0而log2(0)是负无穷。很多初学者在这里直接报错或者得到NaN。应对办法很简单在计算前过滤掉所有概率为0的项。我上面的Python和MATLAB代码都做了这个处理实际项目里千万别省这一步。另一个坑就是连续特征的离散化。我见过不少人在处理连续数据时不假思索地套熵公式把每个浮点值都当成独立取值来计算最后算出来的熵大得离谱信息增益全被连续特征霸占决策树建出来完全不可用。正确的做法是先分箱或者用二分法离散化。sklearn里的DecisionTreeClassifier会自动处理连续特征但如果你自己实现决策树这个问题避不开。关于分箱数量简单说一个经验值在数据量不大的情况下分5到10个箱子通常就够用了不是越多越好。箱子太多每个箱子里样本太少统计概率不靠谱熵值波动极大。5. 常见问题与排查技巧实录5.1 为什么同样的数据不同工具算出的熵不一样这个问题我被问过很多次。同一份数据sklearn算出来的熵和你自己手写脚本算出来的熵经常有细微差异。这不是谁算错了多半是底数不同或者对数实现有差异。sklearn的entropy默认用自然对数e为底而大多数教材和决策树手写教程用2为底。两者只差一个常数倍系数换底公式排序结果和信息增益的相对大小完全一致。但有些场景下底数不统一会出麻烦比如你在论文里报告具体的熵值不标注底数会让读者困惑建议统一用2为底并明确说明。还有一种情况是浮点精度导致的差异比如0.30000000000000004这种经典问题。处理办法是统一用64位浮点并且在做比较时不要用等号判断设置一个极小阈值。5.2 信息增益算出来是负的先别慌理论上信息增益不应该为负因为按条件划分数据后不确定性只会降低或不变。但实际计算时你会偶尔得到负值原因通常就三条连续特征在划分时子集划分不合理导致条件熵比基础熵还大。这说明你的离散化策略和特征不匹配。浮点数累计误差。子集非常多时加权求和环节会引入微小误差负值一般都很小比如 -0.001这种可以忽略。用的不是信息增益而是信息增益率分母的固有值太大导致比值偏小甚至异常。处理方法是先确认负值的绝对值大小如果接近1e-3量级以内基本可以认为是浮点误差不用管如果负值幅度较大要回头检查代码逻辑和数据划分是否有bug。5.3 决策树用信息增益选了“奇怪”的特征怎么办如果你用决策树建模时发现第一个划分特征特别反直觉比如前面提到的“编号”问题或者选了某个和业务常识严重不符的字段建议按下面的顺序排查特征基数这个特征有多少个不同取值如果取值数量接近样本数基本可以判断是基数陷阱考虑改用信息增益率或者对特征做分箱处理。特征相关性有些特征单个看信息增益很高但它可能是其他强特征的下游衍生品。比如“是否下雨”和“地面是否潮湿”高度相关树可能随机选一个这不代表你的数据有问题。数据量太小样本少的时候统计概率波动大信息增益计算结果不稳定。这种情况考虑加数据或者用交叉验证选择特征。我在实际工作中遇到过一种很隐蔽的情况训练集里某个特征缺失值特别多填充方式把数据带偏了结果信息增益异常高。后来排查半天发现是缺失值填充逻辑把标签信息泄漏进了特征。这就是特征工程里常说的泄漏问题计算信息增益之前一定先确认特征里没有混入目标变量的信息。5.4 信息熵、基尼系数、错误率怎么选决策树里除了信息增益还有基尼系数和分类错误率两种纯度度量。很多人纠结到底用哪个。我的实践经验是在大多数分类任务上信息熵和基尼系数的最终效果差别极小经常不到一个百分点的精度差距。基尼系数计算更快不涉及对数运算所以在sklearn这类库的默认配置里分类树默认用的是基尼系数。信息熵的优点是理论解释更清晰课程和论文里更常见。如果你在调参时发现两种度量产出的树结构差异很大通常不是度量方法的问题而是你的数据存在很强的噪声或特征分布极不均衡。这时候应该回头处理数据而不是死磕纯度度量函数。6. 从理解到应用信息增益在真实项目中的使用心得6.1 信息增益不只是决策树的专利很多人以为信息增益只在决策树里出现其实它在特征选择、文本分类、用户画像等领域都有直接应用。做特征选择时可以计算每个特征相对于目标变量的信息增益按数值从大到小排序排名靠后的特征直接丢掉。这是最朴素的过滤式特征选择方法实现简单效果稳定。我在一个用户流失预测项目里用信息增益筛选出十来个核心特征把训练时间缩短了将近一半模型精度反而略有提升因为去掉的噪声特征不再干扰模型。文本分类里的TF-IDF加权思路和信息熵也有千丝万缕的联系。一个词语在某个类别的文档中出现频率高在其他类别中出现频率低说明它的区分能力强这和信息增益衡量“特征带来多少秩序”的逻辑如出一辙。6.2 实操中的一点经验不要迷信信息增益的绝对值信息增益的数值大小没有绝对的“好坏”标准它只有相对比较的意义。IN一个场景下0.1可能已经很高另一个场景下0.3可能也算普通。别给自己定一个“信息增益必须大于某个值才保留特征”的规矩一定要结合具体业务背景来判断。另外信息增益计算的是线性关系它无法捕捉特征和目标之间的非线性交互效应。有些特征单独看信息增益很低但和其他特征组合在一起会产生很强的区分能力。决策树的后续分裂可以在一定程度上自动挖掘这种交互但如果你预先用信息增益做过滤式特征选择可能会误杀这类潜力股。稳妥的做法是信息增益用于粗筛把明显没用的特征去掉保留有潜力的特征交给模型去探索。6.3 之后还能怎么延展理解了信息熵和信息增益之后其实你已经拿到了通往更多知识点的钥匙。互信息、KL散度、交叉熵这三个概念和信息熵直接相关理解了熵再去看交叉熵损失函数就不会觉得是凭空冒出来的公式。神经网络分类问题里的交叉熵损失本质就是在衡量预测分布和真实分布之间的距离这个距离的底层参考系就是信息熵。如果想深入决策树方向接下来可以看C4.5的增益率、CART的基尼系数以及随机森林和梯度提升树如何在决策树基础上做集成。这些进阶内容回头看你会发现底层还是信息增益那套“减少不确定性”的思维在打底。我个人在实际项目中最大的体会是这些概念公式看起来冷冰冰但一旦和实际数据连起来就会变得非常生动。当你看着一棵决策树从根节点开始一级一级选出的特征恰好符合业务直觉时那种“数学果然靠谱”的感觉比任何指标数字都来得踏实。建议你拿到今天这篇里的代码后找一个自己手头的数据集试一试亲手算一次特征的信息增益排序把“按经验选特征”变成“按数学选特征”这个转变带来的提升会比你想象的更明显。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。