Search in sources :

Example 6 with MultiClassGradientBoostedTreesModel

use of org.knime.base.node.mine.treeensemble2.model.MultiClassGradientBoostedTreesModel in project knime-core by knime.

the class LKGradientBoostedTreesLearner method learn.

/**
 * {@inheritDoc}
 *
 * @throws ExecutionException
 * @throws InterruptedException
 */
@Override
public MultiClassGradientBoostedTreesModel learn(final ExecutionMonitor exec) throws CanceledExecutionException, InterruptedException, ExecutionException {
    final TreeData data = getData();
    final TreeTargetNominalColumnData target = (TreeTargetNominalColumnData) data.getTargetColumn();
    final NominalValueRepresentation[] classNomVals = target.getMetaData().getValues();
    final int numClasses = classNomVals.length;
    final String[] classLabels = new String[numClasses];
    final int nrModels = getConfig().getNrModels();
    final int nrRows = target.getNrRows();
    final TreeModelRegression[][] models = new TreeModelRegression[nrModels][numClasses];
    final ArrayList<ArrayList<Map<TreeNodeSignature, Double>>> coefficientMaps = new ArrayList<ArrayList<Map<TreeNodeSignature, Double>>>(nrModels);
    // variables for parallelization
    final ThreadPool tp = KNIMEConstants.GLOBAL_THREAD_POOL;
    final AtomicReference<Throwable> learnThrowableRef = new AtomicReference<Throwable>();
    final int procCount = 3 * Runtime.getRuntime().availableProcessors() / 2;
    exec.setMessage("Transforming problem");
    // transform the original k class classification problem into k regression problems
    final TreeData[] actual = new TreeData[numClasses];
    for (int i = 0; i < numClasses; i++) {
        final double[] newTarget = calculateNewTarget(target, i);
        actual[i] = createNumericDataFromArray(newTarget);
        classLabels[i] = classNomVals[i].getNominalValue();
    }
    final RandomData rd = getConfig().createRandomData();
    final double[][] previousFunctions = new double[numClasses][nrRows];
    TreeNodeSignatureFactory signatureFactory = null;
    final int maxLevels = getConfig().getMaxLevels();
    if (maxLevels < TreeEnsembleLearnerConfiguration.MAX_LEVEL_INFINITE) {
        int capacity = IntMath.pow(2, maxLevels - 1);
        signatureFactory = new TreeNodeSignatureFactory(capacity);
    } else {
        signatureFactory = new TreeNodeSignatureFactory();
    }
    exec.setMessage("Learn trees");
    for (int i = 0; i < nrModels; i++) {
        final Semaphore semaphore = new Semaphore(procCount);
        final ArrayList<Map<TreeNodeSignature, Double>> classCoefficientMaps = new ArrayList<Map<TreeNodeSignature, Double>>(numClasses);
        // prepare calculation of pseudoResiduals
        final double[][] probs = new double[numClasses][nrRows];
        for (int r = 0; r < nrRows; r++) {
            double sumExpF = 0;
            for (int j = 0; j < numClasses; j++) {
                sumExpF += Math.exp(previousFunctions[j][r]);
            }
            for (int j = 0; j < numClasses; j++) {
                probs[j][r] = Math.exp(previousFunctions[j][r]) / sumExpF;
            }
        }
        final Future<?>[] treeCoefficientMapPairs = new Future<?>[numClasses];
        for (int j = 0; j < numClasses; j++) {
            checkThrowable(learnThrowableRef);
            final RandomData rdSingle = TreeEnsembleLearnerConfiguration.createRandomData(rd.nextLong(Long.MIN_VALUE, Long.MAX_VALUE));
            final ExecutionMonitor subExec = exec.createSubProgress(0.0);
            semaphore.acquire();
            treeCoefficientMapPairs[j] = tp.enqueue(new TreeLearnerCallable(rdSingle, probs[j], actual[j], subExec, numClasses, previousFunctions[j], semaphore, learnThrowableRef, signatureFactory));
        }
        for (int j = 0; j < numClasses; j++) {
            checkThrowable(learnThrowableRef);
            semaphore.acquire();
            final Pair<TreeModelRegression, Map<TreeNodeSignature, Double>> pair = (Pair<TreeModelRegression, Map<TreeNodeSignature, Double>>) treeCoefficientMapPairs[j].get();
            models[i][j] = pair.getFirst();
            classCoefficientMaps.add(pair.getSecond());
            semaphore.release();
        }
        checkThrowable(learnThrowableRef);
        coefficientMaps.add(classCoefficientMaps);
        exec.setProgress((double) i / nrModels, "Finished level " + i + "/" + nrModels);
    }
    return MultiClassGradientBoostedTreesModel.createMultiClassGradientBoostedTreesModel(getConfig(), data.getMetaData(), models, data.getTreeType(), 0, numClasses, coefficientMaps, classLabels);
}
Also used : RandomData(org.apache.commons.math.random.RandomData) ArrayList(java.util.ArrayList) ThreadPool(org.knime.core.util.ThreadPool) NominalValueRepresentation(org.knime.base.node.mine.treeensemble2.data.NominalValueRepresentation) Semaphore(java.util.concurrent.Semaphore) TreeNodeSignature(org.knime.base.node.mine.treeensemble2.model.TreeNodeSignature) TreeModelRegression(org.knime.base.node.mine.treeensemble2.model.TreeModelRegression) ExecutionMonitor(org.knime.core.node.ExecutionMonitor) TreeNodeSignatureFactory(org.knime.base.node.mine.treeensemble2.learner.TreeNodeSignatureFactory) Pair(org.knime.core.util.Pair) AtomicReference(java.util.concurrent.atomic.AtomicReference) Future(java.util.concurrent.Future) TreeData(org.knime.base.node.mine.treeensemble2.data.TreeData) HashMap(java.util.HashMap) Map(java.util.Map) TreeTargetNominalColumnData(org.knime.base.node.mine.treeensemble2.data.TreeTargetNominalColumnData)

