其他分享
首页 > 其他分享> > 2022年招行数据赛道公司存款流失预测赛后复盘

2022年招行数据赛道公司存款流失预测赛后复盘

作者:互联网

公司存款流失预测(2022年招行数据赛道)

这个四月参加了招行的数据赛道比赛,感觉氛围不错学到了很多知识。最后在1800+人中拿到了A榜43名,B榜310名的成绩。虽然最终无缘面试,但还是值得复盘分析。

赛题简介

本次比赛为参赛选手提供了两个数据集,即训练数据集(train)和测试数据集(test_A榜/ test_B榜)。通过有效的特征提取,使用分类算法构建公司客户存款流失预测模型,并将模型应用在测试数据集上,输出对测试数据集中公司客户存款流失概率的预测。

数据简介

训练数据集中共包含4万条脱敏数据,

  1. CUST_UID为公司客户唯一标识,
  2. LABEL为公司客户存款是否流失的标志
    1. 其中1表示该公司客户在三个月后存款发生流失
    2. 0表示该公司客户在三个月后存款未发生流失。
    3. 后续的数据列是每个公司客户当月的数据情况,可作为模型使用的变量
    4. 需要注意的是,不是所有变量都适合入模,参赛选手需要对变量进行过滤和筛选。
  3. 测试数据集中包含1.2万条脱敏数据 ,CUST_UID为公司客户唯一标识(训练集和测试集中若存在相同的CUST_UID,不代表同一用户),其余数据列为每个公司客户当月的数据情况。

A榜上分回顾

主要采用的方法

主要的问题

B榜上分回顾

B榜测试数据与训练数据有很大不同,导致线上线下差异极大,很长一段时间线下都是完全过拟合的状态。最后导致了较差的结果

主要采用的方法

基本思路

对抗验证(详见附录A)

简述:将来自训练集的标签赋值为1,测试集的样本标签为0,训练一个学习器判断这样本来自哪一个集合

对于A榜数据

valid_0's auc: 0.492741

AUC约为0.5,表明分类器无法区分样本是来自训练集还是测试集

对于B榜数据

valid_0's auc: 0.969135 valid_0's l2: 0.0640045 
valid_0's auc: 0.978514 valid_0's l2: 0.0516688 
valid_0's auc: 0.982417 valid_0's l2: 0.0461824 
valid_0's auc: 0.984529 valid_0's l2: 0.0429678 
valid_0's auc: 0.98615 valid_0's l2: 0.040339 
valid_0's auc: 0.986933 valid_0's l2: 0.0388808 
Early stopping, best iteration is: valid_0's auc: 0.987338 valid_0's l2: 0.0381312

很明显A榜的训练集和测试集就是从一个数据集中划分得来,而B榜的测试集来自另一个数据集。

而后采用这一分类器从训练集中选择与测试集类似的样本,有助于减少过拟合。

赛后总结

赛后参考一些大佬的开源后发现B榜关键在于删除会导致过拟合的特征

附录A:Adversarial validation-对抗验证| 一种解决训练集与测试集分布不一致的方法

