🧠 第九章 政务与教育:AI赋能治理与教学创新实践
📄 一句话概括

200 个学生 × 20 道题、答题率 45.2%。用 20 题估能力,估出来和真值相关 0.866、RMSE 0.70; 只给 3 题,相关掉到 0.609,而 RMSE 几乎没动(0.72)。 RMSE 看不出差别,是因为这套模型定不出绝对尺度——要看信息够不够,得看相关系数。

📝 本节和前面几节的关系

9.2 的三节都在政务:管窗口、评政策、派工单。从这一节开始换到学校。 「个性化」这个词被用得很虚,落到实处其实只有一个问题:这个学生现在会什么、不会什么。

一、个性化之前,先得有一把尺子

老师凭经验知道「这个孩子基础差」, 但「差多少、差在哪一章」说不出来。没有刻度就没法个性化——你只能凭感觉补,补到哪算哪。 所以第一件事是把「水平」变成一个数。输入只有一份答题记录(谁、哪道题、对没对), 输出是每个学生的能力和每道题的难度。 这件事有个名字叫知识追踪。叫「追踪」是因为它不只算一次总分, 而是随着答题不断更新估计——今天做了 5 道题,能力值就往真实水平挪一点。 它和「算总分」的区别在于:总分不知道题目难易。同样是对 7 道,答的是基础题还是压轴题, 含义完全不同。知识追踪把「题目难度」也当成要估的未知量,一起解出来。

二、只有两个参数的模型

Demo 用的模型简单到只有两行:每个学生一个能力值 θ,每道题一个难度值 b,答对的概率是 σ(θ − b)。 σ 是那个把任意实数压到 0 到 1 之间的函数。 θ 比 b 大,答对概率超过一半;θ 比 b 小,低于一半。就这么点东西, 能解释「会的人做简单题基本对、做难题看运气」这件事。 估计的方法是最朴素的梯度下降: 答对了就把能力往上推一点,答错了往下拉一点,同时题目的难度也按全班的表现跟着调。跑几百轮之后, θ 和 b 就稳定下来了。 必须加正则,不加会崩。Demo 里学生强度的正则系数是 1.0、题目是 1.5, 这不是随手定的——它等于「假设能力服从标准正态分布」时,那个先验方差的倒数。 不加会怎样? 答对率高的学生,能力值会一路冲到几十几百——因为模型可以靠「无限放大能力」去拟合那几条记录。 没有约束,参数一定跑到极值去。这和调学习率是同一类问题。

三、3 道题估不准,但 RMSE 不告诉你

Demo 先给全部 20 题,再只给前 3 题,各估一次:

给几道题 相关系数 RMSE
20 题 0.866 0.70
3 题 0.609 0.72
相关系数从 0.866 掉到 0.609,掉得很明显;RMSE 从 0.70 到 0.72,几乎没动。同一个实验,
两个指标给出两种印象。
为什么 RMSE 看不出来?因为这套模型定不出绝对尺度。所有人同时加 1 分,
答对概率完全不变——
模型只认「谁比谁强」,不认「你是 500 分还是 600 分」。估计的时候先验把值往 0 拉,
于是两边的 RMSE 都被这个「拉」压住了,差异被掩盖。
相关系数不受尺度影响(它只看排序和线性关系),所以它能诚实地反映「3 道题确实估不准」。
这条经验是通用的:评价一个估计量,先分清它是不是尺度依赖的。定不出绝对尺度的模型,
用 RMSE 评价会得出「差不多」的错误结论;换成相关系数或者排序指标(比如 AUC),差别才出来。

四、3 道题为什么估不准:信息量算得出来

3 道题只有对/错 2 种结果,全对、全错、对错错……穷举下来一共 8 种组合。 要把 200 个学生按能力排序,用 8 个桶去装,桶里必然有很多人挤在一起。 这就是「信息不够」的准确含义:不是算法不好,是答案里没有信息。 换成更复杂的模型也没用——输入就那么点。 所以真实系统里,新学生的前几题不该用来判水平,该用来「探路」。 故意挑他有一半把握的题(能力值附近难度的题),答对答错都能提供最多信息。 这就是自适应出题(CAT)的全部原理:不是从易到难,是挑信息量最大的。 反过来,如果按「从易到难」的顺序出, 前 10 道全是简单题、全是答对,信息量接近 0——你只知道「他会最简单的」,别的什么都不知道。

五、落地:三个坑

① 标签不是「真会」,是「这次对了」。猜对、抄对、蒙对都会被当成会。 所以单次答题的记录必须配合作答时长和修改记录一起看,否则估计出来的能力值是虚高的。 ② 题目难度会漂。同一个知识点,换个问法难度就变了; 教材改版之后,去年估的 b 今年就不准了。所以难度要定期重估,不能一次算完用三年。 ③ 别把估计值直接给学生看。这是带先验的估计,对答得少的学生系统性偏低(先验把值往 0 拉)。 给学生看的应该是「下一步练什么」,不是「你在第几名」。 还有一个伦理上的红线:这些数据是未成年人数据。9.1.1 讲的 k-匿名和最小必要原则在这里全部适用, 而且更严——答题记录加上班级学号,基本就还原到个人了。

六、动手 Demo:知识追踪:20 题估能力相关 0.87,只有 3 题掉到 0.61

造 200 个学生、20 道题,真实能力服从标准正态、题目难度服从 0.8 的正态, 按 σ(θ−b) 生成答题记录(实际答题率 45.2%)。 用带 L2 正则的梯度下降同时估学生能力和题目难度,再只拿前 3 道题重估一遍, 比较两种情况下估计值和真值的相关系数与 RMSE。

