项目场景:
最近在做CTR预估,同时有4个业务的一起做,之前在其他平台使用的机器学习没有问题。换到新的深度学习平台,用DNN和DeepFM做auc高的吓人。
问题描述:
模型从一开始就可以稳定收敛,无论是测试集还是训练集都可以稳定在0.99的auc。设定定时任务离线训练了数天后发现,偶尔会有几天auc突然变成0.5,之后有会变成0.99。
原因分析:
遇到这个问题头也是大的,之前没做过这块的工作。只能一个个原因排查:
- 是不是训练数据过拟合?
答:但是在测试集上也有很高的auc很显然不是过拟合。 - 是不是样本数据不均衡?
答:检查后正负样本比例是1:3,而且auc本身对正负样本比例是不敏感的,应该也不是这个问题。 - 是不是auc本身计算有错?
答:看了一下日志,auc计算是分布式的,按每个batch最后算平均,看起来都很正常。 - 是不是模型过于复杂?
答:尝试着减少层数,减少神经元,删除BN都无济于事,dropout也没有用。 - 是不是模型写错了?
答:用了别人的deepfm代码和自己写的DNN,都是一个效果,模型应该也没有问题。 - 是不是数据量太小了?
答:数据量每天100w左右,部分业务有500w,改用热更新之后几天依旧无法解决这个问题。
模型一圈看完了感觉还是数据本身的问题,上知乎搜到一个和我情况很类似的兄弟,提到了“特征穿越”。大概就是特征里面已经包含了样本标签。看了一下很可能是这个原因,决定对特征一个个下手。
解决方案:
暴力二分查找,从33个特征里面找到了一个“360天点击游戏id”的特征,发现单特征auc居然到了0.96!说明这个特征基本上就能确定标签了,对业务逻辑思考后发现,当天产生的该特征和当天产生的正样本会有高度的相似,导致了“特征穿越”。因此在离线训练的时候,需要利用前天的特征拼接昨天的样本,产生训练集。大致意思如下图所示:
|