验证集上的KS/AUC相对较高,测试集上天然会存在decay的现象
训练集与测试集差异明显的典型例子很容易发生在Kaggle比赛,或者国内高水平的比赛上,比赛前期显示的都是在公榜上成绩,最后的评判的却是的额外的私榜上,就会产生很大喜闻乐见的地震。如Kaggle比赛LANL Earthquake Prediction,在public Leaderboard中排名第一的,在private Leaderboard却掉到了2734,而后面一大票老哥却冲到了前排,上演数据世界的地震。
我们发现线下的K折验证无法反映线上效果时该怎么办

  1. 构建一个样本的分类器,该二分类器的任务用于区分样本来源于训练集,还是测试集。因此,需要为原始数据新增一个标签列,将训练集中的样本标记为0, 测试集中的样本标记为1,样本的特征是数据中已有的特征,或者衍生的新特征,生成新的训练数据集;
  2. 将新的训练数据集进行划分,保留部分样本作为该样本分类任务的测试集\(T\), 利用分类算法(XGBoost, LightGBM)等对数据集进行训练,AUC作为模型指标;
  3. 在测试集\(T\)中进行验证,如果模型效果AUC在0.5左右,说明该样本分类模型无法区分样本来源训练集,还是测试集,说明原始数据中训练集,测试集分布是一致的;如果AUC较大,如0.9, 说明样本分类器很容易区分样本,间接说明训练集与测试集存在很大差异;
  4. 根据第3步的结论,对于分布一致的,正常对目标任务训练即可;
  5. 对于分布不一致的,可以继续进行样本挑选的尝试。利用上述样本分类器模型,对原始的训练集进行打分预测,并将样本按照模型分从大到小排序,模型分越大,说明与测试集越接近,那么取训练集中的TOP N 的样本作为目标任务的验证集,这样即可将原始的样本进行拆分得到 训练集,验证集,测试集。那么线上模型验证时,在这样的数据上调参等得到模型,如果在验证集上效果稳定,那么应用在测试集上,大概率结果是一致的

用对抗验证进行特征筛选

对抗验证作为一种特征筛选方法时,可以找出时序波动明显的特征,帮我们快速找到在训练集和测试集上不稳定的特征。步骤如下:

  1. 对划分的训练集和验证集(测试集)进行二元编码, e.g. 训练集增加一个ad_target=1,验证集增加一个ad_target=0
  2. 训练一个简单的二分类模型,目标是对ad_target做二分类
  3. 每次训练只使用一个特征,记录模型收敛时验证集的AUC
  4. 迭代步骤3直到遍历所有特征,对特征按照AUC指标从高到底排序
  5. 重点分析AUC较高所对应的特征,经验阈值可以选0.7,0.8;注意缺失值问题
  6. auc越高,代表越能区分出训练集和测试集,可以选择丢弃这些特征

附录B:提交记录与笔记

第1次提交|0.9518|

第2次提交|0.9523|0.0005

auc l2
0 0.951297 0.0694433
1 0.951351 0.0713171
2 0.951684 0.0707
3 0.945938 0.0745949
4 0.950595 0.0725664

第3次提交|0.9533|0.001

数据:采用第一次提交的数据
特征:使用autogulon,没调任何参数
线下auc:0.952672
线下实验
实验一:

label='LABEL'
save_path = '../usrdata/automl' 	# specifies folder to store trained models
predictor = TabularPredictor(label=label,
                            problem_type='binary',
                            eval_metric='roc_auc',
                            path=save_path).fit(x_train)

输入数据为第二次提交的数据,即做了数值特征统计的数据,验证集最优分数为0.952989
,hyperparameters='multimodal', num_bag_folds=5, num_stack_levels=1

第5次提交|0.954766|0.0015

数据(以下处理按顺序进行):

  1. 区分类别特征和数值特征
  2. 对类别特征进行自然数编码
  3. 数值特征分桶(分桶后的数值特征作为类别特征)
  4. 聚类方法打标签(kmeans n=100, DBSCAN)
  5. 数值特征交叉(加减乘除)
  6. 数值特征统计(由交叉得到的特征不做统计)
    模型:使用autogulon,默认参数
predictor = TabularPredictor(label=label,
                            problem_type='binary',
                            eval_metric='roc_auc',
                            path=save_path).fit(x_train,)

线下auc:0.952419

model score_val
0 WeightedEnsemble_L2 0.952419
1 CatBoost 0.951544
2 LightGBMXT 0.950950
3 LightGBMLarge 0.950814
4 LightGBM 0.0725664
还可以考虑的点

第9次提交|0.95483|6.4e-5

数据:根据catboost筛选特征,取重要性大于0的特征

模型:取boost系列一共五个模型,基模型内部做平均。基模型之间做stack

