实战天池精准医疗大赛之三 _ 分类回归与排序

#算法实战

1. 说明

  开赛第一周挣扎在前 100 的边缘,第二周挣扎在前 20 的边缘,第三周懒得弄了,坐等换数据。初赛的前 100 名可进复赛,所以在前 100 中排名前后也没啥意义,开始的时候觉得自己分数蒙的成份很高,换了数据就完蛋,然后不断改进,坐实;后来就有点瞎叫劲了。又傲娇又胆小,也没结交到队友,至今还是孤军作战。记录一下本周收获,也不知这些都公开之后会不会被打出排行榜 [哭脸]。

2. 分类与回归

  所有回归都可以抽象成分类,比如训练集有 100 个数,最差的情况下就是分成 100 个类,或者处理成 99 次二分类。而对于具体数值的回归,可通过其所属类别中的元素计算,比如:中值,均值,期望值,评估函数最佳值等等。

  细数参与过的几个比赛:医疗大赛是切分正常和糖尿病,微博互动是切分正常和巨量互动,淘宝穿搭是切分普通组合和常见的组合,人品预测是切分普通和人品不好的,股票是切分普通和大涨的。基本都是从正常中寻找反常数据,几乎都可以当成不均衡的分类问题处理,而且它们有个共同的特点,就是越特殊的值权重越大,比如说预测对一个高血糖值对评分的贡献多过上百个普通值。

  把分类理解成数据的抽象,可简化问题,也可以在其上运用复杂的计算。同样是使用 GBDT 类的算法,分类就比回归灵活很多,尤其是二分类。

3. 排序(Rank)

  排序可以视为一种算法,或者算法中的一个实用的小工具。比如特征工程中的排序特征,排序更常见的是用在评价函数之中。

  比如本题原本是一个回归问题,我们把它当成分类处理,分类的边界划在哪?是界定正常值的 6.1,还是界定糖尿病的 11.1,还是中值?问题的核心是:把从黑到白的柔和过渡通过划边界描述成了非黑即白的二元对立——人通常也是这么做的,比如,把人分为好人与坏人。

  排序提供了一种辅助的方法:它把所有人排了序,越靠前是好人的可能性越大。如果越靠前越容易是反常数据,那么取前N个就可以轻松地过滤数据和分类,搜索引擎也是类似的排序原理。

  具体到本题,我是先对所有数据做回归,然后用不同边界分类筛出各个档位的特殊数据,用该档的均值预测特殊数据,其中用排序控制特殊数据的多少。原理非常简单,不过还需要调整算法,比如在分类中想要找可能性最大的前 N 个,不考虑其它,和把所有数据都尽量正常分类,做法肯定不同,详见后面“基于排序的评价函数”。

4. 正常与反常

  上面说到,本题我用了分类加回归,分类那么好,为什么还加回归呢?像上面“分类与回归”中说到的 100 个数回归等 99 次二分类,从这个角度看分类和回归本来是一个东西,只是粒度不同。也就是说处理任何问题,都需要在不同粒度下分析。

  举个例子,追涨杀跌和低买高卖明显是不同的操作策略。

在蓝色点卖出,绿色点买入,相对于黑色的趋势线是低买高卖(细粒度),而根据黑色上升趋势线操作又是追涨行为(组粒度)。这里趋势就是常态,请注意:常态不仅是不动的状态,一条横线,也有可能是斜线或者曲线,它可以是用回归拟合出来的模型;而蓝色和绿色点就是反常,反常没有一定之规,主要看常态是什么。比如大家都上辅导班,你不上就反常了。

5. 基于排序的评价函数

  这里主要基于 xgboost 工具,它提供排序的评价函数有:ams,auc,pre,ndcg,map。其中大多数找不到相应的中文说明,建议看源码:xgboost/src/metric/rank_metric.cc

(1) xgboost 相关说明

  1. 评价函数

