散场之后:一切为什么只往乱里走 书架

第 07 章 / 共 10 章

第七章 · 香农:信息也是一种熵

I'm the writer for chapter 7. Let me write it directly, following the Feynman-style voice rules and the book's context.

你正在压缩一个 10GB 的日志文件,进度条走到一半,压出来的 zip 只有 400MB。你没删任何一行,解压回来一字不差。那 9.6GB 去哪了?它从来就不"在"那里——那是同一句话被写了几万遍占的位置。你的压缩软件干的事,本质上是把"其实没那么意外的东西"重新用更短的方式记下来。

上一章我们放走了麦克斯韦的小妖:它想靠"知道每个分子快慢"来白嫖秩序。我们说,破绽在于它得记住信息,而信息不是免费的。可"信息"到底是个什么量?能称重、能算账吗?这一章就把它称出来。称信息的那杆秤,和称气体乱不乱的那杆秤,是同一杆。

先问一个怪问题:一条消息值多少"意外"

假设我住在一个从不下雨的沙漠城市。我每天早上给你发一条天气短信。如果我发"今天晴",你会翻个白眼——废话,天天晴。这条消息几乎没告诉你任何新东西。但某天我发"今天下雨",你会立刻坐直:出事了,这条消息信息量巨大。

看出门道了吗?一条消息的信息量,不取决于它多长,而取决于它多让你意外。越是"早就猜到"的事,发生了也不值钱;越是"没想到"的事,一旦发生,携带的信息越多。

这就是 香农熵 的核心——它是一个数,度量一件事"平均有多让你意外",或者说,你事先对它有多不确定。香农,一个在贝尔实验室搞电话线路的工程师,1948 年把"意外程度"变成了能计算的东西。

熵在第二章是"一盒气体有多少种排法",在这里是"一条消息平均有多让你意外"。听起来两回事,但都是在数"有多少种可能,而你分不清是哪一种"。可能越多、越分不清,熵越大。它俩是同一个东西穿了两件衣服。

把"意外"变成数字

香农给了个具体算法。假设一件事有几种结果,每种结果发生的概率是 p。那么某个结果一旦发生,它带来的"意外量"就是 log2(1/p) 比特。概率越小,1/p 越大,意外越多。

为什么取 2 的对数(也就是比特,一个只能是 0 或 1 的开关)?因为提问的本质是"是/否"。你想猜中一个结果,最省的办法是不停地问二分问题:"在前一半吗?"每问一次,可能性砍半。要从 8 种里锁定 1 种,得砍 3 次(8→4→2→1),正好 log2(8)=3 个问题、3 比特。比特数,就是你要问多少个"是/否"才能不再意外。

整条消息源的香农熵,是把每种结果的意外量,按它出现的概率加权平均:

H = Σ p × log2(1/p)

拿抛硬币试试。公平硬币,正反各 1/2,H = 0.5×log2(2) + 0.5×log2(2) = 1 比特。合理:一次抛硬币的结果,正好要 1 个"是/否"来确定。

再拿那个沙漠城市试试。假设下雨概率只有 1/100,晴天 99/100。算出来 H ≈ 0.08 比特。也就是说,平均每天的天气只值 0.08 比特——远不到 1 比特。你根本不需要每天收一条完整短信,攒一整年到年底告诉我哪几天下雨就够了。熵低,意味着可以压缩。

为什么 q 后面几乎总是 u

现在看你正在读的这些字。英文里,字母不是均匀出现的。e 到处都是,z 半天见不着一个。更狠的是,字母之间互相"剧透":你看到一个 q,下一个字母几乎必然是 u(queen、quick、quiet)。这个 u 出现时,你毫不意外——它的概率接近 1,log2(1/1)=0 比特,它几乎不携带信息。

香农本人做过一个实验:让人一个字母一个字母地猜英文句子的下一个字母。结果是,母语者常常能连蒙带猜地补出后面一大截。这说明英文每个字母的实际信息量,远低于它表面上占的空间。26 个字母+空格,表面上每个字符要 log2(27)≈4.75 比特,但真实的英文,算上这些"剧透",每个字母只有大约 1 到 1.5 比特的信息。

