健身房里有一位沉默的教练,他看不见学员肌肉内部的力量,只能靠一次次举杠铃的表现——成功了、失败了、重量上去了没有——来悄悄更新心里那张“能力表”。这张表看不见、摸不着,却决定了他下一次给学员排什么课。知识追踪模型,就是给“AI 教练”装上这样一张能力表:学生每做一道题,系统就根据作答历史,实时估计 TA 对每个知识点的掌握程度,并预测下一道题答对的概率。本文用“教练带队”这个比喻贯穿始终,带你看懂三代模型 DKT、SAKT、AKT 的进化之路:从记流水账的老教练,到只回看关键片段的新教练,再到连“多久没练”都记进账本的数据分析师。

岗位关联

对 AI 从业者而言,知识追踪是自适应教育与智能辅导产品的核心引擎。学会读懂这套“学生状态估计”方法,你将拥有从“预测一道题”升级到“读懂一个学生”的能力,在教育科技与司法培训等领域大有可为。

目录
  1. 可视化演示
  2. 知识追踪概述
  3. 答题序列建模
  4. DKT循环网络
  5. SAKT注意力机制
  6. AKT进阶设计
  7. 模型对比评估
  8. 教育应用实践
  9. 未来发展趋势
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

对比DKT的LSTM时序递归、SAKT的自注意力查询与AKT的上下文感知建模,展示三类知识追踪模型如何从学生答题序列估计知识掌握状态。支持三模式切换与播放暂停。

本节配有交互动效(进入视口后自动加载,约 3KB)。

DKT LSTM逐题处理 隐藏状态 按时间步更新学生知识掌握状态。

知识追踪概述

教练永远不会切开运动员的膝盖去看韧带强度,他只能凭借外部表现推断内部状态。学生也是一样——“这题会不会”藏在脑子里,模型能看到的只有一道道作答的“红与绿”。知识追踪的起点就是承认这个现实:知识状态是隐藏变量,只能靠作答序列去反推。

把学习过程写成时间线:第 t 时刻,学生答了题 q_t、得到结果 r_t,我们想估计的是 TA 此刻对各个知识点的掌握程度向量 s_t。在深度学习方法出现前,这类推断依赖专家手工编写规则;而 DKT、SAKT、AKT 这代模型,则把“如何更新状态”变成可以从数据里学出来的函数 f。

这三个模型的骨架完全一致:昨天的状态加上今天的作答,融合成今天的新状态。无论后续的注意力机制多花哨,核心等式始终是这条“状态更新律”。

看得见的训练表现,喂给看不见的能力账本,账本再返回来指导下一场训练。教练的“状态本”每行都在变,s_t 就是 AI 教练手里那本动态更新的账本,而 f 是教练的“记笔记习惯”。

st=f(st−1, xt),xt=(qt,rt)s_t = f(s_{t-1},\, x_t), \qquad x_t = (q_t, r_t)
这是知识追踪的总纲:昨天的状态 + 今天的新作答 → 今天的新状态。f 具体长什么样,正是 DKT、SAKT、AKT 各自交出的答案。
  1. 知识状态 $s_t$模型在第 t 时刻对“学生掌握了多少”的估计,是一个向量,每个维度对应一个知识点或技能。
    sts_t
  2. 上一次状态 $s_{t-1}$前一刻的掌握度,是推理链条中从历史里带过来的“记忆”。
    st−1s_{t-1}
  3. 本次作答 $x_t$由题目编号 q_t 与作答结果 r_t(对/错)打包而成的新观察。
    xt=(qt,rt)x_t = (q_t, r_t)
  4. 更新函数 $f$把旧状态与新观察融合出新状态的规则,具体形态由模型结构和训练数据共同决定。
    f(⋅)f(\cdot)

答题序列建模

教练不会把整场比赛的原始视频存在脑子里,他只会记“关键事件卡”:第几局、谁、什么动作、成没成。模型也一样,原始题目文本信息太杂、无法直接下咽,必须先编码成结构化向量才能喂给神经网络。

一张事件卡就是一个“问题-作答对”(q_t, r_t)。题目编号转成独热向量,作答结果(对/错)也转成两位独热向量,再把两个向量首尾相接,就得到这一时刻模型的输入 x_t。独热编码的意思是:把一个类别拆成一长串 0 与唯一一个 1,这是神经网络能读懂的“数字语言”。

