Closed hjh1011 closed 1 year ago
Passing a Python function to ExpressionTransformer
is supported since SkLearn2PMML 0.88.1.
Example here: https://github.com/jpmml/sklearn2pmml/blob/0.88.1/sklearn2pmml/preprocessing/tests/__init__.py#L190-L193 https://github.com/jpmml/sklearn2pmml/blob/0.88.1/sklearn2pmml/preprocessing/tests/__init__.py#L257-L264
It doesn't work for you, because you're using an outdated SkLearn2PMML package version.
My rant: "FFS people, how hard can it be to UPGRADE YOUR SKLEARN2PMML PACKAGE VERSION before opening any issues at GitHub"?
def pred_LB_conf(X):
However, you would need to rewrite your function definition, because the Python-to-PMML translator component does not support looping constructs (eg. for
statements).
Thank you for the response. Is there an easy way to quickly validate whether a function is allowed for the python-to-pmml translator? Or is there any guidance to follow like what construct is allowed and what is not
Is there an easy way to quickly validate whether a function is allowed for the python-to-pmml translator?
Write a Python expression. If the conversion fails, then take a look which source code file/which line number is involved in raising the exception. Locate this piece of code in the JPMML-Python project, and see what's implemented around there.
Is there an easy way to quickly validate whether a function is allowed for the python-to-pmml translator?
JavaCC grammar for building the Python expression translator is here (linking to the latest 1.1.9 version): https://github.com/jpmml/jpmml-python/blob/1.1.9/pmml-python/src/main/javacc/expression.jj
Now, since looping constructs are not allowed, you're pretty much limited to three statements:
if-elif-else
statementreturn
statement<variable> = <expression>
. A variable cannot be re-assigned a new value, so they are functionally "final" (eg. val
in Scala).@hjh1011 Just thinking out loud - it seems to me that you're trying to emulate an ordinal target value with your pred_LB_conf
function.
What's the approximate number of target categories there (ie. len(X)
)? If it's fairly low, then it may be feasible to craft an if-(elif)*-else
statement outright (possibly generating this piece of Python code programmatically). If the number of target categories is higher, then it will be better to use PMML built-in "cumulative link" pieces of functionality.
For example, the RegressionModel
element comes with pretty comprehensive support for ordinal targets (jump to "Valid combinations" sub-section):
https://dmg.org/pmml/v4-4-1/Regression.html
So, your use case would be addressed by building a two-estimator chain, where the initial XGBoost estimator step computes probabilities, and the final regression step then converts this probability distribution to an ordinal category value.
your use case would be addressed by building a two-estimator chain, where the initial XGBoost estimator step computes probabilities, and the final regression step then converts this probability distribution to an ordinal category value.
If you open an XGBoost PMML file in text editor, then it's possible to see that there's already a RegressionModel
element contained in there...
Now, to emulate an ordinal target, you could simply tweak the configuration of the existing RegressionModel
element, no need to define another one.
I am trying to process the output of a multi-classification model of
xgb.XGBClassifier
with a customized function.But when I try to write it into a xml file with
It gives me error and says expr is not supported? I am wondering what should I look into now