use of org.knime.base.node.mine.treeensemble2.model.TreeNodeSignature in project knime-core by knime.
the class TreeNodeSignatureFactory method getChildSignatureFor.
/**
* Looks up whether a signature with given <b>parent</b> and <b>childIndex</b> exists and returns
* it if it does and otherwise creates a new signature stores it and returns the newly created signature.
* This function is synchronized because different threads will access it during the tree building process.
*
* @param parentSignature
* @param childIndex
* @return signature for child node
*/
public synchronized TreeNodeSignature getChildSignatureFor(final TreeNodeSignature parentSignature, final byte childIndex) {
List<TreeNodeSignature> knownChildren = m_knownSignatures.get(parentSignature);
// case that the child signature does not exist yet
if (knownChildren.size() <= childIndex) {
TreeNodeSignature childSignature = parentSignature.createChildSignature(childIndex);
knownChildren.add(childIndex, childSignature);
return childSignature;
} else {
// there are already signatures registered for parent
TreeNodeSignature childSignature = knownChildren.get(childIndex);
// (unlikely because we usually build the children in order)
if (childSignature == null) {
childSignature = parentSignature.createChildSignature(childIndex);
knownChildren.add(childIndex, childSignature);
}
return childSignature;
}
}
use of org.knime.base.node.mine.treeensemble2.model.TreeNodeSignature in project knime-core by knime.
the class MGradientBoostedTreesLearner method learn.
/**
* {@inheritDoc}
*/
@Override
public AbstractGradientBoostingModel learn(final ExecutionMonitor exec) throws CanceledExecutionException {
final TreeData actualData = getData();
final GradientBoostingLearnerConfiguration config = getConfig();
final int nrModels = config.getNrModels();
final TreeTargetNumericColumnData actualTarget = getTarget();
final double initialValue = actualTarget.getMedian();
final ArrayList<TreeModelRegression> models = new ArrayList<TreeModelRegression>(nrModels);
final ArrayList<Map<TreeNodeSignature, Double>> coefficientMaps = new ArrayList<Map<TreeNodeSignature, Double>>(nrModels);
final double[] previousPrediction = new double[actualTarget.getNrRows()];
Arrays.fill(previousPrediction, initialValue);
final RandomData rd = config.createRandomData();
final double alpha = config.getAlpha();
TreeNodeSignatureFactory signatureFactory = null;
final int maxLevels = config.getMaxLevels();
// this should be the default
if (maxLevels < TreeEnsembleLearnerConfiguration.MAX_LEVEL_INFINITE) {
final int capacity = IntMath.pow(2, maxLevels - 1);
signatureFactory = new TreeNodeSignatureFactory(capacity);
} else {
signatureFactory = new TreeNodeSignatureFactory();
}
exec.setMessage("Learning model");
TreeData residualData;
for (int i = 0; i < nrModels; i++) {
final double[] residuals = new double[actualTarget.getNrRows()];
for (int j = 0; j < actualTarget.getNrRows(); j++) {
residuals[j] = actualTarget.getValueFor(j) - previousPrediction[j];
}
final double quantile = calculateAlphaQuantile(residuals, alpha);
final double[] gradients = new double[residuals.length];
for (int j = 0; j < gradients.length; j++) {
gradients[j] = Math.abs(residuals[j]) <= quantile ? residuals[j] : quantile * Math.signum(residuals[j]);
}
residualData = createResidualDataFromArray(gradients, actualData);
final RandomData rdSingle = TreeEnsembleLearnerConfiguration.createRandomData(rd.nextLong(Long.MIN_VALUE, Long.MAX_VALUE));
final RowSample rowSample = getRowSampler().createRowSample(rdSingle);
final TreeLearnerRegression treeLearner = new TreeLearnerRegression(getConfig(), residualData, getIndexManager(), signatureFactory, rdSingle, rowSample);
final TreeModelRegression tree = treeLearner.learnSingleTree(exec, rdSingle);
final Map<TreeNodeSignature, Double> coefficientMap = calcCoefficientMap(residuals, quantile, tree);
adaptPreviousPrediction(previousPrediction, tree, coefficientMap);
models.add(tree);
coefficientMaps.add(coefficientMap);
exec.setProgress(((double) i) / nrModels, "Finished level " + i + "/" + nrModels);
}
return new GradientBoostedTreesModel(getConfig(), actualData.getMetaData(), models.toArray(new TreeModelRegression[models.size()]), actualData.getTreeType(), initialValue, coefficientMaps);
}
use of org.knime.base.node.mine.treeensemble2.model.TreeNodeSignature in project knime-core by knime.
the class AbstractGBTModelExporter method writeSumSegmentation.
protected void writeSumSegmentation(final Segmentation segmentation, final Collection<TreeModelRegression> trees, final Collection<Map<TreeNodeSignature, Double>> coefficientMaps) {
assert trees.size() == coefficientMaps.size() : "The number of trees does not match the number of coefficient maps.";
segmentation.setMultipleModelMethod(MULTIPLEMODELMETHOD.SUM);
Iterator<TreeModelRegression> treeIterator = trees.iterator();
Iterator<Map<TreeNodeSignature, Double>> coefficientMapIterator = coefficientMaps.iterator();
for (int i = 1; i <= trees.size(); i++) {
Segment segment = segmentation.addNewSegment();
segment.setId(Integer.toString(i));
segment.addNewTrue();
writeTreeIntoSegment(segment, treeIterator.next(), coefficientMapIterator.next());
}
}
use of org.knime.base.node.mine.treeensemble2.model.TreeNodeSignature in project knime-core by knime.
the class AbstractRegressionContentParser method createNode.
@Override
public final TreeNodeRegression createNode(final Node node, final TargetColumnHelper<TreeTargetNumericColumnMetaData> targetHelper, final TreeNodeSignature signature, final List<TreeNodeRegression> children) {
double mean = Double.parseDouble(node.getScore());
OptionalDouble totalSum = node.getExtensionList().stream().filter(e -> e.getName().equals(TranslationUtil.TOTAL_SUM_KEY)).mapToDouble(e -> Double.parseDouble(e.getValue())).findFirst();
OptionalDouble sumSquaredDeviation = node.getExtensionList().stream().filter(e -> e.getName().equals(TranslationUtil.SUM_SQUARED_DEVIATION_KEY)).mapToDouble(e -> Double.parseDouble(e.getValue())).findFirst();
return createNodeInternal(node, targetHelper.getMetaData(), signature, mean, totalSum.orElse(-1), sumSquaredDeviation.orElse(-1), children.toArray(new TreeNodeRegression[children.size()]));
}
use of org.knime.base.node.mine.treeensemble2.model.TreeNodeSignature in project knime-core by knime.
the class ClassificationGBTModelImporter method importFromPMMLInternal.
/**
* {@inheritDoc}
*/
@Override
protected MultiClassGradientBoostedTreesModel importFromPMMLInternal(final MiningModel miningModel) {
Segmentation modelChain = miningModel.getSegmentation();
CheckUtils.checkArgument(modelChain.getMultipleModelMethod() == MULTIPLEMODELMETHOD.MODEL_CHAIN, "The top level segmentation should have multiple model method '%s' but has '%s'", MULTIPLEMODELMETHOD.MODEL_CHAIN, modelChain.getMultipleModelMethod());
List<List<TreeModelRegression>> trees = new ArrayList<>();
List<List<Map<TreeNodeSignature, Double>>> coefficientMaps = new ArrayList<>();
List<String> classLabels = new ArrayList<>();
List<Segment> segments = modelChain.getSegmentList();
for (int i = 0; i < segments.size() - 1; i++) {
Pair<List<TreeModelRegression>, List<Map<TreeNodeSignature, Double>>> gbtPair = processClassSegment(segments.get(i));
trees.add(gbtPair.getFirst());
coefficientMaps.add(gbtPair.getSecond());
classLabels.add(extractClassLabel(segments.get(i)));
}
double initialValue = extractInitialValue(segments.get(0));
return MultiClassGradientBoostedTreesModel.create(getMetaDataMapper().getTreeMetaData(), trees, coefficientMaps, initialValue, TreeType.Ordinary, classLabels);
}
Aggregations