"对抗验证",一个无论你使用百度、google或是知乎都无法获取答案的中文词条,当然,输入英文是可以搜索到答案的。如此拗口且看似逼格很高的东西,到底是干啥的呢?
引用kaggle大佬的一段话。
当面试时,考官问你,“如果模型过拟合,你会用什么方法处理?” 答曰:“正则化技术及对抗验证自编码!”“当训练集与测试集相差很大时,你会怎么办?”答曰:“对抗验证自编码!”
“恭喜你,你被录用了!”来自HR的信息。
如此来说对抗验证有点玩笑,不过足以说明此货还是挺好使的。下面进入正题,来说说
对抗验证是模型验证的一种,通常,我们在训练模型的时候,不会将所有的数据用于训练,而是留出部分数据(验证集)用于评估模型的效果,这样做可以一定程度减少过拟合,经常会使用的到的交叉验证有:留出法 (holdout cross validation),k 折交叉验证(k-fold cross validation)。对其中的留出法作简单举例说明:
>>> X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)以上为留出法,留出20%作为验证集。
什么是对抗验证?对抗验证是什么?怎么用?如何实现?
对抗验证,通常是在发现在训练集上模型表现得非常好,AUC非常高,此时如果采用k-fold交叉验证,模型在验证集上却表现非常糟糕。一种可能性就是训练集与测试集相差非常大。就如同许多数据科学竞赛都面临着测试集与训练集明显不同的问题(这违反了“相同分布”的假设)。因此很难建立一个具有代表性的验证集。对抗验证,选择与测试样本最相似的训练样本,并将其作为验证集。这个方法的核心思想是训练一个分类器来区分训练/测试样本。相反,理想情况下,来自同一分布的训练和测试样本,验证误差就可以很好地估计测试误差,分类器就可以很好地泛化到未发现的测试样本。
此时,你心里肯定有很多疑问,比如,这样选择的话,那岂不是过度拟合测试集了吗?
对抗验证在训练集和测试集分布“不同”的情况下,它做的选择是,宁可过拟合和测试集最相似的训练样本(用于验证),也不去过拟合那些与测试集相去甚远的样本,通过这个方法降低模型的置信度,从而降低AUC。
这么做会达到什么目的呢?这样做的结果是,我模型训练的效果可以与模型测试的效果相匹配,降低模型训练表现特别好,而测试时一团糟的情况。
如何实现呢?
先分享几个实现的链接,实现过程很简单。然后简单描述一下实现的步骤。链接:
1.kaggle-vsb ; 2.fastml ; 3.kaggle-svp
实现步骤:
1.合并训练集和测试集,并且将训练集和测试集的标签分别设置为0和1;
2.构建一个分类器(CNN,RNN或者决策树等),用于学习the different between testing and training data;
3.找到训练集中与测试集最相似的样本(most resemble data),作为验证集,其余的作为训练集;
4.构建一个用于训练的模型(CNN,RNN或者决策树等);
5.观察AUC,理想的状况是在0.5左右。
BY yumo:希望可以帮到你!