use of org.knime.base.node.mine.decisiontree2.PMMLSimpleSetPredicate 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.PMMLSimpleSetPredicate 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.PMMLSimpleSetPredicate 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.PMMLSimpleSetPredicate in project knime-core by knime.
the class ConditionExporter method setValuesFromPMMLCompoundPredicate.
private void setValuesFromPMMLCompoundPredicate(final CompoundPredicate to, final PMMLCompoundPredicate from) {
final PMMLBooleanOperator boolOp = from.getBooleanOperator();
switch(boolOp) {
case AND:
to.setBooleanOperator(CompoundPredicate.BooleanOperator.AND);
break;
case OR:
to.setBooleanOperator(CompoundPredicate.BooleanOperator.OR);
break;
case SURROGATE:
to.setBooleanOperator(CompoundPredicate.BooleanOperator.SURROGATE);
break;
case XOR:
to.setBooleanOperator(CompoundPredicate.BooleanOperator.XOR);
break;
default:
throw new IllegalStateException("Unknown boolean predicate \"" + boolOp + "\".");
}
final List<PMMLPredicate> predicates = from.getPredicates();
for (final PMMLPredicate predicate : predicates) {
if (predicate instanceof PMMLSimplePredicate) {
setValuesFromPMMLSimplePredicate(to.addNewSimplePredicate(), (PMMLSimplePredicate) predicate);
} else if (predicate instanceof PMMLSimpleSetPredicate) {
setValuesFromPMMLSimpleSetPredicate(to.addNewSimpleSetPredicate(), (PMMLSimpleSetPredicate) predicate);
} else if (predicate instanceof PMMLTruePredicate) {
to.addNewTrue();
} else if (predicate instanceof PMMLFalsePredicate) {
to.addNewFalse();
} else if (predicate instanceof PMMLCompoundPredicate) {
final CompoundPredicate compound = to.addNewCompoundPredicate();
final PMMLCompoundPredicate knimeCompound = (PMMLCompoundPredicate) predicate;
setValuesFromPMMLCompoundPredicate(compound, knimeCompound);
} else {
throw new IllegalStateException("Unknown predicate type \"" + predicate + "\".");
}
}
}
use of org.knime.base.node.mine.decisiontree2.PMMLSimpleSetPredicate in project knime-core by knime.
the class TreeModelPMMLTranslator method setValuesFromPMMLSimpleSetPredicate.
private static void setValuesFromPMMLSimpleSetPredicate(final SimpleSetPredicate to, final PMMLSimpleSetPredicate from) {
to.setField(from.getSplitAttribute());
final Enum operator;
final PMMLSetOperator setOp = from.getSetOperator();
switch(setOp) {
case IS_IN:
operator = SimpleSetPredicate.BooleanOperator.IS_IN;
break;
case IS_NOT_IN:
operator = SimpleSetPredicate.BooleanOperator.IS_NOT_IN;
break;
default:
throw new IllegalStateException("Unknown set operator \"" + setOp + "\".");
}
to.setBooleanOperator(operator);
final Set<String> values = from.getValues();
ArrayType array = to.addNewArray();
array.setN(BigInteger.valueOf(values.size()));
org.w3c.dom.Node arrayNode = array.getDomNode();
arrayNode.appendChild(arrayNode.getOwnerDocument().createTextNode(setToWhitspaceSeparatedString(values)));
final org.dmg.pmml.ArrayType.Type.Enum type;
final PMMLArrayType arrayType = from.getArrayType();
switch(arrayType) {
case INT:
type = ArrayType.Type.INT;
break;
case REAL:
type = ArrayType.Type.REAL;
break;
case STRING:
type = ArrayType.Type.STRING;
break;
default:
throw new IllegalStateException("Unknown array type \"" + arrayType + "\".");
}
array.setType(type);
}
Aggregations