事件卡一张一张按顺序翻过去,学习的“故事”才成立:交换两张卡,教练看到的进步曲线就完全不同。序列,就是知识追踪唯一的素材来源。

xt=[onehot(qt); onehot(rt)]∈RQ+2x_t = \left[\text{onehot}(q_t);\ \text{onehot}(r_t)\right] \in \mathbb{R}^{Q+2}
所以每一道题都变成了一串规整的 0/1 数字,模型按顺序逐张翻看这些“事件卡”,顺序就是学习的节奏。
  1. 题目独热 $\text{onehot}(q_t)$把题目编号转成只有一位为 1、其余全为 0 的向量,维度等于题库题目数 Q。
    onehot(qt)\text{onehot}(q_t)
  2. 结果独热 $\text{onehot}(r_t)$把“答对/答错”转换成两个布尔位,答对点亮一位、答错点亮另一位。
    onehot(rt)\text{onehot}(r_t)
  3. 拼接 $[A; B]$把两个短向量首尾相连,合并成一个更长的事件编码,作为该时刻输入。
    [A;B][A; B]
  4. 总维度 $Q+2$Q 个题目位,加上 2 个结果位,共同描述“答了哪道题、答得怎么样”。
    RQ+2\mathbb{R}^{Q+2}

DKT循环网络

老教练的习惯是记“流水账”:每天训练结束,他把全天信息压缩成一段总结,第二天在总结上续写,从不回看完整录像。这正是循环神经网络的工作方式——用一个定长的隐藏向量 h_t 滚动记忆,既有容量约束,又有时间感。

每读入一个“问题-作答对”的编码 x_t,隐藏状态就更新一次,同时输出对所有知识点的“答对概率”预测。训练时用交叉熵损失让预测贴近真实作答,梯度沿时间反向传播,自动调整权重矩阵 W——也就是调校教练的“记笔记习惯”。

老教练的流水账有个毛病:本子容量有限,写到第 500 条时,第 1 天的细节早被冲成淡淡墨迹——这就是 DKT 的长序列局限。但它的优点同样突出:结构简单、训练快、小数据也能跑,至今许多轻量自适应产品仍用它打底。

ht=tanh⁡(Wxxt+Whht−1),yt=σ(Wyht)h_t = \tanh(W_x x_t + W_h h_{t-1}), \qquad y_t = \sigma(W_y h_t)
W_x 决定“这次作答”有多大分量,W_h 决定“历史总结”有多大的惯性;tanh 把状态压到 [-1,1],σ 把预测压成 0 到 1 的概率。
  1. 当前输入 $x_t$本次作答的独热编码,是这条知识河流新汇入的水。
    xtx_t
  2. 旧状态 $h_{t-1}$前一步滚出来的总结,装着截至上一题的所有压缩信息。
    ht−1h_{t-1}
  3. 线性加权 $W_x x_t + W_h h_{t-1}$新旧信息按权重合并,权重由数据学习决定。
    Wxxt+Whht−1W_x x_t + W_h h_{t-1}
  4. 非线性压缩 $\tanh$把合并结果压到 [-1,1],防止状态数值随步数爆炸。
    tanh⁡(⋅)\tanh(\cdot)
  5. 输出预测 $\sigma(W_y h_t)$把当前状态映射到每个知识点“下一题答对”的概率。
    σ(Wyht)\sigma(W_y h_t)

SAKT注意力机制

新来的教练不看按顺序的完整录像,而是“哪里不会倒哪里”:评估当前这个球时,他直接翻出历史上最相关的几个片段,按相关度分配注意力。这个直觉,就是自注意力机制的原型。

在 SAKT 中,序列里的每个交互同时扮演“查询 Q”“键 K”“值 V”三个角色:当前时刻用 Q 去和所有历史时刻的 K 做相似度匹配,得到权重 α,再用 α 去加权汇总对应的 V。权重越大,说明那段历史对当前判断越关键——教练可以指着屏幕说:“这个预测主要参考了上周那道同类题”。

专注教练效率高、还讲得出依据,但他不看日历——“三天前”和“三分钟前”在他眼里没有区别。于是,第三位教练出场了。

