2、信息论基础:信息熵的定义与计算、香农第一定理、冗余度与压缩潜力、条件熵与联合熵
各位同学,欢迎来到第二章。说实话,信息论是整个压缩技术的理论基石。你想想看,没有信息论,我们连“压缩到底能压多少”都说不清楚。我个人习惯把这一章叫做“压缩的物理极限”——搞懂了它,你就知道哪些压缩是可能的,哪些是做梦。
2.1 信息熵:压缩的终极下限
信息熵这个概念,说白了就是“描述一个随机事件平均需要多少比特”。香农老爷子当年用了一个非常优雅的公式:
H(X) = - Σ P(x) * log₂ P(x)
这里的单位是比特(bit)。为什么用2为底?因为计算机里存的就是0和1嘛。
举个例子。假设有一个信源,只输出A、B、C、D四个符号,概率分别是1/2、1/4、1/8、1/8。那么它的熵就是:
H = - (1/2 * log₂(1/2) + 1/4 * log₂(1/4) + 1/8 * log₂(1/8) + 1/8 * log₂(1/8))
= - (-0.5 - 0.5 - 0.375 - 0.375)
= 1.75 比特
这意味着什么?意味着无论你怎么设计编码,平均每个符号至少需要1.75个比特。低于这个数?不可能。我在项目中遇到过有人硬要压到1.5比特,结果解出来全是乱码——嗯,这就是不懂信息论的代价。
核心结论:信息熵是无损压缩的理论极限。任何无损压缩算法的平均码长都不可能低于信源的熵。
2.2 香农第一定理:无失真信源编码定理
香农第一定理,也叫无失真信源编码定理。它告诉我们两件事:
- 存在性:总存在一种编码方式,使得平均码长可以任意接近熵。
- 不可能性:没有任何编码能让平均码长低于熵。
说白了,就是“理论上可行,但别想超越极限”。
定理的数学表述是这样的:
对于任意 ε > 0,存在一种编码,使得:
H(X) ≤ L < H(X) + ε
其中L是平均码长。这个定理给所有压缩算法画了一条红线。我记得刚入行时,老板让我评估一个“号称能压到极限”的算法,我拿熵一算,发现它声称的压缩比已经低于熵了——当场就知道是骗人的。
实战技巧:评估任何压缩算法时,先算一下信源的熵。如果算法声称的压缩比低于熵,要么是算法有损,要么就是数据有特殊结构你没发现。
2.3 冗余度:压缩潜力的真实来源
你可能会问:为什么文件能压缩?因为文件里有冗余。冗余度就是衡量“浪费了多少比特”的指标。
冗余度的定义很简单:
R = 1 - H / H_max
其中H_max是最大可能熵(当所有符号等概率时)。比如英文文本,每个字母的理论最大熵是log₂(26) ≈ 4.7比特,但实际熵只有约1.5比特。所以冗余度大约是:
R = 1 - 1.5 / 4.7 ≈ 68%
也就是说,英文文本有68%的冗余!这就是为什么gzip能把文本压到原来的三分之一。
| 数据类型 | 实际熵(比特/符号) | 最大熵(比特/符号) | 冗余度 |
|---|---|---|---|
| 英文文本 | ~1.5 | 4.7 | 68% |
| 中文文本 | ~3.0 | ~8.0 | 62% |
| 自然图像 | ~2.0 | 8.0 | 75% |
我曾经帮一个团队优化日志存储。他们觉得日志已经用gzip压过了,没法再压了。我算了一下日志的冗余度——好家伙,还有40%的冗余。后来改用列式存储加字典编码,又压了一半。所以说,别被“已经压缩过”骗了,算算冗余度再说。
避坑指南:我曾经见过有人把已经压缩过的文件(比如JPEG、MP3)再拿去压缩,结果发现压不动甚至变大。这是因为这些格式本身已经去除了大部分冗余。压缩前先搞清楚数据是不是“原生”的。
2.4 条件熵与联合熵:考虑相关性
单个符号的熵好算,但现实中的数据是有相关性的。比如英文里Q后面几乎总是U,这种相关性会进一步降低熵。
联合熵衡量的是两个随机变量一起出现的不确定性:
H(X, Y) = - Σ Σ P(x, y) * log₂ P(x, y)
条件熵衡量的是已知一个变量后,另一个变量的不确定性:
H(Y|X) = - Σ Σ P(x, y) * log₂ P(y|x)
它们之间有个漂亮的关系:
H(X, Y) = H(X) + H(Y|X)
这个公式我特别喜欢。它告诉我们:联合熵等于“先知道X的熵”加上“知道X后Y还剩多少不确定性”。
举个例子。假设X是天气(晴/雨),Y是地面状态(干/湿)。如果P(晴)=0.7,P(雨)=0.3,P(干|晴)=0.9,P(湿|雨)=0.8。那么:
H(X) = - (0.7*log₂0.7 + 0.3*log₂0.3) ≈ 0.88 比特
H(Y|X) = 0.7 * (-0.9*log₂0.9 - 0.1*log₂0.1) + 0.3 * (-0.8*log₂0.8 - 0.2*log₂0.2)
≈ 0.7 * 0.47 + 0.3 * 0.72
≈ 0.55 比特
H(X, Y) = 0.88 + 0.55 = 1.43 比特
你想想看,如果不知道天气,直接猜地面状态,熵会更大。但知道了天气,地面状态的不确定性就降低了——这就是条件熵的意义。
压缩启示:很多高级压缩算法(比如PPM、LZMA)本质上就是在利用条件熵。它们通过预测下一个符号的概率分布,来降低实际编码所需的比特数。说白了,预测越准,压缩越好。
2.5 本章小结
这一章的内容,我建议你反复咀嚼。信息熵告诉你极限在哪,冗余度告诉你潜力有多大,条件熵和联合熵告诉你如何利用相关性。这三样东西,是压缩工程师的“内功心法”。
下一章我们会讲具体的编码方法——哈夫曼编码、算术编码这些。但请记住,所有编码方法都是在逼近熵。不懂熵,你就是在黑暗中摸索。
课后练习:找一份你电脑里的文本文件,统计每个字符的出现频率,计算它的熵。然后对比一下用gzip压缩后的实际比特数。看看差距有多大?