⚙️ 第十二章 如何让计算机【学习】
📄 一句话概括

一次划分的成绩里混着运气;交叉验证把数据切成 k 份轮流当考卷——实测五折从 62.5% 到 87.5%,波动 25 个百分点,这就是为什么不能只看一次。

📝 本节和前面几节的关系

12.6 跑出了 87.5%,这一节回答一个更根本的问题:那个数字到底能信几分。

一、一次划分的毛病

80/20 划分有个明显的问题:切得好就分数高,切得差就分数低。 同一份数据、同一个算法,只因为把哪几条分到了测试集,结果就能差一大截。 说白了,这份成绩里混着【运气】。 这不是算法不稳,是【一次抽样的样本太小】。

二、交叉验证怎么做

解决办法叫交叉验证: 把数据切成 k 份 → 每次都拿其中 1 份当测试、剩下 k-1 份当训练 → 轮流 k 次 → 最后把 k 个成绩平均。 每一份都当过一次考卷——所以运气被摊平了。 实测做 5 折交叉验证,5 个数字的平均值比任何单个数字都可靠。 它没有用到新数据,只是把手里这点数据用得更充分。

三、实测的波动有多大

看实测的五个数字:75%、75%、75%、62.5%、87.5%。 五折平均 75%,但最好的一折和最差的一折差了 25 个百分点。 这就是关键的一句:同一个算法、同一份数据,只因为切法不同就能差这么多。 所以单次成绩只能当参考——要说【这个算法好不好】,得看多次平均。 它还有个好处:平均下来 75% 比单次的 87.5% 低——这才是更接近真相的数字。

四、由此得到两条经验

第一:单次得分只能参考,多看几次才敢下结论。 第二:拿测试集反复调参数,等于变相把答案背下来。 第二条尤其重要:如果你试了二十组参数、挑了在测试集上最好的那组, 那你其实是【让测试集参与了训练】——这个分数就不再是对新数据的承诺了。 所以正规做法是再留一份【从不参与任何选择】的数据——它才是最后那张真正的考卷。

五、动手 Demo:尝试交叉验证

一次划分的成绩里混着运气,交叉验证把每一份都轮流当一次考卷。 实测做 5 折,看分数的波动有多大。

xs, ys = make_dataset(per_digit=8)
n, kf, size = len(xs), 5, len(xs) // 5
for i in range(kf):
    s, e = i * size, (i + 1) * size
    rx, ry = xs[:s] + xs[e:], ys[:s] + ys[e:]
    right = sum(1 for q, t in zip(xs[s:e], ys[s:e])
                if knn_predict(rx, ry, q, 3) == t)
    print("第 %d 折 %.1f%%" % (i + 1, right / (e - s) * 100))

实跑输出:

--------------------------------------------------------------------
尝试交叉验证
--------------------------------------------------------------------

**上一节的 80/20 划分有个毛病:切得好就分数高、切得差就分数低。**
  说白了,**这份成绩里混着【运气】。**

  解决办法叫**交叉验证**:

    把数据切成 k 份
    每次都拿其中 1 份当测试、剩下 k-1 份当训练
    轮流 k 次,最后把 k 个成绩平均一下

  **这样一来,每一份都当过测试,运气被摊平了。**
  实测做 5 折交叉验证:

  第几折     训练     测试     准确率
  ------------------------------------
  1          32       8        75.0%
  2          32       8        75.0%
  3          32       8        75.0%
  4          32       8        62.5%
  5          32       8        87.5%

    五折平均准确率          75.0%
    最好的一折              87.5%
    最差的一折              62.5%
    波动                    25.0 个百分点

  **看那个波动**——**同一个人、同一份数据,只因为切法不同就能差这么多。**
  所以那两条经验就有了出处:
    **单次得分只能参考,多看几次才敢下结论。**
    **拿测试集反复调参数,等于变相把答案背下来——那是作弊。**

实测五折:75%、75%、75%、62.5%、87.5%——平均 75%,最好与最差相差 25 个百分点。 同一个算法、同一份数据,只因为切法不同就能差这么多——所以单次成绩只能参考。

30 秒实验

  1. 把折数从 5 改成 8,看平均值会不会更稳。
  2. 在纸上算一算:8 条测试样本里错 1 条,分数会掉多少个百分点。

常见误区

  1. 以为单次分数就是算法的真实水平。它里面混着抽样的运气。
  2. 以为可以反复拿测试集挑参数。那等于把答案背下来,分数不再可信。
自测三问(点开对答案) 1. 交叉验证是怎么做的? —— 把数据切成 k 份,轮流拿一份当测试、其余当训练,跑 k 次后取平均。 2. 这次五折实测的波动有多大? —— 从 62.5% 到 87.5%,相差 25 个百分点,平均 75%。 3. 为什么不能拿测试集反复调参数? —— 因为那等于让测试集参与训练,分数不再代表对没见过的数据的表现。

相关笔记