📘 第14章 人工智能与海量数据和物联网
📄 一句话概括

人工智能的原料是数据,而数据正在以复利的速度长。 这一节算三笔账:存五年要多少钱、能压多小、抽多少才够。 三笔账里最划算的那一刀,往往不是买硬盘,是去重。

📝 本节和前面几节的关系

13.2 算的是算力的账,这一节算存储的账。两者的思路一样:先找出真正的成本在哪一项。 14.2 会把这一节的数据量接到「物联网」上:一台传感器一天只发几百字节, 一千台一年就是几十 TB。

一、存量按复利长

假设一家公司每天的日志、图片、传感器数据加起来是 2 TB,年增长三成。 存储单价每 TB 每月 20 元,每年降两成——这是个很乐观的假设。

年份 每天新增 累计存量 单价 那个月账单
第 1 年 2.00 TB 730 TB 20.0 元 14600 元
第 2 年 2.60 TB 1679 TB 16.0 元 26864 元
第 3 年 3.38 TB 2913 TB 12.8 元 37283 元
第 4 年 4.39 TB 4517 TB 10.2 元 46249 元
第 5 年 5.71 TB 6601 TB 8.2 元 54079 元
存量涨了 9.0 倍,账单只涨了 3.0 倍——单价下降吃掉了一部分。
但「吃掉一部分」不等于「不用管」:单价再降,也降不过存量的复利。
注意「累计存量」那一列只加不减。
这才是数据存储和别的成本最不一样的地方:硬盘不会自己空出来。

二、压缩:能瘦多少

同样一份结构化文本,压一遍能小多少? Demo 造了 2000 条点击日志,字段全是重复的名字:

形式 大小 相对原始
原始 JSON 178.0 KB 100%
压缩(最快档) 23.0 KB 12.9%
压缩(最强档) 17.6 KB 9.9%
最强档比最快档只小了 23.5%,而 CPU 要多花好几倍时间——不值。
因为这份数据高度重复(只有 50 个用户、800 个商品),字典早就建满了。
真实日志也是这样,压到十分之一上下很常见。
但压缩有个上限:它压的是「重复的模式」,不是「重复的整条」。
整条重复的那部分,得靠下一段那个办法。

三、采样:抽多少才够准

一百万个样本,真实均值 99.988。每次抽 n 个算均值,重复 200 次:

每次抽多少 平均绝对误差 最大误差 相对误差
100 1.2242 4.6066 1.224%
1000 0.3571 1.2773 0.357%
10000 0.1226 0.4343 0.123%
100000 0.0364 0.1108 0.036%
样本量乘十,误差降到三分之一左右——正好是根号十。
这就是「抽样误差按样本量的平方根下降」:想准一倍,得抽四倍。
所以百万分之一级的精度,要的是万亿级样本,不是万级。
「数据越多越准」这句话是对的,但它给的折扣很差——
投入翻十倍,精度只翻三倍。

四、去重:最划算的一刀

先看看这批数据里到底有多少是重复的:

项目 数量
原始记录 1350000
去重之后 999538
重复的 350462
省下的空间 26.0%
这批数据里有 26% 是重复的。真实世界的日志、爬虫、备份,重复率经常过半。
去重比压缩更彻底:压缩让同样的内容占更少位置,去重让同样的内容只出现一次。
两层一起用,成本能差一个量级。
而且去重没有精度损失——它删掉的本来就是同一份东西。
这也是为什么它排在三笔账里最前面:不花算力、不掉精度、立刻见效。

五、动手 Demo:数据越多越好,也多得让人付不起

四段:五年账单、压缩三档、采样误差、去重收益。 全部是本地算出来的数:账单按公式滚,压缩用标准库,采样和去重都在内存里跑。 没有连任何数据库。

daily, price, total = 2.0, 20.0, 0.0
for y in range(1, 6):             # 五年:量每年涨三成,单价每年降两成
    total += daily * 365           # 存量只加不减,这就是复利
    print(u"第 %d 年 %.0f 元" % (y, total * price))
    daily *= 1.3
    price *= 0.8

raw = json.dumps(rows, ensure_ascii=False).encode(u"utf-8")
z1 = zlib.compress(raw, 1)        # 最快档,几乎不花 CPU
z9 = zlib.compress(raw, 9)        # 最强档,多花好几倍时间

实跑输出:

--------------------------------------------------------------------
数据越多越好,也多得让人付不起
--------------------------------------------------------------------
==============================================================

[1] 一年长多少,五年后花多少

  假设一个公司每天的日志、图片、传感器数据加起来是 2 TB,年增长三成。
  存储单价按每 TB 每月 20 元算,且每年降两成:

    年份    每天新增    累计存量      单价(元每 TB 月) 那个月账单
    第 1 年 2.00 TB     730 TB        20.0              14600 元
    第 2 年 2.60 TB     1679 TB       16.0              26864 元
    第 3 年 3.38 TB     2913 TB       12.8              37283 元
    第 4 年 4.39 TB     4517 TB       10.2              46249 元
    第 5 年 5.71 TB     6601 TB       8.2               54079 元

  **存量涨了 9.0 倍,账单只涨了 3.0 倍——单价下降吃掉了一部分。**
  **但「吃掉一部分」不等于「不用管」。单价再降,也降不过存量的复利。**

