missing参数导致:xgboost转为pmml格式后与刚训练好的模型预测结果不一致 建模填坑系列 001

335 阅读3分钟

001号坑 missing参数导致:xgb转为pmml格式文件后预测结果与刚训练好的模型预测结果不一致

本人在做风控建模的过程中踩了很多坑,希望在此系列中复现问题,并把解决方案整理于此方便各位同仁解决问题。着急解决问题的朋友可以直接看文章末尾解决方案。

问题描述

一般而言我们在java环境中部署机器学习模型会比较倾向于使用pmml文件,在一次上线部署中发现:使用相同的入参,在Java环境下pmml返回结果与在python环境下刚训练好的模型返回结果不一致。经过一番排查,发现一个大坑:xgb模型的missing参数很容易导致这一问题。

问题原因

xgb为了方便使用者处理缺失值而设置了missing参数,它的作用如下:默认missing=none,这时在模型训练时候把nan认为缺失值;但如果你设置了缺失值例如 missing=-99,那模型训练时会把-99当成缺失值。然后在模型训练的时候缺失值会被当成一个特殊的存在,在每一节点进行判断时,缺失值不会参与分枝节点的大小判断而是直接被一个if missing else 逻辑处理。
我们举一棵树的例子说明一下:
在这里插入图片描述
我们先假设传入的featureA等于-99,如果没有missing的话featureA来到这棵树会参与>100 的比较。-99小于100,该树会返回0.12。但如果你设置了一个missing=-99,那-99到这个分支节点就不会参与与100的比较,而是按既定的缺失值策略直接给出返回值,这个返回值可能是让它返回0.89,也可能返回0.47,还可能返回0.12。这时候问题就来了,如果你的缺失值策略和节点比较结果不一样,那么结果就会不一致。
然后由于许多pmml文件生成工具上都没有显式给出missing的设置参数,所以如果你在建模时使用了missing参数但是没有在生成pmml文件做特殊处理时就会出现线上部署与线下训练结果不一致的问题。
我们给大家对比一下有缺失值策略和没有缺失值策略的pmml文件:
有缺失值策略:
有缺失值策略
没有缺失值策略:
没有缺失值策略

解决方案

在这里提供一下我自己的解决方案。为了方便大家使用,我将https://github.com/jpmml/jpmml-evaluator上的项目封装到了一个java包中,需要的朋友可点击下载链接:链接地址 提取码: 1v1r
然后大家在生成pmml文件的时候通过以下命令:

java -jar target/jpmml-xgboost-executable-1.3-SNAPSHOT.jar --model-input ./model.bin --fmap-input ./fmap.txt --pmml-output xgboost_1.pmml --missing-value 1

为大家解读以下上面命令的各个参数,
(1)target/jpmml-xgboost-executable-1.3-SNAPSHOT.jar 是你下载jar包后存放的地址
(2)./model.bin 是你模型文件存放路劲,可以是.bin的,也可以是.model的
(3)./fmap.txt 是你的特征列表文件路径,该文件格式如图:(feature map 的格式:
<特征 id> <特征名称><q or i or int>
特征 id 排序从 0 开始升序,i指二选一的特征,q指数量值,int指整型特征)
在这里插入图片描述
(4)xgboost_1.pmml 这儿写你生成文件的存放路径及文件名
(5)1 这儿要改成你自己设置的missing值。

至此该问题已被解决。
本人从事风控行业,开设了一个公众号分享一些知识、经验、想法,感兴趣的朋友可以关注一下。
在这里插入图片描述