ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于DeepSeek的教学视频分析:关键教学点自动提取与结构化标注

基于DeepSeek的教学视频分析:关键教学点自动提取与结构化标注 简介面向教育技术研究者、教学视频平台开发者与AI算法工程师整套方案围绕DeepSeek视频理解技术系统讲解关键教学点自动提取与内容结构化标注的完整实现链路。文档共394页、45个大章节从视频理解底层原理、教学视频数据预处理、音频轨道分离、语音转文字ASR到多模态特征融合、时间轴对齐、关键教学点候选区域筛选、浅层语义匹配与深层语义理解均有细致拆解还覆盖技术术语识别、教师教学动作识别、师生互动场景识别等前沿模块并给出无监督预训练、有监督微调、数据标注规范与质量校验指南。资源为单个PDF文件大小12.9MB支持目录章节跳转及书签大纲快速定位排版完整、图表清晰。目前已有65人浏览学习适合需要落地教学视频智能分析项目的开发与研究人员快速搭建技术框架也可作为课程设计与算法选型的参考手册。1. 为什么教学视频分析值得做DeepSeek 教学视频分析方案解决的不只是“看过”一节45分钟的数学课老师想从录像里找到“函数单调性”第一次引入、完整讲解、例题应用分别在哪几个时间点手动拖进度条至少要二十分钟教研员想横向比较20节同课异构视频里各知识点的讲练时长分布靠人工看几乎不可能。传统视频处理只产出“说了什么”和“画面里有什么”而教学分析真正要回答的是“这节课讲了哪些知识点、在什么时刻讲、用了什么教学方式、讲得完整不完整”。以 DeepSeek 为核心的教学视频分析方案用视频理解技术把这条链路补上先拿到带时间戳的转写文本与关键帧描述再由大模型自动提取关键教学点、做内容结构化标注最后产出可检索、可统计、可对比的 JSON 结构。适合教师课后复盘、教研组听评课、课程平台做切片与推荐落地难点不在单点模型能力而在管道设计与参数调优。2. 关键教学点自动提取视频理解链路选型与最小跑通方案2.1 先拆三层镜头识别、语音语义、教学意图不能混为一谈“视频理解”落到工程上不是一个模型把视频吞进去就吐出答案而是三层能力串起来。第一层是镜头与画面识别处理“画面里发生了什么”场景切换、板书出现、PPT 翻页、教师走到白板前。这一层用传统视频处理就能做ffmpeg 的场景检测加轻量目标检测足够不需要大模型参与成本低、速度快、结果稳定。第二层是语音与文本语义处理“师生说了什么”把讲解、提问、学生回答转写成带时间戳的文本。首选 ASR 模型中文课堂场景下 Whisper 的 small 或 medium 是性价比最稳的选择。专有名词和数字是教学视频转写的重灾区需要通过提示词做约束。第三层才是教学意图推断处理“这段内容在教学上意味着什么”哪个片段对应哪个知识点、是概念讲解还是例题演练、和课程知识树的哪个节点相关。这一层适合交给 DeepSeek 这类大语言模型因为教学意图判断依赖上下文推理不是模式匹配。这三层必须分开设计。常见的翻车是把三层塞进同一个模型的提示词指望它“看懂”视频。视频模型拿到的原始输入是像素、帧率、时间戳对教学语义的感知远不如“转写文本加关键帧描述”的组合来得直接。我的一般做法是前两层归为预处理阶段第三层做成独立的语义分析服务前后用 JSON 衔接。这样任何一层想换模型、换参数都不会牵连其他环节。2.2 最小链路ffmpeg 抽音轨 Whisper 转写 抽帧描述 DeepSeek 聚合最小可跑通链路输入是一节 45 分钟的教学视频输出是一个带时间戳的关键教学点 JSON 数组。整条链路分四步。第一步先从视频里抽出音轨统一成 16kHz 单声道 WAV。采样率和声道不统一后续转写时间戳会出现整体漂移这是后面避坑章节要展开的坑。# 1. 提取音轨统一为 16kHz 单声道 WAV避免时间基准错乱 ffmpeg -i lecture.mp4 -vn -acodec pcm_s16le -ar 16000 -ac 1 audio.wav # 2. 抽场景关键帧画面变化超过阈值时抓一帧 mkdir -p frames/scene ffmpeg -i lecture.mp4 -vf selectgt(scene,0.30),setptsN/(25*TB) -vsync vfr frames/scene/scene_%04d.jpg # 3. 抽兜底帧每 30 秒强制补一帧防止长时间静态画面漏检 mkdir -p frames/periodic ffmpeg -i lecture.mp4 -vf fps1/30 -vsync vfr frames/periodic/periodic_%04d.jpg第一条命令里-ar 16000把音频重采样到 16kHzWhisper 在这个采样率下识别最稳-ac 1强制单声道避免双声道带来的人声能量分散。第二条命令用 scene 过滤器做场景切换检测0.30是阈值低于这个值抓帧太频繁教师转身、翻页的过渡帧全被抓出来高过 0.4 则可能漏掉 PPT 翻页。对 PPT 录制课0.250.35 都可接受从 0.30 起步不会有太大偏差。setptsN/(25*TB)把帧时间戳换算成 25fps 基准下的编号后续按帧号定位时不会乱。第三条命令是兜底fps1/30相当于每 30 秒强制抓一帧覆盖老师站在同一页 PPT 前讲了 5 分钟的场景检测盲区。第二步用 Whisper 做中文转写开启词级时间戳和静音过滤。import whisper model whisper.load_model(small, devicecuda) # 显存不足换 base或者用 devicecpu result model.transcribe( audio.wav, languagezh, word_timestampsTrue, vad_filterTrue, initial_prompt这是一段中文课堂教学录像请保留数字、公式和专有名词。, ) for seg in result[segments]: print(f{seg[start]:.1f} - {seg[end]:.1f} {seg[text]})word_timestampsTrue让每个词都带时间戳后面做知识点时间对齐必须依赖它。vad_filterTrue会滤掉纯静音段但对课堂里“老师停下来写板书”这类留白过滤强度太大会把有效停顿切成好几段。如果发现转写结果零碎就把vad_filter关掉或者调低模型里的no_speech_threshold。initial_prompt这一段看着不起眼实际作用极大能明显减少“单调递增”被转成“单调地增”这类错误。转写完成后不要直接用 whisper 返回的短句片段去提取知识点它会把一句话切在中间合并成 150300 字的语义块再送进下一步更稳妥。第三步把关键帧变成文本描述。这步可以调用独立视觉模型也可以走带视觉能力的模型 API输出统一整理成“时间 画面描述”的结构。教学场景里描述的重点是板书或 PPT 上的标题文字、图表类型、教师动作指向屏幕、书写、走动不需要描述服装、光线和背景。描述语句控制在 10 到 20 个词太长会挤占后续提示词的上下文空间。第四步把转写片段和帧描述拼进提示词交给 DeepSeek 提取关键教学点。from openai import OpenAI client OpenAI(api_key你的key, base_urlhttps://api.deepseek.com) SYSTEM_PROMPT 你是教学视频分析器。你收到一段课堂转写文本和关键帧描述都带时间戳。 从中识别关键教学点输出 JSON 数组每个元素包含 - point: 知识点名称2到8个字 - start: 该点开始时间秒 - end: 该点结束时间秒 - teaching_type: 讲解、提问、练习、总结、演示之一 - confidence: 0到1的置信度 只输出合法 JSON不要解释。 USER_PROMPT f转写文本 {transcript_text} 关键帧描述 {frame_descriptions} resp client.chat.completions.create( modeldeepseek-chat, messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: USER_PROMPT}, ], temperature0.2, # 提取任务压低温度输出才稳定 max_tokens1200, response_format{type: json_object}, ) content resp.choices[0].message.content这里三个参数值得说清楚。temperature0.2是提取类任务的保守值拉到 0.7 以上会出现重复教学点或无关泛化描述。max_tokens1200对 45 分钟课堂的单次分片够用但注意上下文过长时输出会被截断这直接引出后面要讲的分片策略。response_format{type: json_object}让 DeepSeek 尽量返回合法 JSON但它只能约束语法不能约束字段完整性解析前必须做校验不能拿到字符串就反序列化。2.3 教学点筛选置信度阈值与 Top-K 策略一次调用返回的往往是 20 到 40 个候选片段其中相当一部分是重复的或置信度低的。直接全收后续结构化标注会很难看过滤太狠又会丢掉老师随口补充但很重要的知识点。我的做法是两道筛选。第一道是置信度和类型过滤confidence 低于 0.65 的丢弃teaching_type 不在五类里的丢弃。当发现某节课导入环节被大量识别成“讲解”时单独把“讲解”阈值提到 0.75对“提问”和“练习”保持 0.6。按类型分开设阈值比全局一刀切更贴近真实分布。第二道是合并时间重叠的片段。同一个知识点经常被切在相邻两段VAD 按静音切句时把一句话断成两半大模型就可能输出两个点。合并规则是两个片段开始时间差小于窗口知识点名相同或语义等价就合并取较早的开始时间与较晚的结束时间。def merge_overlaps(points, window15, min_conf0.65): points sorted(points, keylambda p: p[start]) merged [] for p in points: if p[confidence] min_conf: continue if merged and p[start] merged[-1][end] window: last merged[-1] if _same_point(last[point], p[point]): last[end] max(last[end], p[end]) last[confidence] max(last[confidence], p[confidence]) continue merged.append(p) return mergedsorted按开始时间排序后合并变成一次线性扫描。window15表示两个点间隔在 15 秒内才考虑合并超过 15 秒说明中间隔了其他教学内容强行合并会把两件事揉成一团。_same_point内部做两层判断先做字符串归一化匹配比如“函数单调性”和“单调性”算同一点再做一次轻量语义匹配兜住同名不同表述的情况。这一步做完拿到的就是相对干净的“时间区间 教学点 教学类型”结构。3. 内容结构化标注把“时间轴文本”升级成可检索的教学知识树3.1 教学标注的四层模型片段、知识点、教学活动、课标映射关键教学点提取出来之后只是一串点还不是结构。要让教研系统可检索、可统计标注必须分四层组织。第一层是媒体片段对应原始视频里一段确定的时间区间比如 09:15 到 11:40这一层只存时间戳和片段编号是其他所有层的锚点。第二层是知识点描述这段在讲什么比如“函数单调性定义”“单调区间判断方法”。第三层是教学活动类型标记讲解、提问、练习、总结、演示这层决定了知识点的教学属性。第四层是课标映射把知识点挂到课程知识树上比如“数学必修一·函数·单调性”或者对应某条教学目标编号。层级内容示例核心字段媒体片段09:15–11:40片段3start_time, end_time, segment_id知识点函数单调性定义point_id, point_name教学活动讲解teaching_type, duration课标映射数学·必修一·函数·单调性knowledge_path, curriculum_code四层结构的意义在统计时才能体现。按知识点统计能看到“函数单调性”在一节课里出现 3 次累计时长 12 分钟按教学活动统计能看到讲解占 60%、提问只占 8%讲练比明显失衡按课标映射统计能横向比较两节课覆盖知识点集合的差异这是同课异构教研最需要的输入。没有这层结构所谓“数据分析”就只能停留在数时长上。3.2 用提示词与 JSON Schema 约束 DeepSeek 输出稳定结构想让模型从“返回知识点列表”进化到“返回完整标注结构”靠的是提示词与 JSON Schema 双重约束。提示词里给层次定义和字段说明示例 JSON 负责固定结构。SCHEMA_EXAMPLE { schema_version: 1.0, course: {subject: 数学, grade: 高一, chapter: 函数}, segments: [ { segment_id: 3, start_time: 555, end_time: 700, teaching_type: 讲解, points: [ { point: 函数单调性定义, confidence: 0.92, keywords: [单调递增, 单调递减, 区间] }, { point: 单调区间判断方法, confidence: 0.80, teaching_type: 例题, keywords: [导数符号, 临界点] } ] } ] }这段示例 JSON 不只是“输出格式参考”它要作为 few-shot 示例直接写进系统提示词。实践里我发现的规律是大模型对具体形态的模仿能力远强于对抽象规则的服从。提示词里的字段描述可以短示例必须字段齐全、层级完整。如果你只写“输出 JSON”模型会按它自己习惯的结构返回字段名词不统一下游解析代码就得写一堆兼容分支。模型输出不能直接相信。拿到 JSON 字符串后先做 schema 校验字段缺失或类型不对就重试重试提示词里明确说哪里不对。用 Pydantic 可以把这一步做得干净from pydantic import BaseModel, Field class Point(BaseModel): point: str Field(..., min_length2, max_length8) confidence: float Field(..., ge0, le1) keywords: list[str] [] class Segment(BaseModel): segment_id: int start_time: int end_time: int teaching_type: str Field(..., pattern^(讲解|提问|练习|总结|演示)$) points: list[Point] class CourseAnnotation(BaseModel): schema_version: str course: dict segments: list[Segment]pattern约束教学活动类型必须是五类之一超出直接校验失败。Field(ge0, le1)锁住置信度范围。校验失败时把错误信息拼进重试提示词例如“你的返回里 segment 3 缺少 end_time请补全后重试”这比盲目重试两次更高效。连续失败两次的分片标记为待人工审核不要静默丢弃。3.3 时间对齐、片段去重与跨模态合并从脏标注到干净结构转写文本、关键帧描述、OCR 文本三者来源不同时间错位和内容重复是常态。转写里刚说到“同学们看这个函数图像”关键帧可能已经切到下一页 PPTOCR 识别出一个公式转写里完全没有对应内容。跨模态合并要定主从关系时间对齐以语音为准内容去重以语音加画面综合判断。以 OCR 证据为例每个语音片段在前后 5 秒窗口内查找 OCR 文本命中就作为该片段的画面证据并小幅上调置信度。def align_with_ocr(segments, ocr_items, max_gap5): # 每个语音片段在前后 max_gap 秒内找 OCR 文本作为画面证据 for seg in segments: for ocr in ocr_items: if seg[start_time] - max_gap ocr[time] seg[end_time] max_gap: seg.setdefault(ocr_evidence, []).append(ocr[text]) # 画面和语音同时命中置信度上调上限 0.98 seg[confidence] min(seg.get(confidence, 0) 0.1, 0.98) return segments如果 OCR 里出现“板书标题函数单调性”语音转写里却没有“单调性”说明 ASR 漏词了。这时片段的知识点名称要以画面文本为准同时把“ASR 可能漏词”记录到日志里供后续复查转写质量。这类修复逻辑不能只靠一条规则覆盖我会在批量处理完后跑一遍“知识点—证据来源”对照表排查哪些片段只有画面证据没有语音证据重点人工复核。去重按知识点名做而不是按时间做。两个片段间隔 10 秒一个在导入环节点到一句另一个在正式讲解时展开名字相同但教学作用不同这两个不应该合并。只有时间相邻或高度重叠、教学类型也一致的片段才合并。这类边界情况不适合用代码写死比较稳妥的做法是跑“重复知识点检测”把可疑片段对输出成清单人工抽检一轮再决定是否调整合并参数。4. 落地参数怎么调抽帧、阈值、上下文窗口与 DeepSeek 调用参数4.1 抽帧策略场景阈值与兜底帧率怎么配抽帧参数直接影响后续视觉描述的质量也决定整个管道要处理多少张图。给一份能直接套用的参考配置再解释调整逻辑。场景scene 阈值兜底帧率说明PPT 录课0.301/30PPT 翻页切换明显场景检测稳定手写板书加投影0.201/10板书变化慢但持续阈值降低保召回教师出镜加白板0.251/15教师动作频繁触发场景变化阈值不宜太低纯音频配课件0.351/30画面变化少主要靠兜底帧覆盖scene阈值影响关键帧召回率。阈值太高PPT 翻页可能漏检知识点的画面证据缺失阈值太低教师转身、翻页中间帧全被抓出来帧量暴增。对 45 分钟课场景帧数落在 200400 之间合理超过 500 帧说明阈值偏低。兜底帧率解决的是“长时间同一画面上发生语音讲解”的情况比如老师站在一页公式前讲了五分钟场景检测不触发没有兜底帧就会丢画面证据。帧数量只是第一步帧的可用性更重要。教学视频里很常见的反例是摄像头固定拍讲台全景PPT 在屏幕上只占一块小区域抽出的帧放大后文字依然模糊。这种情况下要加预处理器把 PPT 区域裁剪出来或者直接叠加 OCR 通道而不是指望视觉模型去读画面角落里的文字。这里引出一个贯穿全文的教训预处理的质量决定分析质量的上限模型能力只决定下限。4.2 教学点阈值与 Top-K精确率与召回率的取舍关键教学点提取不是越多越好也不是越少越好取决于下游用途。做内部教研分析可接受 0.65 置信度因为漏掉一个教学点比多一个噪声更严重做对外发布的课程切片目录置信度要提到 0.8 以上宁可少列不重要的点也不能让用户看到错误切片。同一节课里不同类型的教学点置信度分布差异很大。概念讲解类模型判断通常很稳置信度普遍偏高提问互动类最容易被误判转写里“是不是这样”也会被识别成提问练习和演示类不稳定因为画面证据和语音证据不一定同时出现。按类型拆分阈值比全局一个阈值更合理这是调参阶段最值得花时间做的动作。Top-K 约束也有规律45 分钟标准课关键教学点控制在 815 个超过 15 个说明提取粒度太细一节“函数单调性”课被拆出十几个点老师没法看10 分钟微课38 个90 分钟大学课程1525 个。与其把 K 写死不如按“每 5 分钟最多 2 个点”的密度约束超出的部分按置信度裁剪。这样既保证覆盖又避免知识点被反复拆成多个碎片。4.3 DeepSeek 调用参数温度、max_tokens、超时重试与本地部署取舍提取任务把 temperature 压到 0.2 已经是共识但还有两个参数容易被忽略。第一个是 max_tokens出现“返回被截断、JSON 解析失败”的案例八成是 max_tokens 设小了。45 分钟课堂分片后每片 1500 字左右输出最长会到 1000 个 tokenmax_tokens 给 12001500 比较稳。第二个是 timeout课堂分析是批处理任务单次调用偶发变慢很正常客户端超时不能太短30 秒起步重试走指数退避。import time from openai import OpenAI client OpenAI( api_key你的key, base_urlhttps://api.deepseek.com, timeout30, # 课堂文本较长单次超时给 30 秒 ) def call_deepseek(messages, max_retries3): for attempt in range(max_retries): try: resp client.chat.completions.create( modeldeepseek-chat, messagesmessages, temperature0.2, max_tokens1200, response_format{type: json_object}, ) return resp.choices[0].message.content except Exception as e: if attempt max_retries - 1: raise wait 2 ** attempt # 1s, 2s, 4s 退避 time.sleep(wait) return None指数退避的2 ** attempt三次五 次就够不要无限重试。连续失败超过三次说明是配置或服务异常不是偶发抖动这时应该中断任务并告警让值班的人去看日志。重试本身解决的是网络和限流问题解决不了提示词和参数错误。本地部署是另一类高频诉求触发条件一般是课堂视频涉及学生隐私不能走外部 API离线环境批处理量大且 API 成本压不住。本地部署最常见的做法是用 vLLM 把 DeepSeek 开源权重启动成 OpenAI 兼容服务客户端base_url指向本地地址即可。但要注意本地服务的最大序列长度受显存约束不能照抄 API 默认值并发批处理时 GPU 显存会被放大占用一次给太多请求直接 OOM。像 Jetson Orin 这类边缘设备跑本地部署适合部署轻量转写和分类模型完整的知识点提取链路不建议整条压上去效果和显存都撑不住。5. 避坑指南教学视频分析落地最常见的 5 个翻车现场5.1 现象PPT 上的公式和板书在分析结果里“消失”了跑完一批教学视频知识点列表看起来没大问题打开详情却发现凡是涉及公式、化学方程式、板书推导的部分要么没有对应画面描述要么描述是“教师正在书写板书内容不清晰”。原因是视觉模型对公式和手写体识别能力弱而抽帧本身只负责抓画面并不负责做 OCR公式信息在链路里天然丢失。这种丢失最直接的后果是理科课提取出的知识点集中在语言表达明确的部分公式推导环节大面积缺失而且你不会立刻发现要等人工抽检时才暴露。解决在关键帧描述之外加一条 OCR 通道数学课用 LaTeX-OCR 一类的公式识别模型处理公式帧语文英语课用通用 OCR 识别板书。OCR 结果拼进送入 DeepSeek 的提示词但不要把原始输出直接塞先做校正无法识别的公式标注成“[公式:无法识别]”避免模型自己编造内容。这条通道对理科课是刚需不做的话整个分析结果都会有系统性偏差。5.2 现象时间戳整体漂移知识点区间与画面对不上标注完成后拖进度条抽查发现“函数单调性定义”标在 09:15实际视频里是 11:40整批标注集体平移两分多钟。原因是音频重采样或转写时的时间基准与视频时间轴不一致。录制设备采样率不是标准 44.1kHz 或 48kHz 时ffmpeg 重采样到 16kHz 可能引入时间偏移另一个常见来源是视频开头有黑场或静音ASR 把静音段也算进了起点。这类问题不会报错只会让所有结果看起来“差一点”但差这一点就导致下游所有按时间轴操作的环节全部失效。解决转写前用 ffprobe 对比音频真实时长和视频时长偏差超过 0.5 秒先做重采样校准转写完成后取视频里第一句完整语音的时间点和转写文本第一句对齐算出全局偏移量统一加到所有时间戳上。这个校准步骤必须写进管道不能靠人工发现。早期我遇到这类问题总怀疑是模型问题排查到最后十次里有八次是音频轨道本身不干净。5.3 现象DeepSeek 返回 JSON 合法但字段缺失解析后结果残缺设置response_format{type: json_object}后返回的 JSON 语法合法但偶尔会缺字段。比如某个 teaching_type 没返回或者 segments 数组里混入没有 points 字段的片段。语法解析不报错只有后续统计时才会发现知识点数量无故减少然后要回头排查是哪一段丢的很难定位。原因是response_format只保证 JSON 语法不保证 schema 完整性大模型在上下文较长或分片切得不干净时偶尔会缺字段。解决解析后跑一遍 Pydantic 校验校验失败时把“缺什么字段”反馈到重试提示词里重试一次两次失败就把该分片标注成待人工审核不要静默丢弃。宁可让人工看一眼也不要让错误标记进下游统计否则后面所有统计结论都建立在残缺数据上。5.4 现象长视频单次输入超限结果被截断45 分钟课程的转写文本大约 60009000 字加上关键帧描述轻松超过一次调用的上下文窗口。一股脑全丢进去轻则返回内容超出 max_tokens 被截断、JSON 解析失败重则模型只分析了后半部分前半段知识点全丢。原因很直接没有按语义边界分片。解决以场景切换点为主边界没有场景切换时按固定两分钟窗口切每个分片控制在 15002000 字分片之间保留 2030 秒重叠让切在句子中间时上下文依然连续。overlap 区域的知识点会在相邻两个分片里各出现一次最后靠 merge 阶段去重。分片时始终以完整句子结束为切分点不能硬切。转写文本里如果某句话跨了两个窗口宁可把切分点往后挪一两秒也不要从句子中间断开去考验模型的理解能力。5.5 现象本地部署显存不够换小模型后效果断崖式下降本地部署 DeepSeek 跑教学分析GPU 显存不足换成小参数模型结果知识点名称变短、teaching_type 分类乱套之前能稳定提取的结构全没了。原因是小模型指令跟随能力和上下文建模能力不足面对复杂提示词无法稳定输出。换模型不是简单换后端它会改变整个提取行为尤其是标题这类任务对格式要求高小模型最容易在格式约束上翻车。解决先明确哪些环节必须用大模型。转写和 OCR 本身不需要大模型用专用小模型就能完成关键教学点提取和结构化标注必须保留能力完整的模型。本地资源只够跑小模型时把提示词拆短用任务拆解代替长提示词让每个子任务只做一件事。更实用的是 API 加本地混合本地做转写和 OCRAPI 做聚合标注既控制成本又保住质量。新手阶段先跑通混合方案再逐步把部分环节替换成本地模型不要一步到位全本地化。6. 用 20 节课做验证从关键教学点提取走向教学行为诊断6.1 一致性验证标注结果与教师预设知识点的重合率管道搭完不要急着全量跑数据先用小批量样本验证提取质量。我自己的习惯是先挑 20 节覆盖不同学科和课型的课八节语文、六节数学、六节英语每节课请任课老师提前写下“我在这节课打算讲哪些知识点”作为人工基准。评估用三个指标精确率、召回率、F1。所谓命中是系统输出的知识点名与人工基准节点语义等价而语义等价不能靠肉眼判断要把知识点先归一化到课标知识树的节点编号上再用编号比较。def evaluate(predicted_set, ground_truth_set): hits predicted_set ground_truth_set precision len(hits) / max(len(predicted_set), 1) recall len(hits) / max(len(ground_truth_set), 1) f1 2 * precision * recall / max(precision recall, 1e-9) return {precision: precision, recall: recall, f1: f1}20 节课跑下来分布比预想的有规律文科课 F1 明显高于理科课原因就是公式和板书的 OCR 问题实验课 F1 最低因为大量时间是学生分组操作语音和画面都缺乏明确教学点信号。当某一类课的 F1 持续低于 0.7先查那一类课的预处理链路不要急着调模型参数。预处理修正带来的提升通常比调提示词更明显。6.2 进阶从关键教学点清单走向教学行为诊断标注数据累积到几百节课之后价值就不只是“找得到知识点了”而是可以切入教学行为诊断。把每节课的知识点按时间展开能看到完整的教学结构导入占多久、新授占多久、练习占多久哪些知识点重复讲、哪些只提了一次就跳过。教研组拿这个数据对比两节同课异构的课A 课练习环节 20 分钟B 课只有 8 分钟再结合学生作业数据就能讨论哪种节奏更合理。产出行为诊断表的方法是把标注结果聚合导出import collections stats collections.defaultdict(float) for seg in annotation[segments]: for p in seg[points]: stats[(p[point], seg[teaching_type])] (seg[end_time] - seg[start_time]) / 60.0 # 输出格式: 知识点 × 教学类型 × 分钟数聚合结果喂给图表工具一节课的教学时间分布图就出来了。我做这类分析有个固定习惯不看单节看连续多节至少五节同类型课才有统计意义单节课的噪声太大拿单节分布做论断全是玄学。另一个习惯是保留置信度在 0.60.7 之间的边界样本定期翻出来归类看是 ASR 漏转还是画面证据缺失再针对性地补链路而不是每次调提示词想一劳永逸。这套方案的边界也在这里说清楚它能稳定回答“什么时间讲了什么、怎么讲的、讲了多久”但回答不了“讲得好不好”那是叠加学习分析和课堂观察量表之后的事。希望帮到你。本文还有配套的精品资源点击获取
返回列表