使用JPMML评估SAS生成的PMML文件时出现FMTWIDTH错误

我有一个从SAS Miner生成的PMML,我无法使用JPMML 1.1.4正确评估。 JPMML 1.1.4表示它支持PMML 4.2,而PMML表示它是PMML版本4.2。

下面的FMTWIDTHfunction是“SAS-EM-String-Normalize”正确的PMML语法吗?

任何想法为什么我不能使用JPMML评估此function?

我的TransformationDictionary中的函数看起来像,

        1 FMTWIDTH      

我得到以下exception,

线程“main”org.jpmml.evaluator.TypeCheckException中的exception:期望的INTEGER,但在org.jpmml.evaluator.FunctionRegistry $ 36的org.jpmml.evaluator.FieldValue.asInteger(FieldValue.java:125)获得STRING(FMTWIDTH)。评估(FunctionRegistry.java:463)org.jpmml.evaluator.FunctionUtil.evaluate(FunctionUtil.java:38)org.jpmml.evaluator.ExpressionUtil.evaluateApply(ExpressionUtil.java:203)atg.jpmml.evaluator.ExpressionUtil 。在org.jpmml.evaluator.FunctionUtil.evaluate(FunctionUtil.java:76)的org.jpmml.evaluator上的org.jpmml.evaluator.FunctionUtil.evaluate(FunctionUtil.java:76)中评估(ExpressionUtil.java:91)。 ExpressionUtil.evaluateApply(ExpressionUtil.java:203)位于org.jpmml.evaluator上org.jpmml.evaluator.ExpressionUtil.evaluateApply(ExpressionUtil.java:188)的org.jpmml.evaluator.ExpressionUtil.evaluate(ExpressionUtil.java:91) org.jpmml.evaluator.Expres上的org.jpmml.evaluator.ExpressionUtil.evaluate(ExpressionUtil.java:58)中的.ExpressionUtil.evaluate(ExpressionUtil.java:91) org.jpmml.evaluator上的org.jpmml.evaluator.ExpressionUtil.evaluateMapValues(ExpressionUtil.java:169)中的org.jpmml.evaluator.ExpressionUtil.evaluate(ExpressionUtil.java:87)中的sionUtil.evaluate(ExpressionUtil.java:45)位于org.jpmml的org.jpmml.evaluator.RegressionModelEvaluator.evaluateRegressionTable(RegressionModelEvaluator.java:150)org.jpmml.evaluator.ExpressionUtil.evaluate(ExpressionUtil.java:45)的.ExpressionUtil.evaluate(ExpressionUtil.java:58)。评估者.RegressionModelEvaluator.evaluateClassification(RegressionModelEvaluator.java:107)atg.jpmml.evaluator.RegressionModelEvaluator.evaluate(RegressionModelEvaluator.java:57)atg.jpmml.evaluator.ModelEvaluator.evaluate(ModelEvaluator.java:65)at ValidPMMLTesterRandomScores.randomEvaluation ValidPMMLTesterRandomSc的ValidPMMLTesterRandomScores.readModelFromFile(ValidPMMLTesterRandomScores.java:142)上的ValidPMMLTesterRandomScores.printModelInformation(ValidPMMLTesterRandomScores.java:94)中的(ValidPMMLTesterRandomScores.java:116) ores.main(ValidPMMLTesterRandomScores.java:160)

根据PMML内置函数“substring”的forms定义 ,它需要一个字符串参数和两个整数参数。 SAS EM生成的PMML代码尝试使用字符串参数,整数参数和另一个字符串参数substring($AnyCInput, 1, "FMTWIDTH")来调用此函数。

可以通过使用FieldRef元素访问“FMTWIDTH”参数的值来修复此PMML片段:

   1   

总之,JPMML是正确的,SAS EM是错误的。

通过重新排列PMML类模型对象,可以即时更正无效的PMML文档。 JPMML-Model库的Visitor API完全是为此目的而设计的:

 PMML pmml = loadSasEmPMML() Visitor invalidSubstringCorrector = new AbstractVisitor(){ @Override public VisitorAction visit(Apply apply){ if(isInvalidSubstring(apply)){ List expressions = apply.getExpressions(); expressions.set(2, new FieldRef(new FieldName("FMTWIDTH"))); } return super.visit(apply); } private boolean isInvalidSubstring(Apply apply){ if(("substring").equals(apply.getFunction())){ List expressions = apply.getExpressions(); Expression lengthArgument = expressions.get(2); if(lengthArgument instanceof Constant){ Constant constant = (Constant)lengthArgument; return ("FMTWIDTH").equals(constant.getValue()); } } return false; } }; invalidSubstringCorrector.applyTo(pmml); 

目前,方法isInvalidSubstring(Apply)通过仅检查第三个表达式元素是否为字符串常量“FMTWIDTH”来识别有问题的Apply元素。 如果需要更加确定,那么也许最好为第一个和第二个表达式元素添加适当的断言。