P = 1.0 / (1.0 + np.exp(-(th[:, None] - b[None, :])))
R = (rg.random((ns, nq)) < P).astype(float)   # 答题记录

th_hat = np.zeros(ns)                          # 学生能力
b_hat = np.zeros(nq)                           # 题目难度
for _ in range(800):
    ph = sig(th_hat[:, None] - b_hat[None, :])
    th_hat += 0.6 * ((R - ph).sum(axis=1) / nq - 1.0 * th_hat)
    b_hat -= 0.6 * ((R - ph).sum(axis=0) / ns - 1.5 * b_hat)

t3 = fit(list(range(3)))                        # 只给 3 道题
corr3 = float(np.corrcoef(t3 - t3.mean(), th - th.mean())[0, 1])

实跑输出:

--------------------------------------------------------------------
知识追踪:20 题估能力相关 0.87,只有 3 题掉到 0.61
--------------------------------------------------------------------
  学生数 × 题目数          200 × 20
  实际答题率               45.2%
  20 题:相关/RMSE        0.866/0.70
  3 题:相关/RMSE         0.609/0.72
  预测准确率               67.3%
  基线(全猜多数类)       54.8%

  能力估计 RMSE **0.70**、相关系数 **0.866**——**「每个学生的水平」确实能从答题记录里估出来。**
  估计时加了 L2 正则(学生强度 1.0、题目强度 1.5)。**这个数不是随手定的:**
  它等于「假设能力服从标准正态分布」——**正则强度就是那个先验方差的倒数。**
  不加会怎样?答对率高的学生能力值会一路冲上去,**因为模型可以靠「无限放大能力」去拟合那几条记录。**
  这和上一章调学习率是同一个道理:**没有约束,参数会跑到极值。**
  注意估计值和真值都做了**去均值**:**这套模型只能定出相对水平,定不出绝对水平**——所有人同时加 1 分,预测完全不变。这是它的固有性质。
  预测准确率 **67.3%**,比「全猜多数类」的 54.8% 高 12.5 个点。
  最后两行是重点,而且要看**相关系数**而不是 RMSE:
  **20 题相关 0.866,3 题掉到 0.609。**
  那 RMSE 为什么几乎没变(0.70 对 0.72)?**因为这套模型定不出绝对尺度**——
  先验把估计值往 0 拉,**两边的 RMSE 都被这个「拉」压住了**,看它比不出信息量多少。
  **相关系数不受尺度影响**,所以它能反映出「3 题确实估不准」。
  这条经验通用:**评价一个估计量,先分清它是不是尺度依赖的。**
  **这不是算法不好,是信息不够**——3 道题的答案,最多只能把学生分成八种组合。
  所以真实系统里,新学生的前几题**不该用来判水平,该用来「探路」**:故意给中等难度的题,信息量最大。

先看整体:预测准确率 67.3%,比「全猜多数类」的 54.8% 高 12.5 个点。这个提升不算大, 因为答题率只有 45.2%,而且最后一层是硬阈值 0.5。 能力估计:RMSE 0.70、相关 0.866。「每个学生的水平能不能从答题记录里估出来」——答案是能。 3 题那一组:相关 0.609,RMSE 0.72。 相关掉了 0.26,RMSE 只涨 0.02。这就是「尺度依赖」的典型症状。 为什么先验会把两边都压住:估计值往 0 拉,真值也被去均值了,两边都在 0 附近, RMSE 的分母(离散程度)本身就被压小了,差异自然不显。 要说明:这 200 个学生、20 道题全是我造的,而且模型是最简化的 2PL(单参数 logistic), 没有考虑知识点之间的层级、也没有考虑学习增益。 但估计流程、正则的作用、两个指标的性质都是真的。真实系统(比如 BKT、DKT)会多几层, 诊断思路完全一样。

30 秒实验

  1. 把题目数从 20 改成 5、10、40,看相关系数的变化。 会看到明显的边际递减:5 到 10 涨得快,10 到 40 涨得慢。
  2. 把 L2 正则从 1.0 改成 0.0,看重跑会发生什么。 能力值会散到几十的量级,相关系数反而可能掉——过拟合了。
  3. 把答题率从 45% 提到 90%(每人答得更多),看两个指标。 20 题那组会更好,3 题那组几乎不变——它受限于题目数不是答题量。

常见误区

  1. 「RMSE 没变说明 3 道题也够」。 相关从 0.866 掉到 0.609,这套模型定不出绝对尺度,RMSE 被先验压住了。
  2. 「模型更复杂就能用 3 道题估准」。3 道题只有 8 种结果组合,信息上限在那里,换模型越不过去。
  3. 「新学生先做一套从易到难的卷子摸底」。前几题全对的信息量接近 0,应该挑一半把握的题探路。
自测三问(点开对答案) 1. 知识追踪比「算总分」多做了什么? —— 它同时估「题目难度」,所以能区分「对 7 道基础题」和「对 7 道压轴题」,总分做不到这一点。 2. 为什么 3 道题时 RMSE 几乎没变,相关系数却掉了很多? —— 这套模型只能定出相对水平、定不出绝对尺度,先验把估计值往 0 拉,两边的 RMSE 都被压住。 相关系数不受尺度影响,所以能反映差异。 3. 新学生前几道题应该怎么出? —— 挑他大约一半把握的题(能力值附近难度),答对答错都提供最多信息,而不是从易到难。

估出水平之后,下一个问题是「作业和考试谁来批」。 这件事看着简单,但一个字之差就能把意思反过来。

相关笔记