sklearn2pmml xgboost缺失值(missing)处理的坑
今天同事在部署xgboost pmml模型时遇到了大坑,线上spark预测和本地python预测结果怎么都不对应,记录一下处理过程。
看了下同事的代码,貌似也没有问题
from sklearn2pmml import PMMLPipeline
from sklearn2pmml import sklearn2pmml
from xgboost import XGBClassifier
weight = train_y.sum() * 1.0/ (len(train_data) - train_y.sum())
xgb_clf = XGBClassifier(learning_rate=0.1,n_estimators=100,max_depth=3,objective='binary:logistic',seed=1,silent=1,reg_alpha=3,reg_lambda=0.9,scale_pos_weight=1/weight,missing=-9999, eval_metric='auc')
pipeline = PMMLPipeline([('classifier',xgb_clf)])
pipeline.fit(train_x,train_y)
sklearn2pmml(pipeline,'data/a_card_1.pmml',with_repr=True)
首先注意到和之前不同点在于这次缺失值不是nan了,这引起了我的警觉,重新训练了下模型,把样本缺失值处理为np.nan,训练时missing设为默认值None,这时和线上对比发现一致了,果然是missing value的问题。
sklearn2pmml对于xgboost并没有暴露missing这个参数,所以对于missing不为None的童鞋可使用https://github.com/jpmml/jpmml-xgboost 转化。
xgb_clf.get_booster().dump_model('/tmp/a_card_model.dump.txt')
xgb_clf.get_booster().save_model('/tmp/xgb.model')
java -jar target/jpmml-xgboost-executable-1.3-SNAPSHOT.jar --model-input /tmp/xgb.model --fmap-input /tmp/xgb.fmap --pmml-output xgboost_miss.pmml --missing-value -9999
fmap可通过以下方式产生
fmap(feature map file):实现feature id和feature name的对应
格式为 featmap.txt: <featureid> <featurename> <q or i or int>\n
Feature id从0开始直到特征的个数为止,从小到大排列。
i表示是二分类特征
q表示数值变量,如年龄,时间等。q可以缺省
int表示特征为整数(when int is hinted, the decision boundary will be integer)
可根据以下语句通过读取pkl文件的feature_name生成,或者根据feature顺序通过别的方式生成
def ceate_feature_map(file_name,features):
outfile = open(file_name, 'w')
for i