匀速小子
预计阅读时间:1分钟44秒

一文带你了解对抗性检验

0
0

为什么要有对抗性检验?


在打数据竞赛的时候,可能有人遇到这样的情况:我的模型在训练数据上效果很好,但是到测试数据上效果一塌糊涂。


比如Kaggle上2年前的这场社区预测竞赛。在训练集上,就算用简单的决策树,评估指标也能轻松达到满分,但是在测试数据上提交,0.5X。



data/58cc2700-99ba-4553-9c82-c93d077af539/911bc474-9c58-45e2-9052-33a219345703/8156O$73E~BOL4FL$XS{8Q88$`6.png


为什么会出现这种情况呢?原来是训练数据和测试数据的数据分布不一致。

举个简单的例子,比如男性的身高服从均值为170,方差为1的正态分布,女性身高服从均值为160,方差为1的正态分布。用男性的数据训练模型,用女性的数据作为测试数据,模型学会了男性的身高分布情况,但是遇到的是女性的数据,就会表现很差。

怎么做对抗性检验?

那么如何解决上述的情况呢?

既然是数据分布不一致,那就想办法让数据分布变的一致就行,最简单的做法就是删除掉分布不一致的特征,留下的特征都是分布一致的特征


那么如何来找出分布不一致的特征呢?我们让模型自己来判断。

比如有训练数据train_X和train_y,然后有test_X。我们保留下train_X和test_X,然后给这两个数据打上标签'is_test'('is_train'),就是测试集标为1,训练集标为0,然后用模型来做分类任务。

这里将train_X和test_X拼接成total_X, train_is_test和test_is_test拼接成total_is_test,打乱之后划分成训练集和测试集,用total_X预测total_is_test。

如果训练集和测试集分布一致的话,那么模型应该是无法分辨出哪个数据是训练集的,哪个数据是测试集的。反之,模型能够很清楚的分辨出数据的label:'is_test'。


这里就出现了2个问题。

1.如何用数字来描述'模型能够很清楚的分辨出数据'的程度

2.我们如何找出分布不一致的特征。


先来说第二个问题。由于我们目前一般使用的大多是lightgbm之类的树模型,树模型有特征重要性程度的参数'feature_importance',这个参数可以让我们知道哪些特征在识别is_test的时候特别重要,而这些重要的特征就是分布特别不一致的特征。



为什么是roc_auc评估指标?


回到第一个问题,提到分类任务,尤其是二分类任务,我们最先想到的评估指标肯定是准确率。那么为什么我们这里不用准确率作为评估指标呢?


在分类任务中,概率往往比类别包含了更多的信息。我们可以通过概率得到类别,但是不能从类别得到概率。我们的第一个问题是:如何用数字来描述'模型能够很清楚的分辨出数据'的程度

当概率靠近0.5的时候,说明模型自己也不确定这个样本到底该预测为1还是预测为0。但是当概率靠近0.9的时候,说明模型已经能够确定这个样本所属的类别。虽然它们最终预测出来的类别可能都是1,准确率数值上也是一样的,但是其实这2个模型明显前面的模型更迷惑,这也是准确率这个评估指标损失的信息。



综上所述,我们来做个小结:


我们给训练集和测试集打上标签is_test,让模型来做分类任务,用roc_auc来做评估指标,

如果模型不能区分样本属于训练集还是测试集,那就说明数据分布比较一致,此时roc_auc应该近似0.5,也就是瞎猜的水平。

如果模型能够很好的区分,比如auc值接近1,那么我们可以根据特征重要性来知道哪些特征的数据分布不一致,然后进行删除操作。



思考题:时序比赛能不能用对抗性检验?


评论
Copyright Created by DataER | 沪ICP备2024052789号-5 | 沪公网安备31010402336337号