use of org.knime.base.node.mine.decisiontree2.PMMLPredicate in project knime-core by knime.
the class PMMLRuleTranslator method collectPredicates.
/**
* The predicates of a {@link CompoundRule} in the order they appear.
*
* @param compoundRule An xml {@link CompoundRule}.
* @return The flat list of {@link PMMLPredicate}s.
*/
private List<PMMLPredicate> collectPredicates(final CompoundRule compoundRule) {
List<PMMLPredicate> ret = new ArrayList<PMMLPredicate>();
XmlCursor cursor = compoundRule.newCursor();
if (cursor.toFirstChild()) {
do {
XmlObject object = cursor.getObject();
if (object instanceof CompoundRuleDocument.CompoundRule) {
CompoundRuleDocument.CompoundRule cr = (CompoundRuleDocument.CompoundRule) object;
ret.addAll(collectPredicates(cr));
} else if (object instanceof SimpleRule) {
SimpleRule sr = (SimpleRule) object;
ret.add(createRule(sr).getCondition());
} else if (object instanceof SimplePredicate) {
SimplePredicate sp = (SimplePredicate) object;
ret.add(parseSimplePredicate(sp));
} else if (object instanceof CompoundPredicate) {
CompoundPredicate cp = (CompoundPredicate) object;
ret.add(parseCompoundPredicate(cp));
}
} while (cursor.toNextSibling());
}
return ret;
}
use of org.knime.base.node.mine.decisiontree2.PMMLPredicate in project knime-core by knime.
the class PMMLRuleTranslator method setPredicate.
/**
* As the predicates can be of different subclasses of {@link PMMLPredicate}, creating them adding their properties
* to the {@code simpleRule} is done with this method.
*
* @param simpleRule An xml {@link SimpleRule} (recently created).
* @param predicate A {@link PMMLPredicate} with preferably from the Rule versions of
* {@link PMMLRuleSimplePredicate} and {@link PMMLRuleCompoundPredicate}.
* @since 2.12
*/
public void setPredicate(final SimpleRule simpleRule, final PMMLPredicate predicate) {
if (predicate instanceof PMMLFalsePredicate) {
simpleRule.addNewFalse();
} else if (predicate instanceof PMMLTruePredicate) {
simpleRule.addNewTrue();
} else if (predicate instanceof PMMLSimplePredicate) {
PMMLSimplePredicate simple = (PMMLSimplePredicate) predicate;
SimplePredicate pred = simpleRule.addNewSimplePredicate();
pred.setField(simple.getSplitAttribute());
setOperator(pred, simple);
if (simple.getThreshold() != null) {
pred.setValue(simple.getThreshold());
}
} else if (predicate instanceof PMMLCompoundPredicate) {
PMMLCompoundPredicate comp = (PMMLCompoundPredicate) predicate;
CompoundPredicate p = simpleRule.addNewCompoundPredicate();
setCompound(p, comp);
} else if (predicate instanceof PMMLSimpleSetPredicate) {
PMMLSimpleSetPredicate set = (PMMLSimpleSetPredicate) predicate;
SimpleSetPredicate s = simpleRule.addNewSimpleSetPredicate();
setSetPredicate(s, set);
}
}
use of org.knime.base.node.mine.decisiontree2.PMMLPredicate in project knime-core by knime.
the class PMMLRuleTranslator method createRule.
/**
* The compound rules are tricky... We have to pull each simple rule out of them in order and find the first simple
* rule to get the outcome. The result is a simple {@link Rule}.
*
* @param compoundRule An xml {@link CompoundRule}.
* @return The corresponding {@link Rule}.
*/
private Rule createRule(final CompoundRule compoundRule) {
final LinkedList<PMMLPredicate> predicates = new LinkedList<PMMLPredicate>();
predicates.addAll(collectPredicates(compoundRule));
final PMMLCompoundPredicate condition = newCompoundPredicate(PMMLBooleanOperator.AND.toString());
condition.setPredicates(predicates);
// This is suspicious, as the later outcomes are discarded, but this is the right thing
// according to the spec 4.1 (http://www.dmg.org/v4-1/RuleSet.html)
final SimpleRule firstRule = findFirst(compoundRule);
if (firstRule == null) {
throw new IllegalStateException("No SimpleRule was found in " + compoundRule);
}
return new Rule(condition, firstRule.getScore(), firstRule.isSetWeight() ? firstRule.getWeight() : null, firstRule.isSetConfidence() ? firstRule.getConfidence() : null);
}
use of org.knime.base.node.mine.decisiontree2.PMMLPredicate in project knime-core by knime.
the class PMMLRuleTranslator method setPredicate.
/**
* For an xml {@link CompoundPredicate} ({@code cp}) sets the parameters based on {@code pred}'s properties.
*
* @param cp An xml {@link CompoundPredicate}.
* @param pred The {@link PMMLPredicate} with the rule version subclasses.
*/
private void setPredicate(final CompoundPredicate cp, final PMMLPredicate pred) {
if (pred instanceof PMMLFalsePredicate) {
cp.addNewFalse();
} else if (pred instanceof PMMLTruePredicate) {
cp.addNewTrue();
} else if (pred instanceof PMMLSimplePredicate) {
PMMLSimplePredicate simple = (PMMLSimplePredicate) pred;
SimplePredicate s = cp.addNewSimplePredicate();
s.setField(simple.getSplitAttribute());
setOperator(s, simple);
s.setValue(simple.getThreshold());
} else if (pred instanceof PMMLCompoundPredicate) {
PMMLCompoundPredicate compound = (PMMLCompoundPredicate) pred;
CompoundPredicate c = cp.addNewCompoundPredicate();
setCompound(c, compound);
} else if (pred instanceof PMMLSimpleSetPredicate) {
PMMLSimpleSetPredicate set = (PMMLSimpleSetPredicate) pred;
SimpleSetPredicate ss = cp.addNewSimpleSetPredicate();
setSetPredicate(ss, set);
}
}
use of org.knime.base.node.mine.decisiontree2.PMMLPredicate in project knime-core by knime.
the class RuleSetToTable method convertToStringPrecedence.
/**
* @param condition A {@link PMMLPredicate}.
* @param usePrecedence Should we simplify the condition?
* @param parentOperator The parent operator's (logical connective) type, used for precedence, can be {@code null}.
* @param types The type of input columns.
* @return Converted {@code condition} with precedence.
*/
private static String convertToStringPrecedence(final PMMLPredicate condition, final boolean usePrecedence, final PMMLBooleanOperator parentOperator, final Map<String, DataType> types) {
if (condition instanceof PMMLTruePredicate) {
return "TRUE";
}
if (condition instanceof PMMLFalsePredicate) {
return "FALSE";
}
if (condition instanceof PMMLSimplePredicate) {
PMMLSimplePredicate sp = (PMMLSimplePredicate) condition;
DataType dataType = types.get(sp.getSplitAttribute());
switch(sp.getOperator()) {
// intentional fall-through
case EQUAL:
// intentional fall-through
case GREATER_OR_EQUAL:
// intentional fall-through
case GREATER_THAN:
// intentional fall-through
case LESS_OR_EQUAL:
case LESS_THAN:
return dollars(sp.getSplitAttribute()) + " " + sp.getOperator().getSymbol() + " " + asComparisonValue(sp.getThreshold(), dataType);
case NOT_EQUAL:
return "NOT " + dollars(sp.getSplitAttribute()) + " = " + asComparisonValue(sp.getThreshold(), dataType);
case IS_MISSING:
return "MISSING " + dollars(sp.getSplitAttribute());
case IS_NOT_MISSING:
return "NOT MISSING " + dollars(sp.getSplitAttribute());
default:
throw new UnsupportedOperationException("Unknown operator: " + sp.getOperator());
}
}
if (condition instanceof PMMLSimpleSetPredicate) {
PMMLSimpleSetPredicate ssp = (PMMLSimpleSetPredicate) condition;
DataType dataType = types.get(ssp.getSplitAttribute());
switch(ssp.getSetOperator()) {
case IS_IN:
return dollars(ssp.getSplitAttribute()) + " IN (" + asComparisonValues(ssp.getValues(), dataType) + ")";
case IS_NOT_IN:
return "NOT " + dollars(ssp.getSplitAttribute()) + " IN (" + asComparisonValues(ssp.getValues(), dataType) + ")";
default:
throw new UnsupportedOperationException("Unknown operator: " + ssp.getOperator());
}
}
if (condition instanceof PMMLCompoundPredicate) {
PMMLCompoundPredicate cp = (PMMLCompoundPredicate) condition;
List<PMMLPredicate> predicates = cp.getPredicates();
switch(cp.getBooleanOperator()) {
case AND:
// never parentheses, parent XOR, OR, AND, nothing: all fine, SURROGATE is not supported
return parentheses(!usePrecedence, join(PMMLBooleanOperator.AND, cp, types, usePrecedence));
case OR:
// if not nothing or OR, we have to use parentheses
return parentheses(!usePrecedence || (predicates.size() > 1 && parentOperator != null && parentOperator != PMMLBooleanOperator.OR), join(PMMLBooleanOperator.OR, cp, types, usePrecedence));
case XOR:
// if not nothing or XOR or OR, we have to use parentheses, so when it is an AND
return parentheses(!usePrecedence || (predicates.size() > 1 && parentOperator == PMMLBooleanOperator.AND), join(PMMLBooleanOperator.XOR, cp, types, usePrecedence));
case SURROGATE:
{
CheckUtils.checkState(predicates.size() > 1, "At least two arguments are required for SURROGATE, but got only: " + predicates.size() + "\nValues: " + predicates);
return handleSurrogate(cp, predicates, usePrecedence, parentOperator, types);
}
default:
throw new UnsupportedOperationException("Unknown operator: " + cp.getOperator());
}
}
throw new IllegalArgumentException("Unknown predicate type: " + condition + " (" + condition.getClass());
}
Aggregations