使用试卷特征训练XGBoost预测学生考试通过情况是否正确?
现有方案可行性结论
你当前编写的代码完全无法实现「预测特定学生s3参加t7考试能否通过」的需求,本质还是在做试卷整体难易度预测,和你之前预测试卷难度的任务逻辑完全一致,没有结合学生个体差异。
核心问题拆解
你直接丢弃了studentId字段,相当于给模型的输入只有试卷的3个特征,模型学到的逻辑是「只要试卷的文本长度、难词数量、是否含图片三个特征一致,所有学生参加该考试的通过率完全相同」,这显然不符合真实场景:同等难度的试卷,基础好的学生通过率远高于基础差的学生,你要预测的是特定学生的考试结果,必须纳入学生维度的特征。
你当前的方案和content-based filtering的差异也在这里:content-based filtering的核心是同时刻画「用户特征」和「物品特征」,用两者的组合特征预测交互结果(对应这个场景就是学生参加考试是否通过),而你的方案只用到了物品(试卷)侧特征,完全没有用到用户(学生)侧的任何信息。
正确建模思路
- 先加工学生侧特征,用来刻画学生的学习水平,可参考的特征维度包括:
- 学生历史考试的平均通过率
- 学生过往作答试卷的平均难词数量、平均文本长度
- 学生历史参加考试的总次数
- 保留试卷侧已有的长度、难词数、是否含图片特征,也可以把你之前训练得到的试卷难易度标签作为额外特征加入
- 将学生侧特征和对应考试的试卷侧特征拼接,作为模型的输入特征,训练二分类模型预测考试结果
如果后续你的学生-试卷交互数据量足够,也可以加入协同过滤相关的思路:将studentId、testId做Embedding编码,和属性特征拼接后训练,效果会优于纯属性特征的模型。
代码调整示例
# 加工学生维度特征 student_feat = df.groupby('studentId').agg( student_pass_rate=('result', 'mean'), student_avg_words=('Words', 'mean'), student_exam_cnt=('testId', 'count') ).reset_index() # 学生特征拼回原数据表 df = df.merge(student_feat, on='studentId', how='left') # 仅删除不需要的ID字段 cols_to_drop = ['testId', 'studentId'] df.drop(cols_to_drop, axis=1, inplace=True) # 后续训练逻辑保持不变即可 X = df.drop('result', axis=1) y = df['result'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=5) model = XGBClassifier() model.fit(X_train, y_train)
需要预测s3参加t7的结果时,只需将s3对应的学生特征和t7对应的试卷特征拼接,输入模型即可得到预测结果。
内容的提问来源于stack exchange,提问作者futuredataengineer
相关产品推荐
相关产品推荐