Example 7 with MultiClassGradientBoostedTreesModel

use of org.knime.base.node.mine.treeensemble2.model.MultiClassGradientBoostedTreesModel in project knime-core by knime.

the class TreeEnsembleModel method load.

public static TreeEnsembleModel load(final InputStream in) throws IOException {
    // wrapping the argument (zip input) stream in a buffered stream
    // reduces read operation from, e.g. 42s to 2s
    TreeModelDataInputStream input = new TreeModelDataInputStream(new BufferedInputStream(new NonClosableInputStream(in)));
    int version = input.readInt();
    if (version > 20160114) {
        throw new IOException("Tree Ensemble version " + version + " not supported");
    }
    byte ensembleType;
    if (version == 20160114) {
        ensembleType = input.readByte();
    } else {
        ensembleType = 'r';
    }
    TreeType type = TreeType.load(input);
    TreeMetaData metaData = TreeMetaData.load(input);
    int nrModels = input.readInt();
    boolean containsClassDistribution;
    if (version == 20121019) {
        containsClassDistribution = true;
    } else {
        containsClassDistribution = input.readBoolean();
    }
    input.setContainsClassDistribution(containsClassDistribution);
    AbstractTreeModel[] models = new AbstractTreeModel[nrModels];
    boolean isRegression = metaData.isRegression();
    if (ensembleType != 'r') {
        isRegression = true;
    }
    final TreeBuildingInterner treeBuildingInterner = new TreeBuildingInterner();
    for (int i = 0; i < nrModels; i++) {
        AbstractTreeModel singleModel;
        try {
            singleModel = isRegression ? TreeModelRegression.load(input, metaData, treeBuildingInterner) : TreeModelClassification.load(input, metaData, treeBuildingInterner);
            if (input.readByte() != 0) {
                throw new IOException("Model not terminated by 0 byte");
            }
        } catch (IOException e) {
            throw new IOException("Can't read tree model " + (i + 1) + "/" + nrModels + ": " + e.getMessage(), e);
        }
        models[i] = singleModel;
    }
    TreeEnsembleModel result;
    switch(ensembleType) {
        case 'r':
            result = new TreeEnsembleModel(metaData, models, type, containsClassDistribution);
            break;
        case 'g':
            result = new GradientBoostingModel(metaData, models, type, containsClassDistribution);
            break;
        case 't':
            result = new GradientBoostedTreesModel(metaData, models, type, containsClassDistribution);
            break;
        case 'm':
            result = new MultiClassGradientBoostedTreesModel(metaData, models, type, containsClassDistribution);
            break;
        default:
            throw new IllegalStateException("Unknown ensemble type: '" + (char) ensembleType + "'");
    }
    result.loadData(input);
    // does not close the method argument stream!!
    input.close();
    return result;
}
Also used : IOException(java.io.IOException) BufferedInputStream(java.io.BufferedInputStream) NonClosableInputStream(org.knime.core.data.util.NonClosableInputStream) TreeMetaData(org.knime.base.node.mine.treeensemble2.data.TreeMetaData)