αij=exp⁡(QiKj⊤/dk)∑j′exp⁡(QiKj′⊤/dk),zi=∑jαijVj\alpha_{ij} = \dfrac{\exp\left({Q_i K_j^{\top}}/{\sqrt{d_k}}\right)}{\displaystyle\sum_{j'} \exp\left({Q_i K_{j'}^{\top}}/{\sqrt{d_k}}\right)}, \qquad z_i = \sum_j \alpha_{ij} V_j
除以 √d_k 是为了防止高维点积数值过大,softmax 则让所有权重之和为 1,变成一张“按相关度分配注意力”的清单。
  1. 查询与键点积 $Q_i K_j^{\top}$测量“眼前这一题”与“历史那一道题”的相似程度。
    QiKj⊤Q_i K_j^{\top}
  2. 缩放 $\div\sqrt{d_k}$维度增大时点积会变大,缩放后梯度更稳定。
    ÷dk\div\sqrt{d_k}
  3. softmax 归一化把相似度分数变成总和为 1 的非负权重。
    softmax(⋅)\text{softmax}(\cdot)
  4. 加权求和 $\sum_j \alpha_{ij} V_j$用权重把历史“值”汇总成当前时刻的知识状态。
    ∑jαijVj\sum_j \alpha_{ij} V_j

AKT进阶设计

第三位教练是带着数据库的分析师:看视频先看时间戳,“上个月的比赛?参考价值要打个折”。教育心理学中的遗忘曲线说的正是这件事:距离作答时间越久,它对当前知识状态的影响越小。

AKT 在注意力权重上乘了一个随时间衰减的因子。Δ 是两次作答之间的间隔,β 是由数据学出来的“遗忘速度”;间隔越大,历史影响按指数缩水,好比食物放得越久越不新鲜。

除了时间,AKT 还引入协变量注意力:用类似 Rasch 模型的机制刻画题目难度,衡量两道题考察技能是否接近。于是最终的历史权重变成“注意力 × 遗忘衰减 × 题目相似度”三重过滤。分析师教练终于还原了真实学习:人不会用上个月的错误定义今天的水平。

f(Δt)=exp⁡(−β⋅Δt)f(\Delta t) = \exp\left(-\beta \cdot \Delta t\right)
β 越大忘得越快;Δt 为 0 时权重是 1(刚刚发生的完全保留),间隔增大时权重单调下降。
  1. 时间间隔 $\Delta t$当前作答与历史某次作答之间相隔的时长。
    Δt\Delta t
  2. 遗忘速度 $\beta$由训练数据学出来的参数,决定“忘得多快”。
    β\beta
  3. 指数衰减 $\exp(-\beta \Delta t)$间隔翻倍,影响按指数级缩水。
    exp⁡(−βΔt)\exp(-\beta \Delta t)

模型对比评估

三位教练同台竞技,总得有个量化标准。知识追踪领域最常用的排行榜指标是 AUC:随机抽一个“实际答对”的样本和一个“实际答错”的样本,模型给前者预测概率更高的可能性有多大。0.5 等于瞎猜,越接近 1 说明排序越准。

选型没有绝对王者,只有匹配:数据量小、要快速上线,DKT 最稳;数据充足且要解释性,SAKT 的可视化权重是加分项;有丰富作答时间戳、需要长期跟踪,AKT 能把时间信息榨干。反过来,数据不够却硬上 AKT,就像给没有历史战绩的菜鸟队配分析师,巧妇难为无米之炊。

AUC=P(p^r=1>p^r=0)\text{AUC} = P(\hat{p}_{r=1} > \hat{p}_{r=0})
通俗地说,AUC 检验的是“模型是否能把做对的情况排在前面”,它不被预测阈值干扰,适合作答数据中对错不均衡的情况。
  1. 正样本预测值 $\hat{p}_{r=1}$模型对“实际答对”的样本给出的预测概率。
    p^r=1\hat{p}_{r=1}
  2. 负样本预测值 $\hat{p}_{r=0}$模型对“实际答错”的样本给出的预测概率。
    p^r=0\hat{p}_{r=0}
  3. 比较大小 $P(\hat{p}_{r=1} > \hat{p}_{r=0})$随机配对后,正样本排在前面的概率。
    P(p^r=1>p^r=0)P(\hat{p}_{r=1} > \hat{p}_{r=0})

教育应用实践

状态估计最终要落地成产品。自适应学习系统拿到知识状态后,最经典的动作是“动态出题”:把下一题选在学生“跳一跳够得着”的最近发展区——太简单浪费练习,太难打击信心。于是目标变成:找一道题,它的知识点掌握度与理想阈值 θ 最接近。

