如何在sklearn2pmml的PMMLPipeline中实现predict_proba后线性变换?
解决方案
方案一:使用sklearn兼容的自定义Transformer(无需修改PMML)
sklearn2pmml要求Pipeline中的每个步骤必须是sklearn兼容的Estimator/Transformer,不能直接传入普通函数。我们可以用sklearn.preprocessing.FunctionTransformer把后处理函数包装成符合要求的Transformer,同时配置PMMLPipeline让模型输出概率而非类别。
修改后的完整代码
from sklearn.datasets import make_classification from sklearn.tree import DecisionTreeClassifier from sklearn.preprocessing import FunctionTransformer import pandas as pd import numpy as np from sklearn2pmml.pipeline import PMMLPipeline from sklearn2pmml import sklearn2pmml BIRTHDAY_SEED = 1995 nrows, cols = 1000, 5 X, y = make_classification(n_samples=nrows, n_features=cols, n_informative=2, n_redundant=3, n_classes=2, shuffle=True, random_state=BIRTHDAY_SEED) X, y = pd.DataFrame(X), pd.Series(y) # 训练模型 model = DecisionTreeClassifier(random_state=BIRTHDAY_SEED) model.fit(X, y) # 定义后处理函数,适配Transformer输入(接收二维概率数组) def postprocess_linear_transformation(probabilities): # 取类别0的概率,执行线性变换:a*p + b(a=1000,b=100) return probabilities[:, 0] * 1000 + 100 # 用FunctionTransformer包装后处理函数,关闭输入验证以适配概率数组格式 postprocessor = FunctionTransformer(postprocess_linear_transformation, validate=False) # 构建PMMLPipeline pmml_pipeline = PMMLPipeline([ ('classifier', model), ('postprocessing', postprocessor) ]) # 关键配置:指定模型输出类别0的概率,作为后处理步骤的输入,最终输出变换结果 pmml_pipeline.configure(target_fields=["probability(0)"], pmml_outputs=["postprocessing"]) # 导出包含后处理逻辑的PMML sklearn2pmml(pmml_pipeline, "scaled_probability_pipeline.pmml", with_repr=True)
说明
FunctionTransformer将普通函数转换为sklearn兼容的Transformer,确保能被PMMLPipeline识别。pmml_pipeline.configure(...)明确了数据流向:先让模型输出类别0的概率,再传递给后处理步骤生成最终结果。- 导出的PMML可直接在任何PMML兼容引擎中执行,无需额外处理。
方案二:生成基础PMML后修改XML(适合复杂自定义逻辑)
如果方案一无法满足需求,可以先生成仅包含模型的PMML,再手动修改XML添加线性变换逻辑。
步骤
- 导出仅含模型的基础PMML:
pmml_pipeline = PMMLPipeline([('classifier', model)]) sklearn2pmml(pmml_pipeline, "base_model.pmml", with_repr=True)
- 打开
base_model.pmml,找到或添加Output节点,插入线性变换定义:
<Output> <!-- 保留原概率输出(可选) --> <OutputField name="probability(0)" optype="continuous" dataType="double" feature="probability" value="0"/> <!-- 添加线性变换后的输出字段 --> <OutputField name="scaled_probability(0)" optype="continuous" dataType="double"> <Apply function="+"> <Apply function="*"> <FieldRef field="probability(0)"/> <Constant dataType="double">1000</Constant> </Apply> <Constant dataType="double">100</Constant> </Apply> </OutputField> </Output>
- 保存修改后的XML即可,PMML引擎会自动执行该线性变换并输出结果。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