rawdata=pd.read_parquet('../usrdata/data_stat_cross_cat.par')
x_train,x_test=train_test_split(rawdata)
label='LABEL'
save_path = '../usrdata/automl' 	# specifies folder to store trained models
predictor = TabularPredictor(label=label,
                            problem_type='binary',
                            eval_metric='roc_auc',
                            path=save_path).fit(x_train,
                            num_bag_folds=5,
                            num_bag_sets=5,
                            excluded_model_types = ['KNN', 'NN_TORCH','FASTAI','XT','RF']
                            # hyperparameters='multimodal',
                            # presets='best_quality'
                            )

线下auc:0.953084

model score_val
0 WeightedEnsemble_L2 0.953084
1 CatBoost 0.952732
2 LightGBMXT 0.952622
3 LightGBMLarge 0.952592
4 LightGBM 0.952578
5 CatBoost_BAG_L1 0.951938
还可以考虑的点:

第10次提交|0.9545|反面教材——准确率下降

数据:加入类别特征组合(这里的数据有问题,类别特征组合不正确)

模型:

predictor = TabularPredictor(label=label,
                            problem_type='binary',
                            eval_metric='roc_auc',
                            path=save_path).fit(x_train,
                            excluded_model_types = ['KNN', 'NN_TORCH','FASTAI','XT','RF'])

线下AUC:0.953336

model score_val
0 WeightedEnsemble_L2 0.953336
1 LightGBMXT 0.952803
2 LightGBM 0.952675
3 CatBoost 0.951666
4 LightGBMLarge 0.950629
5 XGBoost 0.950304
特征选择后的结果
![[aa0ba6d4-2676-4d0d-bc78-37e1517be678.png]]-=

第12次提交|0.95501|0.00018

数据:加入类别特征组合后用catboost做特征选择
模型:

predictor = TabularPredictor(label=label,
                            problem_type='binary',
                            eval_metric='roc_auc',
                            path=save_path).fit(x_train,
                            num_bag_folds=5,
                            num_bag_sets=5,
                            excluded_model_types = ['KNN', 'NN_TORCH','FASTAI','XT','RF'])

基本没什么突破,该用的招差不多都用完了

第13次提交|0.95506|0.00001

就是把前几次提交中比较好的按0.2,0.2,0.6的比例重新融合

submit-cat_cross_5-2022-05-02-22-05.txt submit-cross_5-2022-05-01-19-51.txt submit-auto_ml_with_num_stat-2022-04-30-18-12.txt 融合成绩
单模成绩 0.95501 0.95482 0.95476
融合比例 0.6 0.2 0.2 0.95506
0.6 0.3 0.1 0.95503
0.7 0.3 0 0.95499
最后成绩0.95506

第17次提交|0.95508|0.00002

特征:在类别特征中取三个交叉(之前是两两交叉),用5折lightgbm做特征选择,取5次交叉的特征重要性之和>10的特征
最后得到2326个特征

模型:AutoGulon常规的13个模型

线下auc:0.9541

第22次提交|0.95527|0.0002

融合之前的提交

submit-2022-05-03-12-31-3_fusion.txt submit-2022-05-05-09-51-stat_3_combine_cross_cat.txt 融合成绩
单模成绩 0.95511 0.95513
融合比例 0.4 0.6 0.955271
0.3 0.7 0.955243
0.5 0.5 0.955278
0.55 0.45 0.955275

还可以考虑的方向

附录C:竞赛高排名方案

方案一:招商银行2022FinTech精英训练营-数据赛道_叶 无忧98的博客-CSDN博客

核心思想是结合分类准确率和对抗验证AUC综合进行筛选, 通过middle_sort对所有特征进行排序,筛选有用的特征

middle_sort= np.where(importance_sort == i)+ np.where(AUC_sort == i)* 2 # auc_gain

方案二:librauee/ZSYH2022: 招商银行2022FinTech精英训练营 (github.com)

标签:赛道,auc,测试,训练,特征,模型,valid,2022,复盘
来源: https://www.cnblogs.com/anime-enjoy/p/16531933.html