这套逻辑在 K12 自适应刷题、智能错题归因里已是大规模商用;在司法领域,法考与法官助理培训平台把“民法合同效力”“证据规则”等拆成知识点,用 AKT 追踪学员掌握曲线,连续答错立即向班主任预警并推送专项训练,试点班级知识点掌握率显著提升。

q∗=arg⁡min⁡q∈Q∣s^cq−θ∣q^{*} = \arg\min_{q \in \mathcal{Q}} \left| \hat{s}_{c_q} - \theta \right|
θ 常取 0.6 左右:掌握度远高于它说明题太简单,远低于它说明题太难,“还差一点”的临界点最有利于学习。
  1. 候选题库 $\mathcal{Q}$系统当前可以抽取的所有题目集合。
    Q\mathcal{Q}
  2. 知识点掌握度 $\hat{s}_{c_q}$模型估计的学生对这道题所属知识点的掌握度。
    s^cq\hat{s}_{c_q}
  3. 与阈值差 $\left| \hat{s}_{c_q} - \theta \right|$衡量“这道题的挑战程度”离理想值多远。
    ∣s^cq−θ∣\left| \hat{s}_{c_q} - \theta \right|
  4. 取最小的 $\arg\min$选出与目标掌握度最接近的那道题。
    arg⁡min⁡q∈Q\arg\min_{q \in \mathcal{Q}}

未来发展趋势

教练的装备还在升级。第一件新装备是“多模态镜头”:除了对错,答题耗时、鼠标轨迹、翻书次数都进入状态估计,知识状态从“一维对错”变成“多维行为画像”。

第二件是“可解释”:注意力权重已经能回答“这个预测为什么这样做”,未来要用自然语言向师生解释每次状态更新,让 AI 从“黑箱评分”变成“教学助手”。第三件是“隐私”:学校数据不出校门,用联邦学习只上传模型参数,再按样本量加权平均,避免直接搬运学生的作答记录。

装备再先进,教练的本职不变——从看得见的作答,推断看不见的状态。理解 DKT、SAKT、AKT 这三代进化,就是读懂了教育智能化的主心骨。

w=∑k=1KnkN wkw = \sum_{k=1}^{K} \frac{n_k}{N}\, w_k
N 是全体参与方的样本总数,n_k 是第 k 个机构(如学校)的样本数,数据量越大的一方在聚合时发言权越大。
  1. 本地模型 $w_k$各参与方在自己的数据上训练出的模型参数。
    wkw_k
  2. 样本占比 $\dfrac{n_k}{N}$该参与方的数据量在全体中的比重。
    nkN\frac{n_k}{N}
  3. 加权求和 $\sum_{k=1}^{K}$把各地模型按比例合并,原始作答数据不出本地。
    ∑k=1KnkNwk\sum_{k=1}^{K} \frac{n_k}{N} w_k

AI 应用场景

自适应练习 App 的动态出题

阶段:模型推理与个性化推荐

解决的问题:传统题库按章节出题或随机抽题,千人一面,简单题浪费时间、难题劝退学生。知识追踪模型通过实时估计各知识点掌握度,把练习聚焦在“临界掌握”区,让每一道题都刚好落在学生够得着的位置。

具体案例:某 K12 数学练习 App 每日产生数百万次作答,后端用 SAKT 实时更新学生的知识状态向量,下一题的难度和知识点即时调整;模型在离线评测中 AUC 达到 0.82,上线后学生平均每章练习时长下降约三成,而正确率稳步提升。

司法培训与法考平台的考点诊断

阶段:智能诊断与学习路径规划

解决的问题:法考知识点多且分散,学员常“只刷题不总结”,错题归因靠人工翻阅,效率低、滞后性强。知识追踪把法条与案例拆成细粒度知识点,按答题序列追踪每个考点的掌握曲线,及时定位薄弱环节。

具体案例:某法官助理培训平台将“民法-合同效力”“刑诉-非法证据排除”等拆成 200 余个知识点,用 AKT 记录每次作答的时间戳,对连续答错学员自动推送专项微课并预警班主任;试点三个月,重点知识点掌握率提升约两成。

智能错题归因与辅导反馈

阶段:学习数据分析与反馈生成