一句话:文字能压缩,不是因为软件聪明,是因为文字本身"废话多"。那些废话——重复的词、可预测的语法、q 后面的 u——本来就没携带多少信息,压缩只是把它们省着写。压到不能再压的那条地板,就是香农熵。低于这条线,无损压缩不可能,谁做到了谁在骗你。

这就是压缩的理论地板

香农证明了一件让人踏实的事:任何无损压缩,平均每个符号最少要用的比特数,不可能低于这个数据源的香农熵。这不是当前技术不够好,是原理上的极限,跟第四章那个"第二类永动机不可能"是同一种"不可能"——不是造不出来,是宇宙的账本不允许。

你可以亲手验证一次。找个文本文件,比如一本英文小说的纯文本,几 MB。用 gzip 压一遍,看压缩比。gzip 就是一个实用压缩工具,干的正是"把可预测的部分记短"。你会发现英文文本大致能压到原来的 30% 上下——因为每字节 8 比特的存储里,真信息只有 2 比特多。现在换一个已经压过的文件(比如一张 JPG 照片,或一个 zip)再 gzip 一次,几乎压不动,甚至会变大一点点。因为它的熵已经被榨干了,剩下的每一比特都真的"意外",没有废话可省。

同一杆秤,藏在你代码的每个角落

一旦你戴上"熵是意外程度"这副眼镜,会发现工程里到处是它在暗中定价。

  • 随机数种子。 你调 random.seed(42),一个 32 位或 64 位的数,就能展开出一整串"看着很随机"的序列。这串序列里真正的意外只有那颗种子那么多比特——后面全是种子按固定规则推出来的,可预测,熵为零。所以它叫伪随机:假的随机,样子唬人,信息量就那么点。真要给密钥用,你得从物理世界(鼠标抖动、热噪声)采集熵,因为那里才有猜不到的意外。种子的比特数,就是这串随机性的天花板。
  • 哈希。 哈希 是把任意长的数据压成一个固定长度指纹的函数。一个好的哈希,理想目标是让输出的每一比特都尽量"满熵"——看不出规律、猜不到、均匀铺满所有可能值。这正是香农熵最大的状态:最乱、最不可压缩。哈希质量差,就是输出有了规律、熵没填满,于是不同输入容易撞到同一个指纹(碰撞)。
  • 缓存命中率。 缓存能有用,全靠访问模式均匀——你反复访问那几个热点数据。均匀就是高熵,你要访问的下一个东西完全不可预测,那缓存就成了摆设,命中率趋近于随机瞎猜。缓存能预测、能压缩、能提速,本质上都在吃"访问模式的熵不够高"这口饭。熵越低,越好猜,缓存越爽。

你看,压缩、伪随机、哈希、缓存,表面上是四个不相干的工程问题,底下是同一个量在定价:这堆数据里,真正不可预测的意外有多少比特。多了压不动、猜不准、缓存不了;少了就能省、能猜、能提速。

钩子:这笔账,物理世界要收

到这里,香农熵还只是个数学量——比特、概率、对数,跟能量没关系。你可能觉得,信息是虚的,气体的熵是实打实带焦耳的,两者只是碰巧共用了"熵"这个名字和一条 log 公式而已。

可回到那只小妖。它要靠"记住哪个分子快"来偷秩序,而记忆是要占内存的。内存有限,早晚得擦掉旧记录腾地方。问题来了:擦掉 1 比特信息,纯粹是把一个"0 或 1"变回"不知道",这个动作——在物理世界里,要不要付钱?

下一章我们会看到一个惊人的答案:擦掉 1 比特,必须向外界放出一小撮热,一分不能少。信息的熵和气体的熵,不是共用了名字,是焊死在同一根能量上的。而这一撮热,正好够把小妖判死刑——也顺便解释了,你的 CPU 为什么会烫手。

散场之后:一切为什么只往乱里走 · 王建硕
面向对世界有好奇心的人 · 费曼式写法 · 由多个 AI 代理撰写与互相审校