java sas pmml

java - Error de FMTWIDTH al usar JPMML para evaluar un archivo PMML producido por SAS



(2)

De acuerdo con la definición formal de la función incorporada PMML "substring" , requiere un argumento de cadena y dos argumentos enteros. El código PMML generado por SAS EM intenta invocar esta función con un argumento de cadena, un argumento entero y otra substring($AnyCInput, 1, "FMTWIDTH") argumento de cadena substring($AnyCInput, 1, "FMTWIDTH") .

Este fragmento PMML se puede arreglar accediendo al valor del parámetro "FMTWIDTH" utilizando el elemento FieldRef :

<Apply function="substring"> <FieldRef field="AnyCInput"/> <Constant>1</Constant> <FieldRef field="FMTWIDTH"/> </Apply>

En conclusión, JPMML es correcto y SAS EM está equivocado.

Tengo un PMML generado por SAS Miner que no puedo evaluar correctamente utilizando JPMML 1.1.4. JPMML 1.1.4 dice que es compatible con PMML 4.2 y el PMML dice que es PMML versión 4.2.

¿El FMTWIDTH en la función siguiente "SAS-EM-String-Normalize" es la sintaxis adecuada de PMML?

¿Alguna idea de por qué no puedo evaluar esta función usando JPMML?

Tengo la función en mi TransformationDictionary que se ve,

<TransformationDictionary> <DefineFunction name="SAS-EM-String-Normalize" optype="categorical" dataType="string"> <ParameterField name="FMTWIDTH" optype="continuous"/> <ParameterField name="AnyCInput" optype="categorical"/> <Apply function="trimBlanks"> <Apply function="uppercase"> <Apply function="substring"> <FieldRef field="AnyCInput"/> <Constant>1</Constant> <Constant>FMTWIDTH</Constant> </Apply> </Apply> </Apply> </DefineFunction> </TransformationDictionary>

Y obtengo la siguiente excepción,

Excepción en el hilo "main" org.jpmml.evaluator.TypeCheckException: INTEGER esperado, pero obtuvo STRING (FMTWIDTH) en org.jpmml.evaluator.FieldValue.asInteger (FieldValue.java:125) en org.jpmml.evaluator.FunctionRegistry $ 36. evalúa (FunctionRegistry.java:463) en org.jpmml.evaluator.FunctionUtil.evaluate (FunctionUtil.java:38) en org.jpmml.evaluator.ExpressionUtil.evaluateApply (ExpressionUtil.java:203) en org.jpmml.evaluator.ExpressionUtil .evaluate (ExpressionUtil.java:91) en org.jpmml.evaluator.FunctionUtil.evaluate (FunctionUtil.java:76) en org.jpmml.evaluator.FunctionUtil.evaluate (FunctionUtil.java:43) en org.jpmml.evaluator. ExpressionUtil.evaluateApply (ExpressionUtil.java:203) en org.jpmml.evaluator.ExpressionUtil.evaluate (ExpressionUtil.java:91) en org.jpmml.evaluator.ExpressionUtil.evaluateApply (ExpressionUtil.java:188) en org.jpmml.evaluator .ExpressionUtil.evaluate (ExpressionUtil.java:91) en org.jpmml.evaluator.ExpressionUtil.evaluate (ExpressionUtil.java:58) en org.jpmml.evaluator.Expres sionUtil.evaluate (ExpressionUtil.java:45) en org.jpmml.evaluator.ExpressionUtil.evaluateMapValues ​​(ExpressionUtil.java:169) en org.jpmml.evaluator.ExpressionUtil.evaluate (ExpressionUtil.java:87) en org.jpmml.evaluator .ExpressionUtil.evaluate (ExpressionUtil.java:58) en org.jpmml.evaluator.ExpressionUtil.evaluate (ExpressionUtil.java:45) en org.jpmml.evaluator.RegressionModelEvaluator.evaluateRegressionTable (RegressionModelEvaluator.java:150) en org.jpmml. evaluator.RegressionModelEvaluator.evaluateClassification (RegressionModelEvaluator.java:107) en org.jpmml.evaluator.RegressionModelEvaluator.evaluate (RegressionModelEvaluator.java:57) en org.jpmml.evaluator.ModelEvaluator.evaluate (ModelEvaluator.java:65) en ValidPMMLTesterRandomScores.randomEvaluation (ValidPMMLTesterRandomScores.java:116) en ValidPMMLTesterRandomScores.printModelInformation (ValidPMMLTesterRandomScores.java:94) en ValidPMMLTesterRandomScores.readModelFromFile (ValidPMMLTesterRandomScores.java:142) en ValidPMMLTesterRandomSc ores.main (ValidPMMLTesterRandomScores.java:160)


Los documentos PMML no válidos se pueden corregir sobre la marcha reorganizando el objeto del modelo de clase PMML. La API de visitante de la biblioteca JPMML-Model está diseñada exactamente para este propósito:

PMML pmml = loadSasEmPMML() Visitor invalidSubstringCorrector = new AbstractVisitor(){ @Override public VisitorAction visit(Apply apply){ if(isInvalidSubstring(apply)){ List<Expression> 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<Expression> 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);

Actualmente, el método isInvalidSubstring(Apply) identifica los elementos Apply problemáticos al verificar solo si el tercer elemento de expresión es una constante de cadena "FMTWIDTH". Si uno necesita estar más seguro, entonces quizás sería una buena idea agregar afirmaciones apropiadas sobre el primero y el segundo elemento de expresión también.