信息论基础:自信息、信息熵、条件熵、互信息
聊压缩,绕不开信息论。很多人觉得这东西太数学,离工程很远。我刚开始做压缩的时候也这么想,直到有一次调一个流式压缩算法,怎么压都压不到目标大小,最后回头一算,才发现数据本身的熵已经锁死了压缩率上限。嗯,从那以后我再也不敢跳过信息论了。
说白了,信息论就是告诉你:这段数据理论上最少能压到多小。它不关心你用哪种算法,只关心数据本身的“信息量”。
2.1 自信息:一条消息到底有多“意外”
先看最基础的概念——自信息。它衡量的是单个事件发生所带来的信息量。
公式很简单:
I(x) = -log₂ P(x)
其中 P(x) 是事件 x 发生的概率。底数取 2,单位就是比特(bit)。
举个例子:
- 如果明天太阳从东边升起,概率接近 1,log₂(1) = 0,自信息为 0。这件事说了等于没说。
- 如果明天彩票中头奖,概率极低,自信息就很大。你想想看,一条“我中奖了”的消息,信息量远大于“我吃饭了”。
我在项目中遇到过一个问题:有人把自信息直接当成压缩后的比特数来用,结果发现压出来的文件比理论值大很多。为什么?因为自信息只针对单个符号,而实际数据是一串符号,我们需要看整体。
2.2 信息熵:整个数据源的平均信息量
信息熵就是自信息的期望值。它衡量的是一个随机变量 X 的平均不确定性。
H(X) = -∑ P(x) · log₂ P(x)
这个值就是无损压缩的理论极限。任何无损压缩算法,平均每个符号需要的比特数都不可能低于 H(X)。
我习惯用一个例子来理解:
| 符号 | 概率 | 自信息 (bit) |
|---|---|---|
| A | 0.5 | 1.0 |
| B | 0.25 | 2.0 |
| C | 0.25 | 2.0 |
熵值 H = 0.5×1.0 + 0.25×2.0 + 0.25×2.0 = 1.5 bit/符号。也就是说,无论你用多好的算法,平均每个符号至少需要 1.5 个比特。
2.3 条件熵:知道一部分后,剩下的不确定性
现实中的数据往往有相关性。比如英文文本里,'q' 后面几乎一定是 'u'。如果你已经知道前一个字符是 'q',那么后一个字符的不确定性就大大降低了。
条件熵 H(Y|X) 衡量的就是:已知 X 的情况下,Y 还剩多少不确定性。
H(Y|X) = -∑ P(x, y) · log₂ P(y|x)
这个值在压缩中极其重要。为什么?
- 如果 H(Y|X) 远小于 H(Y),说明 X 和 Y 高度相关。
- 我们可以利用这种相关性来压缩——比如用前一个像素预测后一个像素,只存差值。
我记得有一次做图像压缩,直接对像素值编码,熵是 7.2 bit/像素。但换成差分编码后,条件熵降到了 3.1 bit/像素。这就是预测模型的价值。
2.4 互信息:两个变量共享了多少信息
互信息 I(X; Y) 是信息论里我最喜欢的概念之一。它衡量的是:知道 X 能减少多少对 Y 的不确定性。
I(X; Y) = H(Y) - H(Y|X)
也可以写成对称形式:
I(X; Y) = ∑∑ P(x, y) · log₂ [P(x, y) / (P(x) · P(y))]
互信息有几个关键性质:
- 非负:I(X; Y) ≥ 0
- 对称:I(X; Y) = I(Y; X)
- 如果 X 和 Y 独立,互信息为 0
2.5 它们与压缩极限的关系
现在我们把四个概念串起来,看看它们如何定义压缩的边界。
核心结论就一句话:信息熵是无损压缩的理论下界。
具体来说:
- 自信息告诉你单个符号需要多少比特。
- 信息熵告诉你整个数据源的平均下界。
- 条件熵告诉你利用上下文后,下界还能降多少。
- 互信息告诉你两个变量之间有多少冗余可以消除。
你想想看,如果一个压缩算法声称能压到比熵还低,那只有两种可能:要么是有损压缩,要么是算法算错了。我见过有人拿一个随机数生成器“压缩”到 10%,结果解压出来全是错的——这就是没理解熵的含义。
2.6 知识体系总览
下面这张图把四个概念的关系画清楚了,我建议你多看几遍:
从图中你能看到一条清晰的脉络:自信息是基础,熵是平均,条件熵是带上下文的熵,互信息是熵的差值。它们共同定义了压缩的理论天花板。
我个人习惯在做任何压缩方案之前,先画一张这样的关系图,把数据源的概率分布、相关性、冗余类型都理清楚。这样选算法的时候才不会跑偏。