简介:这份资源是2022年江苏省研究生数学建模科研创新实践大赛B题的完整赛题PDF,面向备战研究生数学建模竞赛的高校学生与指导教师,聚焦高校课堂教学质量数据的量化分析问题。赛题围绕专家评语量化、课程分类、教学团队授课质量排序、专家评价客观性与专业性、三年教学质量变化趋势等任务展开,涉及LSTM二分类模型、文本相似度计算、K-means++聚类、熵权法与模糊综合评价、灰色模型等多元统计与机器学习方法,适合作为跨学科建模训练与赛前模拟的实战材料。资源包共1个PDF文件,大小约1.12MB,内容含题目背景、问题重述、数据说明与完整求解摘要,可据此还原建模思路与结果呈现方式。目前已有1501人学习,便于读者对照赛题要求梳理建模框架、理解评价类问题的量化路径与论文写作结构。
1. 从一份评语表说起:这套方案要解决什么
高校课堂教学质量评价里最棘手的一环,不是打分,而是把专家写下的那段自由文本评语,变成能进模型、能排序、能横向比较的数字。2022年江苏省研究生数学建模B题给的就是这样一份数据:专家对教师教学总体评价及改进意见的评语、教师教学综合评价、学生学习综合评价,外加专家职称、授课教师职称、课程编号等字段,要求完成课程类型二分类、评语量化、课程差异性检验、教学团队排序、专家专业性客观性评价、三年质量变化分析五件事。这套方案适合正在做数学建模毕设、课程设计,或者要交一份完整量化评价方案的人——它把从数据预处理到模型验收的整条链路都走通了,下面按需求、设计、实现、避坑、验收的顺序拆开讲。
2. 需求拆解与技术选型:五个问题对应五类模型
2.1 先把五个问题翻译成可建模的任务
原题表面是五问,落到建模层面其实是五类任务。问题一拆成两个子任务:课程类型二分类(理论课/实践课)和专家评语量化。问题二拆成课程差异性检验和七个教学团队排序。问题三是对专家做专业性与客观性双维度评价。问题四是时间序列上的质量变化。问题五是开放性的数据再利用。我一般会先画一张任务-模型对照表,把每个子任务的输入字段、输出形式、评价指标固定下来,避免写到一半发现某个模型没有对应的验证手段。
| 子任务 | 输入 | 输出 | 核心模型 | 验证方式 |
|---|---|---|---|---|
| 课程类型分类 | 评语文本 | 理论/实践标签 | LSTM 二分类 | Precision/Recall/F1 |
| 评语量化 | 评语文本+评分标准表 | 百分制得分 | text2vec 文本相似度 | 排序合理性人工抽检 |
| 课程差异性 | 三维评价向量 | 优秀/一般两类 | Kmeans++ | CP、轮廓系数、DVI |
| 团队排序 | 三指标模糊值 | 等级+排序 | 熵权法+模糊综合评价 | 二级评判标准一致性 |
| 专家评价 | 评语+评分记录 | 专业性/客观性得分 | 相似度+评分偏离度 | 专家间横向对比 |
| 质量变化 | 三年月度数据 | 趋势曲线 | 灰色模型+线性拟合 | 残差与周期性检验 |
这张表的价值在于:它逼你在动手前就想清楚每个模型“拿什么证明自己是对的”。建模题最容易翻车的地方不是模型不会写,而是写完不知道结果可信不可信。
2.2 为什么是 LSTM 而不是别的分类器
课程类型分类的难点在于没有现成标签。原始数据里没有“这门课是理论课还是实践课”这一列,只能靠关键词打弱标签:含“设备、示范、实验、操作、仪器”的标为实践课,含“板书、直播、课件”的标为理论课,最终得到 247 条实践课、1465 条理论课标签,剩余 4180 条待预测。有了标签之后,选型上对比了 LinearR、SVC 和 LSTM 三个基线,验证集上 LSTM 的 F1 是 0.750,SVC 是 0.683,LinearR 只有 0.543。文本分类任务里 LSTM 能捕捉词序和长距离依赖,比词袋类方法稳,这是选它的直接理由,不是因为它“高级”。
2.3 评语量化为什么走文本相似度而不是情感分析
评分标准表本身是结构化的:理论课分教学态度、教学内容、方法手段、教学成效四项,权重 0.2/0.3/0.3/0.2;实践课分教学态度、教学组织、教学成效三项。评语量化的本质是判断“专家这句话命中了标准表里的哪一条、命中得多深”,所以用句子向量余弦相似度去对齐标准条目,比情感分析更贴合题意。情感分析只能给出正负倾向,给不出“对应哪一项评分标准”的结构信息,这是选型的核心判断。
3. 总体设计与关键实现:从弱标签到量化得分
3.1 数据预处理与弱标签构建
预处理分三步:jieba 分词、去停用词、词频统计。打标签的逻辑写在下面这段代码里,核心是用关键词命中做弱监督,同时保留未命中样本作为待预测集。
import jieba import pandas as pd # 停用词表按项目实际维护,这里只示意加载方式 stopwords = set(open('stopwords.txt', encoding='utf-8').read().split()) practice_kw = {'设备', '示范', '实验', '操作', '仪器'} theory_kw = {'板书', '直播', '课件'} def label_comment(text): words = set(jieba.lcut(str(text))) - stopwords if words & practice_kw: return 1 # 1 表示实践课 if words & theory_kw: return 0 # 0 表示理论课 return -1 # -1 表示待预测 df = pd.read_excel('teaching_eval.xlsx') df['label'] = df['教师教学总体评价及改进意见'].apply(label_comment) labeled = df[df['label'] != -1] unlabeled = df[df['label'] == -1] print(labeled['label'].value_counts()) # 预期 247 / 1465这段代码的关键参数是关键词集合,它直接决定标签质量。关键词不是拍脑袋定的,是从评分标准表里理论课和实践课的差异条目反推出来的——标准表里实践课强调操作与设备,理论课强调讲授载体,这个对应关系是弱标签合理性的来源。有标签的 1712 条按 9:1 切分,得到 1540 条训练、172 条验证。
3.2 LSTM 分类模型与评价指标
LSTM 的求解过程按输入门、遗忘门、输出门、候选记忆单元、记忆单元更新五步走,目标函数是带 L2 正则的二分类交叉熵。工程实现上不需要手推公式,用框架搭结构即可,但门控顺序和维度要对齐:
import torch import torch.nn as nn class CourseLSTM(nn.Module): def __init__(self, vocab_size, embed_dim=128, hidden_dim=64): super().__init__() self.embed = nn.Embedding(vocab_size, embed_dim, padding_idx=0) self.lstm = nn.LSTM(embed_dim, hidden_dim, batch_first=True) self.fc = nn.Linear(hidden_dim, 2) # 二分类输出 def forward(self, x): x = self.embed(x) out, (h, _) = self.lstm(x) return self.fc(h[-1]) # 取最后时刻隐状态embed_dim 和 hidden_dim 是主要可调参数,语料规模在几千条量级时 128/64 足够,再大容易过拟合。验证指标用 Precision、Recall、F1 三个,公式分别是 TP/(TP+FP)、TP/(TP+FN) 和两者的调和平均。这里有个容易忽略的点:实践课样本只有 247 条,类别不平衡,单看准确率会虚高,必须看 F1 和召回率。最终 20 个待求解样本里,4451、4458、4462 判为实践课,其余 17 个为理论课。
3.3 评语量化:相似度映射与加权累加
量化模型分五步:句子切分、单句与标准条目算相似度、相似度分段映射、乘权重累加、全评语汇总。相似度用词向量平均后算余弦,映射函数是分段线性的:
def map_sim(s): # 相似度分段映射,压低低相似度噪声,保留高相似度信号 if s >= 0.7: return 1.0 if s >= 0.4: return (s - 0.4) / 0.3 return 0.0 def score_comment(sentences, std_items, weights): total = 0.0 for sent in sentences: best = 0.0 for item, w in zip(std_items, weights): sim = cosine_sim(sent, item) # 句子向量余弦相似度 best = max(best, map_sim(sim) * w) total += best return total映射函数的分段点是这套模型最需要解释的参数:0.7 以上视为明确命中,0.4 到 0.7 线性过渡,0.4 以下视为噪声直接归零。这个设计来自一个朴素观察——评语里大量套话与标准条目的相似度集中在 0.3 到 0.5 之间,不设下限会把套话也算成得分。权重直接取标准表给定的 0.2/0.3/0.3/0.2。最终 4450 到 4469 的量化结果里,4457 得 91.63 排第一,4452 得 50.39 垫底,排序结果与人工抽读评语质量基本吻合。
3.4 课程差异性检验:模糊化加 Kmeans++
聚类前先做模糊化,把连续得分按区间压到 95/85/75/60 四档,规则是 [86.5,100] 记 95、[67.5,86.5) 记 85、[60,67.5) 记 75、[0,60) 记 60。然后每个课程用三维向量表示(教师教学、专家评语、学生学习),按列标准化后进 Kmeans++。选 Kmeans++ 而不是普通 Kmeans,是因为初始质心用最远点策略选,避免随机初始化导致的聚类结果漂移——这类小样本聚类对初值极其敏感,普通 Kmeans 跑三次可能出三个结果,这是血泪经验。
聚类效果用三个指标验收:紧密性 CP=1.686、轮廓系数 0.602、邓恩系数 0.443。轮廓系数 0.6 以上说明类间分离度可以接受。结果上课程 0072 在优秀类占比 70.45%,课程 0345 只有 16.21%,差异明显,原题“各课程教学质量存在差异”的结论成立。
3.5 熵权法加模糊综合评价做团队排序
七个团队的排序走两步。第一步熵权法定权重,三个指标(教师教学、学生学习、专家评语)算出的权重分别是 0.2381、0.2464、0.5154,专家评语权重最高,符合“评语信息量最大”的直觉。第二步用频率法构建模糊关系矩阵,与权重做模糊合成得到综合评价向量,再用最大隶属度法定等级。排序规则是二级评判:等级不同看等级,等级相同看隶属度。
import numpy as np def entropy_weight(matrix): # matrix: 样本 x 指标,先极差标准化 norm = (matrix - matrix.min(0)) / (matrix.max(0) - matrix.min(0) + 1e-9) p = norm / (norm.sum(0) + 1e-9) n = matrix.shape[0] h = -np.sum(p * np.log(p + 1e-9), axis=0) / np.log(n) return (1 - h) / (1 - h).sum() def fuzzy_rank(weight, fuzzy_matrix): # fuzzy_matrix: 课程 x 等级 的隶属度矩阵 score = fuzzy_matrix @ weight # 合成综合评价向量 level = np.argmax(fuzzy_matrix, axis=1) # 最大隶属度定级 return score, level最终排序从高到低是课程 0097、0138、0058、0486、0057、0322、0320。这里要注意,模糊合成算子的选择会影响结果,用加权平均型算子比最大最小型更平滑,适合这种指标间可补偿的场景。
3.6 专家评价与时间序列分析
专家专业性用评语规范性量化,思路复用问题一的相似度,但加了一个长度惩罚项:相似度累加值除以 log(评语长度+1),防止“话多得分高”。客观性用评分偏离度,计算某专家对某课程的评分与其他专家均值的差,取绝对值后对所有课程求平均,再做正向化。综合得分是专业性与客观性的加权,倾向因子取 0.5。结果上专家 002 两项都靠前,专家 006 客观性最差。
时间序列部分,年度数据样本少,用灰色 GM(1,1) 预测趋势;月度数据用线性模型拟合并观察周期性。总体结论是教学质量呈下降趋势,2020 年降幅较大。问题五从师资结构切入,统计发现正高教师占比从 8% 降到 4%、初职教师从 6% 涨到近 14%,骨干占比下降与青年教师大量引进共同解释了质量下滑。
4. 避坑与常见问题:五个最容易翻车的地方
4.1 弱标签关键词选错,整条分类链路失真
现象是 LSTM 验证集 F1 忽高忽低,换个随机种子就掉十几个点。原因是关键词集合里混入了“课堂”“教学”这类高频通用词,导致大量理论课被误标成实践课,标签噪声直接传导到模型。解决办法是把关键词限定在评分标准表里两类课程独有的差异条目上,打标后人工抽检 50 条,确认标签纯度再进模型。
4.2 相似度映射不做下限,套话拉高得分
现象是几乎所有评语量化得分都集中在 70 到 85 之间,区分度极低。原因是评语里的客套话与标准条目天然有 0.3 到 0.5 的相似度,不设阈值就全被算成有效命中。解决办法是映射函数在 0.4 以下直接归零,0.4 到 0.7 线性过渡,这个分段点要用实际数据分布校准,不能照搬。
4.3 聚类不标准化,量纲大的指标主导结果
现象是聚类结果几乎只反映教师教学评分,专家评语和学生学习两个维度被淹没。原因是三个指标量纲不同,教师教学评分方差大,欧氏距离被它主导。解决办法是按列做 z-score 标准化后再聚类,同时用轮廓系数验证标准化前后的聚类质量差异。
4.4 模糊综合评价的隶属度矩阵用错来源
现象是排序结果与直觉相反,某个明显优秀的团队排到后面。原因是隶属度矩阵直接用原始评分归一化,而不是用频率法统计各等级出现次数。正确做法是先按模糊化规则把评分压到四个等级,再统计每个课程在各等级上的频率作为隶属度,这样矩阵每一行才满足和为 1。
4.5 灰色模型样本太少硬套,预测不可信
现象是年度趋势预测曲线剧烈波动,残差检验通不过。原因是灰色模型对样本量和数据平滑度有要求,三年数据点做 GM(1,1) 本身就勉强。解决办法是把年度和月度分开处理,年度只做趋势方向判断不做精确预测,月度用线性拟合加周期项,并在结论里明确标注置信边界。
5. 验收与答辩:怎么证明这套模型站得住
验收这套方案,我一般按“每个模型都有独立证据链”的标准走。分类模型看混淆矩阵和 F1,不能只报准确率;评语量化看排序结果与人工抽读的一致性,抽 20 条里至少 15 条排序方向对得上;聚类看三个内部指标是否同时达标,轮廓系数低于 0.5 就要回头查标准化;模糊综合评价看隶属度矩阵行和是否为 1、排序是否满足二级评判规则;时间序列看残差是否白噪声、趋势方向是否与原始数据目测一致。
答辩时最容易被问的三个点,提前准备好答案。第一,“你的弱标签凭什么可信”——答关键词来源、抽检比例、标签纯度。第二,“相似度阈值 0.4 和 0.7 怎么定的”——答用评语相似度分布直方图找的拐点,不是拍脑袋。第三,“聚类两类怎么证明是优秀和一般而不是别的划分”——答用类簇中心在三个指标上的取值分布做解释,优秀类三个维度都高。下面这张验收清单可以直接照着自查:
| 检查项 | 合格标准 | 不达标时的动作 |
|---|---|---|
| 分类 F1 | ≥0.70 | 复查标签纯度与类别平衡 |
| 量化排序一致性 | 抽检 20 条≥15 条方向正确 | 调整相似度映射分段点 |
| 轮廓系数 | ≥0.50 | 重新标准化或换 K 值 |
| 隶属度矩阵行和 | 每行≈1 | 检查频率法统计口径 |
| 灰色模型残差 | 后验差比<0.35 | 降级为趋势定性判断 |
从那以后我每次做这类多模型串联的题,都强制先跑一遍“单模型可验证性”检查——任何一个模型如果拿不出独立的验证指标,就不许进最终方案,宁可少一个模型也不留一个黑匣子。这套习惯让我在答辩现场被追问细节时从来没慌过。希望帮到你。
本文还有配套的精品资源,点击获取