【OpenHarmony/HarmonyOs 】数学知识点掌握度评估:基于正确率的端侧学习分析实践

📅 2026/7/5 1:05:38
【OpenHarmony/HarmonyOs 】数学知识点掌握度评估:基于正确率的端侧学习分析实践
【OpenHarmony/HarmonyOs 】数学知识点掌握度评估基于正确率的端侧学习分析实践项目类型OpenHarmony / HarmonyOS ArkTS 数学学习应用项目名称数学视界对应主题端侧 AI、元服务能力集成、隐私保护方案关键词端侧分析、知识点掌握度、正确率、题库筛选、学习画像、ArkTS 一、这篇和“挑战模块拆解”有什么区别另一个项目已经写过“知识挑战模块拆解”所以这篇不再泛泛讲挑战页流程而是聚焦数学项目里更有区分度的部分如何基于答题结果在端侧评估学生对数学知识点的掌握度。在数学视界中题库不是随便放一组题而是围绕年级知识点分类难度题型答题结果正确率最近挑战记录。这些数据组合起来就可以形成一个轻量的端侧学习分析系统。二、年级体系从小学到高中项目中定义了 12 个年级export const GRADES: Grade[] [ { id:g1,name:一年级, shortName:小一,level:1}, { id:g2,name:二年级, shortName:小二,level:2}, { id:g3,name:三年级, shortName:小三,level:3}, { id:g7,name:七年级, shortName:初一,level:7}, { id:g10,name:高一, shortName:高一,level:10}, { id:g12,name:高三, shortName:高三,level:12}, ]真实代码里每个年级还有color主题色bgColor背景色icon展示图标description学习内容描述sortOrder排序字段。这让挑战页可以根据年级展示不同的学习入口而不是简单写死按钮。三、知识点体系数学学习分析的核心项目中的知识点覆盖几何、代数、函数、概率、三角、数论、应用题等分类export interface KnowledgePoint {id:stringname:stringshortName:stringcategory:stringicon:stringcolor:stringbgColor:stringdescription:stringgrades:string[] difficulty:numberquestionCount:numbersortOrder:number}一个知识点示例{ id: kp_quadratic_func, name: 二次函数, shortName: 二次, category: 函数,icon:,description:二次函数的图像、开口、顶点,grades: [g9,g10,g11],difficulty:4,questionCount:0,sortOrder:17}这种结构非常适合端侧分析因为每一道题都可以绑定一个或多个知识点答题结果也能反向统计到知识点上。四、题库筛选按年级和知识点取题项目中的题库筛选函数很清晰exportfunctiongetQuestionsByGradeAndKnowledge( gradeId:string, knowledgeIds:string[] ): Question[] {if(knowledgeIds.length 0) {returngetQuestionsByGrade(gradeId) }returnQUESTION_BANK.filter((q: Question):boolean q.gradeId gradeId knowledgeIds.some((kid:string):boolean q.knowledgeIds.indexOf(kid) 0) ) }这个函数支持两种模式没选知识点返回该年级全部题选了知识点只返回对应知识点相关题目。挑战页使用它来构建题池let pool: Question[] getQuestionsByGradeAndKnowledge(this.selectedGradeId,this.selectedKnowledgeIds )这就是后续“智能组卷”的基础。五、难度过滤让练习更精细挑战配置中还支持难度过滤if(this.selectedDifficulty 0) { pool pool.filter((q: Question): boolean q.difficulty this.selectedDifficulty ) }然后再随机抽题const questions: Question[] shuffleQuestions(pool,this.selectedCount)shuffleQuestions()使用 Fisher-Yates 洗牌export functionshuffleQuestions(questions:Question[],count: number): Question[] { constshuffled:Question[] [...questions] for (let i: number shuffled.length-1; i 0; i--) {constj:number Math.floor(Math.random() * (i 1)) const temp: Question shuffled[i]shuffled[i]shuffled[j]shuffled[j] temp } returnshuffled.slice(0,Math.min(count,shuffled.length))}这样可以避免每次练习都出现同样顺序提升练习的新鲜感。六、挑战结果端侧分析的数据来源每次答题完成后会生成ChallengeResultconst resultData:ChallengeResult{id:Date.now().toString(),config:this.config??{gradeId:,knowledgeIds:[],questionCount:0},startTime:this.questionStartTime-totalTime*1000,endTime:Date.now(),questions:challengeQuestions,correctCount,totalCount:this.questions.length,totalTime,score,gradeId:this.config?.gradeId??,knowledgeIds:this.config?.knowledgeIds??[],isCompleted:true, }这里面最适合分析的是questions每道题的作答情况correctCount正确数量totalCount总题数score本次得分gradeId年级knowledgeIds本次练习覆盖的知识点。这些数据都在端侧生成不需要上传到服务器。七、统计总成绩整体正确率和最好成绩recordChallengeResult()会累计整体数据recordChallengeResult(result:ChallengeResult):void{conststatsthis.challengeStatsstats.totalChallengesstats.totalQuestionsresult.totalCountstats.totalCorrectresult.correctCountstats.totalTimeSpentresult.totalTimeif(result.totalCount0) {stats.averageScoreMath.round((stats.totalCorrect/stats.totalQuestions) *100)}if(result.scorestats.bestScore) {stats.bestScoreresult.score} }这部分用于回答几个基础问题用户一共挑战了多少次一共做了多少题总正确率是多少最高分是多少总学习时长是多少这已经是学习报告的基础。八、知识点正确率端侧掌握度评估项目里最关键的函数是getKnowledgeCorrectRate()privategetKnowledgeCorrectRate(knowledgeId:string): number{lettotal 0letcorrect 0for(leti 0; i this.challengeStats.recentResults.length; i) {constr this.challengeStats.recentResults[i]for(letj 0; j r.questions.length; j) {if(r.questions[j].question.knowledgeIds.indexOf(knowledgeId) 0) { totalif(r.questions[j].isCorrect) correct } } }returntotal 0? correct / total :0}它的逻辑非常直接遍历最近挑战结果找出包含某个知识点的题统计总题数和正确题数返回正确率。这就是一个本地掌握度模型正确率低于 60%需要复习正确率 60% 到 80%需要巩固正确率高于 80%可以挑战更高难度。九、从正确率到学习建议基于这个函数可以很自然地生成学习建议functionbuildMasteryText(rate: number): string {if(rate 0.6) {return建议先复习概念和例题}if(rate 0.8) {return已经入门适合继续专项练习}return掌握较好可以尝试限时挑战}这类建议虽然不是大模型生成的但非常可解释。学生知道为什么系统推荐他复习因为最近正确率确实偏低。端侧 AI 不一定要复杂。对学习应用来说“准确、透明、可解释”往往比“看起来很智能”更重要。十、掌握年级和掌握知识点项目会把达到一定正确率的知识点加入masteredKnowledgeif(stats.masteredKnowledge.indexOf(kid) 0) { const correctRate this.getKnowledgeCorrectRate(kid)if(correctRate 0.7) { stats.masteredKnowledge.push(kid) } }年级掌握度也类似if(stats.masteredGrades.indexOf(result.gradeId)0) { const correctRate this.getGradeCorrectRate(result.gradeId)if(correctRate 0.7) { stats.masteredGrades.push(result.gradeId) } }这里用0.7作为掌握阈值简单但有效。后续可以继续细化至少答过 10 道题才计算掌握最近 7 天权重更高高难度题权重更高连续两次达标才标记掌握。十一、隐私保护学习画像留在本地知识点掌握度听起来像“学习画像”确实需要谨慎。数学视界当前的好处是这些数据都在本地AppState中完成。不会上传学生错了哪些题哪个知识点薄弱学习时长得分收藏内容。这和“禁止 AI 识图、精细化权限管控”的主题是一致的。不是不做智能而是优先做端侧智能。十二、元服务扩展今日一题与薄弱点复习如果未来把这个能力接到元服务可以做两个轻量入口今日一题根据最近薄弱知识点抽一道题薄弱点复习展示 3 个正确率较低的知识点。数据来源完全可以复用constrate this.getKnowledgeCorrectRate(knowledgeId)这样元服务不需要重新建一套学习系统只需要从已有端侧统计中取数据。十三、总结这篇文章的重点不是挑战页 UI而是数学知识点掌握度分析和另一个项目的“挑战模块拆解”区分开了。核心实现包括 用GRADES建立年级体系 用KnowledgePoint建立知识点体系 用getQuestionsByGradeAndKnowledge()进行题池筛选 用shuffleQuestions()做随机抽题 用ChallengeResult保存答题结果 用getKnowledgeCorrectRate()计算知识点正确率 用masteredKnowledge和masteredGrades标记掌握状态 全部分析在端侧完成不上传学习画像。对数学学习 App 来说这种端侧掌握度评估非常实用。它既能支撑智能推荐又能保护隐私还能自然扩展到今日一题、薄弱点复习、学习报告等元服务场景。