xgboost 中,一般通过 eval_metric 设置软件自带的评价函数,也可以通过 feval 自定义评价函数。评价函数包括回归相关的,分类相关的,这里主要介绍排序相关的。一般评价函数的输入变量是训练数据和预测值。输出是评价函数名称和评价分值。

  1. 参数

有些评价函数可以带参数,形如:ndcg@2,ndcg@,ndcg@2-。一般是从 1-0 的排序,如果设置了减号,可以支持从 0 向 1 的排序。

  1. weight

权重是通过 scale_pos_weight 或者作为 DMatrix 参数设置的,比如正例和反例的比例为 1:4,将 scale_pos_weight 设为 4,在计算时正例将乘权重 4。weight 在有些评估函数中也发挥作用,比如 ams 和 auc。

2) xgboost 提供的评价函数

  1. PRE

PRE 全称是 Precision,即准确率。根据实际和预测的不同,一般有四种情况:tp,fn,fp,tn,如下图所示:

实圈代表实际为真,空圈代表实际为假,tp 是预测成真实际也是真的;tn 为预测是假实际也是假的,fp 是实际是假预测成了真,fn 是实际是真预测成了假。精确率 Precision 和召回率 Recall 是常用的技术指标。

Precision 指的是在所有预测成真的实例中实际为真的比例,也就是绿占圆的比例。该评价可以加参数,即只计算排序后前N个实例的精确率。

  1. MAP

MAP 全称是 Mean Average Precision。翻成中文是平均精度均值,即对均值再求均值,求的是所有类的 average precision 的平均,公式如下:

其中 Q 是类数,AveP(q) 是 q 类的精度均值。

  1. MDCG

MDCG 全称是 Normalized Discounted Cumulative Gain。公式如下:

其中 p 是数据项数,reli 是第 i 项的评分结果,分子表示评级越高分值越高,分母是排名越靠前分母值越小分值越高。DCG 是当前所有条目的评分,而 IDCG 是对当前所有评级评分。

NDCG 是一种源自搜索引擎的算法,越靠前权重越大,单项评级越高权值越大,求最累加得分。

具体说明见:https://en.wikipedia.org/wiki/Discounted_cumulative_gain

  1. AUC

AUC 全称是 Area Under Curve,曲线下面积,其中曲线指的是 ROC 曲线,ROC 的横轴是假阳率 fpr,纵轴是 tpr 真阳率,公式如下:

利用 tpr 和 fpr 画出的曲线,形如:

ROC 曲线上的每个位置描述了在不同分界点上 tpr 和 fpr 的大小,而曲线下面积描述了该模式对各种分界的综合成绩。

AUC 对类别是否均衡并不敏感,几乎是分类常用的评估算法。

  1. AMS

AMS 全称是 Approximate Median Significance,公式如下:

其中 s,b 分别是未经正则化的真正例 (TP) 和假正例 (FP),br 是常数化正则项设为 10,log 是自然对数。

它的格式是 ams@k,其中参数 k 是个百分比,指定 topn 占数据的百分比,它主要评估序列的前 n 项。评价函数求出的是序列中最大的 ams 值,及它所在的位置。

AMS 是 Kaggle 的 Higgs Boson 比赛中的评价函数,详见源码:xgboost/demo/kaggle-higgs。这种评分标准用得不太多。

6. 一些想法

  我觉得写算法和写应用有个明显的不同:写应用可以大量借鉴别人的代码,API 都是一样的,你能做的我也能做,但算法比赛不同,照抄照搬还想超过人家基本不可能。

  在看别人代码的时候,最终成果可能只有几百行,但是推理和尝试的代码量比成果多得多,这部分最终并没呈现出来,看似简单的答案只是冰山一角。因此,有时看了人家的答案,觉得每句都能理解,到了自己做的时候,还是照猫画虎,只能微调。

  我觉得恐怕还是要在实战中磨炼自己的套路。