Example 8 with MultiClassGradientBoostedTreesModel

use of org.knime.base.node.mine.treeensemble2.model.MultiClassGradientBoostedTreesModel 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);
}
Also used : Segmentation(org.dmg.pmml.SegmentationDocument.Segmentation) ArrayList(java.util.ArrayList) TreeNodeSignature(org.knime.base.node.mine.treeensemble2.model.TreeNodeSignature) Segment(org.dmg.pmml.SegmentDocument.Segment) ArrayList(java.util.ArrayList) List(java.util.List)

Example 9 with MultiClassGradientBoostedTreesModel

use of org.knime.base.node.mine.treeensemble2.model.MultiClassGradientBoostedTreesModel in project knime-core by knime.

the class ClassificationGBTModelExporter method addSegmentation.

private void addSegmentation(final MiningModel miningModel, final int c) {
    Segmentation seg = miningModel.addNewSegmentation();
    MultiClassGradientBoostedTreesModel gbt = getGBTModel();
    Collection<TreeModelRegression> trees = IntStream.range(0, gbt.getNrLevels()).mapToObj(i -> gbt.getModel(i, c)).collect(Collectors.toList());
    Collection<Map<TreeNodeSignature, Double>> coefficientMaps = IntStream.range(0, gbt.getNrLevels()).mapToObj(i -> gbt.getCoefficientMap(i, c)).collect(Collectors.toList());
    writeSumSegmentation(seg, trees, coefficientMaps);
}
Also used : IntStream(java.util.stream.IntStream) MININGFUNCTION(org.dmg.pmml.MININGFUNCTION) Enum(org.dmg.pmml.MININGFUNCTION.Enum) Targets(org.dmg.pmml.TargetsDocument.Targets) DATATYPE(org.dmg.pmml.DATATYPE) PMMLMiningSchemaTranslator(org.knime.core.node.port.pmml.PMMLMiningSchemaTranslator) RegressionTable(org.dmg.pmml.RegressionTableDocument.RegressionTable) Output(org.dmg.pmml.OutputDocument.Output) RESULTFEATURE(org.dmg.pmml.RESULTFEATURE) MiningSchema(org.dmg.pmml.MiningSchemaDocument.MiningSchema) Map(java.util.Map) Target(org.dmg.pmml.TargetDocument.Target) FIELDUSAGETYPE(org.dmg.pmml.FIELDUSAGETYPE) TreeNodeSignature(org.knime.base.node.mine.treeensemble2.model.TreeNodeSignature) Collection(java.util.Collection) Segmentation(org.dmg.pmml.SegmentationDocument.Segmentation) RegressionModel(org.dmg.pmml.RegressionModelDocument.RegressionModel) Collectors(java.util.stream.Collectors) MiningField(org.dmg.pmml.MiningFieldDocument.MiningField) OPTYPE(org.dmg.pmml.OPTYPE) MULTIPLEMODELMETHOD(org.dmg.pmml.MULTIPLEMODELMETHOD) NumericPredictor(org.dmg.pmml.NumericPredictorDocument.NumericPredictor) MultiClassGradientBoostedTreesModel(org.knime.base.node.mine.treeensemble2.model.MultiClassGradientBoostedTreesModel) REGRESSIONNORMALIZATIONMETHOD(org.dmg.pmml.REGRESSIONNORMALIZATIONMETHOD) DerivedFieldMapper(org.knime.core.node.port.pmml.preproc.DerivedFieldMapper) MiningModel(org.dmg.pmml.MiningModelDocument.MiningModel) Segment(org.dmg.pmml.SegmentDocument.Segment) OutputField(org.dmg.pmml.OutputFieldDocument.OutputField) TreeModelRegression(org.knime.base.node.mine.treeensemble2.model.TreeModelRegression) Segmentation(org.dmg.pmml.SegmentationDocument.Segmentation) MultiClassGradientBoostedTreesModel(org.knime.base.node.mine.treeensemble2.model.MultiClassGradientBoostedTreesModel) Map(java.util.Map) TreeModelRegression(org.knime.base.node.mine.treeensemble2.model.TreeModelRegression)