[2] 压缩:同样一份数据能瘦多少

    形式                大小          相对原始
    原始 JSON           178.0 KB      100%
    压缩(最快档)      23.0 KB       12.9%
    压缩(最强档)      17.6 KB       9.9%

  **最强档比最快档只小了 23.5%,而 CPU 要多花好几倍时间——不值。**
  **因为这份数据高度重复(只有 50 个用户、800 个商品),字典早就建满了。**
  **真实日志也是这样:字段名反复出现,压到十分之一上下很常见。**

[3] 采样:抽多少才够准

  一百万个样本,真实均值 99.988。
  每次抽 n 个、算均值,重复 200 次,看误差有多大:

    每次抽多少    平均绝对误差    最大误差      相对误差
    100           1.2242          4.6066        1.224%
    1000          0.3571          1.2773        0.357%
    10000         0.1226          0.4343        0.123%
    100000        0.0364          0.1108        0.036%

  **样本量乘十,误差降到三分之一左右——正好是根号十。**
  **这就是「抽样误差按样本量的平方根下降」:想准一倍,得抽四倍。**
  **所以百万分之一级的精度,要的是万亿级样本,不是万级。**

[4] 去重:重复的那部分根本不用存

    项目              数量
    原始记录          1350000
    去重之后          999538
    重复的            350462
    省下的空间        26.0%

  **这批数据里有 26% 是重复的。**
  **真实世界的日志、爬虫、备份,重复率经常过半。**
  **去重比压缩更彻底:压缩让同样的内容占更少位置,去重让同样的内容只出现一次。**

  四段连起来:**存量按复利长,单价降得没它快**;
  **压缩能把结构化文本压到五分之一**;
  **采样误差按样本量的平方根下降,想准一倍得抽四倍**;
  **而去重是性价比最高的一刀——重复的东西根本不该存第二遍。**

第 1 段最该盯的不是账单,而是「累计存量」那一列:730 涨到 6601。 它只加不减,这是数据成本最要命的地方。 第 2 段那个 23.5% 是个陷阱。 压缩级别从 1 跳到 9,CPU 多花好几倍,只换来两成多的体积—— 在线日志一般用最快档,只有在归档时才用最强档。 第 3 段四行数字的比值约等于 1 比 3.16 比 10 比 31.6,正好是根号十的幂。 这就是「误差按平方根下降」在实测里的样子。 第 4 段那 26% 是这一节最值钱的一行。 它不需要任何算法,只要算一遍哈希——这也是它为什么该排在最前面。

30 秒实验

  1. 把第 1 段的年增长率从三成改成五成,重跑。 第五年那个账单会翻好几倍—— 增长率的指数效应,在「存量只加不减」这条规矩下被放大得特别狠。
  2. 把第 2 段的 rows 从 2000 条改成 200000 条,重跑。 压缩比会变得更好——样本越大,字典越能建满,重复模式也越多。
  3. 把第 3 段的抽样从 200 次改成 20 次,重跑。 平均误差差不多,最大误差会明显变大——次数少的时候,「最坏的一次」还没被抽到。

常见误区

  1. 以为「数据存着不花钱」。存量的账是按月付的,而且只加不减。 五年下来,一笔看起来很小的日增量能变成九倍的存量。
  2. 以为「压缩越狠越好」。最强档常只多省一两成,CPU 却要多花好几倍。 在线链路用最快档,归档才用最强档。
  3. 以为「样本翻倍精度就翻倍」。误差按平方根降。想准一倍得抽四倍,想准十倍得抽一百倍。
  4. 以为「去重会丢信息」。去重删的是完全相同的内容, 丢的只是「同一件事被记了几遍」这个计数——需要计数就单独存一列。
自测三问(点开对答案) 1. 为什么存量的倍数比账单的倍数高? —— 因为**单价在降**。**Demo:五年存量涨 9.0 倍,账单只涨 3.0 倍。** **但单价不会一直降——降速慢下来的那一年,账单就会追上存量。** 2. 抽样误差为什么是按平方根降? —— 因为**均值的标准差是总标准差除以样本量的平方根**。 **第 3 段实测:样本乘十,误差落到约三分之一(根号十)。** **这条规律决定了大样本的性价比很差。** 3. 为什么说去重比压缩划算? —— 因为**它不花算力、不掉精度**。**Demo 第 4 段:1350000 条里 26.0% 是重复的,删掉就是白省。** **压缩还得挑级别、还要解压,去重是一次性的。**

这一节讲的是「数据在硬盘上长成什么样」。 下一节换个位置:数据不是躺在硬盘里的,是传感器每秒往外吐的。 一千个传感器一年吐几十 TB——那就得在产生的地方先算掉。

相关笔记