HyperGBM用Adversarial Validation解决数据漂移问题

本文作者:杨健,九章云极 DataCanvas 主任架构师

数据漂移问题近年在机器学习领域来越来越得到关注,成为机器学习模型在实际投产中面对的一个主要挑战。当数据的分布随着时间推移逐渐发生变化,需要预测的数据和用于训练的数据分布表现出明显的偏移,这就是数据漂移问题。

HyperGBM用Adversarial Validation解决数据漂移问题_第1张图片

数据漂移分为三种类型:

  • 变量偏移(Covariate Drift),某些独立的特征发生偏移

  • 先验概率偏移(Prior probability Drift),目标变量发生偏移

  • 概念偏移(Concept Drift),特征和目标变量之间的关系发生偏移

为什么不能通过提升泛化能力来解决数据漂移问题?

数据漂移问题无法通过提升模型泛化能力的方法来解决,因为我们目前的机器学习方法基本是建立在IID(独立同分布)前提下的。在一个真实分布下可观测的训练数据有限,训练好模型在预测时遇到了符合同一个分布但未观测到的样本时准确度下降,这种情况我们通过选择合适的算法、交叉验证、正则化、Ensemble等方式是可以有效改善模型的泛化能力的。但数据漂移的本质是数据的真实分布发生了较大的变化,因此仅仅提升泛化能力是无法有效提升模型效果的。

常用的解决方案

数据漂移常见的解决方案是不断的引入最新的数据重新训练模型,但这种方案存在很大的缺陷,例如:我们在客户流失预警中通常会用历史标注的数据训练模型来预测当月是否有用户流失,模型预测的结果要等下个月通过用户行为反馈后得到标注才能评估,如果我们发现结果大幅下降才能判断数据发生了漂移,因此这种方案存在比较明显的滞后性,这也是有监督学习的主要短板。

使用Adversarial Validation半监督学习解决数据漂移

随着近年来无监督和半监督学习的发展,一种基于Adversarial Validation(对抗验证)的半监督学习技术被提出用于解决数据漂移问题。它的核心思想是通过训练一个Adversarial Classifier来判断是否发生漂移以及哪些特征发生了漂移,进而删除发生漂移的特征来保证模型在新数据上的效果。如下图所示:

HyperGBM用Adversarial Validation解决数据漂移问题_第2张图片

对抗验证的基本过程是把训练数据(先删除目标列)和待预测数据(数据中本身就没有目标列)合并后添加新的二分类目标列(来自训练集为0, 来自测试集为1)。新的数据集shuffle后使用分层采样分割成训练集和评估集,用训练数据fit模型后使用评估集评估AUC,通常如果数据没有发生偏移AUC会接近0.5,否则就可以判断发生了不同程度的数据漂移。接下来就是识别哪些特征发生了漂移,有两种方法:一种是把每一个特征列做为X,单独训练Adversarial Classifier来评估AUC,超过一定阈值(如>0.6),就确定该列发生了漂移。另一种方法是:用全部特征训练Classifier然后评估AUC,如果超过一定阈值,就删除掉特征重要性最高的n个特征,然后重复迭代这个过程,直到AUC降到可接受的范围内。

上面的方法是通过删除漂移特征来保证模型不被干扰,还有一种方法是通过选择合适的验证集来获得更接近于测试集(待预测数据)的模型评估结果,被成为Validation Data Selection。这种方法是训练一个模型来识别训练集中的哪些样本的分布和测试集更相似,把这些样本拿出来做为Validation Data来指导模型训练,让模型可以更好的拟合测试数据的分布。

在HyperGBM中如何自动完成数据漂移检测和处理?

以上这些方法在很多数据集上可以很明显的改善模型的预测效果,目前在HyperGBM中都已经支持,通过配置参数就可以完成。HyperGBM中只需要在构建experiment时设置drift_detection=True就会自动完成数据漂移的检测和处理,需要注意的是Adversarial Validation是一种半监督学习,所以训练时需要提供未观测到目标数据的测试集(比如待预测的下个月的数据,Kaggle竞赛中的测试集),在下面示例中我们只是从数据集中分割了一部分数据删除目标列做为测试集:

from tabular_toolbox.datasets import dsutils
from sklearn.model_selection import train_test_split
from hypergbm.search_space import search_space_general
from hypergbm import make_experiment
# load data into Pandas DataFrame
df = dsutils.load_bank()
target = 'y'
train, test = train_test_split(df, test_size=0.3)
test.pop(target)
#create an experiment
experiment = make_experiment(train, target=target, test_data=test,drift_detection=True)
#run experiment
estimator = experiment.run()
# predict on test data without target values
pred = estimator.predict(test)

实现Validation Data Selection只需要设置train_test_split_strategy=‘adversarial_validation’,示例代码入下:

from tabular_toolbox.datasets import dsutils
from sklearn.model_selection import train_test_split
from hypergbm.search_space import search_space_general
from hypergbm import make_experiment
# load data into Pandas DataFrame
df = dsutils.load_bank()
target = 'y'
train, test = train_test_split(df, test_size=0.3)
test.pop(target)
#create an experiment
experiment = make_experiment(train, target=target, test_data=test,train_test_split_strategy='adversarial_validation')
#run experiment
estimator = experiment.run()
# predict on test data without target values
pred = estimator.predict(test)

更多HyperGBM相关内容请参考:
https://github.com/DataCanvasIO/HyperGBM

你可能感兴趣的:(技术干货,机器学习,人工智能,数据挖掘)