解决的问题:传统错题本只统计“错了几次”,回答不了“为什么会错”。知识追踪输出的状态向量能定位到具体薄弱技能点,并关联对应的讲解视频与变式题,让反馈从“答案对错”升级为“原因诊断”。

具体案例:某智能辅导平台利用 DKT 对每位学生的答题序列建模,生成“知识掌握热力图”;学生每做完一套练习,页面自动列出三个最需要重练的技能点,并推送同类变式题,二次答对率明显提升。

Python 演示

python85 行
import numpy as np  def sigmoid(z):    return 1.0 / (1.0 + np.exp(-np.clip(z, -30, 30)))  def fake_students(n=12, n_q=8, T=20, seed=1):    rng = np.random.RandomState(seed)    qs = rng.randint(0, n_q, (n, T))    skill = rng.randn(n, n_q)    drift = np.linspace(-0.3, 0.3, T)    prob = sigmoid(skill[np.arange(n)[:, None], qs] + drift[None, :])    rs = (rng.rand(n, T) < prob).astype(int)    return qs, rs  class MinimalDKT:    def __init__(self, n_q=8, hidden=12, lr=0.15, seed=0):        rng = np.random.RandomState(seed)        self.n_q, self.hidden, self.lr = n_q, hidden, lr        self.Wx = rng.randn(n_q + 2, hidden) * 0.15        self.Wh = rng.randn(hidden, hidden) * 0.15        self.Wy = rng.randn(hidden, n_q) * 0.15     def _encode(self, q, r):        x = np.zeros(self.n_q + 2)        x[q] = 1.0        x[self.n_q + r] = 1.0        return x     def train(self, qs, rs, epochs=120):        n_stu = len(qs)        for _ in range(epochs):            gWx = np.zeros_like(self.Wx)            gWh = np.zeros_like(self.Wh)            gWy = np.zeros_like(self.Wy)            for s in range(n_stu):                T = len(qs[s])                hs = [np.zeros(self.hidden)]                xs, ps = [], []                for t in range(T - 1):                    x = self._encode(qs[s, t], rs[s, t])                    h = np.tanh(self.Wx @ x + self.Wh @ hs[-1])                    hs.append(h)                    xs.append(x)                    ps.append(sigmoid(self.Wy @ h))                dh = np.zeros(self.hidden)                for t in range(T - 2, -1, -1):                    target = qs[s, t + 1]                    grad = np.zeros(self.n_q)                    grad[target] = ps[t][target] - rs[s, t + 1]                    gWy += np.outer(grad, hs[t + 1])                    dtanh = (self.Wy.T @ grad + dh) * (1 - hs[t + 1] ** 2)                    gWx += np.outer(dtanh, xs[t])                    gWh += np.outer(dtanh, hs[t])                    dh = self.Wh.T @ dtanh            self.Wx -= self.lr * gWx / n_stu            self.Wh -= self.lr * gWh / n_stu            self.Wy -= self.lr * gWy / n_stu     def predict(self, qs, rs):        h = np.zeros(self.hidden)        probs = []        for t in range(len(qs)):            h = np.tanh(self.Wx @ self._encode(qs[t], rs[t]) + self.Wh @ h)            probs.append(sigmoid(self.Wy @ h))        return probs     def evaluate(self, qs, rs):        probs = self.predict(qs, rs)        correct = 0        total = len(qs) - 1        for t in range(total):            guess = int(probs[t][qs[t + 1]] > 0.5)            correct += int(guess == rs[t + 1])        return correct / max(total, 1)  if __name__ == "__main__":    qs, rs = fake_students()    model = MinimalDKT()    model.train(qs[:10], rs[:10])    accs = [model.evaluate(qs[i], rs[i]) for i in range(10, 12)]    print("下一题答对与否预测准确率: %.2f" % (sum(accs) / len(accs)))
目的:用纯 NumPy 实现一个最简 DKT(Elman 循环网络),在 10 名学生的合成作答序列上训练,再用 2 名新学生评测“下一题答对与否”的预测准确率。
  1. qs, rs = fake_students()生成 12 名虚拟学生的作答记录,包括每题答的是哪道题、答对没有。
  2. skill = rng.randn(n, n_q)每个学生对每个知识点都有一个隐藏熟练度,这正是“看不见的知识状态”。
  3. rs = (rng.rand(n, T) < prob).astype(int)用真实隐藏熟练度合成作答结果,当作模型要学习的“录像带”。
  4. x[q] = 1.0把题目编号翻译成独热向量中唯一一个 1。
  5. x[self.n_q + r] = 1.0把对/错结果编码到独热向量的后两个位。
  6. h = np.tanh(self.Wx @ x + self.Wh @ hs[-1])滚动更新隐藏状态,等价于正文里的 h_t = tanh(Wx·x_t + Wh·h_{t-1})。
  7. grad[target] = ps[t][target] - rs[s, t + 1]交叉熵对逻辑回归输出的梯度,误差 = 预测概率 − 真实结果。
  8. self.Wx -= self.lr * gWx / n_stu沿负梯度方向更新权重矩阵,完成一次“调校教练记笔记习惯”。

