use of org.knime.base.node.mine.decisiontree2.PMMLCompoundPredicate in project knime-core by knime.
the class RuleSetToTable method handleSurrogate.
/**
* (This is a recursive method.)
*
* @param cp A SURROGATE {@link PMMLCompoundPredicate}.
* @param predicates The predicates to be converted.
* @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 cp}.
* @throws IllegalStateException If cannot be transformed.
*/
private static String handleSurrogate(final PMMLCompoundPredicate cp, final List<PMMLPredicate> predicates, final boolean usePrecedence, final PMMLBooleanOperator parentOperator, final Map<String, DataType> types) {
// surrogate(a, b) = if not missing(a) then rel(a) else b = ((NOT MISSING a) AND rel(a)) OR ((MISSING a) AND b)
// surrogate(a, surrogate(b, c)) = if not missing(a) then rel(a) else if not missing(b) then rel(b) else c =
// ((NOT MISSING a) AND rel(a)) OR ((MISSING a) AND (((NOT MISSING b) AND rel(b)) OR ((MISSING b) AND rel(c))))
PMMLPredicate first = predicates.get(0);
List<PMMLPredicate> rest = predicates.subList(1, predicates.size());
if (predicates.size() == 1) {
return convertToStringPrecedence(first, usePrecedence, PMMLBooleanOperator.AND, types);
}
CheckUtils.checkState(first instanceof PMMLTruePredicate || first instanceof PMMLFalsePredicate || first instanceof PMMLSimplePredicate || first instanceof PMMLSimpleSetPredicate, "Compound predicates are not supported by the SURROGATE transformation: " + first + " in\n" + cp);
if (first instanceof PMMLFalsePredicate || first instanceof PMMLTruePredicate) {
return convertToString(first, usePrecedence, types);
}
if (first instanceof PMMLSimplePredicate || first instanceof PMMLSimpleSetPredicate) {
return parentheses(!usePrecedence || (parentOperator != null && parentOperator != PMMLBooleanOperator.OR), parentheses(!usePrecedence, /*OR is outside of this AND*/
"NOT MISSING " + dollars(first.getSplitAttribute()) + " AND " + convertToStringPrecedence(first, usePrecedence, PMMLBooleanOperator.AND, types)) + " OR " + parentheses(!usePrecedence, /*OR is outside of this AND*/
"MISSING " + dollars(first.getSplitAttribute()) + " AND " + handleSurrogate(cp, rest, usePrecedence, PMMLBooleanOperator.AND, types)));
}
throw new IllegalStateException("Compound predicates are not supported at this position: " + first + " in\n" + cp);
}
use of org.knime.base.node.mine.decisiontree2.PMMLCompoundPredicate in project knime-core by knime.
the class FromDecisionTreeNodeModel method addRules.
/**
* Adds the rules to {@code rs} (recursively on each leaf).
*
* @param rs The output {@link RuleSet}.
* @param parents The parent stack.
* @param node The actual node.
*/
private void addRules(final RuleSet rs, final List<DecisionTreeNode> parents, final DecisionTreeNode node) {
if (node.isLeaf()) {
SimpleRule rule = rs.addNewSimpleRule();
if (m_rulesToTable.getScorePmmlRecordCount().getBooleanValue()) {
// This increases the PMML quite significantly
BigDecimal sum = BigDecimal.ZERO;
final MathContext mc = new MathContext(7, RoundingMode.HALF_EVEN);
final boolean computeProbability = m_rulesToTable.getScorePmmlProbability().getBooleanValue();
if (computeProbability) {
sum = new BigDecimal(node.getClassCounts().entrySet().stream().mapToDouble(e -> e.getValue().doubleValue()).sum(), mc);
}
for (final Entry<DataCell, Double> entry : node.getClassCounts().entrySet()) {
final ScoreDistribution scoreDistrib = rule.addNewScoreDistribution();
scoreDistrib.setValue(entry.getKey().toString());
scoreDistrib.setRecordCount(entry.getValue());
if (computeProbability) {
if (Double.compare(entry.getValue().doubleValue(), 0.0) == 0) {
scoreDistrib.setProbability(new BigDecimal(0.0));
} else {
scoreDistrib.setProbability(new BigDecimal(entry.getValue().doubleValue(), mc).divide(sum, mc));
}
}
}
}
CompoundPredicate and = rule.addNewCompoundPredicate();
and.setBooleanOperator(BooleanOperator.AND);
DecisionTreeNode n = node;
do {
PMMLPredicate pmmlPredicate = ((DecisionTreeNodeSplitPMML) n.getParent()).getSplitPred()[n.getParent().getIndex(n)];
if (pmmlPredicate instanceof PMMLSimplePredicate) {
PMMLSimplePredicate simple = (PMMLSimplePredicate) pmmlPredicate;
SimplePredicate predicate = and.addNewSimplePredicate();
copy(predicate, simple);
} else if (pmmlPredicate instanceof PMMLCompoundPredicate) {
PMMLCompoundPredicate compound = (PMMLCompoundPredicate) pmmlPredicate;
CompoundPredicate predicate = and.addNewCompoundPredicate();
copy(predicate, compound);
} else if (pmmlPredicate instanceof PMMLSimpleSetPredicate) {
PMMLSimpleSetPredicate simpleSet = (PMMLSimpleSetPredicate) pmmlPredicate;
copy(and.addNewSimpleSetPredicate(), simpleSet);
} else if (pmmlPredicate instanceof PMMLTruePredicate) {
and.addNewTrue();
} else if (pmmlPredicate instanceof PMMLFalsePredicate) {
and.addNewFalse();
}
n = n.getParent();
} while (n.getParent() != null);
// Simple fix for the case when a single condition was used.
while (and.getFalseList().size() + and.getCompoundPredicateList().size() + and.getSimplePredicateList().size() + and.getSimpleSetPredicateList().size() + and.getTrueList().size() < 2) {
and.addNewTrue();
}
if (m_rulesToTable.getProvideStatistics().getBooleanValue()) {
rule.setNbCorrect(node.getOwnClassCount());
rule.setRecordCount(node.getEntireClassCount());
}
rule.setScore(node.getMajorityClass().toString());
} else {
parents.add(node);
for (int i = 0; i < node.getChildCount(); ++i) {
addRules(rs, parents, node.getChildAt(i));
}
parents.remove(node);
}
}
use of org.knime.base.node.mine.decisiontree2.PMMLCompoundPredicate in project knime-core by knime.
the class FromDecisionTreeNodeModel method copy.
/**
* Copies the {@code predicate} to {@code compound}.
*
* @param predicate A PMML xml object for {@link CompoundPredicate}
* @param compund A KNIME domain object for {@link PMMLCompoundPredicate}.
*/
private void copy(final CompoundPredicate predicate, final PMMLCompoundPredicate compound) {
PMMLPredicateTranslator.exportTo(compound, predicate);
predicate.setBooleanOperator(PMMLPredicateTranslator.getOperator(compound.getBooleanOperator()));
for (PMMLPredicate rawPredicate : compound.getPredicates()) {
if (rawPredicate instanceof PMMLSimplePredicate) {
PMMLSimplePredicate sp = (PMMLSimplePredicate) rawPredicate;
copy(predicate.addNewSimplePredicate(), sp);
} else if (rawPredicate instanceof PMMLCompoundPredicate) {
PMMLCompoundPredicate cp = (PMMLCompoundPredicate) rawPredicate;
copy(predicate.addNewCompoundPredicate(), cp);
} else if (rawPredicate instanceof PMMLSimpleSetPredicate) {
PMMLSimpleSetPredicate ssp = (PMMLSimpleSetPredicate) rawPredicate;
copy(predicate.addNewSimpleSetPredicate(), ssp);
} else if (rawPredicate instanceof PMMLTruePredicate) {
predicate.addNewTrue();
} else if (rawPredicate instanceof PMMLFalsePredicate) {
predicate.addNewFalse();
}
}
}
use of org.knime.base.node.mine.decisiontree2.PMMLCompoundPredicate in project knime-core by knime.
the class PMMLRuleTranslator method newCompoundPredicate.
/**
* {@inheritDoc}
*/
@Override
protected PMMLCompoundPredicate newCompoundPredicate(final String operator) {
try {
PMMLBooleanOperator op;
op = PMMLBooleanOperator.get(operator);
return new PMMLCompoundPredicate(op);
} catch (InstantiationException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
}
use of org.knime.base.node.mine.decisiontree2.PMMLCompoundPredicate in project knime-core by knime.
the class PMMLRuleTranslator method setCompound.
/**
* Sets {@code cp}s xml content based on {@code compound}'s properties.
*
* @param cp An xml {@link CompoundPredicate}.
* @param compound A {@link PMMLCompoundPredicate}.
*/
private void setCompound(final CompoundPredicate cp, final PMMLCompoundPredicate compound) {
PMMLBooleanOperator op = compound.getBooleanOperator();
org.dmg.pmml.CompoundPredicateDocument.CompoundPredicate.BooleanOperator.Enum boolOp = PMMLPredicateTranslator.getOperator(op);
if (boolOp == null) {
throw new UnsupportedOperationException("Not supported: " + op);
}
cp.setBooleanOperator(boolOp);
for (PMMLPredicate pp : compound.getPredicates()) {
setPredicate(cp, pp);
}
}
Aggregations