实战天池精准医疗大赛——复赛总结

#算法实战

1. 说明

  精准医疗复赛结束,最终排名在 20 左右。第一名的大神相当厉害,尤其是换数据之后,那分数简直是甩出其他人好几条街,非常想学习一下他的解决方案,可惜答辩定在七月,而且不一定公开,估计到时候都忘了。

  我在复赛中用的是个中规中矩的方案,也在这里记录和分享一下,写得比较随性,各位就别当纯技术文档看了。

2. 特征工程

(1) 特征去噪

  噪声数据是在最后一天才发现的,原因是训练集加入A榜答案之后,线下分数反而下降了,于是怀疑 A 榜数据是不是有什么问题?在检查过程中,阴错阳差地发现,有一些特殊值高出正常值几十倍,比如说有个 BUN(血尿素氮)为 2055,另外 ApoA1 和 ApoB1 存在数据单位不一致的问题,然后对它们进行了修正。

  在本问题中,噪音数据比较容易发现,一方面是特征不多,可以人工过滤,别一方面体验指标有可参考范围,容易界定是否为异常值。如果数据多或者经过了脱敏处理,就需要一些更精确的算法,比如离群点检测等等。

(2) 特征分类

  在本问题中,把特征分成两类:基因数据和其它数据。基因数据是以 SNP 开头的,取值为 1,2,3,估计是位点信息,其值没有大小关系,因此作为枚举类型处理,做了 onehot 变换。其它特征均作为数值型处理。(注:SNP 主要是指在基因组水平上由单个核苷酸的变异所引起的 DNA 序列多态性。)

(3) 标准化

  对数值型数据处了标准化处理,即:新数据=(原数据 - 均值)/标准差。然后将数值型的缺失值全部填充为0,即均值。

(4) 缺失值处理

  对 SNP 数据的缺失值处理试验了三种方法:

  第一种是做 onehot 后不处理缺失值,即 1 变成 [1,0,0], 2 变成 [0,1,0], 3 变成 [0,0,1],缺失变成 [0,0,0]。

  第二种是取出现次数最多的值作为缺失值,比如大多数都是 2,则缺失值设为 2。

  第三种是填加一种新值代表缺失值,这种方法线下效果最好,最终采了此方法。

(5) 特征调整

  去掉了孕前体重和身高,因为特征中还包括了孕前 BMI,从经验看 BMI 可以取代体重和身高带有的信息,从数据看,删掉后的确有所提升。也尝试删掉其它一些特征和特征组合,效果都不明显。

  有一些干扰特征,比无用特征更麻烦,从特征重要性排序看,还挺靠前,其实是来捣乱的。就比如说,有人被杀了,刚好 XX 早上和他打了一架,于是大家把 XX 当成重要嫌疑人,结果真凶跑了。

3. 算法模型

  模型使用的是 xgboost 的分类,5 折交叉验证。这类问题大多数都使用梯度提升决策树算法(GBDT 类),只是具体工具有所差别。

  这里主要的技术点是调参,我是用 sklearn 的 GridSearchCV 实现调参。其中一个核心的参数是 scale_pos_weight,它指定了正反例的权重,直觉是:“患病者”的数据应该更重要。这个值我也是通过调参找到了训练集对应的最佳值。设置后 A 榜成绩提高了,B榜试的少没法下结论。

  使用 scale_pos_weight 引发的问题是,预测的结果分布和训练集不一致。如果想要分布一致,简单地可以把判断标准从 0.5 向上或向下调,规范的一点的方法是做排序之后取前 N 个。

  大家好像都看到了结果的分布问题,于是最后一天,在群里讨论预测结果里有多少个 1?这又涉及了复赛的评分指标 F1。

4. 评分指标

  复赛的评分指标是 F1 分数(F1 Score),是统计学中用来衡量二分类模型精确度的一种指标。它同时兼顾了分类模型的准确率和召回率。F1 分数可以看作是模型准确率和召回率的一种加权平均,它的最大值是 1,最小值是 0.

f1=(2PR)/(P+R)

其中 P 的精确率(预测正确的正样本/预测的正样本),R 是召回率(预测正确的正样本/实际正样本).

  简单的说,如果瞎蒙一半对一半错,F1 在 0.5 左右,如果蒙全 1,F1 为 0.667。看起来,如果拿不准就蒙成 1,胜算更大。

5. 其它尝试

  还尝试了一些其它方法,但都因效果不佳,没用到最终代码里,也在此分享一下思路。

  1. 模型融合:将同一模型,不同参数的概率结果取均值作为预测。

  2. 取更多的 1:针对评价标准,调高 scale_pos_weight,使预测中含更多的 1。

  3. 组合和去掉一些特征:用循环组合的方式加入和去掉一些特征。

  4. 取各模型的 TopX 值:取各个模型分别认为最可能患病的实例。

6. 结果分析

  分析了一下模型预测的结果,基本分为三部分:

  第一种:各个算法的结论一致,并且是对的。

  第二种:各个算法的结论一致,并且是错的。

  第三种:各个算法的结论不一致,有对有错。

  前两种往往混在一起的,算法都得到了一致的结论,能查出来就查出来了,查不出来也没办法了,毕竟数据也并非携带了所有信息。而第三种是疑似状态,也正是检验算法的关键。

7. 遗憾和教训

  遗憾的是还有一些算法,不同算法的组合,特征组合,尤其是不同基因的组合,还都没有尝试,就结束了。教训也很多:

  1. 不要试图参加 deadline 时间相近的多个比赛,时间不够,就没法做大的修改。

  2. 数据量小的比赛里暂时领先并不说明能模型好,很可能是过拟合了。

  3. 多看,仔细看别人的方案,少做“重复造轮子”的事情。

  4. 不要总是使用熟悉的工具,在这种比赛里尝试更重要。

  除了加强技术以外,安排,心态也都很重要。总之,成绩不好,就是还有提升空间,继续努力中。