教学锚定的代码聚类:从形态分组到可解释的学情分析

发布时间:2026/10/18 15:43:48
教学锚定的代码聚类:从形态分组到可解释的学情分析 如果你教编程类课程或者在做教学数据挖掘一定遇到过这种尴尬把几百份学生代码丢进常见的聚类算法出来的簇表面上看“确实是一类”但你盯着簇里的代码根本解释不了它们为什么被分在一起——有的簇里递归写得稀烂的菜鸟和剪枝高手挤在同一堆有的簇里全是照抄模板的作业还有的簇压根不知道在说什么。PACCPedagogically Anchored Code Clustering教学锚定的代码聚类就是为这个场景设计的思路。它的核心变化是把聚类的主导权从“代码长得像不像”交还给“代码承担了什么教学角色”。这篇文章会从教学场景的特殊性出发讲清楚PACC的设计逻辑、完整实现路线、评估方法和落地案例。适合三类人看在高校里做程序设计课程教学改革的老师做学习分析方向的研究生以及所有和编程题目打交道、想从代码堆里挖出教学信号的人。1. 教学场景下的代码聚类为什么不能照搬传统方案1.1 传统代码聚类的三个致命局限传统代码聚类无论是基于字符串相似度还是基于抽象语法树结构特征的聚合本质上都在回答同一个问题这些代码在“形态”上是不是一致的。形态一致在软件工程里有价值——比如检测代码克隆、识别重复模块、做版本归属分析。但在教学场景里“形态一致”不等于“学习状态一致”。我先说第一个局限形态判断会把不同学习层次的学生混在一起。我试过一个真实场景某次C语言递归作业题目要求用递归实现斐波那契。代码A是典型菜鸟写法不用递归反而用循环模拟递归代码B也用了循环但它是为了性能优化主动做了尾递归转迭代。这两份代码在结构特征上高度相似都有for循环、都没有递归调用可一个是没掌握递归一个是掌握了递归之后的选择性优化。教学含义完全相反。传统聚类把它们放进同一个簇这个簇你根本没法用来指导教学。第二个局限模板代码会摧毁簇结构。作业题和工程项目最大的区别是课程会提供大量框架代码、头文件、输入输出模板学生只需要在留白处补充核心逻辑。这导致一个非常头疼的现象不同学生提交的代码可能有60%以上是完全相同的。当你做全局相似度计算时这个“共同底座”会像引力中心一样把不同题目、不同知识点的代码全吸进同一个大簇。就算你想办法把公共部分删掉剩下的核心逻辑可能只有几十行特征非常稀疏。第三个局限聚类结果没有教学解释性。传统聚类输出的簇编号是0、1、2、3你需要再人工去翻代码、猜规律才能给每个簇起个教学含义的名字。这个“事后解释”环节既费时又主观。同一批代码不同的人解释出来的教学结论可能完全不一样没有办法复现更没有可积累性。1.2 PACC的核心思路教学锚点到底是什么PACC的解法从根上换了一个起点。它不是先看代码“像不像”而是先问代码“为什么出现在这里”。每一份学生代码都对应一个明确的教学上下文——它是哪道题的答案这道题想考察哪个或哪几个知识点难度层级是多少属于概念巩固还是综合应用甚至预期会遇到哪类典型错误。这些信息就是教学锚点Pedagogical Anchor。PACC的基本思路是把这些锚点作为聚类的先导约束在特征空间里给代码的归类方向“定调”然后再用代码自身的结构特征做精细化切分。用一个书架类比来说。你整理一个书架如果只看书的封面颜色会把一本红皮的科幻小说和一本红皮的编程教材放一起这样的分类对书架使用者没有意义。PACC的逻辑是先搞清楚每本书的用途——是入门教材还是进阶读物是某个学科的习题集还是课外拓展然后再在这个大框架下根据书的写作风格和篇幅做具体排布。教学锚点就是那个“用途”维度代码特征就是那个“风格”维度。传统的聚类是让数据自己说话PACC是让教学目标和数据一起说话。这就是“Anchored锚定”这个词的分量锚不是用来限制数据长相的而是用来确保聚类结果在语义上站得住脚。2. 从零构建一个PACC聚类管线2.1 数据准备代码样本与教学上下文的对齐PACC的第一步不是写算法而是做数据对齐。你需要为每一份代码样本建立一条“代码-题目-锚点”的三元关联。真实教学环境里这个对齐工作大多是现成的——在线评测系统或者教学平台里每条提交记录本身就带有题号、学生ID、提交时间只要把题号对应到课程知识库锚点信息就补全了。有一个容易忽略的坑同一道题在不同教学阶段的锚点可能是变化的。比如同样是“写出排序算法”这道题第一周布置它是为了练习数组操作第五周布置它是为了理解时间复杂度期末再出现它就是为了综合应用加算法优化。所以锚点不能只绑在题号上应该绑在“题目-教学批次”这个组合上。我在实际处理中通常会给每个题目组合一个锚点版本号这样即使同一道题隔了两个月再用锚点也不会错位。数据清洗方面除了常规的编译报错过滤和空提交过滤我强烈建议额外做一遍“框架指纹扣减”。做法很朴素找到一道题的标准框架代码计算它的结构哈希然后从每一份学生代码里显式扣除框架部分。否则就像我前面说的模板代码会变成聚类里的“引力中心”让所有簇都严重偏向公共底座。2.2 代码结构特征提取从AST到特征向量扣掉框架之后剩下的就是学生的真实逻辑。这个部分我推荐以抽象语法树AST为主文本特征为辅。AST特征有几个关键维度节点类型直方图统计If节点、For节点、While节点、Switch节点、函数调用节点等的出现次数这能快速反映学生的编程习惯。比如一个学生极度偏爱用if-else而不写switch这个偏好会在直方图里非常明显。树的深度和最大子树宽度递归或深层嵌套的代码通常树更深循环密集的代码通常宽度更大。这两个特征对判别“递归型写法”和“迭代型写法”很有帮助。数据流特征变量定义的位置、变量引用距离。这个特征能捕捉到学生对变量作用域和状态维护的理解程度。比如一个变量定义之后立刻被覆盖和定义之后间隔了30行才被使用教学含义完全不同。我一般用通用的AST解析库先把代码转成语法树然后只提取上述结构统计量不做全树序列嵌入。原因有两个第一统计量具备跨长度可比性几十行的题和上百行的题都能站在同一个维度上第二统计量相对稳定不会因为学生改了变量名、调整了空格就产生剧烈波动这对聚类来说非常关键。除此之外还可以加一组轻量级的文本特征作为补充注释占行比例、标识符命名风格密度是喜欢用a、b、c还是用total、sum、flag、代码分段的空行分布。这些特征在区分“严谨型”和“赶工型”代码时有一定作用但它们不是PACC的主角权重不要给太高。2.3 教学锚点特征怎么生成锚点特征有两种生成路线。一种是全自动从题目描述里抽取关键词映射到课程知识图谱。课程知识图谱不用做得多复杂一门课有几十个核心知识点就够了。比如题目描述里出现“用递归实现斐波那契数列的前N项输出”词典匹配就能命中“递归”“斐波那契”认知层次因为是“实现”动作可以标为“应用”。这个路线适合题库量大、人工打标打不过来的情况。另一种是人工标注老师或助教在布置作业时顺手给每一道题打上三到五个标签包括核心知识点、认知层次记忆、理解、应用、分析、评价、创造、练习阶段课前预习、课中示范、课后巩固、综合实战、预期错误模式。这个路线质量最高但工作量取决于题库规模。我见过的高效做法是期中期末各标注一次平时作业只标知识点认知层次和错误模式用上一个学期的标注结果做迁移。锚点特征落到向量上每一维就是一个教学语义的编码。知识点维度用多热编码一道题涉及三个知识点对应三个位置为1认知层次用单热编码练习阶段用有序数值1到4。注意有序数值只表示阶段的递进关系不代表“创造性比记忆高级”这只是一个位置标记不是价值判断。多热和单热编码会让特征矩阵变得很稀疏但后续在联合距离里我们会用加权办法把锚点凸出来所以稀疏不影响效果。2.4 联合表示与距离度量设计拿到了代码结构特征向量和教学锚点特征向量它们必须联合起来参与聚类。联合方式不是简单的向量拼接而是加权距离融合。我推荐的计算方式是最终距离 α × 结构特征距离 (1 - α) × 锚点特征距离这里的α取值很讲究。α太大又回到了传统聚类的老路结构相似度主导一切α太小聚类退化成提前打标签失去从代码中发现新教学信号的能力。根据我自己的调参经验综合类编程题目α取0.4到0.55比较合适单纯练习某个特定知识点的题目α可以取到0.7左右。调参时先固定要考察的知识点再去跑实验网格α的鲁棒区间通常比较宽不会一改就崩。在计算结构特征距离时用余弦距离因为结构特征向量是稀疏直方图余弦距离对样本长度不敏感。在计算锚点特征距离时用带权重的Jaccard距离因为锚点是离散标签Jaccard天然适合处理这种“有哪些共同知识点”的比较。两者归一化之后再做加权不要让量纲偏差影响α的物理含义。2.5 聚类算法的选择谱聚类为什么更适合特征和距离确定之后聚类的算法选择也很关键。K-Means最省事但它是基于凸簇假设的——它默认簇是球形、大小差不多的团块。代码特征根本不是球形分布一份正确解和一份半成品可能特征距离很近但教学含义差得很远两份完全不同的解法可能结构特征差距极大但锚点把它们拉在同一类。K-Means对这种非球形、各向异性的分布非常吃力。我实际用的方案是谱聚类。谱聚类的基本思路是先把样本两两之间的相似度构造成一张图每个样本是节点、相似度是边权然后对这个图做拉普拉斯特征映射把节点嵌入到低维空间最后在低维空间做K-Means。它的优势在于它只关心图上的连通结构和密度结构不关心样本在原始空间里是不是“球状分布”。实现上谱聚类只需要传入两两相似度矩阵所以前面设计的加权距离可以直接无缝接进去。矩阵规模如果到几千份代码谱聚类的计算压力也不算大标准的特征分解工具都能扛住。如果你手头样本超过两万份可以考虑先用最近邻图稀疏化相似度矩阵再用稀疏特征分解速度会快一个数量级。3. 聚类质量怎么评教学一致性与传统指标如何配合3.1 传统聚类指标为什么不完全够用聚类结果出来之后绕不开的问题就是这一组聚类结果到底好不好传统的评价方式看轮廓系数、Calinski-Harabasz指数、Davies-Bouldin指数。这些指标对PACC有价值但不能作为唯一标准因为它们衡量的都是几何意义上的紧密性和可分性。问题在于PACC的最优解在几何上不一定是最紧密的。举个例子同一个知识点“指针操作”一份代码是VLA写法另一份代码是用下标模拟指针它们在结构特征上差了十万八千里但教学锚点把它们拉进同一个簇。这个簇的轮廓系数一定不会特别高。如果你只盯着轮廓系数调参很快就会被带偏最后不知不觉又调回了纯结构聚类。所以我在评估PACC结果时会同时看两部分传统几何指标作为参考PACC专用指标作为主判据。3.2 教学一致性指标的设计Anchor Purity 和 Teaching CoveragePACC的专用评估指标我习惯用两个。第一个是锚点纯度Anchor Purity。任何一个簇都应该有一个占主导地位的教学主题。簇里面所有样本的锚点集合会有一个出现频率最高的锚点比如“递归实现”这个锚点在簇内样本中的占比就是锚点纯度。锚点纯度越高说明这个簇的教学含义越聚焦老师拿到这个簇越能直接开口讲课。第二个是教学覆盖度Teaching Coverage。课程知识图谱里一共有N个知识点聚类结果里每个簇都对应某个知识点覆盖到的知识点数量除以总知识点数量就是教学覆盖度。如果一个知识点在聚类结果里隐藏了、和别的知识点混在一起很难拆开这个指标会立即报警。PACC不仅要把学生分组还要确保每一组都能映射到课程教学目标上去教学覆盖度就是干这个用的。实际操作中我是先算传统指标再算这两个PACC指标然后放在一起对比。如果一个方案的轮廓系数高、但锚点纯度低我不会选它如果一个方案的锚点纯度高但教学覆盖度略低我反而会去检查是不是数据预处理环节出了问题——比如框架扣减没做干净。3.3 调参实验的一个实例我复盘一次实际调参过程。数据来自某高校C语言课程期中机考300份代码课程知识图谱里有8个核心知识点。我跑了三组方案表格同一数据集上三种方案的指标对比方案锚点权重α簇数K轮廓系数锚点纯度教学覆盖度纯结构特征0.060.3241%67%加权融合0.560.2978%100%纯锚点1.060.1891%83%纯结构特征方案轮廓系数最高0.32但锚点纯度只有41%覆盖度只有67%有将近三分之一的知识点在教学分组里完全被淹没了。加权融合方案轮廓系数略降但锚点纯度跳到78%覆盖度到100%所有知识点都出现在明确的教学分组里。纯锚点方案锚点纯度最高可覆盖度掉到了83%因为它过度追随标签分布把一些隐藏的知识点关系漏掉了。最后上线的方案是加权融合。这个案例能很直观地说明一件事PACC不是去挑战聚类算法的极限而是把教学质量目标显式地前置到评估函数里让算法为教学目标服务。4. 我在实操中踩过的坑和排查经验4.1 锚点特征不该直接拼接要加权融合我最开始实现PACC的时候图省事把结构特征和锚点特征直接拼接成一个长向量然后丢进K-Means。结果非常惨簇结构完全被文本特征和AST特征中的高维噪声主导锚点知识点的作用几乎没体现出来。原因在于直接拼接的向量各维度的量纲和方差完全不一致欧氏距离会天然偏向方差大的维度。后来才明白锚点特征的作用应该是“先分箱再细分”。正确做法是像前面说的分开计算结构距离和锚点距离再加权合并。这一步的改动看着小但实验效果提升极其明显。4.2 重复代码与“抄作业”样本会导致簇结构失真有一次跑聚类跑出来一个大得异常的簇里面什么题目都有。排查了半天发现这300份代码里有相当一部分学生提交的代码是直接从课程讨论区复制的前人答案或是从同学那里要来的“最终版”代码高度雷同。这些雷同代码在特征空间里像一堆质量极大的恒星把周围的样本成片吸附过来。解决办法是在预处理阶段增加一轮代码指纹去重计算每份代码的结构哈希把相似度超过95%的样本只保留一份打上标记其余作为重复样本挂到簇的附属记录里但不参与聚类计算。这样聚类的主体是真实的多样化代码重复样本的归属关系可以在聚类结束后再回填。从教学角度重复代码其实是一种非常重要的信号——它反映了学生对这道题没有独立建模能力。但是这种信号不应该进入聚类特征因为它会污染其他教学信号的提取应该在去重的同时单独记录下来用于考勤和诚信分析。4.3 簇数K不是拍脑袋定的要看课程目标K值选择我最初用经典的手肘法看特征值拐点选出来的K值数学上很好看但教学上没法用——因为某个知识点被切成了三半另外两个知识点又被强行揉成一个簇。问题的根源是手肘法只考虑了数据内在的几何结构没有考虑教学目标的结构。后来我的做法是先把课程知识图谱里设定的知识点数量作为基准K比如核心知识点是6个初始K就取6。跑完第一轮聚类之后检查锚点纯度和教学覆盖度再调整K。如果某个锚点纯度过高比如接近100%可以考虑继续细分拆出更细的教学子类型如果两个簇的锚点高度重叠就考虑合并。这样K值的调整始终围绕“教学解释是否清晰”来展开而不是围绕特征的几何特性。4.4 特征工程阶段的“教学锚定”比聚类算法本身更重要这是我在反复试错中总结出的一句话。很多人一听PACC以为重头戏是谱聚类、是相似度矩阵、是调参。但实际上聚类算法只要能保证基础效果就够了真正决定教学价值的是你在把代码变成向量的过程中有没有把教学上下文真正放进去。我见过有人把锚点做成一维权重乘以结构特征向量结果完全没效果也见过有人把题目难度等级硬编码成大数字导致这一维独大聚出来的结果和按难度分类没有区别。教学锚定是需要在特征空间的尺度和方向上做精细设计的不是简单打个标签就能生效。5. PACC结果能怎么用从分组到学习路径规划5.1 典型应用场景作业分组、试题推荐、学情诊断聚类只是前半程后半程是让聚类结果变成教学动作。最简单的用法是分组。以前分组靠老师目测现在可以按PACC聚类结果分组每一个簇就是一个有清晰教学主题的学习小组。簇A聚起来的是“循环边界条件容易出错”的学生簇B是“指针访问越界”的学生。老师给簇A补循环边界的专题练习给簇B补指针安全相关的案例辅导起来有针对多了。更进一步PACC可以配合试题推荐。当识别出某个聚类簇的锚点是某个薄弱知识点后老师可以直接从题库里筛出同锚点、但难度更低的题给学生做预备训练。这里用“同锚点”而不是“同题目”很重要学生要的是同一知识点的不同情境不是同一道题换个数字。学生自己也能从结果里获益。当一份代码被归入某个教学主题清晰的簇时学生可以看到自己的解法和同簇同学的解法的差异也可以看到相邻簇的解法在结构上的差异这对于自我诊断非常直观。我知道有老师会把聚类的簇说明做成学习路径图学生点进某个簇看到的是“你在递归思想上是这个水平建议下一步做这几道题”。5.2 一次真实的PACC分析故事有一次某高校的C语言课程老师请我帮忙分析一次机考数据。机考里有一道约瑟夫环问题全班250人在线提交得分率却只有58%老师很想知道学生到底卡在哪里。我用PACC的思路跑了完整流程手工标注了这道题的锚点包括“循环链表操作”“环形遍历”“边界条件处理”三个知识点认知层次定为“应用”然后跑谱聚类。聚出来的簇出乎意料地清晰。其中有一个簇锚点纯度极高几乎全是“边界条件处理”出问题的代码另一个簇则是“环形遍历”结构写错的代码。老师拿到这个结果之后做了两件事第一针对边界条件簇专门出了一节课用三个不同数据规模的约瑟夫环变种题让学生感受边界判断的敏感性第二针对环形遍历簇给了标准环形链表遍历模板带着学生逐行拆解循环终止条件。两周之后的随堂小测同样的知识点正确率提升到81%。这里面PACC贡献最大的部分不是聚类本身的“准确率”而是它把模糊的“很多人写不好”拆解成了“具体是哪道坎过不去”这让老师能把教学干预精确地压在病灶上。6. 常见问题速查表现象可能原因快速处理聚出的簇里有大量不同知识点的混编锚点权重太低结构特征主导调高锚点权重优先保证递归式的先分箱某个簇大得异常其他簇很小模板代码没有扣除公共框架形成引力中心做框架指纹扣减和代码去重锚点纯度很高但教学覆盖度低锚点标签本身稀疏知识点分布不均检查知识图谱是否覆盖所有题目的锚点补标注纯锚点方案的轮廓系数很低锚点语义多样几何上无法紧凑不要强求轮廓系数改用锚点纯度和覆盖度评估聚类结果稳定但老师觉得没教学价值特征工程没做教学锚定结果只是形态分组回到第二节检查锚点特征的生成和融合方式不同批次的学生代码聚不到一起教学锚点版本不一致统一锚点版本号或同步教学批次标签最后再分享一个我在多次实验中养成的习惯所有中间结果包括相似度矩阵、每个簇的成员列表、锚点纯度报告都保留存档。教同一门课的老师下一届再跑PACC的时候可以直接拿上一届的簇结构做对比看这届学生的共性问题和上届比是缓解还是加剧。这个“对照基线”的用法比任何单次聚类结果都有价值而且随着数据积累教学诊断会越来越准。PACC这套思路落到最小可落地版本其实不需要一开始就全套铺开。挑一门本学期作业量适中的课程选两三个核心知识点先打标用加权距离跑一次谱聚类再用锚点纯度去校验簇的成色你很快会看到它的效果——至少当你再打开那个满是学生代码的文件夹时你看到的不再只是一堆待批改的文件而是一张写满学生认知状态的地图。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询