前言

这是我接触数据挖掘后的第一个与之有关的比赛,很标准的表格题,业务背景也不复杂,自我感觉非常适合像我这样的新人去完整地了解,熟悉数据挖掘比赛的整体流程。我也是在这次比赛中慢慢了解特征工程的重要性,也了解并应用了一些基础的特征构造方法,也第一次听说并使用(还没探索其背后的原理)那些个 boosting 模型:xgboost,catboost,lightgbm。

在比赛中也认识了队友,油菜花和勇哥,团队带来的学习增益和激励增益是庞大的,队友积累的经验和知识也是一笔巨大的财富。

最终成绩:复赛第三,决赛三等奖。

代码地址:https://github.com/LogicJake/tianyicup-education

赛题背景

随着人工智能(AI)的发展,“AI+教育”“智慧课堂”等名词逐渐出现在大众视野,越来越多的学校将人工智能助手融入课堂,当下中国正逐步进入“智慧教育”时代。在传统课堂中,由于时间和精力的限制,老师和家长无法兼顾学生的学习状态和学业进展,不会关注大量对于学生能反应其真实问题和情况的数据。

智慧教育通过将传统教育行业的场景和当下最新的人工智能算法紧密结合,深度挖掘学生在各个知识点上的历史答题表现数据,最终预测学生在考试中的分数表现。

赛题描述

请参赛选手,利用比赛对应训练集提供的学生信息、考试知识点信息、考试总得分信息等建立模型,预测测试集中学生在指定考试中的成绩总分,预测目标如下:

初赛:利用初中最后一年的相关考试和考点信息,预测初中最后一学期倒数第二、第三次考试的成绩。
复赛:利用初中 4 年中的相关考试和考点信息,预测初中最后一学期最后一次考试的的成绩。

数据下载

初赛数据下载(右键保存下载),复赛数据不可下载。

解决方案

简单的数据分析

课程类别 课程名称 知识点数量
course_class1 course1 368
course2 367
course3 262
course_class2 course4 219
course5 335
course6 146
course7 316
course8 223

课程数据包括课程类别,课程名称和所包含的知识点。课程类别只有两类,大概率就是理科和文科的区别。主要难点在于课程的知识点维度非常大,课程考试虽然每次只包含少量的知识点,但是为了向量空间统一,假如采用01向量表示考试的知识点分布情况,该向量将是巨维且十分稀疏的。

成绩分布
成绩分布

该数据集还有个好处就是数据完整,不存在数据缺失或异常值的情况,除了标签数据‘成绩’出现了0分。从上图成绩分布可以看到,大部分成绩都在60分以上,60以下的就很稀疏。我们将0分看做异常值,可以认为是由学生缺考或者作弊被取消成绩导致的,这部分0分数据不能代表学生正常的考试水平且模型也学习不到这种无规律情况,所以将这部分数据进行剔除。由上面成绩分布可以知道,模型的预测也大概率集中在60以上,所以对于0分样本,计算出来的MSE指标非常大。所以这一题线上线下MSE分数差距比较大,可以确定线上测试集也包含了0分样本。当时曾经和队友讨论能否单独建模预测0分的出现,但效果很差,毕竟学生缺考和作弊行为也没法从给出的数据中推演出来(笑)。

特征工程

基础特征

基础的特征工程比较简单,就是做一下统计特征,比如考试次序,考试的知识点数量和知识点跨度。将知识点映射为其所属段落和类别,又可以构造数量和跨度特征。每个知识点有难度属性,每门考试的知识点占比乘以对于难度,得到衡量考试整体难度的特征。在数据分析中提到,知识点维度巨大且稀疏,假如使用原始01向量代表知识点的分布,会大大降低模型的效率。所以我们使用经典的PCA进行降维,在实际操作中,对考试的知识点占比,知识点种类和段落占比分别降维到60维。当然我们也尝试过使用 deepwalk 之类的 embedding 方法进行降维,但效果不行,在决赛答辩阶段,听其他队伍介绍也使用了 deepwalk, 但当评委问起 embedding 效果时,也回答效果不好。此外还简单使用了交叉特征,如知识点数量和考试难度拼接交叉。

相似考试特征

在构造特征的时候,我们认为一个学生面对一门新考试,其成绩应该与和这次考试相似的考试成绩相近。所以我们找出每门考试最相似的三门考试,然后对学生三门考试成绩与考试相似度进行加权求和,得到预估的本次考试成绩,作为一个伪标签。在定义相似时,我们采用了三个指标:知识点分布相似,知识点段落分布相似,知识点类别分布相似。

相似考试特征构造示意图
相似考试特征构造示意图

五折交叉标签统计特征