Example 10 with MultiClassGradientBoostedTreesModel

use of org.knime.base.node.mine.treeensemble2.model.MultiClassGradientBoostedTreesModel in project knime-core by knime.

the class GradientBoostingClassificationPredictorNodeModel method configure.

/**
 * {@inheritDoc}
 */
@Override
protected PortObjectSpec[] configure(final PortObjectSpec[] inSpecs) throws InvalidSettingsException {
    TreeEnsembleModelPortObjectSpec modelSpec = (TreeEnsembleModelPortObjectSpec) inSpecs[0];
    String targetColName = modelSpec.getTargetColumn().getName();
    if (m_configuration == null) {
        m_configuration = TreeEnsemblePredictorConfiguration.createDefault(false, targetColName);
    } else if (!m_configuration.isChangePredictionColumnName()) {
        m_configuration.setPredictionColumnName(TreeEnsemblePredictorConfiguration.getPredictColumnName(targetColName));
    }
    modelSpec.assertTargetTypeMatches(false);
    DataTableSpec dataSpec = (DataTableSpec) inSpecs[1];
    GradientBoostingPredictor<MultiClassGradientBoostedTreesModel> predictor = new GradientBoostingPredictor<>(null, modelSpec, dataSpec, m_configuration);
    ColumnRearranger rearranger = predictor.getPredictionRearranger();
    return new PortObjectSpec[] { rearranger.createSpec() };
}
Also used : DataTableSpec(org.knime.core.data.DataTableSpec) ColumnRearranger(org.knime.core.data.container.ColumnRearranger) TreeEnsembleModelPortObjectSpec(org.knime.base.node.mine.treeensemble2.model.TreeEnsembleModelPortObjectSpec) MultiClassGradientBoostedTreesModel(org.knime.base.node.mine.treeensemble2.model.MultiClassGradientBoostedTreesModel) GradientBoostingPredictor(org.knime.base.node.mine.treeensemble2.node.gradientboosting.predictor.GradientBoostingPredictor) TreeEnsembleModelPortObjectSpec(org.knime.base.node.mine.treeensemble2.model.TreeEnsembleModelPortObjectSpec) PortObjectSpec(org.knime.core.node.port.PortObjectSpec)

Aggregations

MultiClassGradientBoostedTreesModel (org.knime.base.node.mine.treeensemble2.model.MultiClassGradientBoostedTreesModel)7 TreeEnsembleModelPortObjectSpec (org.knime.base.node.mine.treeensemble2.model.TreeEnsembleModelPortObjectSpec)5 DataTableSpec (org.knime.core.data.DataTableSpec)5 ColumnRearranger (org.knime.core.data.container.ColumnRearranger)4 ArrayList (java.util.ArrayList)3 Segmentation (org.dmg.pmml.SegmentationDocument.Segmentation)3 GradientBoostingModelPortObject (org.knime.base.node.mine.treeensemble2.model.GradientBoostingModelPortObject)3 TreeNodeSignature (org.knime.base.node.mine.treeensemble2.model.TreeNodeSignature)3 GradientBoostingPredictor (org.knime.base.node.mine.treeensemble2.node.gradientboosting.predictor.GradientBoostingPredictor)3 Map (java.util.Map)2 Segment (org.dmg.pmml.SegmentDocument.Segment)2 GradientBoostedTreesModel (org.knime.base.node.mine.treeensemble2.model.GradientBoostedTreesModel)2 TreeModelRegression (org.knime.base.node.mine.treeensemble2.model.TreeModelRegression)2 BufferedInputStream (java.io.BufferedInputStream)1 IOException (java.io.IOException)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Future (java.util.concurrent.Future)1 Semaphore (java.util.concurrent.Semaphore)1