常见误区

误区很多初学者觉得知识追踪模型就是个预测分类器,比赛成绩看“下一题预测准不准”就够了,能预测对就是好模型。

正解预测只是副产品。模型真正的产出是隐状态 s_t / h_t——对每个知识点掌握度的估计。自适应出题、错题归因、学习预警全靠状态向量,而不是单个预测值。就像教练的价值不在“猜中下一个球得不得分”,而在于读懂球员状态并调整训练计划;预测准只是“读懂”的附带证明。

为何常见:训练目标函数确实是对作答的预测,损失函数盯着“对错”,容易让人误以为模型等于预测器。

误区不少人认为 RNN 像记忆大师,作答序列越长,它能记住的学生信息就越全面,对学生了解就越准确。

正解定长隐向量的容量有限,加上梯度沿时间反向传播时不断衰减,序列过长时早期信息会被稀释,长程依赖反而变差。所以 SAKT、AKT 才用注意力“跳过”中间步骤直接回看重点历史。老教练的流水账写到第 500 天,第 1 天的细节早被冲淡了。

为何常见:RNN 的递归结构给人“串联记忆、越记越多”的直觉,但信息容量和梯度问题常常被低估。

误区有人以为自注意力完全取代了循环结构,SAKT 对历史打乱顺序也无所谓,顺序信息不重要了。

正解标准自注意力是置换不变的——把历史交互打乱,计算出的权重一模一样。因此 SAKT 通常要叠加位置编码来补偿顺序,而 AKT 更进一步用“相对时间”而非绝对位置,把“多久前答的”也建模进来。顺序与时间信息没有消失,只是换了一种注入方式。

为何常见:“注意力不看距离”的直觉让人误以为顺序无所谓,忽略了序列本身是知识追踪的信息载体。

误区看到论文里 AKT 的 AUC 最高,便认为参数越多效果越好,任何项目都无脑选 AKT。

正解参数多意味着需要更多数据、更长训练时间;数据量小时复杂模型容易过拟合,轻量 DKT 基线往往更稳、上线更快。正确的选型流程是“先跑简单基线,再量化评估复杂模型的增量”。数据不足时,分析师教练的分析再漂亮也难落地。

为何常见:基准测试排行榜上的数字会掩盖数据规模、训练成本和场景约束等现实因素。

面试题

Q1. 知识追踪(DKT/SAKT/AKT)最核心的目标是什么?

单选题 · easy

  • A.判断学生此次作答是否正确
  • B.估计学生内在的知识掌握状态← 正确答案
  • C.生成新题目并扩充题库内容
  • D.统计学生累计做题的总时长

答案:B。知识追踪把“会不会”当作看不见的隐藏状态,用可观察的作答序列去推断它,就像教练凭比赛表现推断运动员状态。A 是预测任务,属于状态推断的副产品;C 是出题,D 是统计,都不是核心目标。

Q2. 一个“问题-作答对”在喂给模型前通常如何表示?

单选题 · easy

  • A.直接拼接题目文本与选项
  • B.独热编码题目并拼接正误← 正确答案
  • C.只保留题目编号这一个整数
  • D.将作答过程渲染成灰度图

答案:B。独热编码将题目 ID 变成一位为 1 的向量,作答结果也编码成“答对/答错”两个位,再拼接成 x_t,对应正文的 [onehot(q_t); onehot(r_t)]。输入必须结构化,原始文本和单个整数都无法表达“答了哪题、答得怎样”这对信息。

Q3. DKT 中的“隐藏状态” h_t 代表什么?