在接触这个比赛之前,我一直认为特征是特征,标签是标签,标签信息是无法使用或丢给模型学习的。这一点本质没错,因为直接使用标签进行学习,必然造成数据泄露,得到一个毫无意义的模型。但只要稍加变通,就能充分使用标签信息。换句话说,我们在评估一个学生的成绩好坏时,常常会说这个学生的平均成绩如何如何,这个时候不也是用了标签信息吗?甚至我们可以因此推断,学生的考试平均成绩,因为是一个强特征,它对预测学生考试成绩时十分重要。因此引入了特征工程中一个比较重要的构造方式,target encode,其在 ctr 类型的比赛中使用广泛。刚刚我们说过,一方面平均成绩很重要,但另一方面引入标签信息会泄露。泄露的本质就是在为样本构造特征的时候,使用了本样本的标签信息,那么为了避免泄露,我们在 target encode 时,只要避免使用本次样本的标签信息就可以了,常见的做法为五折交叉统计,将历史考试成绩数据分为五折,每次用4折构造特征,给训练集中的另外1折。

五折交叉统计(引用自鱼佬知乎专栏)
五折交叉统计(引用自鱼佬知乎专栏)

以此类推,我们不仅可以构造成绩平均值,还可以借助五折框架构造更多关于成绩的统计特征。
将构造过程分为对象和统计方法两部分:
对象:

  • 学生所有考试成绩
  • 学生所有考试排名
  • 学生考试成绩 / 本次考试平均分
  • 学生在所有考试上表现出来的抗压能力
  • 学生在某门课考试上表现出来的抗压能力
  • 某门课程的所有考试成绩
  • 学生在某门课程上的考试成绩
  • 学生在某门课程上某次考试成绩 / 某次考试平均成绩
  • 某性别学生在某门课程上所有考试成绩

统计方法:

  • 最大值(max)
  • 最小值(min)
  • 平均值(mean)
  • 标准差(std)
  • 中值(median)
  • 变异系数(cv)

时序特征

学生最近几次的考试成绩可以反映一个学生最近的学习状态,所以我们可以用最近几次的考试成绩构造时序特征。差分,窗口是时序常用的方法。

  • 最近三次考试成绩 mean std
  • 最近三次考试排名 mean std
  • 最近三次考试成绩差值的平均
  • 对最近三次考试成绩平均分做窗口为8的平均
  • 对最近三次考试成绩平均分差值做窗口为3的平均
  • 最近三次考试成绩

“嫁接”特征

“嫁接”学习源于这样一个问题:初赛复赛数据分布不一致。在IJCAL2018比赛中,大家发现前六天和最后一天数据分布不同,大部分人于是用同分布的第七天上半天的数据预测下半天,而植物大佬在这个基础用前六天训练了一个模型,预测第七天得到的 probability 作为第七天模型的 feature ,再用第七天上半天的数据预测下半天,使最后的分数遥遥领先,轻松得到 solo 冠军。套用到这个比赛,复赛利用初中 4 年中的相关考试和考点信息,预测初中最后一学期最后一次考试的的成绩。我们可以认为前三年的考试和最后一年的考试是不同分布,而要预测的最后一次考试和最后一年的考试是同分布的,所以我们利用前三年数据构造部分特征,预测最后一年的考试成绩。利用全量数据构造的特征加上预测的最后一年的考试成绩预测最后一次考试成绩。

模型

本方案采用五折交叉验证框架,分别训练 lightgbm 和 xgboost 模型,将两个模型的预测分数根据线上模型得分加权融合。模型分数见下表。

模型 Public分数
xgboost 7.289815178
lightgbm 7.288464145
融合 7.286831301

总结

赛后拜读了第一大佬的开源。第一名方案对特征分别建模训练,总共分为三部分模型:第一部分模型将成绩预测问题视为回归问题进行分析,第二部分模型将成绩预测问题视为一种短期时间序列预测的问题,第三部分模型对成绩、试卷考点分布、学生考点掌握整体进行数学抽象。在第一部分模型当中,处理考试的知识点特征的时候,采用 NMF 算法进行降维处理。最让我感兴趣的是第三部分模型,在我的方案中,其实对知识点处理的不是很好,无法构造出学生对知识点的掌握情况。第一名方案采用这样一种假设:试卷-考点分布矩阵(exam)乘以学生-考点掌握矩阵(stu)就能得到试卷-学生成绩矩阵(score)。exam 矩阵和 score 矩阵都是已知,所以直接采用优化算法解得 stu 矩阵即可。形式化表示如下:

  • score : m * n (exam_number * student_numbers) 试卷-学生成绩矩阵
  • exam : m * s(exam_number * course_section) 试卷-考点分布矩阵
  • stu : s * n (course_section * student_numbers) 学生-考点掌握矩阵

其中,m 为各科考试次数,n 为学生数目 s 为各科考点数,目标函数为 Argmin (Σ(score - exam * stu)^2)
最后通过学生-考点掌握矩阵乘以要预测的考试知识点分布矩阵,从而得到待预测考试的预测成绩。从模型效果来看,该部分方案十分优秀,线上得分7.33,令人佩服。

参考资料