单选题 · mid

  • A.当前题目在题库中的难度分数
  • B.学生对各知识点的掌握程度向量← 正确答案
  • C.教师对学生成绩的主观评价
  • D.学生答题速度的滚动平均值

答案:B。h_t 是循环网络看完前 t 次作答后压缩出的“状态本”,本质上是对知识掌握度的向量估计,并随每次作答滚动更新。A 属于题目属性,C 是人工评价,D 只是统计量,都不是模型学习出的隐藏状态。

Q4. 相比 DKT,SAKT 用自注意力带来的主要优势是?

单选题 · mid

  • A.完全不需要任何训练数据
  • B.直接刻画哪些历史作答最相关← 正确答案
  • C.能够记住无限制长度的历史
  • D.可直接把题目难度设为常数 1

答案:B。自注意力为每个当前时刻计算它与所有历史交互的相似度,权重越大表示那段历史越相关,相当于教练直接回放关键片段。A 违背机器学习常识;C 错误,注意力窗口仍有序列长度限制;D 与注意力机制无关。

Q5. AKT 相比 SAKT 的关键改进包括哪些?

多选题 · hard

  • A.加入“距离上次作答”的相对时间← 正确答案
  • B.用指数衰减权重刻画遗忘曲线← 正确答案
  • C.用协变量注意力衡量题目相似← 正确答案
  • D.用随机打乱替代注意力计算

答案:ABC。AKT 的三板斧正是相对时间编码、遗忘曲线衰减和协变量注意力,对应正文公式 f(Δt)=exp(−βΔt) 与题目相似度加权。D 恰恰与注意力机制相反,是干扰项。

Q6. 关于 DKT 在长作答序列上的局限,正确的是?

单选题 · hard

  • A.序列越长梯度越容易消失与稀释← 正确答案
  • B.序列越长计算速度反而越快
  • C.序列变长后无需再更新状态
  • D.长度不影响模型对近题的预测

答案:A。循环网络把信息压进定长隐向量,时间步增加时早期梯度多次连乘后趋于消失,久远作答难以影响当前估计,就像教练的流水账写到后面忘了开头。B、C、D 与 RNN 的递归更新机制相矛盾。

Q7. 下列哪些属于知识追踪模型的实际应用?

多选题 · mid

  • A.自适应练习按掌握度推荐题目← 正确答案
  • B.为答错题目自动生成辅导内容← 正确答案
  • C.预测学生未来成绩并发出预警← 正确答案
  • D.直接替代教师完成作文批改

答案:ABC。知识追踪输出的掌握度可用于动态选下一题(A)、定位薄弱点生成辅导(B)、预测后续表现做风险预警(C)。D 作文批改属于自然语言处理任务,不依赖“作答序列→知识状态”的建模思路。

Q8. AUC 用于评价知识追踪模型时,主要衡量什么?

单选题 · easy

  • A.正样本预测值普遍高于负样本← 正确答案
  • B.模型参数量足够少且轻量
  • C.训练数据中答对题目的总数
  • D.推荐题目文本长度的合理性

答案:A。AUC = P(正样本预测值 > 负样本预测值),即随机抽一个“实际答对”和一个“实际答错”样本,模型更看好前者的概率,衡量排序区分能力且不受阈值影响。B、C、D 与排序性能无关。

Q9. 若数据量小且需快速上线,合理的模型选型做法是?

多选题 · hard

  • A.优先考虑 DKT 这类轻量循环模型← 正确答案
  • B.无脑选择最复杂的 AKT 模型
  • C.用简单基线再量化评估增量← 正确答案
  • D.干脆放弃建模改用随机出题

答案:AC。数据少时复杂模型易过拟合,应先以 DKT 做基线(A),再评估复杂模型带来的增量值不值(C)。B 盲目追求复杂度,D 直接放弃建模,都不合理。

Q10. 在司法/职业培训场景中,知识追踪的主要价值是?

单选题 · mid

  • A.自动生成法律文书的措辞
  • B.诊断考点掌握度并定制路径← 正确答案
  • C.直接判断案件的胜诉概率
  • D.替代法官完成最终量刑建议

答案:B。法考培训平台把“法条/案例”当作知识点,用答题序列估计学员对各考点的掌握度,再定制学习路径与预警,这正是正文“司法培训应用”的核心。A 属于文本生成,C、D 属于法律决策,都不属于学生建模。