From 5c49882b22b3a8314c6dfcc8c026456c887262fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 14:33:22 +0100 Subject: [PATCH 01/33] Added some classifiers for multi-label classification --- .../samoa/instances/MultiLabelPrediction.java | 8 + .../LocalMultiTargetClassifier.java | 145 +++++++++ .../classifiers/multilabel/meta/MTOzaBag.java | 107 +++++++ .../multilabel/trees/ISOUPOptionTree.java | 277 ++++++++++++++++++ .../tasks/EvaluatePrequentialMultiTarget.java | 7 +- 5 files changed, 542 insertions(+), 2 deletions(-) create mode 100644 moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index d59395ce4..ea4eaf26b 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -28,6 +28,10 @@ public MultiLabelPrediction(int numOutputAttributes) { for (int i=0; i classifiers = null; + LinkedList headers = null; + + @Override + public boolean isRandomizable() { + // TODO Auto-generated method stub + return true; + } + + private InstancesHeader getHeader(int target) { + if (headers == null) + makeHeaders(); + return headers.get(target); + + } + + private void makeHeaders() { + if (headers == null) { + headers = new LinkedList(); + for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { + List attributes = new LinkedList(); + List indexValues = new LinkedList(); + for (int i = 0; i < getModelContext().numInputAttributes(); i++) { + attributes.add(getModelContext().inputAttribute(i)); + indexValues.add(i); + } + attributes.add(getModelContext().outputAttribute(target)); + indexValues.add(getModelContext().numInputAttributes()); + InstancesHeader STHeader = new InstancesHeader(); + STHeader.setAttributes(attributes, indexValues); + STHeader.setClassIndex(getModelContext().numInputAttributes()); + headers.add(STHeader); + } + } + } + + private Instance getSTInstance(MultiLabelInstance inst, int target) { + double[] instanceData = new double[getModelContext().numInputAttributes() + 1]; + for (int i = 0; i < inst.numInputAttributes(); i++) + instanceData[i] = inst.valueInputAttribute(i); + instanceData[inst.numInputAttributes()] = inst.valueOutputAttribute(target); + DenseInstance STInst = new DenseInstance(inst.weight(), instanceData); + STInst.setDataset(getHeader(target)); + return STInst; + } + + @Override + public void trainOnInstanceImpl(MultiLabelInstance instance) { + // TODO Auto-generated method stub + initializeClassifiers(); + + for (int j = 0; j < instance.numberOutputTargets(); j++) { + Instance STInst = getSTInstance(instance, j); + + classifiers.get(j).trainOnInstance(STInst); + } + } + + @Override + public Prediction getPredictionForInstance(MultiLabelInstance inst) { + initializeClassifiers(); + + MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); + for (int j = 0; j < inst.numberOutputTargets(); j++) { + Instance STInst = getSTInstance(inst, j); + + prediction.setVote(j, 1, classifiers.get(j).getVotesForInstance(STInst)[0]); + } + return prediction; + } + + @Override + public void resetLearningImpl() { + classifiers = null; + + } + + public void initializeClassifiers() { + this.classifierRandom.setSeed(1234); + if (classifiers == null) { + makeHeaders(); + classifiers = new LinkedList(); + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + Classifier learner = (Classifier) getPreparedClassOption(this.classifierOption); + classifiers.add(learner); + learner.resetLearning(); + ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; + learner.setModelContext(getHeader(i)); + } + } + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + for (int i =0; i < getModelContext().numOutputAttributes(); i++) { + out.append(getModelContext().outputAttribute(i).name() + '\n'); + ((AbstractClassifier) classifiers.get(i)).getModelDescription(out, indent); + } + + } + +} + \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java new file mode 100644 index 000000000..e2db81e43 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java @@ -0,0 +1,107 @@ +/* + * MLOzaBag.java + * Copyright (C) 2012 University of Waikato, Hamilton, New Zealand + * @author Jesse Read (jesse@tsc.uc3m.es) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.classifiers.multilabel.meta; + +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +import com.yahoo.labs.samoa.instances.Prediction; + +import moa.classifiers.Classifier; +import moa.classifiers.MultiLabelLearner; +import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.meta.OzaBag; +import moa.core.DoubleVector; +import moa.core.Example; +import moa.options.ClassOption; + +/** + * OzaBag for Multi-label data. + * + * @author Jesse Read (jesse@tsc.uc3m.es) + * @version $Revision: 1 $ + */ +public class MTOzaBag extends OzaBag implements MultiLabelLearner, MultiTargetRegressor { + + public MTOzaBag() { + super(); + this.baseLearnerOption = new ClassOption("baseLearner", 'l', + "Classifier to train.", MultiLabelLearner.class, "multilabel.trees.ISOUPTree"); + } + + @Override + public void resetLearningImpl() { + this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; + MultiLabelLearner baseLearner = (MultiLabelLearner) getPreparedClassOption(this.baseLearnerOption); + baseLearner.resetLearning(); + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i] = baseLearner.copy(); + } + } + + @Override + public void setModelContext(InstancesHeader raw_header) { + + //set the multilabel model context + this.modelContext = raw_header; + + // reset ensemble + this.resetLearningImpl(); + + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i].setModelContext(raw_header); + this.ensemble[i].resetLearning(); + } + } + + @Override // @note don't need this here + public boolean isRandomizable() { + return true; + } + + public Prediction getPredictionForInstance(MultiLabelInstance inst) { + DoubleVector[][] predictions = new DoubleVector[this.ensemble.length][getModelContext().numOutputAttributes()]; + for (int i = 0; i < this.ensemble.length; i++) { + Prediction basePrediction = this.ensemble[i].getPredictionForInstance(inst); + predictions[i] = ((MultiLabelPrediction) basePrediction).getPrediction(); + } + DoubleVector[] prediction = new DoubleVector[getModelContext().numOutputAttributes()]; + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + prediction[j] = new DoubleVector(); + for (int i = 0; i < this.ensemble.length; i++) { + prediction[j].addValues(predictions[i][j]); + } + prediction[j].scaleValues(1.0 / this.ensemble.length); + } + return new MultiLabelPrediction(prediction); + } + + @Override + public void trainOnInstanceImpl(MultiLabelInstance instance) { + trainOnInstanceImpl((Instance) instance); + } + + @Override + public Prediction getPredictionForInstance(Example example) { + return getPredictionForInstance((MultiLabelInstance)example.getData()); + } + +} diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java new file mode 100644 index 000000000..93de284a0 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java @@ -0,0 +1,277 @@ +package moa.classifiers.multilabel.trees; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.MultiLabelInstance; + +import moa.classifiers.multilabel.trees.ISOUPTree.LeafNode; +import moa.classifiers.multilabel.trees.ISOUPTree.Node; +import moa.classifiers.multilabel.trees.ISOUPTree.SplitNode; +import moa.classifiers.trees.ORTO; +import moa.classifiers.trees.FIMTDD.InnerNode; +import moa.classifiers.trees.ORTO.OptionNode; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.Measurement; + +public class ISOUPOptionTree extends ISOUPTree { + + private static final long serialVersionUID = 1L; + + private int innerNodeCount = 0; + private int optionNodeCount = 0; + + private int numTrees = 1; + + //region ================ OPTIONS ================ + + public IntOption maxTreesOption = new IntOption( + "maxTrees", + 'm', + "The maximum number of trees contained in the option tree.", + 10, 1, Integer.MAX_VALUE); + + public IntOption maxOptionLevelOption = new IntOption( + "maxOptionLevel", + 'x', + "The maximal depth at which option nodes can be created.", + 10, 0, Integer.MAX_VALUE); + + public FloatOption optionDecayFactorOption = new FloatOption( + "optionDecayFactor", + 'z', + "The option decay factor that determines how many options can be selected at a given level.", + 0.9, 0.0, 1.0); + + public MultiChoiceOption optionNodeAggregationOption = new MultiChoiceOption( + "optionNodeAggregation", + 'o', + "The aggregation method used to combine predictions in option nodes.", + new String[]{"average", "bestTree"}, new String[]{"Average", "Best tree"}, 0); + + public FloatOption optionFadingFactorOption = new FloatOption( + "optionFadingFactor", + 'q', + "The fading factor used for comparing subtrees of an option node.", + 0.9995, 0.0, 1.0); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public static class OptionNode extends InnerNode { + protected AutoExpandVector optionFFSSL; + protected AutoExpandVector optionFFSeen; + + public OptionNode(ISOUPTree tree) { + super(tree); + } + + public void resetFF() { + optionFFSSL = new AutoExpandVector(); + optionFFSeen = new AutoExpandVector(); + for (int i = 0; i < numChildren(); i++) { + optionFFSSL.set(i, new DoubleVector()); + optionFFSeen.set(i, new DoubleVector()); + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + optionFFSSL.get(i).setValue(j, 0.0); + optionFFSeen.get(i).setValue(j, 0.0); + } + } + } + + public int getNumSubtrees() { + int num = 0; + for (Node child : children) { + num += child.getNumSubtrees(); + } + return num; + } + + public double[] getPrediction(MultiLabelInstance inst) { + double[][] predictions = new double[numChildren()][tree.getModelContext().numOutputAttributes()]; + for (int i = 0; i < numChildren(); i++) { + predictions[i] = getChild(i).getPrediction(inst); + } + return aggregate(predictions); + } + + private double[] aggregate(double[][] predictions) { + if (((ISOUPOptionTree) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average + double[] sums = new double[tree.getModelContext().numOutputAttributes()]; + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + for (int i = 0; i < numChildren(); i++) { + sums[j] += predictions[i][j]; + } + sums[j] = sums[j] / numChildren(); + } + return sums; + } else if (((ISOUPOptionTree) tree).optionNodeAggregationOption.getChosenIndex() == 1) { + int d = directionForBestTree(); + return predictions[d]; + } else { + return new double[] {}; + } + } + + public int directionForBestTree() { + int d = 0; + double min = Double.MAX_VALUE; + for (int i = 0; i < numChildren(); i++) { + double avg = 0.0; + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + avg += getFFRatio(i, j); + } + avg /= tree.getModelContext().numOutputAttributes(); + if (avg < min) { + min = avg; + d = i; + } + } + return d; + } + + public double getFFRatio(int childIndex, int targetIndex) { + return optionFFSSL.get(childIndex).getValue(targetIndex) / optionFFSeen.get(childIndex).getValue(targetIndex); + } + + protected boolean skipInLevelCount() { + return true; + } + } + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + public String getPurposeString() { + return "Implementation of the ORTO tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + super.resetLearningImpl(); + this.innerNodeCount = 0; + this.optionNodeCount = 0; + } + + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("number of subtrees", this.numTrees), + //new Measurement("tree size (nodes)", this.leafNodeCount + this.innerNodeCount), + //new Measurement("tree size (leaves)", this.leafNodeCount), + new Measurement("number of option nodes", this.optionNodeCount),}; + } + + @Override + public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + if (node instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) node, prediction, normalError, growthAllowed, inAlternate); + } else { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } else { + currentNode.examplesSeen += inst.weight(); +// if (!inAlternate && iNode.alternateTree != null) { +// boolean altTree = true; +// double lossO = Math.pow(inst.classValue() - prediction, 2); +// double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); +// +// iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; +// iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; +// iNode.lossExamplesSeen++; +// +// double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); +// double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; +// iNode.lossSumQi += Qi; +// iNode.lossNumQiTests += 1; +// double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; +// +// if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { +// iNode.previousWeight = iNode.lossExamplesSeen; +// if (Qi > 0) { +// // Switch the subtrees +// Node parent = currentNode.parent; +// +// if (parent != null) { +// Node replacementTree = iNode.alternateTree; +// parent.setChild(parent.getChildIndex(iNode), replacementTree); +// if (growthAllowed) replacementTree.restartChangeDetection(); +// } else { +// treeRoot = iNode.alternateTree; +// treeRoot.restartChangeDetection(); +// } +// optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); +// removeExcessTrees(); +// +// currentNode = iNode.alternateTree; +// currentNode.originalNode = null; +// altTree = false; +// } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { +// // Remove the alternate tree +// iNode.alternateTree = null; +// if (growthAllowed) iNode.restartChangeDetection(); +// altTree = false; +// } +// } +// if (altTree) { +// growthAllowed = false; // this is the growth of the original tree +// processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree +// } else if (currentNode instanceof OptionNode) { +// // this happens when an option node is switched into the tree +// for (Node child : ((OptionNode) currentNode).children) { +// processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); +// } +// break; +// } +// } + +// if (iNode.changeDetection && !inAlternate) { +// if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { +// iNode.initializeAlternateTree(); +// } +// } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); + } else if (currentNode instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) currentNode, prediction, normalError, growthAllowed, inAlternate); + break; + } + } + } + } + + } + + public void processInstanceOptionNode(MultiLabelInstance inst, OptionNode node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { +// if (node.changeDetection) { +// double error = Math.abs(prediction - inst.classValue()); +// node.sumOfAbsErrors += error; +// +// if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { +// node.initializeAlternateTree(); +// } +// } + + for (Node child : node.children) { + int i = node.getChildIndex(child); + double[] childPrediction = child.getPrediction(inst); + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + node.optionFFSeen.get(i).setValue(j, node.optionFFSeen.get(i).getValue(j) * optionFadingFactorOption.getValue() + 1); + node.optionFFSSL.get(i).setValue(j, node.optionFFSSL.get(i).getValue(j) * optionFadingFactorOption.getValue() + Math.pow(childPrediction[j] - inst.valueOutputAttribute(j), 2)); + } + } + + for (Node child : node.children) { + processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); + } + } + + //endregion ================ METHODS ================ + +} diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index eba9b70b5..55ee5302d 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -202,8 +202,11 @@ protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { Prediction prediction = learner.getPredictionForInstance(testInst); // Output prediction if (outputPredictionFile != null) { - double trueClass = ((Instance) trainInst.getData()).classValue(); - outputPredictionResultStream.println(prediction + "," + trueClass); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); } //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); From 6715ccf4064e5ee5a910ca567c6f091f6a8ff461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 14:43:19 +0100 Subject: [PATCH 02/33] Updates to multi-label methods --- .../samoa/instances/MultiLabelPrediction.java | 8 + .../NumericAttributeBinaryTest.java | 2 +- .../LocalMultiTargetClassifier.java | 145 ++ .../splitcriteria/ICVarianceReduction.java | 113 + .../classifiers/multilabel/meta/MTOzaBag.java | 125 ++ .../multilabel/trees/ISOUPOptionTree.java | 277 +++ .../multilabel/trees/ISOUPTree.java | 1515 +++++++++++++ .../java/moa/classifiers/trees/FIMTDD.java | 1912 +++++++++-------- .../main/java/moa/classifiers/trees/ORTO.java | 1838 +++++----------- 9 files changed, 3673 insertions(+), 2262 deletions(-) create mode 100644 moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index d59395ce4..7e821ce9f 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -29,6 +29,10 @@ public MultiLabelPrediction(int numOutputAttributes) { prediction[i]= new DoubleVector(); } + public MultiLabelPrediction(DoubleVector[] prediction) { + this.prediction = prediction; + } + @Override public int numOutputAttributes() { return prediction.length; @@ -95,5 +99,9 @@ public boolean hasVotesForAttribute(int outputAttributeIndex) { public int size() { return prediction.length; } + + public DoubleVector[] getPrediction() { + return prediction; + } } diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java index 1b67102b9..87a3f2e0e 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java @@ -52,7 +52,7 @@ public int branchForInstance(Instance inst) { if (inst.isMissing(instAttIndex)) { return -1; } - double v = inst.value(instAttIndex); + double v = inst.valueInputAttribute(instAttIndex); if (v == this.attValue) { return this.equalsPassesTest ? 0 : 1; } diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java new file mode 100644 index 000000000..6d79d6dab --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -0,0 +1,145 @@ +package moa.classifiers.multilabel; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Vector; + +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +import com.yahoo.labs.samoa.instances.Prediction; + +import moa.classifiers.AbstractClassifier; +import moa.classifiers.AbstractMultiLabelLearner; +import moa.classifiers.Classifier; +import moa.classifiers.MultiLabelClassifier; +import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.classifiers.trees.FIMTDD; +import moa.core.DoubleVector; +import moa.core.Measurement; +import moa.learners.Learner; +import moa.options.ClassOption; + +public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner + implements MultiLabelClassifier, MultiTargetRegressor { + + public ClassOption classifierOption = new ClassOption( + "classifier", + 'c', + "Classifier to use.", + Classifier.class, + "moa.classifiers.trees.FIMTDD"); + + ArrayList classifiers = null; + ArrayList headers = null; + + @Override + public boolean isRandomizable() { + // TODO Auto-generated method stub + return true; + } + + private InstancesHeader getHeader(int target) { + if (headers == null) + makeHeaders(); + return headers.get(target); + + } + + private void makeHeaders() { + if (headers == null) { + headers = new ArrayList(); + for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { + List attributes = new LinkedList(); + List indexValues = new LinkedList(); + for (int i = 0; i < getModelContext().numInputAttributes(); i++) { + attributes.add(getModelContext().inputAttribute(i)); + indexValues.add(i); + } + attributes.add(getModelContext().outputAttribute(target)); + indexValues.add(getModelContext().numInputAttributes()); + InstancesHeader STHeader = new InstancesHeader(); + STHeader.setAttributes(attributes, indexValues); + STHeader.setClassIndex(getModelContext().numInputAttributes()); + headers.add(STHeader); + } + } + } + + private Instance getSTInstance(MultiLabelInstance inst, int target) { + double[] instanceData = new double[getModelContext().numInputAttributes() + 1]; + for (int i = 0; i < inst.numInputAttributes(); i++) + instanceData[i] = inst.valueInputAttribute(i); + instanceData[inst.numInputAttributes()] = inst.valueOutputAttribute(target); + DenseInstance STInst = new DenseInstance(inst.weight(), instanceData); + STInst.setDataset(getHeader(target)); + return STInst; + } + + @Override + public void trainOnInstanceImpl(MultiLabelInstance instance) { + // TODO Auto-generated method stub + initializeClassifiers(); + + for (int j = 0; j < instance.numberOutputTargets(); j++) { + Instance STInst = getSTInstance(instance, j); + + classifiers.get(j).trainOnInstance(STInst); + } + } + + @Override + public Prediction getPredictionForInstance(MultiLabelInstance inst) { + initializeClassifiers(); + + MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); + for (int j = 0; j < inst.numberOutputTargets(); j++) { + Instance STInst = getSTInstance(inst, j); + prediction.setVote(j, 1, classifiers.get(j).getVotesForInstance(STInst)[0]); + } + return prediction; + } + + @Override + public void resetLearningImpl() { + classifiers = null; + + } + + public void initializeClassifiers() { + this.classifierRandom.setSeed(1234); + if (classifiers == null) { + makeHeaders(); + classifiers = new ArrayList(); + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + Classifier learner = ((Classifier) getPreparedClassOption(this.classifierOption)).copy(); + classifiers.add(learner); + learner.resetLearning(); + ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; + learner.setModelContext(getHeader(i)); + } + } + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + for (int i =0; i < getModelContext().numOutputAttributes(); i++) { + out.append(getModelContext().outputAttribute(i).name() + '\n'); + ((AbstractClassifier) classifiers.get(i)).getModelDescription(out, indent); + } + + } + +} + \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java new file mode 100644 index 000000000..c3f2299d2 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java @@ -0,0 +1,113 @@ +package moa.classifiers.multilabel.core.splitcriteria; + +import moa.classifiers.rules.core.Utils; +import moa.core.DoubleVector; +import moa.core.ObjectRepository; +import moa.options.AbstractOptionHandler; +import moa.tasks.TaskMonitor; +import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion;; + + + +public class ICVarianceReduction extends AbstractOptionHandler implements MultiLabelSplitCriterion { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + public double getMeritOfSplit(DoubleVector[] preSplitDist, DoubleVector[][] postSplitDists) { + double error=0; + int numOutputs=preSplitDist.length; + for (int i=0; i 1) { + return (squares - sum * sum / n) / (n - 1); + } + return 0; + } + + private double computeVariance(DoubleVector v) { + return computeVariance(v.getValue(0), v.getValue(1), v.getValue(2)); + } + + @Override + public double [] getBranchesSplitMerits(DoubleVector[][] postSplitDists){ + int numOutputs=postSplitDists.length; + int numBranches=postSplitDists[0].length; + double [] merits=new double[numBranches]; + for(int j=0; j0) + merits[i]-=branchMeritsOutput[i]; + else + merits[i]=Double.MIN_VALUE; + } + } + return merits; + } + + protected double getMeritOfSplitForOutput(DoubleVector[] preSplitDist, DoubleVector[][] postSplitDists, int outputAttributeIndex){ + return getMeritOfSplitForOutput(preSplitDist[outputAttributeIndex],postSplitDists[outputAttributeIndex]); + } + + protected double getMeritOfSplitForOutput(DoubleVector preSplitDist, DoubleVector[] postSplitDists) { + double merit=0; + //count number of branches with weightSeen higher than threshold + int count = 0; + for(int i = 0; i < postSplitDists.length; i++) + if(postSplitDists[i].getValue(0) >=0.05*preSplitDist.getValue(0)) + count = count +1; + //Consider split if all branches have required weight seen + if(count == postSplitDists.length){ + double varPreSplit=computeVariance(preSplitDist); + double sumVarPostSplit=0; + double weightTotal=0; + for (int i=0; i0) + sumVarPostSplit+=(postSplitDists[i].getValue(0)/weightTotal*variances[i]); //weight variance + merit= 1 - sumVarPostSplit / varPreSplit; + } + /*if(merit<0 || merit>1) + System.out.println("out of range");*/ + return merit; + } + + public double getRangeOfMerit(DoubleVector [] preSplitDist) { + return 1; + } + + + + @Override + public void getDescription(StringBuilder sb, int indent) { + + } + + @Override + protected void prepareForUseImpl(TaskMonitor monitor, + ObjectRepository repository) { + } + + +} diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java new file mode 100644 index 000000000..2594f61be --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java @@ -0,0 +1,125 @@ +/* + * MLOzaBag.java + * Copyright (C) 2012 University of Waikato, Hamilton, New Zealand + * @author Jesse Read (jesse@tsc.uc3m.es) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.classifiers.multilabel.meta; + +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +import com.yahoo.labs.samoa.instances.Prediction; + +import moa.classifiers.Classifier; +import moa.classifiers.MultiLabelLearner; +import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.meta.OzaBag; +import moa.core.DoubleVector; +import moa.core.Example; +import moa.options.ClassOption; + +/** + * OzaBag for Multi-label data. + * + * @author Jesse Read (jesse@tsc.uc3m.es) + * @version $Revision: 1 $ + */ +public class MTOzaBag extends OzaBag implements MultiLabelLearner, MultiTargetRegressor { + + public MTOzaBag() { + super(); + this.baseLearnerOption = new ClassOption("baseLearner", 'l', + "Classifier to train.", MultiLabelLearner.class, "multilabel.trees.ISOUPTree"); + } + + @Override + public void resetLearningImpl() { + this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; + MultiLabelLearner baseLearner = (MultiLabelLearner) getPreparedClassOption(this.baseLearnerOption); + baseLearner.resetLearning(); + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i] = baseLearner.copy(); + } + } + + @Override + public void setModelContext(InstancesHeader raw_header) { + + //set the multilabel model context + this.modelContext = raw_header; + + // reset ensemble + this.resetLearningImpl(); + + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i].setModelContext(raw_header); + this.ensemble[i].resetLearning(); + } + } + + @Override // @note don't need this here + public boolean isRandomizable() { + return true; + } + + public Prediction getPredictionForInstance(MultiLabelInstance inst) { + DoubleVector[][] predictions = new DoubleVector[this.ensemble.length][getModelContext().numOutputAttributes()]; + for (int i = 0; i < this.ensemble.length; i++) { + Prediction basePrediction = this.ensemble[i].getPredictionForInstance(inst); + predictions[i] = ((MultiLabelPrediction) basePrediction).getPrediction(); + } + DoubleVector[] prediction = new DoubleVector[getModelContext().numOutputAttributes()]; + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + prediction[j] = new DoubleVector(); + for (int i = 0; i < this.ensemble.length; i++) { + prediction[j].addValues(predictions[i][j]); + } + prediction[j].scaleValues(1.0 / this.ensemble.length); + } + return new MultiLabelPrediction(prediction); + } + + public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) { + int actual = Math.max(1, Math.min(n, this.ensemble.length)); + DoubleVector[][] predictions = new DoubleVector[actual][getModelContext().numOutputAttributes()]; + for (int i = 0; i < actual; i++) { + Prediction basePrediction = this.ensemble[i].getPredictionForInstance(inst); + predictions[i] = ((MultiLabelPrediction) basePrediction).getPrediction(); + } + DoubleVector[] prediction = new DoubleVector[getModelContext().numOutputAttributes()]; + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + prediction[j] = new DoubleVector(); + for (int i = 0; i < actual; i++) { + prediction[j].addValues(predictions[i][j]); + } + prediction[j].scaleValues(1.0 / actual); + } + return new MultiLabelPrediction(prediction); + } + + @Override + public void trainOnInstanceImpl(MultiLabelInstance instance) { + trainOnInstanceImpl((Instance) instance); + } + + @Override + public Prediction getPredictionForInstance(Example example) { + return getPredictionForInstance((MultiLabelInstance)example.getData()); + } + +} diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java new file mode 100644 index 000000000..93de284a0 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java @@ -0,0 +1,277 @@ +package moa.classifiers.multilabel.trees; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.MultiLabelInstance; + +import moa.classifiers.multilabel.trees.ISOUPTree.LeafNode; +import moa.classifiers.multilabel.trees.ISOUPTree.Node; +import moa.classifiers.multilabel.trees.ISOUPTree.SplitNode; +import moa.classifiers.trees.ORTO; +import moa.classifiers.trees.FIMTDD.InnerNode; +import moa.classifiers.trees.ORTO.OptionNode; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.Measurement; + +public class ISOUPOptionTree extends ISOUPTree { + + private static final long serialVersionUID = 1L; + + private int innerNodeCount = 0; + private int optionNodeCount = 0; + + private int numTrees = 1; + + //region ================ OPTIONS ================ + + public IntOption maxTreesOption = new IntOption( + "maxTrees", + 'm', + "The maximum number of trees contained in the option tree.", + 10, 1, Integer.MAX_VALUE); + + public IntOption maxOptionLevelOption = new IntOption( + "maxOptionLevel", + 'x', + "The maximal depth at which option nodes can be created.", + 10, 0, Integer.MAX_VALUE); + + public FloatOption optionDecayFactorOption = new FloatOption( + "optionDecayFactor", + 'z', + "The option decay factor that determines how many options can be selected at a given level.", + 0.9, 0.0, 1.0); + + public MultiChoiceOption optionNodeAggregationOption = new MultiChoiceOption( + "optionNodeAggregation", + 'o', + "The aggregation method used to combine predictions in option nodes.", + new String[]{"average", "bestTree"}, new String[]{"Average", "Best tree"}, 0); + + public FloatOption optionFadingFactorOption = new FloatOption( + "optionFadingFactor", + 'q', + "The fading factor used for comparing subtrees of an option node.", + 0.9995, 0.0, 1.0); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public static class OptionNode extends InnerNode { + protected AutoExpandVector optionFFSSL; + protected AutoExpandVector optionFFSeen; + + public OptionNode(ISOUPTree tree) { + super(tree); + } + + public void resetFF() { + optionFFSSL = new AutoExpandVector(); + optionFFSeen = new AutoExpandVector(); + for (int i = 0; i < numChildren(); i++) { + optionFFSSL.set(i, new DoubleVector()); + optionFFSeen.set(i, new DoubleVector()); + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + optionFFSSL.get(i).setValue(j, 0.0); + optionFFSeen.get(i).setValue(j, 0.0); + } + } + } + + public int getNumSubtrees() { + int num = 0; + for (Node child : children) { + num += child.getNumSubtrees(); + } + return num; + } + + public double[] getPrediction(MultiLabelInstance inst) { + double[][] predictions = new double[numChildren()][tree.getModelContext().numOutputAttributes()]; + for (int i = 0; i < numChildren(); i++) { + predictions[i] = getChild(i).getPrediction(inst); + } + return aggregate(predictions); + } + + private double[] aggregate(double[][] predictions) { + if (((ISOUPOptionTree) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average + double[] sums = new double[tree.getModelContext().numOutputAttributes()]; + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + for (int i = 0; i < numChildren(); i++) { + sums[j] += predictions[i][j]; + } + sums[j] = sums[j] / numChildren(); + } + return sums; + } else if (((ISOUPOptionTree) tree).optionNodeAggregationOption.getChosenIndex() == 1) { + int d = directionForBestTree(); + return predictions[d]; + } else { + return new double[] {}; + } + } + + public int directionForBestTree() { + int d = 0; + double min = Double.MAX_VALUE; + for (int i = 0; i < numChildren(); i++) { + double avg = 0.0; + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + avg += getFFRatio(i, j); + } + avg /= tree.getModelContext().numOutputAttributes(); + if (avg < min) { + min = avg; + d = i; + } + } + return d; + } + + public double getFFRatio(int childIndex, int targetIndex) { + return optionFFSSL.get(childIndex).getValue(targetIndex) / optionFFSeen.get(childIndex).getValue(targetIndex); + } + + protected boolean skipInLevelCount() { + return true; + } + } + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + public String getPurposeString() { + return "Implementation of the ORTO tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + super.resetLearningImpl(); + this.innerNodeCount = 0; + this.optionNodeCount = 0; + } + + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("number of subtrees", this.numTrees), + //new Measurement("tree size (nodes)", this.leafNodeCount + this.innerNodeCount), + //new Measurement("tree size (leaves)", this.leafNodeCount), + new Measurement("number of option nodes", this.optionNodeCount),}; + } + + @Override + public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + if (node instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) node, prediction, normalError, growthAllowed, inAlternate); + } else { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } else { + currentNode.examplesSeen += inst.weight(); +// if (!inAlternate && iNode.alternateTree != null) { +// boolean altTree = true; +// double lossO = Math.pow(inst.classValue() - prediction, 2); +// double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); +// +// iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; +// iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; +// iNode.lossExamplesSeen++; +// +// double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); +// double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; +// iNode.lossSumQi += Qi; +// iNode.lossNumQiTests += 1; +// double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; +// +// if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { +// iNode.previousWeight = iNode.lossExamplesSeen; +// if (Qi > 0) { +// // Switch the subtrees +// Node parent = currentNode.parent; +// +// if (parent != null) { +// Node replacementTree = iNode.alternateTree; +// parent.setChild(parent.getChildIndex(iNode), replacementTree); +// if (growthAllowed) replacementTree.restartChangeDetection(); +// } else { +// treeRoot = iNode.alternateTree; +// treeRoot.restartChangeDetection(); +// } +// optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); +// removeExcessTrees(); +// +// currentNode = iNode.alternateTree; +// currentNode.originalNode = null; +// altTree = false; +// } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { +// // Remove the alternate tree +// iNode.alternateTree = null; +// if (growthAllowed) iNode.restartChangeDetection(); +// altTree = false; +// } +// } +// if (altTree) { +// growthAllowed = false; // this is the growth of the original tree +// processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree +// } else if (currentNode instanceof OptionNode) { +// // this happens when an option node is switched into the tree +// for (Node child : ((OptionNode) currentNode).children) { +// processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); +// } +// break; +// } +// } + +// if (iNode.changeDetection && !inAlternate) { +// if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { +// iNode.initializeAlternateTree(); +// } +// } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); + } else if (currentNode instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) currentNode, prediction, normalError, growthAllowed, inAlternate); + break; + } + } + } + } + + } + + public void processInstanceOptionNode(MultiLabelInstance inst, OptionNode node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { +// if (node.changeDetection) { +// double error = Math.abs(prediction - inst.classValue()); +// node.sumOfAbsErrors += error; +// +// if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { +// node.initializeAlternateTree(); +// } +// } + + for (Node child : node.children) { + int i = node.getChildIndex(child); + double[] childPrediction = child.getPrediction(inst); + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + node.optionFFSeen.get(i).setValue(j, node.optionFFSeen.get(i).getValue(j) * optionFadingFactorOption.getValue() + 1); + node.optionFFSSL.get(i).setValue(j, node.optionFFSSL.get(i).getValue(j) * optionFadingFactorOption.getValue() + Math.pow(childPrediction[j] - inst.valueOutputAttribute(j), 2)); + } + } + + for (Node child : node.children) { + processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); + } + } + + //endregion ================ METHODS ================ + +} diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java new file mode 100644 index 000000000..bc01e6471 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -0,0 +1,1515 @@ +/* + * FIMTDDMultilabel.java + * Copyright (C) 2014 Jožef Stefan Institute, Ljubljana, Slovenia + * @author Aljaž Osojnik + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +/* Project MAESTRA (Learning from Massive, Incompletely annotated, and Structured Data) + * + * Contact: saso.dzeroski@ijs.si + */ + +package moa.classifiers.multilabel.trees; + + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +import com.yahoo.labs.samoa.instances.Prediction; + +import moa.AbstractMOAObject; +import moa.classifiers.AbstractMultiLabelLearner; +import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.multilabel.core.splitcriteria.ICVarianceReduction; +import moa.classifiers.rules.core.Predicate; +import moa.classifiers.rules.multilabel.attributeclassobservers.AttributeStatisticsObserver; +import moa.classifiers.rules.multilabel.attributeclassobservers.MultiLabelBSTree; +import moa.classifiers.rules.multilabel.attributeclassobservers.MultiLabelNominalAttributeObserver; +import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; +import moa.classifiers.rules.multilabel.core.AttributeExpansionSuggestion; +import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.Measurement; +import moa.core.SizeOf; +import moa.core.StringUtils; + +/** + * iSOUPTrees class for structured output prediction. + * + * @author Aljaž Osojnik (aljaz.osojnik@ijs.si) + * @version $Revision: 1 $ + */ +public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetRegressor { + + private static final long serialVersionUID = 1L; + + public Node treeRoot; + + private int leafNodeCount = 0; + private int splitNodeCount = 0; + + private double examplesSeen = 0.0; + private DoubleVector sumOfValues = new DoubleVector(); + private DoubleVector sumOfSquares = new DoubleVector(); + + private DoubleVector sumOfAttrValues = new DoubleVector(); + private DoubleVector sumOfAttrSquares = new DoubleVector(); + + public int maxID = 0; + + //region ================ OPTIONS ================ + + // public ClassOption splitCriterionOption = new ClassOption( + // "splitCriterion", + // 's', + // "Split criterion to use.", + // SplitCriterion.class, + // "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); + // TODO not used at the moment, consider later when the implementation catches up + + public IntOption gracePeriodOption = new IntOption( + "gracePeriod", + 'g', + "The number of instances a leaf should observe between split attempts.", + 200, 0, Integer.MAX_VALUE); + + public FloatOption splitConfidenceOption = new FloatOption( + "splitConfidence", + 'c', + "The allowable error in split decision, values closer to 0 will take longer to decide.", + 0.0000001, 0.0, 1.0); + + public FloatOption tieThresholdOption = new FloatOption( + "tieThreshold", + 't', + "Threshold below which a split will be forced to break ties.", + 0.05, 0.0, 1.0); + + public FloatOption PageHinckleyAlphaOption = new FloatOption( + "PageHinckleyAlpha", + 'a', + "The alpha value to use in the Page Hinckley change detection tests.", + 0.005, 0.0, 1.0); + + public IntOption PageHinckleyThresholdOption = new IntOption( + "PageHinckleyThreshold", + 'h', + "The threshold value to be used in the Page Hinckley change detection tests.", + 50, 0, Integer.MAX_VALUE); + + public FloatOption alternateTreeFadingFactorOption = new FloatOption( + "alternateTreeFadingFactor", + 'f', + "The fading factor to use when deciding if an alternate tree should replace an original.", + 0.995, 0.0, 1.0); + + public IntOption alternateTreeTMinOption = new IntOption( + "alternateTreeTMin", + 'y', + "The Tmin value to use when deciding if an alternate tree should replace an original.", + 150, 0, Integer.MAX_VALUE); + + public IntOption alternateTreeTimeOption = new IntOption( + "alternateTreeTime", + 'u', + "The 'time' (in terms of number of instances) value to use when deciding if an alternate tree should be discarded.", + 1500, 0, Integer.MAX_VALUE); + + public FlagOption regressionTreeOption = new FlagOption( + "regressionTree", + 'r', + "Build a regression tree instead of a model tree."); + + public FloatOption learningRatioOption = new FloatOption( + "learningRatio", + 'l', + "Learning ratio to use for training the Perceptrons in the leaves.", + 0.02); + + public FloatOption learningRateDecayFactorOption = new FloatOption( + "learningRatioDecayFactor", + 'd', + "Learning rate decay factor (not used when learning rate is constant).", + 0.001); + + public FlagOption learningRatioConstOption = new FlagOption( + "learningRatioConst", + 'o', + "Keep learning rate constant instead of decaying (if kept constant learning ratio is suggested to be 0.001)."); + + public FlagOption doNotNormalizeOption = new FlagOption( + "doNotNormalize", + 'n', + "Don't normalize."); + + public FlagOption printLogsOption = new FlagOption( + "printLogs", + 'z', + "Print logs."); + + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public abstract static class Node extends AbstractMOAObject { + + private static final long serialVersionUID = 1L; + + protected double weightSeenAtLastSplitEvaluation; + + public int ID; + + protected ISOUPTree tree; + + // The parent of this particular node + protected SplitNode parent; + + protected Node alternateTree; + protected Node originalNode; + + protected AutoExpandVector attributeObservers = new AutoExpandVector(); + + // The error values for the Page Hinckley test + // PHmT = the cumulative sum of the errors + // PHMT = the minimum error value seen so far + protected boolean changeDetection = true; + + // The statistics for this node: + // Number of instances that have reached it + protected double examplesSeen; + // Sum of y values + protected DoubleVector sumOfValues = new DoubleVector(); + // Sum of squared y values + protected DoubleVector sumOfSquares = new DoubleVector(); + + public Node(ISOUPTree tree) { + this.tree = tree; + } + + public void copyStatistics(Node node) { + examplesSeen = node.examplesSeen; + sumOfValues = (DoubleVector) node.sumOfValues.copy(); + sumOfSquares = (DoubleVector) node.sumOfSquares.copy(); + } + + public int calcByteSize() { + return (int) SizeOf.fullSizeOf(this); + } + + /** + * Set the parent node + */ + public void setParent(SplitNode parent) { + this.parent = parent; + } + + /** + * Return the parent node + */ + public Node getParent() { + return parent; + } + + public void disableChangeDetection() { + changeDetection = false; + } + + public void restartChangeDetection() { + changeDetection = true; + } + + public void getDescription(StringBuilder sb, int i) {} + + public double[] getPrediction(MultiLabelInstance inst) { + return null; + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf"); + } + + public int getLevel() { + Node target = this; + int level = 0; + while (target.getParent() != null) { + if (target.skipInLevelCount()) { + target = target.getParent(); + continue; + } + level = level + 1; + target = target.getParent(); + } + if (target.originalNode == null) { + return level; + } else { + return level + originalNode.getLevel(); + } + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + } + + public static class LeafNode extends Node { + + private static final long serialVersionUID = 1L; + + // Perceptron model that carries out the actual learning in each node + public MultitargetPerceptron learningModel; + + public DoubleVector errorP = new DoubleVector(); + public DoubleVector errorM = new DoubleVector(); + + protected double examplesSeenAtLastSplitEvaluation = 0; + + /** + * Create a new LeafNode + */ + public LeafNode(ISOUPTree tree) { + super(tree); + if (tree.buildingModelTree()) { + learningModel = tree.newLeafModel(); + } + examplesSeen = 0; + sumOfValues = new DoubleVector(); + sumOfSquares = new DoubleVector(); + } + + /** + * Method to learn from an instance that passes the new instance to the perceptron learner, + * and also prevents the class value from being truncated to an int when it is passed to the + * attribute observer + */ + public void learnFromInstance(MultiLabelInstance inst, double[] prediction, boolean growthAllowed) { + // Update the statistics for this node + // number of instances passing through the node + double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; + double[] predictionM = getPredictionTargetMean(inst); + + examplesSeen += inst.weight(); + + for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + // sum of y values + sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); + + // sum of squared y values + sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); + + if (tree.buildingModelTree()) { + errorP.setValue(i, errorP.getValue(i) * 0.95 + Math.abs(predictionP[i] - inst.valueOutputAttribute(i))); + errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - inst.valueOutputAttribute(i))); + } + } + + if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); + + for (int i = 0; i < inst.numInputAttributes(); i++) { + AttributeStatisticsObserver obs = attributeObservers.get(i); + if (obs == null) { + // At this stage all nominal attributes are ignored + if (inst.inputAttribute(i).isNumeric()) { + obs = tree.newNumericClassObserver(); + attributeObservers.set(i, obs); + } else if (inst.inputAttribute(i).isNominal()) { + obs = tree.newNominalClassObserver(); + attributeObservers.set(i, obs); + } + + } + if (obs != null) { + DoubleVector[] observations = new DoubleVector[inst.numOutputAttributes()]; + for (int j = 0; j < inst.numOutputAttributes(); j++) { + observations[j] = new DoubleVector(); + observations[j].setValue(0, inst.weight()); + observations[j].setValue(1, inst.weight() * inst.valueOutputAttribute(j)); + observations[j].setValue(2, inst.weight() * inst.valueOutputAttribute(j) * inst.valueOutputAttribute(j)); + } + obs.observeAttribute(inst.valueInputAttribute(i), observations); + + //obs.observeAttributeClassVector(inst.valueInputAttribute(i), getTargetVector(inst), inst.weight()); + } + } + + if (growthAllowed) { + checkForSplit(); + } + } + + /** + * Return the best split suggestions for this node using the given split criteria + */ + public AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCriterion criterion) { + + List bestSuggestions = new LinkedList(); + + for (int i = 0; i < attributeObservers.size(); i++) { + AttributeStatisticsObserver obs = attributeObservers.get(i); + if (obs != null) { + DoubleVector[] preSplitStatistics = new DoubleVector[tree.getModelContext().numOutputAttributes()]; + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + preSplitStatistics[j] = new DoubleVector(); + preSplitStatistics[j].setValue(0, examplesSeen); + preSplitStatistics[j].setValue(1, sumOfValues.getValue(j)); + preSplitStatistics[j].setValue(2, sumOfSquares.getValue(j)); + } + + AttributeExpansionSuggestion bestSuggestion = null; + bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, preSplitStatistics, i); + + if (bestSuggestion != null) { + bestSuggestions.add(bestSuggestion); + } + } + } + return bestSuggestions.toArray(new AttributeExpansionSuggestion[bestSuggestions.size()]); + } + + /** + * Retrieve the class votes using the perceptron learner + */ + public double[] getPredictionModel(MultiLabelInstance inst) { + return learningModel.prediction(inst); + } + + public double[] getPredictionTargetMean(MultiLabelInstance inst) { + double[] pred = new double[inst.numOutputAttributes()]; + for (int i = 0; i < inst.numOutputAttributes(); i++) { + if (examplesSeen > 0) { + pred[i] = sumOfValues.getValue(i) / examplesSeen; + } else { + pred[i] = 0; + } + } + return pred; + } + + public double[] getPrediction(MultiLabelInstance inst) { + if (tree.buildingModelTree()) { + double[] predictionP = getPredictionModel(inst); + double[] predictionM = getPredictionTargetMean(inst); + double[] prediction = new double[predictionP.length]; + for (int i = 0; i < predictionP.length; i++) { + if (errorP.getValue(i) < errorM.getValue(i)) { + prediction[i] = predictionP[i]; + } else { + prediction[i] = predictionM[i]; + } + } + return prediction; + } else { + return getPredictionTargetMean(inst); + } + + } + + // public double[] getClassVotes(MultiLabelInstance inst, ISOUPTrees tree) { + // return new double[] {getPrediction(inst, tree)}; + // } + + public void checkForSplit() { + // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node + if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { + int index = (parent != null) ? parent.getChildIndex(this) : 0; + tree.attemptToSplit(this, parent, index); + + // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation + examplesSeenAtLastSplitEvaluation = examplesSeen; + } + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf "); + if (tree.buildingModelTree()) { + learningModel.getModelDescription(out, 0); + } else { + //out.append(tree.getClassNameString() + " = " + String.format("%.4f", (sumOfValues / examplesSeen))); + StringUtils.appendNewline(out); + } + } + + } + + public static abstract class InnerNode extends Node { + // The InnerNode and SplitNode design is used for easy extension in ISOUPOptionTree + private static final long serialVersionUID = 1L; + + protected AutoExpandVector children = new AutoExpandVector(); + + // Sum of absolute errors + protected DoubleVector sumOfAbsErrors = new DoubleVector(); // Needed for PH tracking of mean error + + protected DoubleVector PHsums = new DoubleVector(); + protected DoubleVector PHmins = new DoubleVector(); + + // Keep track of the statistics for loss error calculations + protected double lossExamplesSeen; + protected double lossFadedSumOriginal; + protected double lossFadedSumAlternate; + protected double lossNumQiTests; + protected double lossSumQi; + protected double previousWeight = 0; + + public InnerNode(ISOUPTree tree) { + super(tree); + } + + public int numChildren() { + return children.size(); + } + + public Node getChild(int i) { + return children.get(i); + } + + public int getChildIndex(Node child) { + return children.indexOf(child); + } + + public void setChild(int i, Node child) { + children.set(i, child); + } + + public void disableChangeDetection() { + changeDetection = false; + for (Node child : children) { + child.disableChangeDetection(); + } + } + + public void restartChangeDetection() { + if (this.alternateTree == null) { + changeDetection = true; + PHsums = new DoubleVector(); + PHmins = new DoubleVector(); + for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + PHmins.setValue(i, Double.MAX_VALUE); + } + for (Node child : children) + child.restartChangeDetection(); + } + } + + /** + * Check to see if the tree needs updating + */ + public boolean PageHinckleyTest(double error, double threshold, int targetIndex) { + // Update the cumulative mT sum + PHsums.addToValue(targetIndex, error); + + // Update the minimum mT value if the new mT is + // smaller than the current minimum + if(PHsums.getValue(targetIndex) < PHmins.getValue(targetIndex)) { + PHmins.setValue(targetIndex, PHsums.getValue(targetIndex));; + } + // Return true if the cumulative value - the current minimum is + // greater than the current threshold (in which case we should adapt) + return PHsums.getValue(targetIndex) - PHmins.getValue(targetIndex) > threshold; + } + + public void initializeAlternateTree(ISOUPTree tree) { + // Start a new alternate tree, beginning with a learning node + alternateTree = tree.newLeafNode(); + alternateTree.originalNode = this; + + // Set up the blank statistics + // Number of instances reaching this node since the alternate tree was started + lossExamplesSeen = 0; + // Faded squared error (original tree) + lossFadedSumOriginal = 0; + // Faded squared error (alternate tree) + lossFadedSumAlternate = 0; + // Number of evaluations of alternate tree + lossNumQiTests = 0; + // Sum of Qi values + lossSumQi = 0; + // Number of examples at last test + previousWeight = 0; + + // Disable the change detection mechanism bellow this node + disableChangeDetection(); + } + } + + public static class SplitNode extends InnerNode { + + private static final long serialVersionUID = 1L; + + protected Predicate predicate; + + /** + * Create a new SplitNode + * @param predicate + * @param tree + */ + public SplitNode(Predicate predicate, ISOUPTree tree) { + super(tree); + this.predicate = predicate; + ID = tree.maxID; + } + + public int instanceChildIndex(MultiLabelInstance inst) { + return (predicate.evaluate(inst)) ? 0 : 1; + } + + public void describeSubtree(StringBuilder out, int indent) { + for (int branch = 0; branch < children.size(); branch++) { + Node child = getChild(branch); + if (child != null) { + if (branch == 0) { + StringUtils.appendIndented(out, indent, "if "); + this.predicate.getDescription(out, 0); + } else { + StringUtils.appendIndented(out, indent, "else"); + } + out.append(": "); + StringUtils.appendNewline(out); + child.describeSubtree(out, indent + 2); + } + } + } + + public double[] getPrediction(MultiLabelInstance inst) { + return children.get(predicate.evaluate(inst) ? 0 : 1).getPrediction(inst); + } + } + + public class MultitargetPerceptron { + + protected ISOUPTree tree; + + // The Perception weights + public double[][] weights; + + // The number of instances contributing to this model + protected int instancesSeen = 0; + + public String getPurposeString() { + return "A multi-target perceptron"; + } + + public MultitargetPerceptron(ISOUPTree tree, MultitargetPerceptron original) { + this.tree = tree; + weights = original.weights.clone(); + // TODO check if this is necessary +// for (int i = 0; i < this.tree.getModelContext().numOutputAttributes(); i++) { +// weights[i] = (DoubleVector) original.weights[i].copy(); +// } + } + + public MultitargetPerceptron(ISOUPTree tree) { + this.tree = tree; + initializeWeights(); + } + + public void initializeWeights() { + instancesSeen = 0; + int numTargets = tree.getModelContext().numOutputAttributes(); + int numInputs = tree.getModelContext().numInputAttributes(); + weights = new double[numTargets][numInputs+1]; + tree.classifierRandom.setSeed(1234); + for (int i = 0; i < numTargets; i++) { + for (int j = 0; j < numInputs + 1; j++) { + // The last index corresponds to the constant b + weights[i][j] = 2 * tree.classifierRandom.nextDouble() - 1; + } + } + normalizeWeights(); + } + + /** + * Update the model using the provided instance + */ + public void updatePerceptron(MultiLabelInstance inst) { + // Update attribute statistics + instancesSeen += inst.weight(); + + // Update weights + double learningRatio = 0.0; + if (tree.learningRatioConstOption.isSet()) { + learningRatio = tree.learningRatioOption.getValue(); + } else { + learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); + } + + // Loop for compatibility with bagging methods + for (int i = 0; i < (int) inst.weight(); i++) { + updateWeights(inst, learningRatio); + } + } + + public void updateWeights(MultiLabelInstance inst, double learningRatio) { + if (instancesSeen > 1.0) { + // Compute the normalized instance and the delta + double[] normalizedInput = tree.normalizedInputVector(inst); + double[] normalizedPrediction = prediction(normalizedInput); + + double[] normalizedTarget = tree.normalizedTargetVector(inst); + for (int i = 0; i < inst.numOutputAttributes(); i++){ + double delta = normalizedTarget[i] - normalizedPrediction[i]; + for (int j = 0; j < normalizedInput.length; j++) { + weights[i][j] += delta * learningRatio * normalizedInput[j]; + } + } + normalizeWeights(); + } + } + + public void normalizeWeights() { + for (int j =0; j < weights.length; j++) { + double sum = 0; + for (int i = 0; i < weights[j].length; i++) + sum += Math.abs(weights[j][i]); + for (int i = 0; i < weights[j].length; i++) + weights[j][i] /= sum; + } + } + + + /** + * Output the prediction made by this perceptron on the given instance + */ + public double[] prediction(double[] instanceValues) { + double[] out = new double[tree.getModelContext().numOutputAttributes()]; + for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + out[i] = 0; + for (int j = 0; j < instanceValues.length; j++) { + out[i] += weights[i][j] * instanceValues[j]; + } + } + return out; + } + + private double[] prediction(MultiLabelInstance inst) { + double[] normalizedInput = tree.normalizedInputVector(inst); + double[] normalizedPrediction = prediction(normalizedInput); + return denormalizePrediction(normalizedPrediction); + } + + private double[] denormalizePrediction(double[] normalizedPrediction) { + double[] out = new double[normalizedPrediction.length]; + if (tree.normalize()) { + for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + double mean = tree.sumOfValues.getValue(i) / tree.examplesSeen; + double sd = computeSD(tree.sumOfSquares.getValue(i), tree.sumOfValues.getValue(i), tree.examplesSeen); + if (examplesSeen > 1) + out[i] = normalizedPrediction[i] * sd + mean; + else + out[i] = 0; + } + return out; + } else return normalizedPrediction; + } + + public void getModelDescription(StringBuilder out, int indent) { + for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "]"); + //if (getModelContext() != null) { + //for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { + // if (getModelContext().attribute(j).isNumeric()) { + // // TODO + // //out.append((j == 0 || weightAttribute.getValue(j) < 0) ? " " : " + "); + // //out.append(String.format("%.4f", weightAttribute.getValue(j))); + // out.append(" * "); + // out.append(getAttributeNameString(j)); + // } + //} + //out.append(" + " + weightAttribute.getValue((getModelContext().numAttributes() - 1))); + //} + } + StringUtils.appendNewline(out); + } + } + + // public class SOPNumericAttributeClassObserver implements MultitargetAttributeClassObserver { + // + // private static final long serialVersionUID = 1L; + // + // protected class Node implements Serializable { + // + // private static final long serialVersionUID = 1L; + // + // // The split point to use + // public double cut_point; + // + // // E-BST statistics + // public double leftCount = 0; + // public double rightCount = 0; + // public DoubleVector leftSums = new DoubleVector(); + // public DoubleVector leftSquares = new DoubleVector(); + // public DoubleVector rightSums = new DoubleVector(); + // public DoubleVector rightSquares = new DoubleVector(); + // + // // Child nodes + // public Node left; + // public Node right; + // + // public Node(double val, DoubleVector labelVector, double weight) { + // cut_point = val; + // leftCount += 1; + // for (int i = 0; i < labelVector.numValues(); i++) { + // leftSums.addToValue(i, labelVector.getValue(i)); + // leftSquares.addToValue(i, labelVector.getValue(i) * labelVector.getValue(i)); + // } + // } + // + // /** + // * Insert a new value into the tree, updating both the sum of values and + // * sum of squared values arrays + // */ + // public void insertValue(double val, DoubleVector labelVector, double weight) { + // + // // If the new value equals the value stored in a node, update + // // the left (<=) node information + // if (val == cut_point) { + // leftCount += 1; + // for (int i = 0; i < labelVector.numValues(); i++) { + // leftSums.addToValue(i, labelVector.getValue(i)); + // leftSquares.addToValue(i, labelVector.getValue(i) * labelVector.getValue(i)); + // } + // } // If the new value is less than the value in a node, update the + // // left distribution and send the value down to the left child node. + // // If no left child exists, create one + // else if (val <= cut_point) { + // + // leftCount += 1; + // for (int i = 0; i < labelVector.numValues(); i++) { + // leftSums.addToValue(i, labelVector.getValue(i)); + // leftSquares.addToValue(i, labelVector.getValue(i) * labelVector.getValue(i)); + // } + // if (left == null) { + // left = new Node(val, labelVector, weight); + // } else { + // left.insertValue(val, labelVector, weight); + // } + // } // If the new value is greater than the value in a node, update the + // // right (>) distribution and send the value down to the right child node. + // // If no right child exists, create one + // else { // val > cut_point + // rightCount += 1; + // for (int i = 0; i < labelVector.numValues(); i++) { + // rightSums.addToValue(i, labelVector.getValue(i)); + // rightSquares.addToValue(i, labelVector.getValue(i) * labelVector.getValue(i)); + // } + // if (right == null) { + // right = new Node(val, labelVector, weight); + // } else { + // right.insertValue(val, labelVector, weight); + // } + // } + // } + // } + // + // // Root node of the E-BST structure for this attribute + // protected Node root = null; + // + // // Global variables for use in the FindBestSplit algorithm + // DoubleVector sumsTotalLeft; + // DoubleVector sumsTotalRight; + // DoubleVector squaresTotalLeft; + // DoubleVector squaresTotalRight; + // double countRightTotal; + // double countLeftTotal; + // + // public void observeAttributeClass(double attVal, double classVal, double weight) { + // // DEPRECATED (used for single-target cases) + // + // // if (Double.isNaN(attVal)) { //Instance.isMissingValue(attVal) + // // } else { + // // if (root == null) { + // // root = new Node(attVal, classVal, weight); + // // } else { + // // root.insertValue(attVal, classVal, weight); + // // } + // // } + // } + // + // public void observeAttributeClass(double attVal, DoubleVector classVector, double weight) { + // if (Double.isNaN(attVal)) { //Instance.isMissingValue(attVal) + // } else { + // if (root == null) { + // root = new Node(attVal, classVector, weight); + // } else { + // root.insertValue(attVal, classVector, weight); + // } + // } + // + // } + // + // public double probabilityOfAttributeValueGivenClass(double attVal, int classVal) { + // // TODO: NaiveBayes broken until implemented + // return 0.0; + // } + // + // @Override + // public AttributeSplitSuggestion getBestEvaluatedSplitSuggestion(SplitCriterion criterion, double examlpesSeen, DoubleVector preSplitSums, DoubleVector preSplitSquares, int numTargets, int attIndex, boolean binaryOnly) { + // // Initialise global variables + // sumsTotalLeft = new DoubleVector(); + // sumsTotalRight = preSplitSums; + // squaresTotalLeft = new DoubleVector(); + // squaresTotalRight = preSplitSquares; + // countLeftTotal = 0; + // countRightTotal = examplesSeen; + // + // // Hardcoded for ICV reduction + // double preSplitVariance = 0; + // for (int i = 0; i < numTargets; i++) { + // preSplitVariance += (preSplitSquares.getValue(i) - examplesSeen * preSplitSums.getValue(i) * preSplitSums.getValue(i)) / examplesSeen; + // } + // + // return searchForBestSplitOption(root, null, preSplitVariance, attIndex, numTargets); + // } + // + // public AttributeSplitSuggestion getBestEvaluatedSplitSuggestion(SplitCriterion criterion, double[] preSplitDist, int attIndex, boolean binaryOnly) { + // // DEPRECATED + // return null; + // } + // + // /** + // * Implementation of the FindBestSplit algorithm from E.Ikonomovska et al. + // */ + // protected AttributeSplitSuggestion searchForBestSplitOption(Node currentNode, AttributeSplitSuggestion currentBestOption, double preSplitVariance, int attIndex, int numTargets) { + // // Return null if the current node is null or we have finished looking through all the possible splits + // if (currentNode == null || countRightTotal == 0.0) { + // return currentBestOption; + // } + // + // if (currentNode.left != null) { + // currentBestOption = searchForBestSplitOption(currentNode.left, currentBestOption, preSplitVariance, attIndex, numTargets); + // } + // + // sumsTotalLeft.addValues(currentNode.leftSums); + // sumsTotalRight.subtractValues(currentNode.leftSums); + // squaresTotalLeft.addValues(currentNode.leftSquares); + // squaresTotalRight.subtractValues(currentNode.leftSquares); + // countLeftTotal += currentNode.leftCount; + // countRightTotal -= currentNode.leftCount; + // + // // double[][] postSplitDists = new double[][]{{countLeftTotal, sumTotalLeft, sumSqTotalLeft}, {countRightTotal, sumTotalRight, sumSqTotalRight}}; + // // double[] preSplitDist = new double[]{(countLeftTotal + countRightTotal), (sumTotalLeft + sumTotalRight), (sumSqTotalLeft + sumSqTotalRight)}; + // // double merit = criterion.getMeritOfSplit(preSplitDist, postSplitDists); + // + // double postSplitVariance = 0; + // for (int i = 0; i < numTargets; i++) { + // postSplitVariance += (squaresTotalLeft.getValue(i) - examplesSeen * sumsTotalLeft.getValue(i) * sumsTotalLeft.getValue(i)) / countLeftTotal; + // postSplitVariance += (squaresTotalRight.getValue(i) - examplesSeen * sumsTotalRight.getValue(i) * sumsTotalRight.getValue(i)) / countRightTotal; + // } + // + // double merit = preSplitVariance - postSplitVariance; + // + // if ((currentBestOption == null) || (merit > currentBestOption.merit)) { + // currentBestOption = new AttributeSplitSuggestion( + // new NumericAttributeBinaryTest(attIndex, + // currentNode.cut_point, true), new double[0][0], merit); + // + // } + // + // if (currentNode.right != null) { + // currentBestOption = searchForBestSplitOption(currentNode.right, currentBestOption, preSplitVariance, attIndex, numTargets); + // } + // + // sumsTotalLeft.subtractValues(currentNode.leftSums); + // sumsTotalRight.addValues(currentNode.leftSums); + // squaresTotalLeft.subtractValues(currentNode.leftSquares); + // squaresTotalRight.addValues(currentNode.leftSquares); + // countLeftTotal -= currentNode.leftCount; + // countRightTotal += currentNode.leftCount; + // + // return currentBestOption; + // } + // + // /** + // * A method to remove all nodes in the E-BST in which it and all it's + // * children represent 'bad' split points + // */ + // public void removeBadSplits(SplitCriterion criterion, double lastCheckRatio, double lastCheckSDR, double lastCheckE, int numTargets) { + // removeBadSplitNodes(criterion, root, lastCheckRatio, lastCheckSDR, lastCheckE, numTargets); + // } + // + // /** + // * Recursive method that first checks all of a node's children before + // * deciding if it is 'bad' and may be removed + // */ + // private boolean removeBadSplitNodes(SplitCriterion criterion, Node currentNode, double lastCheckRatio, double lastCheckSDR, double lastCheckE, int numTargets) { + // boolean isBad = false; + // + // if (currentNode == null) { + // return true; + // } + // + // if (currentNode.left != null) { + // isBad = removeBadSplitNodes(criterion, currentNode.left, lastCheckRatio, lastCheckSDR, lastCheckE, numTargets); + // } + // + // if (currentNode.right != null && isBad) { + // isBad = removeBadSplitNodes(criterion, currentNode.left, lastCheckRatio, lastCheckSDR, lastCheckE, numTargets); + // } + // + // if (isBad) { + // + // double preSplitVariance = 0; + // for (int i = 0; i < numTargets; i++) { + // preSplitVariance += (currentNode.leftSquares.getValue(i) + currentNode.rightSquares.getValue(i) - examplesSeen * + // (currentNode.leftSums.getValue(i) + currentNode.rightSums.getValue(i)) * (currentNode.leftSums.getValue(i) + currentNode.rightSums.getValue(i))) / examplesSeen; + // } + // + // double postSplitVariance = 0; + // for (int i = 0; i < numTargets; i++) { + // postSplitVariance += (currentNode.leftSquares.getValue(i) - currentNode.leftCount * currentNode.leftSums.getValue(i) * currentNode.leftSums.getValue(i)) / currentNode.leftCount; + // postSplitVariance += (currentNode.rightSquares.getValue(i) - currentNode.rightCount * currentNode.rightSums.getValue(i) * currentNode.rightSums.getValue(i)) / currentNode.rightCount; + // } + // + // + // // double[][] postSplitDists = new double[][]{{currentNode.leftStatistics.getValue(0), currentNode.leftStatistics.getValue(1), currentNode.leftStatistics.getValue(2)}, {currentNode.rightStatistics.getValue(0), currentNode.rightStatistics.getValue(1), currentNode.rightStatistics.getValue(2)}}; + // // double[] preSplitDist = new double[]{(currentNode.leftStatistics.getValue(0) + currentNode.rightStatistics.getValue(0)), (currentNode.leftStatistics.getValue(1) + currentNode.rightStatistics.getValue(1)), (currentNode.leftStatistics.getValue(2) + currentNode.rightStatistics.getValue(2))}; + // // double merit = criterion.getMeritOfSplit(preSplitDist, postSplitDists); + // double merit = preSplitVariance - postSplitVariance; + // + // if ((merit / lastCheckSDR) < (lastCheckRatio - (2 * lastCheckE))) { + // currentNode = null; + // return true; + // } + // } + // + // return false; + // } + // + // @Override + // public void getDescription(StringBuilder sb, int indent) { + // // TODO Auto-generated method stub + // } + // + // protected void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { + // // TODO Auto-generated method stub + // } + // + // @Override + // public void observeAttributeClass(double attVal, int classVal, + // double weight) { + // // TODO Auto-generated method stub + // + // } + // + // @Override + // public void observeAttributeTarget(double attVal, double target) { + // // TODO Auto-generated method stub + // + // } + // + // @Override + // public String getPurposeString() { + // // TODO Auto-generated method stub + // return null; + // } + // + // @Override + // public Options getOptions() { + // // TODO Auto-generated method stub + // return null; + // } + // + // @Override + // public void prepareForUse() { + // // TODO Auto-generated method stub + // + // } + // + // @Override + // public void prepareForUse(TaskMonitor monitor, + // ObjectRepository repository) { + // // TODO Auto-generated method stub + // + // } + // + // @Override + // public OptionHandler copy() { + // // TODO Auto-generated method stub + // return null; + // } + // + // @Override + // public String getCLICreationString(Class expectedType) { + // // TODO Auto-generated method stub + // return null; + // } + // + // @Override + // public int measureByteSize() { + // // TODO Auto-generated method stub + // return 0; + // } + // + // + // + // @Override + // public void observeAttributeClassVector(double attVal, + // DoubleVector classVector, double weight) { + // // TODO Auto-generated method stub + // + // } + // + // + // } + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + // Regressor methods + public ISOUPTree() {} + + public String getPurposeString() { + return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + treeRoot = null; + leafNodeCount = 0; + splitNodeCount = 0; + examplesSeen = 0.0; + sumOfValues = new DoubleVector(); + sumOfSquares = new DoubleVector(); + + sumOfAttrValues = new DoubleVector(); + sumOfAttrSquares = new DoubleVector(); + } + + public boolean isRandomizable() { + return true; + } + + public void getModelDescription(StringBuilder out, int indent) { + if (treeRoot != null) treeRoot.describeSubtree(out, indent); + } + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + //new Measurement("tree size (nodes)", this.leafNodeCount + this.splitNodeCount), + //new Measurement("tree size (leaves)", this.leafNodeCount) + }; + } + + public int calcByteSize() { + int size = (int) SizeOf.sizeOf(this); + if (this.treeRoot != null) { + size += this.treeRoot.calcByteSize(); + } + return size; + } + + public Prediction getPredictionForInstance(MultiLabelInstance inst) { + checkRoot(); + double[] predictionVector = treeRoot.getPrediction(inst); + MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + prediction.setVote(i, 1, predictionVector[i]); + } + return prediction; + } + + public double[] normalizedInputVector(MultiLabelInstance inst) { + // Normalize Instance + double[] normalizedInput = new double[inst.numInputAttributes()+1]; + if (normalize()) { + for (int j = 0; j < inst.numInputAttributes(); j++) { + Attribute attr = inst.inputAttribute(j); + double value = inst.valueInputAttribute(j); + double mean = sumOfAttrValues.getValue(j) / examplesSeen; + double sd = computeSD(sumOfAttrSquares.getValue(j), sumOfAttrValues.getValue(j), examplesSeen); + if (examplesSeen > 1 && sd > 0.00001) { + if (attr.isNumeric()) + normalizedInput[j] = (value - mean) / sd; + else + normalizedInput[j] = value; + } else + normalizedInput[j] = 0; + } + if (examplesSeen > 1) + normalizedInput[inst.numInputAttributes()] = 1.0; // Value to be multiplied with the constant factor + else + normalizedInput[inst.numInputAttributes()] = 0.0; + } else { + for (int j = 0; j < inst.numInputAttributes(); j++) { + normalizedInput[j] = inst.valueInputAttribute(j); + } + normalizedInput[inst.numInputAttributes()] = 1.0; + } + return normalizedInput; + } + + public double[] normalizedTargetVector(MultiLabelInstance inst) { + double[] out = new double[getModelContext().numOutputAttributes()]; + if (normalize()) { + for (int i = 0; i < inst.numOutputAttributes(); i++) { + double value = inst.valueOutputAttribute(i); + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); + double average = sumOfValues.getValue(i) / examplesSeen; + if (sd > 0 && examplesSeen > 1) + out[i] = (value - average) / (sd); + else + out[i] = 0; + } + } else { + for (int i = 0; i < inst.numOutputAttributes(); i++) { + out[i] = inst.valueOutputAttribute(i); + } + } + return out; + } + + public double[] normalizeTargetVector(double[] pred) { + if (normalize()) { + double[] out = new double[pred.length]; + for (int i = 0; i < pred.length; i++) { + double value = pred[i]; + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); + double average = sumOfValues.getValue(i) / examplesSeen; + if (sd > 0 && examplesSeen > 1) + out[i] = (value - average) / sd; + else + out[i] = 0; + } + return out; + } else return pred; + } + + + public double normalizeTargetValue(MultiLabelInstance inst, int i) { + if (normalize()) { + if (examplesSeen > 1) { + double value = inst.valueOutputAttribute(i); + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); + double average = sumOfValues.getValue(i) / examplesSeen; + if (sd > 0) + return (value - average) / sd; + else + return 0; + } + return 0; + } else return inst.valueOutputAttribute(i); + } + + public double normalizeTargetValue(double value, int i) { + if (normalize()) { + if (examplesSeen > 1) { + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); + double average = sumOfValues.getValue(i) / examplesSeen; + if (sd > 0) + return (value - average) / sd; + else + return 0; + } + return 0; + } else return value; + } + + public double[] getNormalizedError(MultiLabelInstance inst, double[] prediction) { + double[] normalPrediction = normalizeTargetVector(prediction); + double[] normalValue = normalizedTargetVector(inst); + double[] out = new double[getModelContext().numOutputAttributes()]; + for (int i = 0; i < inst.numOutputAttributes(); i++) { + out[i] = Math.abs(normalValue[i] - normalPrediction[i]); + } + return out; + } + + + /** + * Method for updating (training) the model using a new instance + */ + public void trainOnInstanceImpl(MultiLabelInstance inst) { + if (inst.weight() > 0) { + checkRoot(); + + double[] prediction = treeRoot.getPrediction(inst); + double[] normalError = getNormalizedError(inst, prediction); + + processInstance(inst, treeRoot, prediction, normalError, true, false); + + examplesSeen += inst.weight(); + for (int i = 0; i < inst.numberOutputTargets(); i++) { + sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); + sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); + } + + for (int i = 0; i < inst.numInputAttributes(); i++) { + sumOfAttrValues.addToValue(i, inst.weight() * inst.valueInputAttribute(i)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.valueInputAttribute(i) * inst.valueInputAttribute(i)); + } + + //normalError.scaleValues(inst.weight()); + + } + } + + public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } else { + currentNode.examplesSeen += inst.weight(); + //currentNode.sumOfAbsErrors.addValues(normalError); + // SplitNode iNode = (SplitNode) currentNode; + // if (!inAlternate && iNode.alternateTree != null) { + // boolean altTree = true; + // double lossO = Math.pow(inst.valueOutputAttribute() - prediction, 2); + // double lossA = Math.pow(inst.valueOutputAttribute() - iNode.alternateTree.getPrediction(inst), 2); + // + // iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + // iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + // iNode.lossExamplesSeen++; + // + // double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + // double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // iNode.lossSumQi += Qi; + // iNode.lossNumQiTests += 1; + // double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // + // if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + // iNode.previousWeight = iNode.lossExamplesSeen; + // if (Qi > 0) { + // SplitNode parent = currentNode.getParent(); + // + // if (parent != null) { + // Node replacementTree = iNode.alternateTree; + // parent.setChild(parent.getChildIndex(currentNode), replacementTree); + // if (growthAllowed) replacementTree.restartChangeDetection(); + // } else { + // treeRoot = iNode.alternateTree; + // treeRoot.restartChangeDetection(); + // } + // + // currentNode = iNode.alternateTree; + // altTree = false; + // } else if ( + // (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) + // || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() + // ) { + // iNode.alternateTree = null; + // if (growthAllowed) iNode.restartChangeDetection(); + // altTree = false; + // } + // } + // + // if (altTree) { + // growthAllowed = false; + // processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + // } + // } + + // if (iNode.changeDetection && !inAlternate) { + // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + // iNode.initializeAlternateTree(this); + // } + // } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); + } else { // if the replaced alternate tree is just a leaf node + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } + } + } + } + + //region --- Object instatiation methods + + protected NumericStatisticsObserver newNumericClassObserver() { + return new MultiLabelBSTree(); + } + + public NominalStatisticsObserver newNominalClassObserver() { + return new MultiLabelNominalAttributeObserver(); + } + + // protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + // maxID++; + // return new SplitNode(splitTest, this); + // } + + protected SplitNode newSplitNode(Predicate predicate) { + maxID++; + return new SplitNode(predicate, this); + } + + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } + + public MultitargetPerceptron newLeafModel() { + return new MultitargetPerceptron(this); + } + + //endregion --- Object instatiation methods + + //region --- Processing methods + protected void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + leafNodeCount = 1; + } + } + + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } + + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } + + public boolean normalize() { + return !doNotNormalizeOption.isSet(); + } + + protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) { + //System.out.println("Evaluating splits"); + //System.out.println(examplesSeen); + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + MultiLabelSplitCriterion splitCriterion = new ICVarianceReduction(); + + // Using this criterion, find the best split per attribute and rank the results + AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine if any of the splits should be performed + boolean shouldSplit = false; + + // If only one split was returned, use it + if (bestSplitSuggestions.length < 2) { + shouldSplit = bestSplitSuggestions.length > 0; + } else { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + //System.out.print(hoeffdingBound); + //System.out.print(" "); + ///System.out.println(secondBestSuggestion.merit / bestSuggestion.merit); + if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { + shouldSplit = true; + } + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + else { + // TODO pruning is currently disabled + for (int i = 0; i < node.attributeObservers.size(); i++) { + AttributeStatisticsObserver obs = node.attributeObservers.get(i); + if (obs != null) { + if (getModelContext().attribute(i).isNumeric()); + //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); + if (getModelContext().attribute(i).isNominal()); + // TODO nominal class observers + } + } + } + + if (hoeffdingBound < this.tieThresholdOption.getValue() && this.printLogsOption.isSet()) System.out.println("Forced to split due to tie at " + this.examplesSeen); + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (shouldSplit) { + if (node.parent == null && this.printLogsOption.isSet()) { + System.out.println("splitting root node at " + this.examplesSeen); + } + AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + + SplitNode newSplit = newSplitNode(splitDecision.predicate); + newSplit.copyStatistics(node); + newSplit.changeDetection = node.changeDetection; + newSplit.ID = node.ID; + leafNodeCount--; + //System.out.println("Splitting"); + //System.out.println(examplesSeen); + for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) + LeafNode newChild = newLeafNode(); + if (buildingModelTree()) { + // Copy the splitting node's perceptron to it's children + newChild.learningModel = new MultitargetPerceptron(this, (MultitargetPerceptron) node.learningModel); + + } + newChild.changeDetection = node.changeDetection; + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + leafNodeCount++; + } + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + parent.setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + + splitNodeCount++; + } + } + + public double computeSD(double squaredVal, double val, double size) { + if (size > 1) + return Math.sqrt((squaredVal - ((val * val) / size)) / size); + else + return 0.0; + } + + public static double scalarProduct(DoubleVector u, DoubleVector v) { + double ret = 0.0; + for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { + ret += u.getValue(i) * v.getValue(i); + } + return ret; + } + //endregion --- Processing methods + + //endregion ================ METHODS ================ +} diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java index ebff655c3..1479c2b18 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java @@ -1,920 +1,992 @@ - /* - * FFIMTDD.java - * Copyright (C) 2013 University of Porto, Portugal - * @author Katie de Lange, E. Almeida, J. Gama - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ - -/* Project Knowledge Discovery from Data Streams, FCT LIAAD-INESC TEC, - * - * Contact: jgama@fep.up.pt - */ - - package moa.classifiers.trees; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import moa.AbstractMOAObject; -import moa.classifiers.Regressor; -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.conditionaltests.InstanceConditionalTest; -import moa.classifiers.core.splitcriteria.SDRSplitCriterion; -import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.core.DoubleVector; -import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; - -/* - * Implementation of FIMTDD, regresion tree for data streams. - */ - -public class FIMTDD extends HoeffdingTree implements Regressor{ - - private static final long serialVersionUID = 1L; - - @Override - public String getPurposeString() { - return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; - } - - // For the moment at least, force the split criterion to be SDRSplitCriterion and the - // numeric estimator to be FIMTLDDNumericAttributeClassObserver - public FIMTDD() { - - numericEstimatorOption = new ClassOption("numericEstimator", - 'n', "Numeric estimator to use.", FIMTDDNumericAttributeClassObserver.class, - "FIMTDDNumericAttributeClassObserver"); - - splitCriterionOption = new ClassOption("splitCriterion", - 's', "Split criterion to use.", SDRSplitCriterion.class, - "SDRSplitCriterion"); - } - - protected DoubleVector splitRatioStatistics = new DoubleVector(); - - // Store the lowest node in the tree that requires adaptation - protected ArrayList nodesToAdapt = new ArrayList(); - - protected boolean Adaptable = true; - - protected double initLearnRate = 0.1; - - protected double learnRateDecay = 0.001; - - //============================= SET OPTIONS ==============================// - - public FloatOption PageHinckleyAlphaOption = new FloatOption( - "PageHinckleyAlpha", - 'a', - "The alpha value to use in the Page Hinckley change detection tests.", - 0.005, 0.0, 1.0); - - public IntOption PageHinckleyThresholdOption = new IntOption( - "PageHinckleyThreshold", - 'h', - "The threshold value to be used in the Page Hinckley change detection tests.", - 50, 0, Integer.MAX_VALUE); - - public FloatOption AlternateTreeFadingFactorOption = new FloatOption( - "AlternateTreeFadingFactor", - 'f', - "The fading factor to use when deciding if an alternate tree should replace an original.", - 0.995, 0.0, 1.0); - - public IntOption AlternateTreeTMinOption = new IntOption( - "AlternateTreeTMin", - 'y', - "The Tmin value to use when deciding if an alternate tree should replace an original.", - 150, 0, Integer.MAX_VALUE); - - public IntOption AlternateTreeTimeOption = new IntOption( - "AlternateTreeTime", - 'u', - "The 'time' (in terms of number of instances) value to use when deciding if an alternate tree should be discarded.", - 1500, 0, Integer.MAX_VALUE); - - public FloatOption learningRatioOption = new FloatOption("learningRatio", 'w', "Learning ratio to use for training the Perceptrons in the leaves.", 0.01); - - public FlagOption learningRatio_Decay_or_Const_Option = new FlagOption("learningRatio_Decay_or_Const", 'j', - "learning Ratio Decay or const parameter."); - - //=============================== CLASSES ================================// - - /** - * A new interface for nodes to be used in an adaptive setting - */ - public interface AdaptationCompatibleNode { - - public void setParent(Node parent); - - public Node getParent(); - } - - /** - * A modified ActiveLearningNode that uses a Perceptron as the leaf node - * model, and ensures that the class values sent to the attribute observers - * are not truncated to ints if regression is being performed - */ - public static class FIMTDDActiveLearningNode extends ActiveLearningNode implements AdaptationCompatibleNode{ - - // Create a Perceptron model that carries out the actual learning in each node - public FIMTDDPerceptron learningModel = new FIMTDDPerceptron(); - - // The parent of this particular leaf node - protected Node parent; - - // The statistics for this node: - // Number of instances that have reached it - // Sum of y values - // Sum of squared y values - protected DoubleVector nodeStatistics; - - // The error values for the Page Hinckley test - // PHmT = the cumulative sum of the errors - // PHMT = the minimum error value seen so far - protected double PHmT = 0; - protected double PHMT = Double.MAX_VALUE; - - /** - * Create a new FIMTDDActiveLearningNode - */ - public FIMTDDActiveLearningNode(double[] initialClassObservations) { - super(initialClassObservations); - learningModel.resetLearningImpl(); - nodeStatistics = new DoubleVector(); - } - - /** - * Set the parent node - */ - public void setParent(Node parent) { - this.parent = parent; - } - - /** - * Return the parent node - */ - public Node getParent() { - return parent; - } - - @Override - public double getWeightSeen() { - if(nodeStatistics != null) - { - return this.nodeStatistics.getValue(0); - } - else - { - return 0; - } - } - - @Override - /** - * Method to learn from an instance that passes the new instance to the perceptron learner, - * and also prevents the class value from being truncated to an int when it is passed to the - * attribute observer - */ - public void learnFromInstance(Instance inst, HoeffdingTree ht) { - // this.observedClassDistribution.addToValue((int)inst.classValue(),inst.weight()); - - // Update the statistics for this node - // number of instances passing through the node - nodeStatistics.addToValue(0, 1); - // sum of y values - nodeStatistics.addToValue(1, inst.classValue()); - // sum of squared y values - nodeStatistics.addToValue(2, inst.classValue() * inst.classValue()); - // sum of absolute errors - // Normalise values prior to calculating absolute error - double sd = Math.sqrt((nodeStatistics.getValue(2) - ((nodeStatistics.getValue(1) * - nodeStatistics.getValue(1))/nodeStatistics.getValue(0)))/nodeStatistics.getValue(0)); - double mean = nodeStatistics.getValue(1) / nodeStatistics.getValue(0); - nodeStatistics.addToValue(3, Math.abs(((inst.classValue()-mean)/sd) - ((learningModel.prediction(inst)-mean)/sd))); - // sum of squared errors - nodeStatistics.setValue(4, Math.pow(this.getError(inst), 2) + nodeStatistics.getValue(4) * ((FIMTDD) ht).AlternateTreeFadingFactorOption.getValue()); - - - learningModel.trainOnInstanceImpl(inst, (FIMTDD)ht); - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); - AttributeClassObserver obs = this.attributeObservers.get(i); - if (obs == null) { - // At this stage all nominal attributes are ignored - if(inst.attribute(instAttIndex).isNumeric()) - { - obs = ((FIMTDD)ht).newNumericClassObserver(); - this.attributeObservers.set(i, obs); - } - } - if(obs != null) - { - ((FIMTDDNumericAttributeClassObserver)obs).observeAttributeClass(inst.value(instAttIndex),inst.classValue(), inst.weight()); - } - } - } - - @Override - /** - * Return the best split suggestions for this node using the given split criteria - */ - public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion, HoeffdingTree ht) { - - List bestSuggestions = new LinkedList(); - - // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution - double[] nodeSplitDist = this.nodeStatistics.getArrayCopy(); - double[] preSplitDist = this.observedClassDistribution.getArrayCopy(); - - if (!ht.noPrePruneOption.isSet()) { - // add null split as an option - bestSuggestions.add(new AttributeSplitSuggestion(null,new double[0][], criterion.getMeritOfSplit(nodeSplitDist,new double[][]{nodeSplitDist}))); - } - for (int i = 0; i < this.attributeObservers.size(); i++) { - AttributeClassObserver obs = this.attributeObservers.get(i); - if (obs != null) { - - // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED - AttributeSplitSuggestion bestSuggestion = null; - if(obs instanceof FIMTDDNumericAttributeClassObserver) { - bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion,nodeSplitDist, i, ht.binarySplitsOption.isSet()); - } - - if (bestSuggestion != null) { - bestSuggestions.add(bestSuggestion); - } - } - } - return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); - } - - /** - * Retrieve the class votes using the perceptron learner - */ - public double getPrediction(Instance inst, HoeffdingTree ht) { - return learningModel.prediction(inst); - - } - /** - * Retrieve the class votes using the target mean - */ - public double getPredictionTargetMean(Instance inst, HoeffdingTree ht) { - double valor = 0.0; - if(this.nodeStatistics.getValue(0) > 0.0){ - valor = this.nodeStatistics.getValue(1)/this.nodeStatistics.getValue(0); - } - return valor; - } - - @Override - public double[] getClassVotes(Instance inst, HoeffdingTree ht) { - double[] ret = new double[1]; - double perceptronPrediction = getPrediction(inst, ht); // Prediction using perceptron - double targetMeanPrediction = getPredictionTargetMean(inst, ht); // Prediction using Target Mean - double perceptronError = Math.abs(inst.classValue() - perceptronPrediction); - double targetMeanError = Math.abs(inst.classValue() - targetMeanPrediction); - if(perceptronError < targetMeanError){ // Adaptative strategy - ret[0] = perceptronPrediction; - }else{ - ret[0] = targetMeanPrediction; - } - - - return ret; - } - -/* @Override - public double[] getClassVotes(Instance inst, HoeffdingTree ht) { - double[] ret = {getPrediction(inst, ht)}; - return ret; - }*/ - - /** - * Return the error for a given instance - */ - public double getError(Instance inst) - { - return inst.classValue() - learningModel.prediction(inst); - } - - /** - * A method returning the Page-Hinckley error produced on this instance in the leaf node, - * which will then be back-propagated back through the tree to allow the - * Page-Hinckley change detection tests to be updated - */ - public double getPHError(Instance inst) - { - double sd = Math.sqrt((nodeStatistics.getValue(2) - ((nodeStatistics.getValue(1) * nodeStatistics.getValue(1))/nodeStatistics.getValue(0)))/nodeStatistics.getValue(0)); - double mean = nodeStatistics.getValue(1) / nodeStatistics.getValue(0); - return Math.abs(((inst.classValue()-mean)/sd) - ((learningModel.prediction(inst)-mean)/sd)) - ((nodeStatistics.getValue(3) + Math.abs(((inst.classValue()-mean)/sd) - ((learningModel.prediction(inst)-mean)/sd))) / (nodeStatistics.getValue(0)+1)); - } - - /** - * Returns the squared error, for use in determining if an alternate tree is performing better than an original - * tree, or if the alternate tree should be deleted - */ - public double getSquaredError() - { - return nodeStatistics.getValue(4); - } - } - - /** - * A modified SplitNode method implementing the extra information regarding it's parent, - * and the ability to track the error rate and perform Page-Hinckley tests - */ - public static class FIMTDDSplitNode extends SplitNode implements AdaptationCompatibleNode { - - // A reference to the parent of this node - protected Node parent; - - // The error values for the Page Hinckley test - // PHmT = the cumulative sum of the errors - // PHMT = the minimum error value seen so far - protected double PHmT = 0; - protected double PHMT = Double.MAX_VALUE; - - // Scope for an alternate tree that may need to be grown from this node - protected FIMTDD alternateTree; - - // Keep track of the statistics for loss error calculations - protected DoubleVector lossStatistics = new DoubleVector(); - - protected int weightSeen = 0; - protected int previousWeight = 0; - - /** - * Create a new FIMTDDSplitNode - */ - public FIMTDDSplitNode(InstanceConditionalTest splitTest, double[] classObservations) { - super(splitTest,classObservations); - } - - /** - * Set the parent node - */ - public void setParent(Node parent) - { - this.parent = parent; - } - - /** - * Return the parent node - */ - public Node getParent() - { - return parent; - } - - /** - * Check to see if the tree needs updating - */ - public boolean PageHinckleyTest(double error, double threshold) - { - // Update the cumulative mT sum - PHmT += error; - - // Update the minimum mT value if the new mT is - // smaller than the current minimum - if(PHmT < PHMT) - { - PHMT = PHmT; - } - // Return true if the cumulative value - the current minimum is - // greater than the current threshold (in which case we should adapt) - return PHmT - PHMT > threshold; - } - - /** - * This method has been added to the SplitNode subclass to allow alternate trees - * to be grown and compared to the current tree, to allow adaptation in the face - * of concept drift - */ - public void learnFromInstance(Instance inst, FIMTDD ht, boolean growingAltTree) { - - if(growingAltTree) - { - weightSeen++; - - // If no alternate tree exists - if (this.alternateTree == null) - { - // Start a new alternate tree, beginning with a learning node - this.alternateTree = (FIMTDD)ht.copy(); - this.alternateTree.resetLearningImpl(); - this.alternateTree.Adaptable = false; - - // Set up the blank statistics - // Number of instances reaching this node since the alternate tree was started - lossStatistics.setValue(0,0); - // Sum of Qi values - lossStatistics.setValue(1,0); - weightSeen = 0; - previousWeight = 0; - } - - // If an alternate tree already exists, check if the current tree should be replaced with it, - // or if the alternate tree should be discarded. - else if(weightSeen - previousWeight >= ht.AlternateTreeTMinOption.getValue()) - { - - // Update the weight at which a decision was tested for - previousWeight = weightSeen; - - // Update the loss statistics for the alternate tree - FoundNode foundNode = this.alternateTree.treeRoot.filterInstanceToLeaf(inst,null,-1); - Node leaf = foundNode.node; - double squaresAlternate= 0.0; - if(leaf instanceof FIMTDDActiveLearningNode) - { - squaresAlternate = ((FIMTDDActiveLearningNode)leaf).getSquaredError(); - - } - - // Update the loss statistics for the current tree - foundNode = this.getChild(this.instanceChildIndex(inst)).filterInstanceToLeaf(inst,null,-1); - leaf = foundNode.node; - double squaresOriginal = 0.0; - if(leaf instanceof FIMTDDActiveLearningNode) - { - squaresOriginal = ((FIMTDDActiveLearningNode)leaf).getSquaredError(); - - } - - // Compute the Qi statistics - double Qi = Math.log(squaresOriginal /squaresAlternate); - double previousQiAverage = lossStatistics.getValue(1) / lossStatistics.getValue(0); - lossStatistics.addToValue(0,1); - lossStatistics.addToValue(1,Qi); - double QiAverage = lossStatistics.getValue(1) / lossStatistics.getValue(0); - - // If appropriate, replace the current tree with the alternate tree - if(Qi > 0) - { - FIMTDDSplitNode parent = (FIMTDDSplitNode)this.parent; - //Replace the main FIMT-DD tree at a subtree - if(parent != null) - { - parent.setChild(parent.instanceChildIndex(inst),this.alternateTree.treeRoot); - ht.nodesToAdapt.remove(this); - this.alternateTree = null; - } - // Or occasionally at the root of the tree - else - { - ht = this.alternateTree; - ht.nodesToAdapt = new ArrayList(); - ht.Adaptable = true; - this.alternateTree = null; - } - - - } - // Otherwise, check if the alternate tree should be discarded - else if (QiAverage < previousQiAverage && lossStatistics.getValue(0) >= (10 * ht.AlternateTreeTMinOption.getValue()) || weightSeen >= ht.AlternateTreeTimeOption.getValue()) - { - ht.nodesToAdapt.remove(ht.nodesToAdapt.indexOf(this)); - this.alternateTree = null; - } - } - - // Learn the alternate tree (if it has not just been discarded) - if(this.alternateTree != null) - { - this.alternateTree.trainOnInstanceImpl(inst); - } - - - } - - // Determine which of the current children this instance should - // be sent to, and learn that child - int childBranch = this.instanceChildIndex(inst); - Node child = this.getChild(childBranch); - if (child != null) { - - if(child instanceof FIMTDDActiveLearningNode) - { - ((FIMTDDActiveLearningNode)child).learnFromInstance(inst, ht); - } - else - { - ((FIMTDDSplitNode)child).learnFromInstance(inst,ht, false); - } - } - } - - } - - /** - * A Perceptron classifier modified to conform to the specifications of Ikonomovska et al. - */ - public static class FIMTDDPerceptron extends AbstractMOAObject{ - - // The Perception weights - protected double[] weightAttribute; - - // Statistics used for error calculations - protected DoubleVector attributeStatistics = new DoubleVector(); - protected DoubleVector squaredAttributeStatistics = new DoubleVector(); - - // The number of instances contributing to this model - protected int instancesSeen = 0; - - // If the model should be reset or not - protected boolean reset; - - @Override - public void getDescription(StringBuilder sb, int indent) { - // TODO Auto-generated method stub - } - - public FIMTDDPerceptron(FIMTDDPerceptron copy) - { - this.weightAttribute = copy.getWeights(); - } - - public FIMTDDPerceptron() - { - this.reset = true; - } - - public void setWeights(double[] w) - { - this.weightAttribute = w; - } - - public double[] getWeights() - { - return this.weightAttribute; - } - - /** - * A method to reset the model - */ - public void resetLearningImpl() { - this.reset = true; - } - - /** - * Update the model using the provided instance - */ - public void trainOnInstanceImpl(Instance inst, FIMTDD ft) { - - // Initialise Perceptron if necessary - if (this.reset == true) { - this.reset = false; - this.weightAttribute = new double[inst.numAttributes()]; - this.instancesSeen = 0; - this.attributeStatistics = new DoubleVector(); - this.squaredAttributeStatistics = new DoubleVector(); - for (int j = 0; j < inst.numAttributes(); j++) { - weightAttribute[j] = 2 * Math.random() - 1; - } - } - - // Update attribute statistics - instancesSeen++; - for(int j = 0; j < inst.numAttributes() -1; j++) - { - attributeStatistics.addToValue(j, inst.value(j)); - squaredAttributeStatistics.addToValue(j, inst.value(j)*inst.value(j)); - } - - // Update weights - - double learningRatio = 0.0; - if(ft.learningRatio_Decay_or_Const_Option.isSet()){ - learningRatio = ft.learningRatioOption.getValue(); - }else{ - learningRatio = ft.initLearnRate / (1+ instancesSeen*ft.learnRateDecay); - } - // double learningRatio = ft.learningRatioOption.getValue(); - double actualClass = inst.classValue(); - double predictedClass = this.prediction(inst); - - //System.out.println("Actual Class: " + actualClass + " Prediction: " + predictedClass); - - // SET DELTA TO ACTUAL - PREDICTED, NOT PREDICTED - ACTUAL AS SAID IN PAPER - double delta = actualClass - predictedClass; - - for (int j = 0; j < inst.numAttributes() - 1; j++) { - - if(inst.attribute(j).isNumeric()) - { - // Update weights. Ensure attribute values are normalised first - double sd = Math.sqrt((squaredAttributeStatistics.getValue(j) - ((attributeStatistics.getValue(j) * attributeStatistics.getValue(j))/instancesSeen))/instancesSeen); - double instanceValue = 0; - if(sd > 0.0000001) // Limit found in implementation by Ikonomovska et al (2011) - { - instanceValue = (inst.value(j) - (attributeStatistics.getValue(j)/instancesSeen))/(3*sd); - } - this.weightAttribute[j] += learningRatio * delta * instanceValue; - } - } - this.weightAttribute[inst.numAttributes() - 1] += learningRatio * delta; - } - - /** - * Output the prediction made by this perceptron on the given instance - */ - public double prediction(Instance inst) - { - double prediction = 0; - if(this.reset == false) - { - for (int j = 0; j < inst.numAttributes() - 1; j++) { - if(inst.attribute(j).isNumeric()) - { - prediction += this.weightAttribute[j] * inst.value(j); - } - } - prediction += this.weightAttribute[inst.numAttributes() - 1]; - } - - // Return prediction to 3dp - return (double)Math.round(prediction * 1000) / 1000; - } - - } - - - - //=============================== METHODS ================================// - - //================= TRAIN and TEST ================// - /** - * Method for updating (training) the model using a new instance - */ - @Override - public void trainOnInstanceImpl(Instance inst) { - - // Convert any nominal attributes to numeric ones??? - - // If no model exists yet, begin with an empty leaf node (the root) - if (this.treeRoot == null) { - this.treeRoot = newLearningNode(); - this.activeLeafNodeCount = 1; - } - - // Take the current example and traverse it through the tree to a leaf - FoundNode foundNode = this.treeRoot.filterInstanceToLeaf(inst, null, -1); - Node leafNode = foundNode.node; - - // If no appropriate leaf already existed, create one - if (leafNode == null) { - FIMTDDActiveLearningNode newNode = newLearningNode(); - foundNode.parent.setChild(foundNode.parentBranch, newNode); - newNode.setParent(foundNode.parent); - leafNode = newNode; - this.activeLeafNodeCount++; - } - - // Update the change detection tests on the path traversed in a bottom-up - // fashion (i.e. using the error from the leaf node) - if(leafNode instanceof FIMTDDActiveLearningNode) - { - FIMTDDActiveLearningNode currentNode = (FIMTDDActiveLearningNode)leafNode; - - // Retrieve the error for the found leaf node - //currentNode.learnFromInstance(inst, this); - Double leafError = currentNode.getPHError(inst) - this.PageHinckleyAlphaOption.getValue(); - - // Back-propagate the error through all the parent nodes - FIMTDDSplitNode parent = (FIMTDDSplitNode)currentNode.getParent(); - while(parent != null && Adaptable) - { - // Update the Page-Hinckley error test in the parent node - if(parent.PageHinckleyTest(leafError, this.PageHinckleyThresholdOption.getValue()) == true) - { - if(!nodesToAdapt.contains(parent)) - { - nodesToAdapt.add(parent); - nodesToAdapt.remove(parent.getChild(parent.instanceChildIndex(inst))); - } - } - - // Propagate back to the next parent node - parent = (FIMTDDSplitNode)parent.getParent(); - } - } - - if(nodesToAdapt.size() > 0 && Adaptable) - { - // Adapt the model tree by creating an alternate tree at this node which - // will be updated as new instances arrive and may, in time, replace the current subtree - for(int i = 0; i < nodesToAdapt.size(); i++) - { - nodesToAdapt.get(i).learnFromInstance(inst, this, true); - } - - } - else - { - // Check that the current node is in fact a leaf node (i.e. that we - // haven't accidently stopped earlier in the tree) - if (leafNode instanceof LearningNode) { - - LearningNode learningNode = (LearningNode) leafNode; - - // Update the statistics in this leaf node, based on the new instance - learningNode.learnFromInstance(inst, this); - - // Provided growth is allowed, and this leaf node hasn't been deactivated... - if (this.growthAllowed && (learningNode instanceof FIMTDDActiveLearningNode)) { - - // Extract details about this leaf, and the number of examples it has seen - FIMTDDActiveLearningNode activeLearningNode = (FIMTDDActiveLearningNode) learningNode; - double weightSeen = activeLearningNode.getWeightSeen(); - - // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node - if (weightSeen - activeLearningNode.getWeightSeenAtLastSplitEvaluation() >= this.gracePeriodOption.getValue()) { - - FIMTDD_attemptToSplit(activeLearningNode, (FIMTDDSplitNode)foundNode.parent, foundNode.parentBranch); - - // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation - activeLearningNode.setWeightSeenAtLastSplitEvaluation(weightSeen); - } - } - } - - /*if (this.trainingWeightSeenByModel% this.memoryEstimatePeriodOption.getValue() == 0) { - estimateModelByteSizes(); - }*/ - } - } - - - /** - * Method used to split a leaf node and generate child nodes, if appropriate - */ - protected void FIMTDD_attemptToSplit(FIMTDDActiveLearningNode node, FIMTDDSplitNode parent, int parentIndex) { - - // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); - - // Using this criterion, find the best split per attribute and rank the results - AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion, this); - Arrays.sort(bestSplitSuggestions); - - // Declare a variable to determine if any of the splits should be performed - boolean shouldSplit = false; - - // If only one split was returned, use it - if (bestSplitSuggestions.length < 2) { - shouldSplit = bestSplitSuggestions.length > 0; - } - // Otherwise, consider which of the splits proposed may be worth trying - else { - - // Determine the hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1,this.splitConfidenceOption.getValue(), node.getWeightSeen()); - - // Determine the top two ranked splitting suggestions - AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - - splitRatioStatistics.addToValue(0,1); - splitRatioStatistics.addToValue(1,secondBestSuggestion.merit / bestSuggestion.merit); - - // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), - // as determined using the hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this - // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and - // splitting should occur. - // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit - // (default 0.05) is applied to the hoeffding bound; if the hoeffding bound is smaller than this limit then the two - // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - if ((((splitRatioStatistics.getValue(1)/splitRatioStatistics.getValue(0)) + hoeffdingBound) < 1) || (hoeffdingBound < this.tieThresholdOption.getValue())) { - - shouldSplit = true; - - } - // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - else - { - for (int i = 0; i < node.attributeObservers.size(); i++) { - AttributeClassObserver obs = node.attributeObservers.get(i); - if (obs != null) { - ((FIMTDDNumericAttributeClassObserver)obs).removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); - } - } - } - - - // If the user has selected this option, it is also possible to remove poor attributes at this stage - if ((this.removePoorAttsOption != null) - && this.removePoorAttsOption.isSet()) { - Set poorAtts = new HashSet(); - // scan 1 - add any poor to set - for (int i = 0; i < bestSplitSuggestions.length; i++) { - if (bestSplitSuggestions[i].splitTest != null) { - int[] splitAtts = bestSplitSuggestions[i].splitTest.getAttsTestDependsOn(); - if (splitAtts.length == 1) { - if (((bestSuggestion.merit / secondBestSuggestion.merit) + hoeffdingBound) < 1) { - poorAtts.add(new Integer(splitAtts[0])); - } - } - } - } - // scan 2 - remove good ones from set - for (int i = 0; i < bestSplitSuggestions.length; i++) { - if (bestSplitSuggestions[i].splitTest != null) { - int[] splitAtts = bestSplitSuggestions[i].splitTest.getAttsTestDependsOn(); - if (splitAtts.length == 1) { - if (((bestSuggestion.merit / secondBestSuggestion.merit) + hoeffdingBound) < 1) { - poorAtts.remove(new Integer(splitAtts[0])); - } - } - } - } - for (int poorAtt : poorAtts) { - node.disableAttribute(poorAtt); - } - } - } - - // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (shouldSplit) { - - - AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - - // Deactivate this node if the best split was to do nothing - if (splitDecision.splitTest == null) { - // preprune - null wins - deactivateLearningNode(node, parent, parentIndex); - } - // Otherwise - else { - - FIMTDDSplitNode newSplit = newSplitNode(splitDecision.splitTest, - node.getObservedClassDistribution()); - for (int i = 0; i < splitDecision.numSplits(); i++) { - FIMTDDActiveLearningNode newChild = newLearningNode(splitDecision.resultingClassDistributionFromSplit(i)); - newChild.learningModel = new FIMTDDPerceptron(node.learningModel); - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - } - this.activeLeafNodeCount--; - this.decisionNodeCount++; - this.activeLeafNodeCount += splitDecision.numSplits(); - if (parent == null) { - this.treeRoot = newSplit; - } else { - parent.setChild(parentIndex, newSplit); - newSplit.setParent(parent); - } - - } - // Check the memory limits are not being exceeded - enforceTrackerLimit(); - } - } - - /** - * Return an empty FIMTDDActiveLearningNode - */ - protected FIMTDDActiveLearningNode newLearningNode() { - return newLearningNode(new double[0]); - } - - /** - * Return a new FIMTDDActiveLearningNode using the initial class observations - */ - protected FIMTDDActiveLearningNode newLearningNode(double[] initialClassObservations) { - return new FIMTDDActiveLearningNode(initialClassObservations); - } - - /** - * Return a new FIMTDDSplitNode - */ - protected FIMTDDSplitNode newSplitNode(InstanceConditionalTest splitTest,double[] classObservations) { - return new FIMTDDSplitNode(splitTest, classObservations); - } -} +/* + * FIMTDD.java + * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia + * @author Aljaž Osojnik + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package moa.classifiers.trees; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import com.yahoo.labs.samoa.instances.Instance; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; + +import moa.options.ClassOption; +import moa.AbstractMOAObject; +import moa.classifiers.Regressor; +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; +import moa.classifiers.core.conditionaltests.InstanceConditionalTest; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.classifiers.AbstractClassifier; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.Measurement; +import moa.core.SizeOf; +import moa.core.StringUtils; + +/* + * Implementation of FIMTDD, regression and model trees for data streams. + */ + +public class FIMTDD extends AbstractClassifier implements Regressor { + + private static final long serialVersionUID = 1L; + + protected Node treeRoot; + + protected int leafNodeCount = 0; + protected int splitNodeCount = 0; + + protected double examplesSeen = 0.0; + protected double sumOfValues = 0.0; + protected double sumOfSquares = 0.0; + + protected DoubleVector sumOfAttrValues = new DoubleVector(); + protected DoubleVector sumOfAttrSquares = new DoubleVector(); + + public int maxID = 0; + + //region ================ OPTIONS ================ + + public ClassOption splitCriterionOption = new ClassOption( + "splitCriterion", 's', "Split criterion to use.", + SplitCriterion.class, "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); + + public IntOption gracePeriodOption = new IntOption( + "gracePeriod", 'g', "Number of instances a leaf should observe between split attempts.", + 200, 0, Integer.MAX_VALUE); + + public FloatOption splitConfidenceOption = new FloatOption( + "splitConfidence", 'c', "Allowed error in split decision, values close to 0 will take long to decide.", + 0.0000001, 0.0, 1.0); + + public FloatOption tieThresholdOption = new FloatOption( + "tieThreshold", 't', "Threshold below which a split will be forced to break ties.", + 0.05, 0.0, 1.0); + + public FloatOption PageHinckleyAlphaOption = new FloatOption( + "PageHinckleyAlpha", 'a', "Alpha value to use in the Page Hinckley change detection tests.", + 0.005, 0.0, 1.0); + + public IntOption PageHinckleyThresholdOption = new IntOption( + "PageHinckleyThreshold", 'h', "Threshold value used in the Page Hinckley change detection tests.", + 50, 0, Integer.MAX_VALUE); + + public FloatOption alternateTreeFadingFactorOption = new FloatOption( + "alternateTreeFadingFactor", 'f', "Fading factor used to decide if an alternate tree should replace an original.", + 0.995, 0.0, 1.0); + + public IntOption alternateTreeTMinOption = new IntOption( + "alternateTreeTMin", 'y', "Tmin value used to decide if an alternate tree should replace an original.", + 150, 0, Integer.MAX_VALUE); + + public IntOption alternateTreeTimeOption = new IntOption( + "alternateTreeTime", 'u', "The number of instances used to decide if an alternate tree should be discarded.", + 1500, 0, Integer.MAX_VALUE); + + public FlagOption regressionTreeOption = new FlagOption( + "regressionTree", 'e', "Build a regression tree instead of a model tree."); + + public FloatOption learningRatioOption = new FloatOption( + "learningRatio", 'l', "Learning ratio to used for training the Perceptrons in the leaves.", + 0.003, 0, 1.00); + + public FloatOption learningRateDecayFactorOption = new FloatOption( + "learningRatioDecayFactor", 'd', "Learning rate decay factor (not used when learning rate is constant).", + 0.001, 0, 1.00); + + public FlagOption learningRatioConstOption = new FlagOption( + "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public abstract static class Node extends AbstractMOAObject { + + private static final long serialVersionUID = 1L; + + public int ID; + + protected FIMTDD tree; + + protected boolean changeDetection = true; + + protected Node parent; + + protected Node alternateTree; + protected Node originalNode; + + // The statistics for this node: + // Number of instances that have reached it + protected double examplesSeen; + // Sum of y values + protected double sumOfValues; + // Sum of squared y values + protected double sumOfSquares; + // Sum of absolute errors + protected double sumOfAbsErrors; // Needed for PH tracking of mean error + + public Node(FIMTDD tree) { + this.tree = tree; + ID = tree.maxID; + } + + public void copyStatistics(Node node) { + examplesSeen = node.examplesSeen; + sumOfValues = node.sumOfValues; + sumOfSquares = node.sumOfSquares; + sumOfAbsErrors = node.sumOfAbsErrors; + } + + public int calcByteSize() { + return (int) SizeOf.fullSizeOf(this); + } + + /** + * Set the parent node + */ + public void setParent(Node parent) { + this.parent = parent; + } + + /** + * Return the parent node + */ + public Node getParent() { + return parent; + } + + public void disableChangeDetection() { + changeDetection = false; + } + + public void restartChangeDetection() { + changeDetection = true; + } + + public void getDescription(StringBuilder sb, int indent) { + + } + + public double getPrediction(Instance inst) { + return 0; + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf"); + } + + public int getLevel() { + Node target = this; + int level = 0; + while (target.getParent() != null) { + if (target.skipInLevelCount()) { + target = target.getParent(); + continue; + } + level = level + 1; + target = target.getParent(); + } + if (target.originalNode == null) { + return level; + } else { + return level + originalNode.getLevel(); + } + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + } + + public static class LeafNode extends Node { + + private static final long serialVersionUID = 1L; + + public double errorModel = 0.0; + public double errorTargetMean = 0.0; + + // Perceptron model that carries out the actual learning in each node + public FIMTDDPerceptron learningModel; + + protected AutoExpandVector attributeObservers = new AutoExpandVector(); + + protected double examplesSeenAtLastSplitEvaluation = 0; + + /** + * Create a new LeafNode + */ + public LeafNode(FIMTDD tree) { + super(tree); + if (tree.buildingModelTree()) { + learningModel = tree.newLeafModel(); + } + examplesSeen = 0; + sumOfValues = 0; + sumOfSquares = 0; + sumOfAbsErrors = 0; + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + + /** + * Method to learn from an instance that passes the new instance to the perceptron learner, + * and also prevents the class value from being truncated to an int when it is passed to the + * attribute observer + */ + public void learnFromInstance(Instance inst, boolean growthAllowed, double prediction) { + //The prediction must be calculated here -- it may be different from the tree's prediction due to alternate trees + + // Update the statistics for this node + // number of instances passing through the node + examplesSeen += inst.weight(); + + // sum of y values + sumOfValues += inst.weight() * inst.classValue(); + + // sum of squared y values + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + // sum of absolute errors + sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - prediction))); + + if (tree.buildingModelTree()) { + double predictionModel = getPredictionModel(inst); + double predictionTargetMean = getPredictionTargetMean(inst); + + errorModel = errorModel * 0.95 + Math.abs(predictionModel - inst.classValue()); + errorTargetMean = errorTargetMean * 0.95 + Math.abs(predictionTargetMean - inst.classValue()); + + learningModel.updatePerceptron(inst); + } + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); + FIMTDDNumericAttributeClassObserver obs = attributeObservers.get(i); + if (obs == null) { + // At this stage all nominal attributes are ignored + if (inst.attribute(instAttIndex).isNumeric()) { + obs = tree.newNumericClassObserver(); + this.attributeObservers.set(i, obs); + } + } + if (obs != null) { + obs.observeAttributeClass(inst.value(instAttIndex), inst.classValue(), inst.weight()); + } + } + + if (growthAllowed) { + checkForSplit(); + } + } + + /** + * Return the best split suggestions for this node using the given split criteria + */ + public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion) { + + List bestSuggestions = new LinkedList(); + + // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution + double[] nodeSplitDist = new double[] {examplesSeen, sumOfValues, sumOfSquares}; + + for (int i = 0; i < this.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = this.attributeObservers.get(i); + if (obs != null) { + + // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED + AttributeSplitSuggestion bestSuggestion = null; + if (obs instanceof FIMTDDNumericAttributeClassObserver) { + bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, nodeSplitDist, i, true); + } + + if (bestSuggestion != null) { + bestSuggestions.add(bestSuggestion); + } + } + } + return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); + } + + /** + * Retrieve the class votes using the perceptron learner + */ + public double getPredictionModel(Instance inst) { + return learningModel.prediction(inst); + } + + public double getPredictionTargetMean(Instance inst) { + return (examplesSeen > 0.0) ? sumOfValues / examplesSeen : 0.0; + } + + public double getPrediction(Instance inst) { + if (tree.buildingModelTree()) { + //return getPredictionModel(inst); + return (errorModel < errorTargetMean) ? getPredictionModel(inst) : getPredictionTargetMean(inst); + } else + return getPredictionTargetMean(inst); + } + + public void checkForSplit() { + // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node + if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { + int index = (parent != null) ? parent.getChildIndex(this) : 0; + tree.attemptToSplit(this, parent, index); + + // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation + examplesSeenAtLastSplitEvaluation = examplesSeen; + } + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf "); + if (tree.buildingModelTree()) { + learningModel.getModelDescription(out, 0); + } else { + out.append(tree.getClassNameString() + " = " + String.format("%.4f", sumOfValues / examplesSeen)); + StringUtils.appendNewline(out); + } + } + } + + public abstract static class InnerNode extends Node { + // The InnerNode and SplitNode design is used for easy extension in ORTO + private static final long serialVersionUID = 1L; + + protected AutoExpandVector children = new AutoExpandVector(); + + // The error values for the Page Hinckley test + // PHmT = the cumulative sum of the errors + // PHMT = the minimum error value seen so far + protected double PHsum = 0; + protected double PHmin = Double.MAX_VALUE; + + // Keep track of the statistics for loss error calculations + protected double lossExamplesSeen; + protected double lossFadedSumOriginal; + protected double lossFadedSumAlternate; + protected double lossNumQiTests; + protected double lossSumQi; + protected double previousWeight = 0; + + public InnerNode(FIMTDD tree) { + super(tree); + } + + public int numChildren() { + return children.size(); + } + + public Node getChild(int index) { + return children.get(index); + } + + public int getChildIndex(Node child) { + return children.indexOf(child); + } + + public void setChild(int index, Node child) { + children.set(index, child); + } + + public void disableChangeDetection() { + changeDetection = false; + for (Node child : children) { + child.disableChangeDetection(); + } + } + + public void restartChangeDetection() { + if (alternateTree == null) { + changeDetection = true; + PHsum = 0; + PHmin = Integer.MAX_VALUE; + for (Node child : children) + child.restartChangeDetection(); + } + } + + /** + * Check to see if the tree needs updating + */ + public boolean PageHinckleyTest(double error, double threshold) { + // Update the cumulative mT sum + PHsum += error; + + // Update the minimum mT value if the new mT is + // smaller than the current minimum + if(PHsum < PHmin) { + PHmin = PHsum; + } + // Return true if the cumulative value - the current minimum is + // greater than the current threshold (in which case we should adapt) + return PHsum - PHmin > threshold; + } + + public void initializeAlternateTree() { + // Start a new alternate tree, beginning with a learning node + alternateTree = tree.newLeafNode(); + alternateTree.originalNode = this; + + // Set up the blank statistics + // Number of instances reaching this node since the alternate tree was started + lossExamplesSeen = 0; + // Faded squared error (original tree) + lossFadedSumOriginal = 0; + // Faded squared error (alternate tree) + lossFadedSumAlternate = 0; + // Number of evaluations of alternate tree + lossNumQiTests = 0; + // Sum of Qi values + lossSumQi = 0; + // Number of examples at last test + previousWeight = 0; + + // Disable the change detection mechanism bellow this node + disableChangeDetection(); + } + } + + public static class SplitNode extends InnerNode { + + private static final long serialVersionUID = 1L; + + protected InstanceConditionalTest splitTest; + + /** + * Create a new SplitNode + * @param tree + */ + public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { + super(tree); + this.splitTest = splitTest; + } + + public int instanceChildIndex(Instance inst) { + return splitTest.branchForInstance(inst); + } + + public Node descendOneStep(Instance inst) { + return children.get(splitTest.branchForInstance(inst)); + } + + public void describeSubtree(StringBuilder out, int indent) { + for (int branch = 0; branch < children.size(); branch++) { + Node child = getChild(branch); + if (child != null) { + StringUtils.appendIndented(out, indent, "if "); + out.append(this.splitTest.describeConditionForBranch(branch, + tree.getModelContext())); + out.append(": "); + StringUtils.appendNewline(out); + child.describeSubtree(out, indent + 2); + } + } + } + + public double getPrediction(Instance inst) { + return children.get(splitTest.branchForInstance(inst)).getPrediction(inst); + } + } + + public class FIMTDDPerceptron implements Serializable { + + private static final long serialVersionUID = 1L; + + protected FIMTDD tree; + + // The Perception weights + protected double[] weightAttribute; + + // The number of instances contributing to this model + protected double instancesSeen = 0; + + public String getPurposeString() { + return "A perceptron regressor as specified by Ikonomovska et al. used for FIMTDD"; + } + + public FIMTDDPerceptron(FIMTDDPerceptron original) { + this.tree = original.tree; + weightAttribute = original.weightAttribute.clone(); + } + + public FIMTDDPerceptron(FIMTDD tree) { + this.tree = tree; + initializeWeights(); + + } + + public void initializeWeights() { + weightAttribute = new double[tree.getModelContext().numInputAttributes()+1]; + instancesSeen = 0; + for (int j = 0; j < tree.getModelContext().numInputAttributes()+1; j++) { + // The last index corresponds to the constant b + weightAttribute[j] = 2 * tree.classifierRandom.nextDouble() - 1; + } + normalizeWeights(); + } + + /** + * Update the model using the provided instance + */ + public void updatePerceptron(Instance inst) { + + // Update attribute statistics + instancesSeen += inst.weight(); + + // Update weights + double learningRatio = 0.0; + if (tree.learningRatioConstOption.isSet()) { + learningRatio = learningRatioOption.getValue(); + } else { + learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); + } + + // Loop for compatibility with bagging methods + for (int i = 0; i < (int) inst.weight(); i++) { + updateWeights(inst, learningRatio); + } + + } + + public void updateWeights(Instance inst, double learningRatio) { + // Compute the normalized instance and the delta + double[] normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + double normalizedValue = tree.normalizeTargetValue(inst.classValue()); + double delta = normalizedValue - normalizedPrediction; + for (int i = 0; i < weightAttribute.length; i++) { + weightAttribute[i] += delta * learningRatio * normalizedInstance[i]; + } + + normalizeWeights(); + } + + public void normalizeWeights() { + double sum = 0; + for (int i = 0; i < this.weightAttribute.length; i++) + sum += Math.abs(weightAttribute[i]); + for (int i = 0; i < this.weightAttribute.length; i++) + weightAttribute[i] /= sum; + } + + public double[] normalizedInstance(Instance inst) { + // Normalize Instance + double[] normalizedInstance = new double[inst.numInputAttributes()+1]; + for (int j = 0; j < inst.numInputAttributes(); j++) { + double mean = tree.sumOfAttrValues.getValue(j) / tree.examplesSeen; + double sd = computeSD(tree.sumOfAttrSquares.getValue(j), tree.sumOfAttrValues.getValue(j), tree.examplesSeen); + if (inst.inputAttribute(j).isNumeric() && tree.examplesSeen > 1 && sd > 0.0000001) + normalizedInstance[j] = (inst.valueInputAttribute(j) - mean) / (sd); + else + normalizedInstance[j] = 0; + } + normalizedInstance[inst.numInputAttributes()] = tree.examplesSeen > 1 ? 1 : 0; // Value to be multiplied with the constant factor + return normalizedInstance; + } + + /** + * Output the prediction made by this perceptron on the given instance + */ + public double prediction(double[] instanceValues) { + double ret = 0; + for (int i = 0; i < instanceValues.length; i++) + ret += instanceValues[i] * weightAttribute[i]; + return ret; + } + + protected double prediction(Instance inst) { + double[] normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + return denormalizePrediction(normalizedPrediction); + } + + private double denormalizePrediction(double normalizedPrediction) { + double mean = tree.sumOfValues / tree.examplesSeen; + double sd = computeSD(tree.sumOfSquares, tree.sumOfValues, tree.examplesSeen); + if (examplesSeen > 1) + return normalizedPrediction * sd + mean; + else + return 0.0; + } + + public void getModelDescription(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, getClassNameString() + " ="); + if (getModelContext() != null) { + for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { + if (getModelContext().attribute(j).isNumeric()) { + out.append((j == 0 || weightAttribute[j] < 0) ? " " : " + "); + out.append(String.format("%.4f", weightAttribute[j])); + out.append(" * "); + out.append(getAttributeNameString(j)); + } + } + out.append(" + " + weightAttribute[getModelContext().numInputAttributes()]); + } + StringUtils.appendNewline(out); + } + } + + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + // region --- Regressor methods + + public String getPurposeString() { + return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + this.treeRoot = null; + this.leafNodeCount = 0; + this.splitNodeCount = 0; + this.maxID = 0; + this.examplesSeen = 0; + this.sumOfValues = 0.0; + this.sumOfSquares = 0.0; + + this.sumOfAttrValues = new DoubleVector(); + this.sumOfAttrSquares = new DoubleVector(); + } + + public boolean isRandomizable() { + return true; + } + + public void getModelDescription(StringBuilder out, int indent) { + if (treeRoot != null) treeRoot.describeSubtree(out, indent); + } + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("tree size (leaves)", this.leafNodeCount) + }; + } + + public int calcByteSize() { + return (int) SizeOf.fullSizeOf(this); + } + + public double[] getVotesForInstance(Instance inst) { + if (treeRoot == null) { + return new double[] {0}; + } + + double prediction = treeRoot.getPrediction(inst); + + return new double[] {prediction}; + } + + public double normalizeTargetValue(double value) { + if (examplesSeen > 1) { + double sd = Math.sqrt((sumOfSquares - ((sumOfValues * sumOfValues)/examplesSeen))/examplesSeen); + double average = sumOfValues / examplesSeen; + if (sd > 0 && examplesSeen > 1) + return (value - average) / sd; + else + return 0.0; + } + return 0.0; + } + + public double getNormalizedError(Instance inst, double prediction) { + double normalPrediction = normalizeTargetValue(prediction); + double normalValue = normalizeTargetValue(inst.classValue()); + return Math.abs(normalValue - normalPrediction); + } + + + /** + * Method for updating (training) the model using a new instance + */ + public void trainOnInstanceImpl(Instance inst) { + checkRoot(); + + double prediction = treeRoot.getPrediction(inst); + double normalError = getNormalizedError(inst, prediction); + + processInstance(inst, treeRoot, prediction, normalError, true, false); + + examplesSeen += inst.weight(); + sumOfValues += inst.weight() * inst.classValue(); + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int aIndex = modelAttIndexToInstanceAttIndex(i, inst); + sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); + } + + + } + + public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); + break; + } else { + currentNode.examplesSeen += inst.weight(); + currentNode.sumOfAbsErrors += inst.weight() * normalError; + InnerNode iNode = (InnerNode) currentNode; + if (!inAlternate && iNode.alternateTree != null) { + boolean altTree = true; + double lossO = Math.pow(inst.classValue() - prediction, 2); + double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); + + // Loop for compatibility with bagging methods + for (int i = 0; i < inst.weight(); i++) { + iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + iNode.lossExamplesSeen++; + + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + iNode.lossSumQi += Qi; + iNode.lossNumQiTests += 1; + } + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + + if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + iNode.previousWeight = iNode.lossExamplesSeen; + if (Qi > 0) { + // Switch the subtrees + Node parent = iNode.getParent(); + + if (parent != null) { + Node replacementTree = iNode.alternateTree; + parent.setChild(parent.getChildIndex(iNode), replacementTree); + if (growthAllowed) replacementTree.restartChangeDetection(); + } else { + treeRoot = iNode.alternateTree; + treeRoot.restartChangeDetection(); + } + + currentNode = iNode.alternateTree; + currentNode.originalNode = null; + altTree = false; + } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { + // Remove the alternate tree + iNode.alternateTree = null; + if (growthAllowed) iNode.restartChangeDetection(); + altTree = false; + } + } + + if (altTree) { + growthAllowed = false; + processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + } + } + + if (false && iNode.changeDetection && !inAlternate) { + if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + iNode.initializeAlternateTree(); + growthAllowed = false; + } + } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).descendOneStep(inst); + } + } + } + } + + // endregion --- Regressor methods + + // region --- Object instatiation methods + + protected FIMTDDNumericAttributeClassObserver newNumericClassObserver() { + return new FIMTDDNumericAttributeClassObserver(); + } + + protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + maxID++; + return new SplitNode(splitTest, this); + } + + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } + + protected FIMTDDPerceptron newLeafModel() { + return new FIMTDDPerceptron(this); + } + + //endregion --- Object instatiation methods + + // region --- Processing methods + + protected void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + leafNodeCount = 1; + } + } + + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } + + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } + + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); + + // Using this criterion, find the best split per attribute and rank the results + AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine if any of the splits should be performed + boolean shouldSplit = false; + + // If only one split was returned, use it + if (bestSplitSuggestions.length < 2) { + shouldSplit = bestSplitSuggestions.length > 0; + } else { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, this.splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { + shouldSplit = true; + } + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + else { + for (int i = 0; i < node.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = node.attributeObservers.get(i); + if (obs != null) { + obs.removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); + } + } + } +// if (hoeffdingBound < this.tieThresholdOption.getValue() && !(secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound)) { +// System.out.println("Forced to split due to tie at " + this.examplesSeen); +// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); +// } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (shouldSplit) { +// System.out.println("splitting node"); +// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); +// if (node.parent == null) { +// System.out.println("splitting root node at " + this.examplesSeen); +// } + AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + + SplitNode newSplit = newSplitNode(splitDecision.splitTest); + newSplit.copyStatistics(node); + newSplit.changeDetection = node.changeDetection; + newSplit.ID = node.ID; + leafNodeCount--; + for (int i = 0; i < splitDecision.numSplits(); i++) { + LeafNode newChild = newLeafNode(); + if (buildingModelTree()) { + // Copy the splitting node's perceptron to it's children + newChild.learningModel = new FIMTDDPerceptron((FIMTDDPerceptron) node.learningModel); + + } + newChild.changeDetection = node.changeDetection; + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + leafNodeCount++; + } + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + ((SplitNode) parent).setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + + splitNodeCount++; + } + } + + public double computeSD(double squaredVal, double val, double size) { + if (size > 1) + return Math.sqrt((squaredVal - ((val * val) / size)) / size); + else + return 0.0; + } + + public double scalarProduct(DoubleVector u, DoubleVector v) { + double ret = 0.0; + for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { + ret += u.getValue(i) * v.getValue(i); + } + return ret; + } + //endregion --- Processing methods + + //endregion ================ METHODS ================ +} + diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index fcdff7f73..d0a6ab79d 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -1,7 +1,7 @@ - /* +/* * ORTO.java - * Copyright (C) Jožef Stefan Institute, Ljubljana - * @author Aljaž Osojnik + * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia + * @author Aljaž Osojnik * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,1359 +18,515 @@ * */ -/* Based on the FIMTDD implementation by Katie de Lange, E. Almeida, J. Gama. See FIMTDD.java. - * - * Contact: aljaz.osojnik@ijs.si - */ - package moa.classifiers.trees; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; import java.util.Stack; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Set; -import moa.AbstractMOAObject; -import moa.classifiers.AbstractClassifier; + +import com.yahoo.labs.samoa.instances.Instance; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; + import moa.classifiers.Regressor; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.NullAttributeClassObserver; -import moa.classifiers.core.conditionaltests.InstanceConditionalTest; -import moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion; -// import moa.classifiers.core.splitcriteria.SDRSplitCriterion; import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.core.DoubleVector; +import moa.classifiers.trees.FIMTDD.InnerNode; +import moa.classifiers.trees.FIMTDD.Node; import moa.core.AutoExpandVector; import moa.core.Measurement; -import moa.core.SizeOf; -import moa.options.ClassOption; -// import weka.core.Utils; +import moa.core.StringUtils; /* - * Implementation of ORTO, option tree for data streams. + * Implementation of ORTO, option trees for data streams. */ -public class ORTO extends AbstractClassifier implements Regressor{ - - private static final long serialVersionUID = 1L; - - //============================== INTERNALS ===============================// - - protected Node treeRoot; - - private int leafNodeCount = 0; - private int innerNodeCount = 0; - private int optionNodeCount = 0; - - private int numTrees = 1; - - protected int maxDepth = 0; - - protected double inactiveLeafByteSizeEstimate; - - protected double activeLeafByteSizeEstimate; - - protected double byteSizeEstimateOverheadFraction; - - // Store the lowest node (lowest level) in the tree that requires adaptation - protected ArrayList nodesToAdapt = new ArrayList(); - - protected boolean Adaptable = true; - - protected double initLearnRate = 0.1; - - protected double learnRateDecay = 0.001; - - public int maxID = 0; - - private double learnTime = 0.0; - - private double predictTime = 0.0; - - //============================ END INTERNALS =============================// - - //============================= SET OPTIONS ==============================// - - public FloatOption PageHinckleyAlphaOption = new FloatOption( - "PageHinckleyAlpha", - 'a', - "The alpha value to use in the Page Hinckley change detection tests.", - 0.005, 0.0, 1.0); - - public IntOption PageHinckleyThresholdOption = new IntOption( - "PageHinckleyThreshold", - 'h', - "The threshold value to be used in the Page Hinckley change detection tests.", - 50, 0, Integer.MAX_VALUE); - - public FloatOption AlternateTreeFadingFactorOption = new FloatOption( - "AlternateTreeFadingFactor", - 'f', - "The fading factor to use when deciding if an alternate tree should replace an original.", - 0.995, 0.0, 1.0); - - public IntOption AlternateTreeTMinOption = new IntOption( - "AlternateTreeTMin", - 'y', - "The Tmin value to use when deciding if an alternate tree should replace an original.", - 150, 0, Integer.MAX_VALUE); - - public IntOption AlternateTreeTimeOption = new IntOption( - "AlternateTreeTime", - 'u', - "The 'time' (in terms of number of instances) value to use when deciding if an alternate tree should be discarded.", - 1500, 0, Integer.MAX_VALUE); - - public FloatOption LearningRatioOption = new FloatOption( - "LearningRatio", - 'w', - "Learning ratio to use for training the Perceptrons in the leaves.", - 0.01, 0.0, 1.0); - - public FlagOption LearningRatioDecayOrConstOption = new FlagOption( - "LearningRatioDecayOrConst", - 'j', - "learning Ratio Decay or const parameter."); - - public IntOption MaxTreesOption = new IntOption( - "MaxTrees", - 'm', - "The maximum number of trees contained in the option tree.", - 10, 1, Integer.MAX_VALUE); - - public IntOption MaxOptionLevelOption = new IntOption( - "MaxOptionLevel", - 'l', - "The maximal depth at which option nodes can be created.", - 10, 0, Integer.MAX_VALUE); - - public FloatOption OptionDecayFactorOption = new FloatOption( - "OptionDecayFactor", - 'd', - "The option decay factor that determines how many options can be selected at a given level.", - 0.9, 0.0, 1.0); - - public ClassOption splitCriterionOption = new ClassOption( - "splitCriterion", - 's', - "Split criterion to use.", - VarianceReductionSplitCriterion.class, - "VarianceReductionSplitCriterion"); - - public ClassOption numericEstimatorOption = new ClassOption( - "numericEstimator", - 'n', - "Numeric estimator to use.", - FIMTDDNumericAttributeClassObserver.class, - "FIMTDDNumericAttributeClassObserver"); - - public IntOption gracePeriodOption = new IntOption( - "gracePeriod", - 'g', - "The number of instances a leaf should observe between split attempts.", - 200, 0, Integer.MAX_VALUE); - - public FloatOption splitConfidenceOption = new FloatOption( - "splitConfidence", - 'c', - "The allowable error in split decision, values closer to 0 will take longer to decide.", - 0.0000001, 0.0, 1.0); - - public FloatOption tieThresholdOption = new FloatOption( - "tieThreshold", - 't', - "Threshold below which a split will be forced to break ties.", - 0.05, 0.0, 1.0); - - public FlagOption removePoorAttsOption = new FlagOption( - "removePoorAtts", - 'p', - "Disable poor attributes."); - - public MultiChoiceOption OptionNodeAggregationOption = new MultiChoiceOption( - "OptionNodeAggregation", - 'o', - "The aggregation method used to combine predictions in option nodes.", - new String[]{"average", "bestTree"}, new String[]{"Average", "Best tree"}, 0); - - public FloatOption OptionFadingFactorOption = new FloatOption( - "OptionFadingFactor", - 'q', - "The fading factor used for comparing subtrees of an option node.", - 0.9995, 0.0, 1.0); - - //============================= END OPTIONS ==============================// - - //=============================== CLASSES ================================// - - public abstract static class Node extends AbstractMOAObject /*implements AdaptationCompatibleNode*/ { - - private static final long serialVersionUID = 1L; - - public int ID; - - protected InnerNode parent; - - protected Node alternateTree; - - protected boolean Alternate = false; - - protected boolean Adaptable = true; - - public Node(int id) { - this.ID = id; - } - - @Override - public void getDescription(StringBuilder sb, int indent) { - } - - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); - } - - public boolean isLeaf() { - return true; - } - - public void calculateDetph(ORTO tree) { - int level = this.getLevel(); - if (level > tree.maxDepth) { - tree.maxDepth = level; - } - } - - public int getLevel() { - Node target = (Node) this.getParent(); - while (target instanceof OptionNode) { - target = (Node) target.getParent(); - } - if (target == null) { - if (!Alternate) { - // Actual tree root - return 0; - } else { - // Root of alternate tree - return alternateTree.getLevel(); - } - } else { - return target.getLevel() + 1; - } - } - - /** - * Set the parent node - */ - public void setParent(InnerNode parent) - { - this.parent = parent; - } - - /** - * Return the parent node - */ - public InnerNode getParent() - { - return parent; - } - - public void setChild(int parentBranch, Node node) { - } - - public int getChildIndex(Node child) { - return 0; - } - - public int getNumSubtrees() { - return 1; - } - - public double[] processInstance(Instance inst, ORTO tree) { - // The returned values represent (by index): - // 0: the prediction of the node - // 1: the faded MSE - // 2: examples seen - // 3: the back propagated PH error - return new double[] {0.0, 0.0, 0.0, 0.0}; - } - - public double[] getPrediction(Instance inst, ORTO tree) { - // The returned values represent (by index): - // 0: the prediction of the node - // 1: the faded MSE - // 2: examples seen - return new double[] {0.0, 0.0, 0.0}; - } - - public void setAdaptable(boolean value) { - Adaptable = value; - } - - public void setAlternate(boolean value) { - Alternate = value; - } - } - - public abstract static class InnerNode extends Node { - private static final long serialVersionUID = 1L; - - protected AutoExpandVector children = new AutoExpandVector(); - - protected double PHmT = 0; - protected double PHMT = Double.MAX_VALUE; - - // Keep track of the statistics for loss error calculations - protected DoubleVector lossStatistics = new DoubleVector(); - - protected int weightSeen = 0; - protected int previousWeight = 0; - - public InnerNode(int id) { - super(id); - } - - public int numChildren() { - return this.children.size(); - } - - public Node getChild(int index) { - return this.children.get(index); - } - - public int getChildIndex(Node child) { - return this.children.indexOf(child); - } - - public void setChild(int index, Node child) { - this.children.set(index, child); - } - - public void setAlternateTree(Node tree) { - this.alternateTree = tree; - } - - public Node getAlternateTree() { - return this.alternateTree; - } - - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this) + (int) SizeOf.fullSizeOf(children); - } - - public void calculateDetph(ORTO tree) { - if (this.getLevel() > tree.maxDepth) { - tree.maxDepth = this.getLevel(); - } - - for (Node child : children) { - child.calculateDetph(tree); - } - } - - /** - * Check to see if the tree needs updating - */ - public boolean PageHinckleyTest(double error, double threshold) - { - // Update the cumulative mT sum - PHmT += error; - - // Update the minimum mT value if the new mT is - // smaller than the current minimum - if(PHmT < PHMT) - { - PHMT = PHmT; - } - // Return true if the cumulative value - the current minimum is - // greater than the current threshold (in which case we should adapt) - return PHmT - PHMT > threshold; - } - - public void setAdaptable(boolean value) { - Adaptable = value; - - for (Node child : children) { - child.setAdaptable(value); - } - } - - public void setAlternate(boolean value) { - Alternate = value; - - for (Node child : children) { - child.setAlternate(value); - } - } - - } - - public static class SplitNode extends InnerNode { - - private static final long serialVersionUID = 1L; - - protected InstanceConditionalTest splitTest; - - public void setChild(int index, Node child) { - if ((this.splitTest.maxBranches() >= 0) && (index >= this.splitTest.maxBranches())) { - throw new IndexOutOfBoundsException(); - } - this.children.set(index, child); - } - - public SplitNode(InstanceConditionalTest splitTest, int id) { - super(id); - this.splitTest = splitTest; - } - - public int instanceChildIndex(Instance inst) { - return this.splitTest.branchForInstance(inst); - } - - @Override - public boolean isLeaf() { - return false; - } - - public int getNumSubtrees() { - int num = 1; - for (Node child : children) { - num += child.getNumSubtrees(); - } - num -= children.size(); - return num; - } - - public double[] processInstance(Instance inst, ORTO tree) { - int branch = splitTest.branchForInstance(inst); - Node child = children.get(branch); - if (child == null) { - tree.maxID++; - child = new ActiveLearningNode(tree.maxID); - this.setChild(branch, child); - child.setParent(this); - } - - double[] processed = child.processInstance(inst, tree); - - weightSeen++; - - // Convert any nominal attributes to numeric ones??? - - // If no model exists yet, begin with an empty leaf node (the root) - // Take the current example and traverse it through the tree to a leaf - if (Adaptable) { - if (this.alternateTree == null) { - // Retrieve the error for the found leaf node - // currentNode.learnFromInstance(inst, this); - double PHerror = processed[3] - tree.PageHinckleyAlphaOption.getValue(); - - // Back-propagate the error through all the parent nodes - if(PageHinckleyTest(PHerror, tree.PageHinckleyThresholdOption.getValue())) { - if (tree.nodesToAdapt.contains(child)) { - tree.nodesToAdapt.remove(child); - } - tree.nodesToAdapt.add(this); - } - } else if (this.alternateTree != null) { - - // If an alternate tree already exists, check if the current tree should be replaced with it, - // or if the alternate tree should be discarded. - - // this.alternateTree.checkRoot(); - - double[] processedAlt = this.alternateTree.processInstance(inst, tree); - - // Update the loss statistics for the alternate tree - double qAlt = processedAlt[1]; - double qOrg = processed[1]; - - // Compute the Qi statistics - double Qi = Math.log(qOrg / qAlt); - lossStatistics.addToValue(0,1); - lossStatistics.addToValue(1,Qi); - double QiAverage = lossStatistics.getValue(1) / lossStatistics.getValue(0); - - if(weightSeen - previousWeight >= tree.AlternateTreeTMinOption.getValue()) { - - // Update the weight at which a decision was tested for - previousWeight = weightSeen; - - - // If appropriate, replace the current tree with the alternate tree - if(Qi > 0) { - // Replace the main FIMT-DD tree at a subtree - alternateTree.setAdaptable(true); - alternateTree.Alternate = false; - if(parent != null) { - parent.setChild(parent.getChildIndex(this), alternateTree); - alternateTree.setParent(parent); - tree.numTrees = tree.numTrees - this.getNumSubtrees() + alternateTree.getNumSubtrees(); - alternateTree.alternateTree = null; - } else { // Or occasionally at the root of the tree - tree.numTrees = tree.numTrees - this.getNumSubtrees() + alternateTree.getNumSubtrees(); - tree.treeRoot = alternateTree; - alternateTree.alternateTree = null; - } - tree.removeExcessTrees(); - } - // Otherwise, check if the alternate tree should be discarded - else if (QiAverage < lossStatistics.getValue(2) && lossStatistics.getValue(0) >= (10 * tree.AlternateTreeTMinOption.getValue()) || weightSeen >= tree.AlternateTreeTimeOption.getValue()) { - // tree.nodesToAdapt.remove(tree.nodesToAdapt.indexOf(this)); - this.alternateTree = null; - setAdaptable(true); - } - - lossStatistics.setValue(2, QiAverage); - } - } - } - - return processed; - - } - - public double[] getPrediction(Instance inst, ORTO tree) { - int branch = splitTest.branchForInstance(inst); - Node child = children.get(branch); - if (child == null) { - tree.maxID++; - child = new ActiveLearningNode(tree.maxID); - this.setChild(branch, child); - child.setParent(this); - } - return child.getPrediction(inst, tree); - } - - } - - public static class OptionNode extends InnerNode { - - private static final long serialVersionUID = 1L; - - protected double[] optionFFSSL; - protected double[] optionFFSeen; - // protected double[] optionBaseFFSSL; - - public OptionNode(int id) { - super(id); - } - - public void resetFF() { - this.optionFFSSL = new double[this.children.size()]; - this.optionFFSeen = new double[this.children.size()]; - // this.optionBaseFFSSL = new double[this.children.size()]; - for (int i = 0; i < this.children.size(); i++) { - this.optionFFSSL[i] = 0.0; - this.optionFFSeen[i] = 0.0; - // this.optionBaseFFSSL[i] = 0.0; - } - } - - @Override - public boolean isLeaf() { - return false; - } - - public int getNumSubtrees() { - int num = 0; - for (Node child : children) { - num += child.getNumSubtrees(); - } - return num; - } - - public int directionForBestTree() { - int d = 0; - double tmp = 0.0, min = Double.MAX_VALUE; - for (int i = 0; i < children.size(); i++) { - tmp = optionFFSSL[i] / optionFFSeen[i]; - if (tmp < min) { - min = tmp; - d = i; - } - } - return d; - } - - public double[] getPrediction(Instance inst, ORTO tree) { - double[][] predictions = new double[this.children.size()][]; - if (tree.OptionNodeAggregationOption.getChosenIndex() != 1) { - int i = 0; - for (i = 0; i < this.children.size(); i++) { - predictions[i] = this.getChild(i).getPrediction(inst, tree); - } - return aggregate(predictions, tree); - } else { - int d = directionForBestTree(); - return this.getChild(d).getPrediction(inst, tree); - } - } - - public double[] processInstance(Instance inst, ORTO tree) { - double[][] processed = new double[this.numChildren()][]; - int i = 0; - - for (i = 0; i < this.numChildren(); i++) { - processed[i] = this.getChild(i).processInstance(inst, tree); // All the children get to see the instance - } - - double[] prediction; - - if (tree.OptionNodeAggregationOption.getChosenIndex() != 1) { - prediction = aggregate(processed, tree); - } else { - prediction = processed[directionForBestTree()]; - } - - if (Adaptable) { - if (this.alternateTree == null) { - // Retrieve the error for the found leaf node - double PHerror = inst.classValue() - prediction[0]; - - // Back-propagate the error through all the parent nodes - if(PageHinckleyTest(PHerror, tree.PageHinckleyThresholdOption.getValue())) { - for (Node node : tree.nodesToAdapt) { - if (children.contains(node)) { - tree.nodesToAdapt.remove(node); - } - } - tree.nodesToAdapt.add(this); - } - } else { - // If an alternate tree already exists, check if the current tree should be replaced with it, - // or if the alternate tree should be discarded. - double[] predictionAlt = this.alternateTree.processInstance(inst, tree); - - // Update the loss statistics for the alternate tree - double qOrg = prediction[1]; - double qAlt = predictionAlt[1]; - - // Compute the Qi statistics - double Qi = Math.log(qOrg / qAlt); - lossStatistics.addToValue(0,1); - lossStatistics.addToValue(1,Qi); - double QiAverage = lossStatistics.getValue(1) / lossStatistics.getValue(0); - - if (weightSeen - previousWeight >= tree.AlternateTreeTMinOption.getValue()) { - - // Update the weight at which a decision was tested for - previousWeight = weightSeen; - - // If appropriate, replace the current tree with the alternate tree - if(Qi > 0) { - alternateTree.setAdaptable(true); - alternateTree.Alternate = false; - if (parent != null) { // Replace the main tree at a subtree - parent.setChild(parent.getChildIndex(this), alternateTree); - tree.numTrees = tree.numTrees - this.getNumSubtrees() + alternateTree.getNumSubtrees(); - alternateTree.setParent(parent); - this.alternateTree = null; - } else { // Or occasionally at the root of the tree - tree.treeRoot = this.alternateTree; - tree.numTrees = tree.numTrees - this.getNumSubtrees() + alternateTree.getNumSubtrees(); - tree.Adaptable = true; - this.alternateTree = null; - } - tree.removeExcessTrees(); - } - - // Otherwise, check if the alternate tree should be discarded - else if (QiAverage < lossStatistics.getValue(2) && lossStatistics.getValue(0) >= (10 * tree.AlternateTreeTMinOption.getValue()) || weightSeen >= tree.AlternateTreeTimeOption.getValue()) { - // tree.nodesToAdapt.remove(tree.nodesToAdapt.indexOf(this)); ? - this.alternateTree = null; - setAdaptable(true); - } - - lossStatistics.setValue(2, QiAverage); - } - } - - double sqLoss; - - if (weightSeen + 1 > tree.gracePeriodOption.getValue() + 50) { - for (i = 0; i < this.children.size(); i++) { - sqLoss = Math.pow(processed[i][0] - inst.classValue(), 2); - optionFFSSL[i] = optionFFSSL[i] * tree.OptionFadingFactorOption.getValue() + sqLoss; - optionFFSeen[i] = optionFFSeen[i] * tree.OptionFadingFactorOption.getValue() + 1; - } - } - } - - weightSeen++; - - return prediction; - } - - private double[] aggregate(double[][] predictions, ORTO tree) { - if (tree.OptionNodeAggregationOption.getChosenIndex() == 0) { // Average - double[] average = new double[predictions[0].length]; - for (int i = 0; i < predictions[0].length; i++) { - average[i] = 0.0; - } - for (int i = 0; i < predictions[0].length; i++) { - for (int j = 0; j < predictions.length; j++) { - average[i] += predictions[j][i]; - } - average[i] = average[i] / predictions.length; - } - - return average; - } else { - assert false : tree.OptionNodeAggregationOption.getChosenLabel(); - return new double[] {0.0}; - } - } - - public double getFFRatio(int childIndex) { - return optionFFSSL[childIndex] / optionFFSeen[childIndex]; - } - } - - public static class ActiveLearningNode extends Node { - - private static final long serialVersionUID = 1L; - - // Create a Perceptron model that carries out the actual learning in each node - public ORTOPerceptron learningModel = new ORTOPerceptron(); - - // The statistics for this node: - // Sum of y values - // Sum of squared y values - protected DoubleVector nodeStatistics = new DoubleVector(); - - protected DoubleVector splitRatioStatistics = new DoubleVector(); - - // The error values for the Page Hinckley test - // PHmT = the cumulative sum of the errors - // PHMT = the minimum error value seen so far - protected double PHmT = 0; - protected double PHMT = Double.MAX_VALUE; - - protected int examplesSeenAtLastSplitEvaluation; - - protected int examplesSeen = 0; - - protected AutoExpandVector attributeObservers = new AutoExpandVector(); - - public ActiveLearningNode(int id) { - super(id); - this.learningModel = new ORTOPerceptron(); - } - - @Override - public int calcByteSize() { - return super.calcByteSize() + (int) (SizeOf.fullSizeOf(this.attributeObservers)) + (int) (SizeOf.fullSizeOf(this.learningModel)); - } - - /** - * Return the best split suggestions for this node using the given split criteria - */ - public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion, ORTO tree) { - List bestSuggestions = new LinkedList(); - - // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution - double[] nodeSplitDist = this.nodeStatistics.getArrayCopy(); - - for (int i = 0; i < this.attributeObservers.size(); i++) { - AttributeClassObserver obs = this.attributeObservers.get(i); - if (obs != null) { - // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED - AttributeSplitSuggestion bestSuggestion = null; - if (obs instanceof FIMTDDNumericAttributeClassObserver) { - bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, nodeSplitDist, i, true /*ht.binarySplitsOption.isSet()*/); - } - if (bestSuggestion != null) { - bestSuggestions.add(bestSuggestion); - } - } - } - return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); - } - - - public void disableAttribute(int attIndex) { - this.attributeObservers.set(attIndex, new NullAttributeClassObserver()); - } - - public double getPHError(Instance inst) { - double sd = Math.sqrt((nodeStatistics.getValue(2) - ((nodeStatistics.getValue(1) * nodeStatistics.getValue(1))/nodeStatistics.getValue(1)))/examplesSeen); - double mean = nodeStatistics.getValue(2) / nodeStatistics.getValue(1); - // AbsErr(inst) - (SumAbsErr + AbsErr(inst)) / (N + 1) || SumAbsErr only contains errors for the first N examples and not the last one - return Math.abs( (inst.classValue() - learningModel.prediction(inst)) / sd ) - ((nodeStatistics.getValue(3) + Math.abs(((inst.classValue()-mean)/sd) - ((learningModel.prediction(inst)-mean)/sd))) / (nodeStatistics.getValue(1)+1)); - } - - /** - * Returns the squared error, for use in determining if an alternate tree is performing better than an original - * tree, or if the alternate tree should be deleted - */ - public double getSquaredError() { - return nodeStatistics.getValue(4); - } - - /** - * Return the error for a given instance - */ - public double getError(Instance inst) - { - return inst.classValue() - learningModel.prediction(inst); - } - - public double[] processInstance(Instance inst, ORTO tree) { - double prediction = getPrediction(inst, tree)[0]; - examplesSeen++; - - // Update the statistics for this node - // number of instances passing through the node - nodeStatistics.addToValue(0, 1); - // sum of y values - // sum of squared y values - nodeStatistics.addToValue(2, inst.classValue() * inst.classValue()); - - // sum of absolute errors - // Normalize values prior to calculating absolute error - double sd = Math.sqrt((nodeStatistics.getValue(2) - ((nodeStatistics.getValue(1) * nodeStatistics.getValue(1))/examplesSeen))/examplesSeen); - double error = this.getError(inst); - nodeStatistics.addToValue(3, Math.abs(error / sd)); - // sum of squared errors - // nodeStatistics.addToValue(4, error * error); - nodeStatistics.setValue(4, nodeStatistics.getValue(4) * tree.AlternateTreeFadingFactorOption.getValue() + error * error); - - double ph = getPHError(inst); - - learningModel.trainOnInstanceImpl(inst, tree); - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); - AttributeClassObserver obs = this.attributeObservers.get(i); - if (obs == null) { - // At this stage all nominal attributes are ignored - if (inst.attribute(instAttIndex).isNumeric()) { - obs = tree.newNumericClassObserver(); - this.attributeObservers.set(i, obs); - } - } - if (obs != null) { - ((FIMTDDNumericAttributeClassObserver) obs).observeAttributeClass(inst.value(instAttIndex), inst.classValue(), inst.weight()); - } - } - - // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node - if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { - // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - SplitCriterion splitCriterion = (SplitCriterion) tree.getPreparedClassOption(tree.splitCriterionOption); - - // Using this criterion, find the best split per attribute and rank the results - AttributeSplitSuggestion[] bestSplitSuggestions = getBestSplitSuggestions(splitCriterion, tree); - List acceptedSplits = new LinkedList(); - Arrays.sort(bestSplitSuggestions); - - // Declare a variable to determine the number of splits to be performed - int numSplits = 0; - - // If only one split was returned, use it - if (bestSplitSuggestions.length == 1) { - numSplits = 1; - acceptedSplits.add(bestSplitSuggestions[0]); - } else if (bestSplitSuggestions.length > 1) { // Otherwise, consider which of the splits proposed may be worth trying - - // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, tree.splitConfidenceOption.getValue(), examplesSeen); - - // Determine the top two ranked splitting suggestions - AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - - // assert false : bestSuggestion.merit; - - // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), - // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this - // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and - // splitting should occur. - // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit - // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two - // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - if (secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) { - numSplits = 1; - acceptedSplits.add(bestSuggestion); - } else if (tree.numTrees < tree.MaxTreesOption.getValue() && getLevel() <= tree.MaxOptionLevelOption.getValue()) { - for (AttributeSplitSuggestion suggestion : bestSplitSuggestions) { - if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { - numSplits++; - acceptedSplits.add(suggestion); - } - } - } else if (hoeffdingBound < tree.tieThresholdOption.getValue()) { - numSplits = 1; - acceptedSplits.add(bestSplitSuggestions[0]); - } else { // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - for (int i = 0; i < attributeObservers.size(); i++) { - AttributeClassObserver obs = attributeObservers.get(i); - if (obs != null) { - ((FIMTDDNumericAttributeClassObserver) obs).removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); - } - } - } - // If the user has selected this option, it is also possible to remove poor attributes at this stage - if ((tree.removePoorAttsOption != null) && tree.removePoorAttsOption.isSet()) { - Set poorAtts = new HashSet(); - for (int i = 0; i < bestSplitSuggestions.length; i++) { // scan 1 - add any poor to set - if (bestSplitSuggestions[i].splitTest != null) { - int[] splitAtts = bestSplitSuggestions[i].splitTest.getAttsTestDependsOn(); - if (splitAtts.length == 1) { - if (((bestSuggestion.merit / secondBestSuggestion.merit) + hoeffdingBound) < 1) { - poorAtts.add(new Integer(splitAtts[0])); - } - } - } - } - for (int i = 0; i < bestSplitSuggestions.length; i++) { // scan 2 - remove good ones from set - if (bestSplitSuggestions[i].splitTest != null) { - int[] splitAtts = bestSplitSuggestions[i].splitTest.getAttsTestDependsOn(); - if (splitAtts.length == 1) { - if (((bestSuggestion.merit / secondBestSuggestion.merit) + hoeffdingBound) < 1) { - poorAtts.remove(new Integer(splitAtts[0])); - } - } - } - } - for (int poorAtt : poorAtts) { - this.disableAttribute(poorAtt); - } - } - } - - // assert numSplits == 0 : numSplits; - - // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (numSplits > 0) { - - double optionFactor = numSplits * Math.pow(tree.OptionDecayFactorOption.getValue(), (double) getLevel()); - - // Deactivate this node if the best split was to do nothing - if (numSplits == 1 || optionFactor < 2.0 || tree.MaxTreesOption.getValue() - tree.numTrees <= 1) { - AttributeSplitSuggestion splitDecision = acceptedSplits.get(0); - tree.maxID++; - SplitNode newSplit = new SplitNode(splitDecision.splitTest, tree.maxID); - newSplit.Adaptable = Adaptable; - for (int i = 0; i < splitDecision.numSplits(); i++) { - tree.maxID++; - ActiveLearningNode newChild = new ActiveLearningNode(tree.maxID); - newChild.setParent(newSplit); - newChild.Adaptable = Adaptable; - newSplit.setChild(i, newChild); - } - tree.leafNodeCount--; - tree.innerNodeCount++; - tree.leafNodeCount += splitDecision.numSplits(); - if (parent == null) { - tree.treeRoot = newSplit; - } else { - parent.setChild(parent.getChildIndex(this), newSplit); - newSplit.setParent(parent); - } - } else { - tree.maxID++; - OptionNode optionNode = new OptionNode(tree.maxID); - optionNode.Adaptable = Adaptable; - tree.leafNodeCount--; - int j = 0; - - for (AttributeSplitSuggestion splitDecision : acceptedSplits) { - if (j > optionFactor || tree.MaxTreesOption.getValue() - tree.numTrees <= 0) { - break; - } - tree.maxID++; - SplitNode newSplit = new SplitNode(splitDecision.splitTest, tree.maxID); - newSplit.Adaptable = Adaptable; - for (int i = 0; i < splitDecision.numSplits(); i++) { - tree.maxID++; - ActiveLearningNode newChild = new ActiveLearningNode(tree.maxID); - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - newChild.Adaptable = Adaptable; - } - - tree.leafNodeCount += splitDecision.numSplits(); - tree.innerNodeCount++; - tree.numTrees++; - - newSplit.setParent(optionNode); - optionNode.setChild(j, newSplit); - j++; - } - - tree.innerNodeCount++; - tree.optionNodeCount++; - - if (parent == null) { - tree.treeRoot = optionNode; - } else { - parent.setChild(parent.getChildIndex(this), optionNode); - optionNode.setParent(parent); - } - - optionNode.resetFF(); - } - } - - // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation - examplesSeenAtLastSplitEvaluation = examplesSeen; - } - - return new double[] {prediction, nodeStatistics.getValue(4), examplesSeen, ph}; - } - - public double[] getPrediction(Instance inst, ORTO tree) { - return new double[] {this.learningModel.prediction(inst), this.nodeStatistics.getValue(4), this.examplesSeen}; - } - - } - - /** - * A Perceptron classifier modified to conform to the specifications of Ikonomovska et al. - */ - public static class ORTOPerceptron extends AbstractMOAObject { - private static final long serialVersionUID = 1L; - - // The Perception weights - protected double[] weightAttribute; - - // Statistics used for error calculations - protected DoubleVector attributeStatistics = new DoubleVector(); - protected DoubleVector squaredAttributeStatistics = new DoubleVector(); - - // The number of instances contributing to this model - protected int instancesSeen = 0; - - // If the model should be reset or not - protected boolean reset; - - @Override - public void getDescription(StringBuilder sb, int indent) { - //TODO Auto-generated method stub - } - - public ORTOPerceptron(ORTOPerceptron copy) { - this.weightAttribute = copy.getWeights(); - } - - public ORTOPerceptron() { - this.reset = true; - } - - public void setWeights(double[] w) { - this.weightAttribute = w; - } - - public double[] getWeights() { - return this.weightAttribute; - } - - /** - * A method to reset the model - */ - public void resetLearningImpl() { - this.reset = true; - } - - /** - * Update the model using the provided instance - */ - public void trainOnInstanceImpl(Instance inst, ORTO ft) { - // Initialize Perceptron if necessary - if (this.reset == true) { - this.reset = false; - this.weightAttribute = new double[inst.numAttributes()]; - this.instancesSeen = 0; - this.attributeStatistics = new DoubleVector(); - this.squaredAttributeStatistics = new DoubleVector(); - for (int j = 0; j < inst.numAttributes(); j++) { - weightAttribute[j] = 2 * ft.classifierRandom.nextDouble() - 1; - } - } - - // Update attribute statistics - instancesSeen++; - for(int j = 0; j < inst.numAttributes() -1; j++) - { - attributeStatistics.addToValue(j, inst.value(j)); - squaredAttributeStatistics.addToValue(j, inst.value(j)*inst.value(j)); - } - - // Update weights - - double learningRatio = 0.0; - if(ft.LearningRatioDecayOrConstOption.isSet()){ - learningRatio = ft.LearningRatioOption.getValue(); - } else { - learningRatio = ft.initLearnRate / (1 + instancesSeen * ft.learnRateDecay); - } - // double learningRatio = ft.learningRatioOption.getValue(); - double actualClass = inst.classValue(); - double predictedClass = this.prediction(inst); - - // SET DELTA TO ACTUAL - PREDICTED, NOT PREDICTED - ACTUAL AS SAID IN PAPER - double delta = actualClass - predictedClass; - - for (int j = 0; j < inst.numAttributes() - 1; j++) { - - if (inst.attribute(j).isNumeric()) { - // Update weights. Ensure attribute values are normalized first - double sd = Math.sqrt((squaredAttributeStatistics.getValue(j) - ((attributeStatistics.getValue(j) * attributeStatistics.getValue(j))/instancesSeen))/instancesSeen); - double instanceValue = 0; - if (sd > 0.0000001) { // Limit found in implementation by Ikonomovska et al (2011) - instanceValue = (inst.value(j) - (attributeStatistics.getValue(j)/instancesSeen))/(3*sd); - } - this.weightAttribute[j] += learningRatio * delta * instanceValue; - } - } - this.weightAttribute[inst.numAttributes() - 1] += learningRatio * delta; - } - - /** - * Output the prediction made by this perceptron on the given instance - */ - public double prediction(Instance inst) - { - double prediction = 0; - if (this.reset == false) { - for (int j = 0; j < inst.numAttributes() - 1; j++) { - if(inst.attribute(j).isNumeric()) - { - prediction += this.weightAttribute[j] * inst.value(j); - } - } - prediction += this.weightAttribute[inst.numAttributes() - 1]; - } - - // Return prediction to 3dp - return (double)Math.round(prediction * 1000) / 1000; - } - } - - //============================= END CLASSES ==============================// - - //=============================== METHODS ================================// - - @Override - public String getPurposeString() { - return "Implementation of the ORTO tree as described by Ikonomovska et al."; - } - - // For the moment at least, force the split criterion to be SDRSplitCriterion and the - // numeric estimator to be FIMTLDDNumericAttributeClassObserver - public ORTO() { -// numericEstimatorOption = new ClassOption("numericEstimator", -// 'n', "Numeric estimator to use.", FIMTDDNumericAttributeClassObserver.class, -// "FIMTDDNumericAttributeClassObserver"); - - splitCriterionOption = new ClassOption("splitCriterion", - 's', "Split criterion to use.", VarianceReductionSplitCriterion.class, - "VarianceReductionSplitCriterion"); - } - - @Override - public void resetLearningImpl() { - this.treeRoot = null; - this.numTrees = 1; - this.innerNodeCount = 0; - this.leafNodeCount = 0; - this.optionNodeCount = 0; - this.maxID = 0; - - this.learnTime = 0.0; - this.predictTime = 0.0; - } - - public boolean isRandomizable() { - return true; - } - - protected void checkRoot() { - if (treeRoot == null) { - maxID++; - treeRoot = new ActiveLearningNode(maxID); - leafNodeCount = 1; - } - } - - @Override - protected Measurement[] getModelMeasurementsImpl() { - // if (this.treeRoot != null) { - // this.treeRoot.calculateDetph(this); - // } - return new Measurement[]{ - new Measurement("number of subtrees", this.numTrees), - new Measurement("tree size (nodes)", this.leafNodeCount + this.innerNodeCount), - new Measurement("tree size (leaves)", this.leafNodeCount), - new Measurement("number of option nodes", this.optionNodeCount), - // new Measurement("tree depth", this.maxDepth), - // new Measurement("option count", this.countOptions()), - // new Measurement("learning time", learnTime), - // new Measurement("prediction time", predictTime), - /*new Measurement("tree depth", measureTreeDepth()), - new Measurement("active leaf byte size estimate", - this.activeLeafByteSizeEstimate), - new Measurement("inactive leaf byte size estimate", - this.inactiveLeafByteSizeEstimate), - new Measurement("byte size estimate overhead", - this.byteSizeEstimateOverheadFraction), - new Measurement("maximum prediction paths used", - this.maxPredictionPaths) */ }; - } - - public int calcByteSize() { - int size = (int) SizeOf.sizeOf(this); - if (this.treeRoot != null) { - size += this.treeRoot.calcByteSize(); - } - return size; - } - - @Override - public void getModelDescription(StringBuilder out, int indent) { - } - - @Override - public double[] getVotesForInstance(Instance inst) { - - if (this.treeRoot != null) { - double start = System.nanoTime(); - double[] out = {this.treeRoot.getPrediction(inst, this)[0]}; - predictTime += System.nanoTime() - start; - - return out; - } - return new double[0]; - } - - //================= TRAIN and TEST ================// - /** - * Method for updating (training) the model using a new instance - */ - @Override - public void trainOnInstanceImpl(Instance inst) { - - double start = System.nanoTime(); - - checkRoot(); - - treeRoot.processInstance(inst, this); - - for (InnerNode node : nodesToAdapt) { - if (node.Adaptable) { - maxID++; - node.alternateTree = new ActiveLearningNode(maxID); - node.alternateTree.Adaptable = false; - node.alternateTree.Alternate = true; - node.alternateTree.alternateTree = node; - - node.setAdaptable(false); - - // Reset the node statistics - node.lossStatistics.setValue(0,0); - node.lossStatistics.setValue(1,0); - node.lossStatistics.setValue(2,0); - node.PHmT = 0; - node.PHMT = Double.MAX_VALUE; // TODO Does this reset too? - node.weightSeen = 0; - node.previousWeight = 0; - } - } - nodesToAdapt = new ArrayList(); - - learnTime += System.nanoTime() - start; - } - - protected AttributeClassObserver newNumericClassObserver() { - AttributeClassObserver numericClassObserver = (AttributeClassObserver) getPreparedClassOption(numericEstimatorOption); // FIXME fix this - // AttributeClassObserver observer = new FIMTDDNumericAttributeClassObserver(); - return (AttributeClassObserver) numericClassObserver; - } - - public static double computeHoeffdingBound(double range, double confidence, double n) { - return Math.sqrt(((range * range) * Math.log(1.0 / confidence)) / (2.0 * n)); - } - - protected Node findWorstOption() { - Stack stack = new Stack(); - stack.add(this.treeRoot); - - double ratio = Double.MIN_VALUE; - Node out = null; - - while (!stack.empty()) { - Node node = stack.pop(); - if (node.parent instanceof OptionNode) { - OptionNode myParent = (OptionNode) node.parent; - int myIndex = myParent.getChildIndex(node); - double myRatio = myParent.getFFRatio(myIndex); - - if (myRatio > ratio) { - ratio = myRatio; - out = node; - } - } - if (node instanceof InnerNode) { - for (Node child : ((InnerNode) node).children) { - stack.add(child); - } - } - } - - return out; - } - - protected void removeExcessTrees() { - while (numTrees > MaxTreesOption.getValue()) { - Node option = findWorstOption(); - OptionNode parent = (OptionNode) option.parent; - int index = parent.getChildIndex(option); - - if (parent.children.size() == 2) { - parent.children.remove(index); - - for (Node chld : parent.children) { - chld.parent = parent.parent; - parent.parent.setChild(parent.parent.getChildIndex(parent), chld); - } - } else { - AutoExpandVector children = new AutoExpandVector(); - double[] optionFFSSL = new double[parent.children.size() - 1]; - double[] optionFFSeen = new double[parent.children.size() - 1]; - - int seen = 0; - - for (int i = 0; i < parent.children.size() - 1; i++) { - if (parent.getChild(i) != option) { - children.add(parent.getChild(i)); - optionFFSSL[i] = parent.optionFFSSL[i + seen]; - optionFFSeen[i] = parent.optionFFSeen[i + seen]; - } else { - seen = 1; - } - } - - parent.children = children; - parent.optionFFSSL = optionFFSSL; - parent.optionFFSeen = optionFFSeen; - - assert parent.children.size() == parent.optionFFSSL.length; - } - - numTrees--; - } - } - +public class ORTO extends FIMTDD implements Regressor { + + private static final long serialVersionUID = 1L; + + private int innerNodeCount = 0; + private int optionNodeCount = 0; + + private int numTrees = 1; + + + //region ================ OPTIONS ================ + + public IntOption maxTreesOption = new IntOption( + "maxTrees", + 'm', + "The maximum number of trees contained in the option tree.", + 10, 1, Integer.MAX_VALUE); + + public IntOption maxOptionLevelOption = new IntOption( + "maxOptionLevel", + 'x', + "The maximal depth at which option nodes can be created.", + 10, 0, Integer.MAX_VALUE); + + public FloatOption optionDecayFactorOption = new FloatOption( + "optionDecayFactor", + 'z', + "The option decay factor that determines how many options can be selected at a given level.", + 0.9, 0.0, 1.0); + + public MultiChoiceOption optionNodeAggregationOption = new MultiChoiceOption( + "optionNodeAggregation", + 'o', + "The aggregation method used to combine predictions in option nodes.", + new String[]{"average", "bestTree"}, new String[]{"Average", "Best tree"}, 0); + + public FloatOption optionFadingFactorOption = new FloatOption( + "optionFadingFactor", + 'q', + "The fading factor used for comparing subtrees of an option node.", + 0.9995, 0.0, 1.0); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public static class OptionNode extends InnerNode { + + private static final long serialVersionUID = 1L; + + protected double[] optionFFSSL; + protected double[] optionFFSeen; + + public OptionNode(FIMTDD tree) { + super(tree); + } + + public void resetFF() { + optionFFSSL = new double[children.size()]; + optionFFSeen = new double[children.size()]; + + for (int i = 0; i < children.size(); i++) { + optionFFSSL[i] = 0.0; + optionFFSeen[i] = 0.0; + } + } + + public int getNumSubtrees() { + int num = 0; + for (Node child : children) { + num += child.getNumSubtrees(); + } + return num; + } + + public int directionForBestTree() { + int d = 0; + double min = Double.MAX_VALUE; + for (int i = 0; i < numChildren(); i++) { + double tmp = getFFRatio(i); + if (tmp < min) { + min = tmp; + d = i; + } + } + return d; + } + + public double getPrediction(Instance inst) { + double[] predictions = new double[numChildren()]; + for (int i = 0; i < numChildren(); i++) { + predictions[i] = getChild(i).getPrediction(inst); + } + return aggregate(predictions); + } + + private double aggregate(double[] predictions) { + if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average + double sum = 0.0; + for (int i = 0; i < predictions.length; i++) { + sum += predictions[i]; + } + return sum / predictions.length; + } else if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 1) { + int d = directionForBestTree(); + return predictions[d]; + } else { + return 0.0; + } + } + + public double getFFRatio(int childIndex) { + return optionFFSSL[childIndex] / optionFFSeen[childIndex]; + } + + protected boolean skipInLevelCount() { + return true; + } + + @Override + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "[option node]"); + StringUtils.appendNewline(out); + for (int childIndex = 0; childIndex < children.size(); childIndex++) { + Node split = getChild(childIndex); + StringUtils.appendIndented(out, indent, "[" + childIndex + "]"); + StringUtils.appendNewline(out); + split.describeSubtree(out, indent + 2); + } + } + } + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + // region --- Regressor methods + + public String getPurposeString() { + return "Implementation of the ORTO tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + super.resetLearningImpl(); + this.innerNodeCount = 0; + this.optionNodeCount = 0; + } + + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("number of subtrees", this.numTrees), + new Measurement("tree size (nodes)", this.leafNodeCount + this.innerNodeCount), + new Measurement("tree size (leaves)", this.leafNodeCount), + new Measurement("number of option nodes", this.optionNodeCount),}; + } + + public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { + if (node instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) node, prediction, normalError, growthAllowed, inAlternate); + } else { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); + break; + } else { + currentNode.examplesSeen += inst.weight(); + currentNode.sumOfAbsErrors += inst.weight() * normalError; + InnerNode iNode = (InnerNode) currentNode; + if (!inAlternate && iNode.alternateTree != null) { + boolean altTree = true; + double lossO = Math.pow(inst.classValue() - prediction, 2); + double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); + + // Loop for compatibility with bagging methods + for (int i = 0; i < inst.weight(); i++) { + iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + iNode.lossExamplesSeen++; + + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + iNode.lossSumQi += Qi; + iNode.lossNumQiTests += 1; + } + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + + if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + iNode.previousWeight = iNode.lossExamplesSeen; + if (Qi > 0) { + // Switch the subtrees + Node parent = iNode.getParent(); + + if (parent != null) { + Node replacementTree = iNode.alternateTree; + parent.setChild(parent.getChildIndex(iNode), replacementTree); + if (growthAllowed) replacementTree.restartChangeDetection(); + } else { + treeRoot = iNode.alternateTree; + treeRoot.restartChangeDetection(); + } + optionNodeCount += iNode.alternateTree.getNumSubtrees() - iNode.getNumSubtrees(); + removeExcessTrees(); + + currentNode = iNode.alternateTree; + currentNode.originalNode = null; + altTree = false; + } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { + // Remove the alternate tree + iNode.alternateTree = null; + if (growthAllowed) iNode.restartChangeDetection(); + altTree = false; + } + } + if (altTree) { + growthAllowed = false; // this is the growth of the original tree + processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree + } else if (currentNode instanceof OptionNode) { + // this happens when an option node is switched into the tree + for (Node child : ((OptionNode) currentNode).children) { + processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); + } + break; + } + } + + if (iNode.changeDetection && !inAlternate) { + if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + iNode.initializeAlternateTree(); + } + } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).descendOneStep(inst); + } else if (currentNode instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) currentNode, prediction, normalError, growthAllowed, inAlternate); + break; + } + } + } + } + + } + + public void processInstanceOptionNode(Instance inst, OptionNode node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { + node.examplesSeen += inst.weight(); + node.sumOfAbsErrors += inst.weight() * normalError; + if (node.changeDetection) { + double error = Math.abs(prediction - inst.classValue()); + node.sumOfAbsErrors += error; + + if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + node.initializeAlternateTree(); + growthAllowed = false; + } + } + + for (Node child : node.children) { + int index = node.getChildIndex(child); + double childPrediction = child.getPrediction(inst); + node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; + node.optionFFSSL[index] = node.optionFFSSL[index] * optionFadingFactorOption.getValue() + Math.pow(childPrediction - inst.classValue(), 2); + } + + for (Node child : node.children) { + processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); + } + } + + // endregion --- Regressor methods + + // region --- Object instantiation methods + + protected OptionNode newOptionNode() { + maxID++; + return new OptionNode(this); + } + + // endregion --- Object instantiation methods + + // region --- Processing methods + + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + + // Initialize the split criterion + SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); + + // Using this criterion, find the best split per attribute and rank the results + AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); + List acceptedSplits = new LinkedList(); + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine the number of splits to be performed + int numSplits = 0; + + // If only one split was returned, use it (this generally shouldn't happen) + if (bestSplitSuggestions.length == 1) { + numSplits = 1; + acceptedSplits.add(bestSplitSuggestions[0]); + } else if (bestSplitSuggestions.length > 1) { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + + // Determine the top two ranked splitting suggestions + AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + if (secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) { + numSplits = 1; + acceptedSplits.add(bestSuggestion); + } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { + for (int i = 0; i < bestSplitSuggestions.length; i++) { + AttributeSplitSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; + if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { + numSplits++; + acceptedSplits.add(suggestion); + } else { + break; + } + + } + + } else if (hoeffdingBound < tieThresholdOption.getValue()) { + numSplits = 1; + acceptedSplits.add(bestSplitSuggestions[0]); + } else { // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + for (int i = 0; i < node.attributeObservers.size(); i++) { + AttributeClassObserver obs = node.attributeObservers.get(i); + if (obs != null) { + ((FIMTDDNumericAttributeClassObserver) obs).removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); + } + } + } + } + + // If the splitting criterion was met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (numSplits > 0) { + double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); + + if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 0) { + AttributeSplitSuggestion splitDecision = acceptedSplits.get(0); + SplitNode newSplit = newSplitNode(splitDecision.splitTest); + for (int i = 0; i < splitDecision.numSplits(); i++) { + LeafNode newChild = newLeafNode(); + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + leafNodeCount--; + innerNodeCount++; + leafNodeCount += splitDecision.numSplits(); + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + parent.setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + } else { + OptionNode optionNode = newOptionNode(); + leafNodeCount--; + int j = 0; + + for (AttributeSplitSuggestion splitDecision : acceptedSplits) { + if (j > optionFactor || maxTreesOption.getValue() - numTrees <= 0) { + break; + } + SplitNode newSplit = newSplitNode(splitDecision.splitTest); + for (int i = 0; i < splitDecision.numSplits(); i++) { + LeafNode newChild = newLeafNode(); + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + + leafNodeCount += splitDecision.numSplits(); + innerNodeCount++; + numTrees++; + + newSplit.setParent(optionNode); + optionNode.setChild(j, newSplit); + j++; + } + + innerNodeCount++; + optionNodeCount++; + + if (parent == null) { + treeRoot = optionNode; + } else { + parent.setChild(parentIndex, optionNode); + optionNode.setParent(parent); + } + + optionNode.resetFF(); + } + } + } + + // endregion --- Processing methods + + // region --- Option tree methods + protected Node findWorstOption() { + Stack stack = new Stack(); + stack.add(treeRoot); + + double ratio = Double.MIN_VALUE; + Node out = null; + + while (!stack.empty()) { + Node node = stack.pop(); + if (node.getParent() instanceof OptionNode) { + OptionNode myParent = (OptionNode) node.getParent(); + int nodeIndex = myParent.getChildIndex(node); + double nodeRatio = myParent.getFFRatio(nodeIndex); + + if (nodeRatio > ratio) { + ratio = nodeRatio; + out = node; + } + } + if (node instanceof InnerNode) { + for (Node child : ((InnerNode) node).children) { + stack.add(child); + } + } + } + + return out; + } + + protected void removeExcessTrees() { + while (numTrees > maxTreesOption.getValue()) { + Node option = findWorstOption(); + OptionNode parent = (OptionNode) option.parent; + int index = parent.getChildIndex(option); + + if (parent.children.size() == 2) { + parent.children.remove(index); + for (Node chld : parent.children) { + chld.parent = parent.parent; + parent.parent.setChild(parent.parent.getChildIndex(parent), chld); + } + } else { + AutoExpandVector children = new AutoExpandVector(); + double[] optionFFSSL = new double[parent.children.size() - 1]; + double[] optionFFSeen = new double[parent.children.size() - 1]; + + int seen = 0; + + for (int i = 0; i < parent.children.size() - 1; i++) { + if (parent.getChild(i) != option) { + children.add(parent.getChild(i)); + optionFFSSL[i] = parent.optionFFSSL[i + seen]; + optionFFSeen[i] = parent.optionFFSeen[i + seen]; + } else { + seen = 1; + } + } + + parent.children = children; + parent.optionFFSSL = optionFFSSL; + parent.optionFFSeen = optionFFSeen; + + assert parent.children.size() == parent.optionFFSSL.length; + } + numTrees--; + } + } + + // endregion --- Option tree methods + + //endregion ================ METHODS ================ } \ No newline at end of file From fedd0d2a8e23b838b85a43e006124b43177d94f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 14:50:42 +0100 Subject: [PATCH 03/33] Cosmetic changes (fixed indentation) --- .../multilabel/MultilabelHoeffdingTree.java | 60 +-- .../tasks/EvaluatePrequentialMultiTarget.java | 401 +++++++++--------- 2 files changed, 232 insertions(+), 229 deletions(-) diff --git a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java index 5bee4b482..934eae252 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java @@ -46,9 +46,9 @@ * */ public class MultilabelHoeffdingTree extends HoeffdingTreeClassifLeaves implements MultiLabelLearner, MultiTargetRegressor { -// Needs to use InfoGainSplitCriterionMultiLabel, since multilabel entropy is calculated in a different way -// Trains a mlinstance adding statistics of several class values and training node classifiers -// Get votes from the training node classifier + // Needs to use InfoGainSplitCriterionMultiLabel, since multilabel entropy is calculated in a different way + // Trains a mlinstance adding statistics of several class values and training node classifiers + // Get votes from the training node classifier private static final long serialVersionUID = 1L; @@ -56,19 +56,19 @@ public class MultilabelHoeffdingTree extends HoeffdingTreeClassifLeaves implemen // Converts multi-label format to single-label format //protected Converter converter = null; - + @Override public void setModelContext(InstancesHeader raw_header) { //set the multilabel model context this.modelContext = raw_header; } - @Override + @Override public Prediction getPredictionForInstance(Example example) { return getPredictionForInstance((MultiLabelInstance)example.getData()); } - - @Override + + @Override public Prediction getPredictionForInstance(MultiLabelInstance instance) { double[] predictionArray = this.getVotesForInstance(instance); @@ -100,17 +100,17 @@ public void learnFromInstance(Instance inst, HoeffdingTree ht) { } } } - + // It uses classifier at nodes, and to be able to train with several class values public class MultilabelLearningNodeClassifier extends LearningNodeClassifier { - + //protected Classifier classifier; private static final long serialVersionUID = 1L; public MultilabelLearningNodeClassifier(double[] initialClassObservations, Classifier cl, MultilabelHoeffdingTree ht ) { super(initialClassObservations); - + if (cl== null) { this.classifier = ((Classifier) getPreparedClassOption(ht.learnerOption)).copy(); this.classifier.resetLearning(); @@ -136,13 +136,13 @@ public double[] getClassVotes(Instance inst, HoeffdingTree ht) { public void disableAttribute(int attIndex) { // should not disable poor atts - they are used in NB calc } - + public Classifier getClassifier() { return this.classifier; } - + //It uses different class values - @Override + @Override public void learnFromInstance(Instance mlinst, HoeffdingTree ht) { this.classifier.trainOnInstance(mlinst); MultilabelHoeffdingTree mht = ((MultilabelHoeffdingTree) ht); @@ -152,7 +152,7 @@ public void learnFromInstance(Instance mlinst, HoeffdingTree ht) { } Instance inst = mlinst; //mht.converter.formatInstance(mlinst); for (int i = 0; i < inst.numInputAttributes(); i++) { - //for (int i = 1; i < inst.numAttributes(); i++) { + //for (int i = 1; i < inst.numAttributes(); i++) { int instAttIndex = inst.inputAttribute(i).index(); //modelAttIndexToInstanceAttIndex(i, inst); AttributeClassObserver obs = this.attributeObservers.get(instAttIndex); //i if (obs == null) { @@ -176,13 +176,13 @@ protected LearningNode newLearningNode(double[] initialClassObservations) { // Create new Learning Node null return new MultilabelLearningNodeClassifier(initialClassObservations,null,this); } - + //@Override protected LearningNode newLearningNode(double[] initialClassObservations, Classifier cl) { // Create new Learning Node return new MultilabelLearningNodeClassifier(initialClassObservations,cl,this); } - + //It uses MultilabelInactiveLearningNode since there are several class values @Override protected void deactivateLearningNode(ActiveLearningNode toDeactivate, @@ -229,21 +229,21 @@ public double[] getVotesForInstance(Instance inst) { // Return empty array (this should only happen once! -- before we build the root node). return new double[this.m_L]; } - + @Override public void trainOnInstanceImpl(MultiLabelInstance instance) { - trainOnInstanceImpl((Instance) instance); - } - - private List getRelevantLabels(Instance x) { - List classValues = new LinkedList(); - //get all class attributes - for (int j = 0; j < m_L; j++) { - if (x.value(j) > 0.0) { - classValues.add(j); - } - } - return classValues; - } + trainOnInstanceImpl((Instance) instance); + } + + private List getRelevantLabels(Instance x) { + List classValues = new LinkedList(); + //get all class attributes + for (int j = 0; j < m_L; j++) { + if (x.value(j) > 0.0) { + classValues.add(j); + } + } + return classValues; + } } diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index eba9b70b5..cf8090816 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -59,222 +59,225 @@ */ public class EvaluatePrequentialMultiTarget extends MultiTargetMainTask { - @Override - public String getPurposeString() { - return "Evaluates a classifier on a stream by testing then training with each example in sequence."; - } + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); + public ClassOption learnerOption = new ClassOption("learner", 'l', + "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); - public ClassOption streamOption = new ClassOption("stream", 's', - "Stream to learn from.", MultiTargetInstanceStream.class, - "MultiTargetArffFileStream"); + public ClassOption streamOption = new ClassOption("stream", 's', + "Stream to learn from.", MultiTargetInstanceStream.class, + "MultiTargetArffFileStream"); - public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', - "Classification performance evaluation method.", - MultiTargetPerformanceEvaluator.class, - "BasicMultiTargetPerformanceEvaluator"); + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + MultiTargetPerformanceEvaluator.class, + "BasicMultiTargetPerformanceEvaluator"); - public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', - "Maximum number of instances to test/train on (-1 = no limit).", - 100000000, -1, Integer.MAX_VALUE); + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); - public IntOption timeLimitOption = new IntOption("timeLimit", 't', - "Maximum number of seconds to test/train for (-1 = no limit).", -1, - -1, Integer.MAX_VALUE); + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); - public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", - 'f', - "How many instances between samples of the learning performance.", - 100000, 0, Integer.MAX_VALUE); + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); - public IntOption memCheckFrequencyOption = new IntOption( - "memCheckFrequency", 'q', - "How many instances between memory bound checks.", 100000, 0, - Integer.MAX_VALUE); + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); - public FileOption dumpFileOption = new FileOption("dumpFile", 'd', - "File to append intermediate csv results to.", null, "csv", true); + public FileOption dumpFileOption = new FileOption("dumpFile", 'd', + "File to append intermediate csv results to.", null, "csv", true); - public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', - "File to append output predictions to.", null, "pred", true); + public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', + "File to append output predictions to.", null, "pred", true); - //New for prequential method DEPRECATED - public IntOption widthOption = new IntOption("width", - 'w', "Size of Window", 1000); + //New for prequential method DEPRECATED + public IntOption widthOption = new IntOption("width", + 'w', "Size of Window", 1000); - public FloatOption alphaOption = new FloatOption("alpha", - 'a', "Fading factor or exponential smoothing factor", .01); - //End New for prequential methods + public FloatOption alphaOption = new FloatOption("alpha", + 'a', "Fading factor or exponential smoothing factor", .01); + //End New for prequential methods - @Override - public Class getTaskResultType() { - return LearningCurve.class; - } + @Override + public Class getTaskResultType() { + return LearningCurve.class; + } - @Override - protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { - Learner learner = (Learner) getPreparedClassOption(this.learnerOption); - ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); - LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); - LearningCurve learningCurve = new LearningCurve( - "learning evaluation instances"); + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + Learner learner = (Learner) getPreparedClassOption(this.learnerOption); + ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); + LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); + LearningCurve learningCurve = new LearningCurve( + "learning evaluation instances"); - //New for prequential methods - if (evaluator instanceof WindowClassificationPerformanceEvaluator) { - //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); - if (widthOption.getValue() != 1000) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { - //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { - //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - //End New for prequential methods + //New for prequential methods + if (evaluator instanceof WindowClassificationPerformanceEvaluator) { + //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); + if (widthOption.getValue() != 1000) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { + //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { + //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + //End New for prequential methods - learner.setModelContext(stream.getHeader()); - int maxInstances = this.instanceLimitOption.getValue(); - long instancesProcessed = 0; - int maxSeconds = this.timeLimitOption.getValue(); - int secondsElapsed = 0; - monitor.setCurrentActivity("Evaluating learner...", -1.0); + learner.setModelContext(stream.getHeader()); + int maxInstances = this.instanceLimitOption.getValue(); + long instancesProcessed = 0; + int maxSeconds = this.timeLimitOption.getValue(); + int secondsElapsed = 0; + monitor.setCurrentActivity("Evaluating learner...", -1.0); - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - //File for output predictions - File outputPredictionFile = this.outputPredictionFileOption.getFile(); - PrintStream outputPredictionResultStream = null; - if (outputPredictionFile != null) { - try { - if (outputPredictionFile.exists()) { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile, true), true); - } else { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open prediction result file: " + outputPredictionFile, ex); - } - } - boolean firstDump = true; - boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); - long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - long lastEvaluateStartTime = evaluateStartTime; - double RAMHours = 0.0; - while (stream.hasMoreInstances() - && ((maxInstances < 0) || (instancesProcessed < maxInstances)) - && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { - Example trainInst = stream.nextInstance(); - Example testInst = (Example) trainInst; //.copy(); - //testInst.setClassMissing(); - //double[] prediction = learner.getVotesForInstance(testInst); - Prediction prediction = learner.getPredictionForInstance(testInst); - // Output prediction - if (outputPredictionFile != null) { - double trueClass = ((Instance) trainInst.getData()).classValue(); - outputPredictionResultStream.println(prediction + "," + trueClass); - } + File dumpFile = this.dumpFileOption.getFile(); + PrintStream immediateResultStream = null; + if (dumpFile != null) { + try { + if (dumpFile.exists()) { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile, true), true); + } else { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open immediate result file: " + dumpFile, ex); + } + } + //File for output predictions + File outputPredictionFile = this.outputPredictionFileOption.getFile(); + PrintStream outputPredictionResultStream = null; + if (outputPredictionFile != null) { + try { + if (outputPredictionFile.exists()) { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile, true), true); + } else { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open prediction result file: " + outputPredictionFile, ex); + } + } + boolean firstDump = true; + boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); + long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + long lastEvaluateStartTime = evaluateStartTime; + double RAMHours = 0.0; + while (stream.hasMoreInstances() + && ((maxInstances < 0) || (instancesProcessed < maxInstances)) + && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { + Example trainInst = stream.nextInstance(); + Example testInst = (Example) trainInst; //.copy(); + //testInst.setClassMissing(); + //double[] prediction = learner.getVotesForInstance(testInst); + Prediction prediction = learner.getPredictionForInstance(testInst); + // Output prediction + if (outputPredictionFile != null) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); + } - //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); - evaluator.addResult(testInst, prediction); - learner.trainOnInstance(trainInst); - instancesProcessed++; - if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 - || stream.hasMoreInstances() == false) { - long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); - double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); - double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs - RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours - RAMHours += RAMHoursIncrement; - lastEvaluateStartTime = evaluateTime; - learningCurve.insertEntry(new LearningEvaluation( - new Measurement[]{ - new Measurement( - "learning evaluation instances", - instancesProcessed), - new Measurement( - "evaluation time (" - + (preciseCPUTiming ? "cpu " - : "") + "seconds)", - time), - new Measurement( - "model cost (RAM-Hours)", - RAMHours) - }, - evaluator, learner)); + //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); + evaluator.addResult(testInst, prediction); + learner.trainOnInstance(trainInst); + instancesProcessed++; + if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 + || stream.hasMoreInstances() == false) { + long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); + double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); + double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs + RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours + RAMHours += RAMHoursIncrement; + lastEvaluateStartTime = evaluateTime; + learningCurve.insertEntry(new LearningEvaluation( + new Measurement[]{ + new Measurement( + "learning evaluation instances", + instancesProcessed), + new Measurement( + "evaluation time (" + + (preciseCPUTiming ? "cpu " + : "") + "seconds)", + time), + new Measurement( + "model cost (RAM-Hours)", + RAMHours) + }, + evaluator, learner)); - if (immediateResultStream != null) { - if (firstDump) { - immediateResultStream.println(learningCurve.headerToString()); - firstDump = false; - } - immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); - immediateResultStream.flush(); - } - } - if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { - if (monitor.taskShouldAbort()) { - return null; - } - long estimatedRemainingInstances = stream.estimatedRemainingInstances(); - if (maxInstances > 0) { - long maxRemaining = maxInstances - instancesProcessed; - if ((estimatedRemainingInstances < 0) - || (maxRemaining < estimatedRemainingInstances)) { - estimatedRemainingInstances = maxRemaining; - } - } - monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 - : (double) instancesProcessed - / (double) (instancesProcessed + estimatedRemainingInstances)); - if (monitor.resultPreviewRequested()) { - monitor.setLatestResultPreview(learningCurve.copy()); - } - secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() - - evaluateStartTime); - } - } - StringBuilder sb= new StringBuilder(); - learner.getDescription(sb, 0); - System.out.println(sb.toString()); - if (immediateResultStream != null) { - immediateResultStream.close(); - } - if (outputPredictionResultStream != null) { - outputPredictionResultStream.close(); - } - return learningCurve; - } + if (immediateResultStream != null) { + if (firstDump) { + immediateResultStream.println(learningCurve.headerToString()); + firstDump = false; + } + immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); + immediateResultStream.flush(); + } + } + if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { + if (monitor.taskShouldAbort()) { + return null; + } + long estimatedRemainingInstances = stream.estimatedRemainingInstances(); + if (maxInstances > 0) { + long maxRemaining = maxInstances - instancesProcessed; + if ((estimatedRemainingInstances < 0) + || (maxRemaining < estimatedRemainingInstances)) { + estimatedRemainingInstances = maxRemaining; + } + } + monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 + : (double) instancesProcessed + / (double) (instancesProcessed + estimatedRemainingInstances)); + if (monitor.resultPreviewRequested()) { + monitor.setLatestResultPreview(learningCurve.copy()); + } + secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() + - evaluateStartTime); + } + } + StringBuilder sb= new StringBuilder(); + learner.getDescription(sb, 0); + System.out.println(sb.toString()); + if (immediateResultStream != null) { + immediateResultStream.close(); + } + if (outputPredictionResultStream != null) { + outputPredictionResultStream.close(); + } + return learningCurve; + } } From 4e3116ae22afc259caa4f4e7d967ae369aae367c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 15:22:23 +0100 Subject: [PATCH 04/33] Removed merging artefacts --- .../samoa/instances/MultiLabelPrediction.java | 5 +- .../LocalMultiTargetClassifier.java | 31 +- .../classifiers/multilabel/meta/MTOzaBag.java | 94 +- .../multilabel/trees/ISOUPTree.java | 144 +-- .../java/moa/classifiers/trees/FIMTDD.java | 986 +----------------- .../main/java/moa/classifiers/trees/ORTO.java | 114 +- .../tasks/EvaluatePrequentialMultiTarget.java | 59 +- 7 files changed, 63 insertions(+), 1370 deletions(-) diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index 838f90c7b..bb9824e9d 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -32,10 +32,7 @@ public MultiLabelPrediction(int numOutputAttributes) { public MultiLabelPrediction(DoubleVector[] prediction) { this.prediction = prediction; } - - public MultiLabelPrediction(DoubleVector[] prediction) { - this.prediction = prediction; - } + @Override public int numOutputAttributes() { diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 38c82f7e9..35223d3db 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -1,12 +1,8 @@ package moa.classifiers.multilabel; -<<<<<<< HEAD import java.util.ArrayList; -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa import java.util.LinkedList; import java.util.List; -import java.util.Vector; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; @@ -21,16 +17,14 @@ import moa.classifiers.Classifier; import moa.classifiers.MultiLabelClassifier; import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.classifiers.trees.FIMTDD; -import moa.core.DoubleVector; import moa.core.Measurement; -import moa.learners.Learner; import moa.options.ClassOption; public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner implements MultiLabelClassifier, MultiTargetRegressor { + private static final long serialVersionUID = 1L; + public ClassOption classifierOption = new ClassOption( "classifier", 'c', @@ -38,17 +32,11 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner Classifier.class, "moa.classifiers.trees.FIMTDD"); -<<<<<<< HEAD ArrayList classifiers = null; ArrayList headers = null; -======= - LinkedList classifiers = null; - LinkedList headers = null; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa @Override public boolean isRandomizable() { - // TODO Auto-generated method stub return true; } @@ -61,11 +49,7 @@ private InstancesHeader getHeader(int target) { private void makeHeaders() { if (headers == null) { -<<<<<<< HEAD headers = new ArrayList(); -======= - headers = new LinkedList(); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { List attributes = new LinkedList(); List indexValues = new LinkedList(); @@ -95,7 +79,6 @@ private Instance getSTInstance(MultiLabelInstance inst, int target) { @Override public void trainOnInstanceImpl(MultiLabelInstance instance) { - // TODO Auto-generated method stub initializeClassifiers(); for (int j = 0; j < instance.numberOutputTargets(); j++) { @@ -112,10 +95,6 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); for (int j = 0; j < inst.numberOutputTargets(); j++) { Instance STInst = getSTInstance(inst, j); -<<<<<<< HEAD -======= - ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa prediction.setVote(j, 1, classifiers.get(j).getVotesForInstance(STInst)[0]); } return prediction; @@ -131,15 +110,9 @@ public void initializeClassifiers() { this.classifierRandom.setSeed(1234); if (classifiers == null) { makeHeaders(); -<<<<<<< HEAD classifiers = new ArrayList(); for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { Classifier learner = ((Classifier) getPreparedClassOption(this.classifierOption)).copy(); -======= - classifiers = new LinkedList(); - for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { - Classifier learner = (Classifier) getPreparedClassOption(this.classifierOption); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa classifiers.add(learner); learner.resetLearning(); ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java index a4c64a809..bdf2c7ffd 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java @@ -41,41 +41,43 @@ */ public class MTOzaBag extends OzaBag implements MultiLabelLearner, MultiTargetRegressor { - public MTOzaBag() { - super(); - this.baseLearnerOption = new ClassOption("baseLearner", 'l', - "Classifier to train.", MultiLabelLearner.class, "multilabel.trees.ISOUPTree"); - } - - @Override - public void resetLearningImpl() { - this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; - MultiLabelLearner baseLearner = (MultiLabelLearner) getPreparedClassOption(this.baseLearnerOption); - baseLearner.resetLearning(); - for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i] = baseLearner.copy(); - } - } - - @Override - public void setModelContext(InstancesHeader raw_header) { - - //set the multilabel model context - this.modelContext = raw_header; - - // reset ensemble - this.resetLearningImpl(); - - for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i].setModelContext(raw_header); - this.ensemble[i].resetLearning(); - } - } - - @Override // @note don't need this here - public boolean isRandomizable() { - return true; - } + private static final long serialVersionUID = 1L; + + public MTOzaBag() { + super(); + this.baseLearnerOption = new ClassOption("baseLearner", 'l', + "Classifier to train.", MultiLabelLearner.class, "multilabel.trees.ISOUPTree"); + } + + @Override + public void resetLearningImpl() { + this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; + MultiLabelLearner baseLearner = (MultiLabelLearner) getPreparedClassOption(this.baseLearnerOption); + baseLearner.resetLearning(); + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i] = baseLearner.copy(); + } + } + + @Override + public void setModelContext(InstancesHeader raw_header) { + + //set the multilabel model context + this.modelContext = raw_header; + + // reset ensemble + this.resetLearningImpl(); + + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i].setModelContext(raw_header); + this.ensemble[i].resetLearning(); + } + } + + @Override // @note don't need this here + public boolean isRandomizable() { + return true; + } public Prediction getPredictionForInstance(MultiLabelInstance inst) { DoubleVector[][] predictions = new DoubleVector[this.ensemble.length][getModelContext().numOutputAttributes()]; @@ -93,8 +95,8 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { } return new MultiLabelPrediction(prediction); } -<<<<<<< HEAD - + + public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) { int actual = Math.max(1, Math.min(n, this.ensemble.length)); DoubleVector[][] predictions = new DoubleVector[actual][getModelContext().numOutputAttributes()]; @@ -112,17 +114,15 @@ public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) } return new MultiLabelPrediction(prediction); } -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - - @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { - trainOnInstanceImpl((Instance) instance); - } - - @Override + + @Override + public void trainOnInstanceImpl(MultiLabelInstance instance) { + trainOnInstanceImpl((Instance) instance); + } + + @Override public Prediction getPredictionForInstance(Example example) { return getPredictionForInstance((MultiLabelInstance)example.getData()); } - + } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index 592a0c5c6..1873b87cf 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -66,14 +66,7 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR private static final long serialVersionUID = 1L; -<<<<<<< HEAD public Node treeRoot; -======= - protected Node treeRoot; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - - private int leafNodeCount = 0; - private int splitNodeCount = 0; private double examplesSeen = 0.0; private DoubleVector sumOfValues = new DoubleVector(); @@ -86,7 +79,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR //region ================ OPTIONS ================ -<<<<<<< HEAD // public ClassOption splitCriterionOption = new ClassOption( // "splitCriterion", // 's', @@ -95,8 +87,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR // "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); // TODO not used at the moment, consider later when the implementation catches up -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa public IntOption gracePeriodOption = new IntOption( "gracePeriod", 'g', @@ -115,7 +105,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR "Threshold below which a split will be forced to break ties.", 0.05, 0.0, 1.0); -<<<<<<< HEAD public FloatOption PageHinckleyAlphaOption = new FloatOption( "PageHinckleyAlpha", 'a', @@ -127,19 +116,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR 'h', "The threshold value to be used in the Page Hinckley change detection tests.", 50, 0, Integer.MAX_VALUE); -======= -// public FloatOption PageHinckleyAlphaOption = new FloatOption( -// "PageHinckleyAlpha", -// 'a', -// "The alpha value to use in the Page Hinckley change detection tests.", -// 0.005, 0.0, 1.0); -// -// public IntOption PageHinckleyThresholdOption = new IntOption( -// "PageHinckleyThreshold", -// 'h', -// "The threshold value to be used in the Page Hinckley change detection tests.", -// 50, 0, Integer.MAX_VALUE); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa public FloatOption alternateTreeFadingFactorOption = new FloatOption( "alternateTreeFadingFactor", @@ -185,15 +161,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR "doNotNormalize", 'n', "Don't normalize."); -<<<<<<< HEAD - - public FlagOption printLogsOption = new FlagOption( - "printLogs", - 'z', - "Print logs."); -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - //endregion ================ OPTIONS ================ @@ -342,17 +309,11 @@ public LeafNode(ISOUPTree tree) { */ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, boolean growthAllowed) { // Update the statistics for this node -<<<<<<< HEAD - // number of instances passing through the node - double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; - double[] predictionM = getPredictionTargetMean(inst); - -======= + double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; double[] predictionM = getPredictionTargetMean(inst); // number of instances passing through the node ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa examplesSeen += inst.weight(); for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { @@ -367,10 +328,7 @@ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, bool errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - inst.valueOutputAttribute(i))); } } -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); for (int i = 0; i < inst.numInputAttributes(); i++) { @@ -443,17 +401,11 @@ public double[] getPredictionModel(MultiLabelInstance inst) { public double[] getPredictionTargetMean(MultiLabelInstance inst) { double[] pred = new double[inst.numOutputAttributes()]; -<<<<<<< HEAD for (int i = 0; i < inst.numOutputAttributes(); i++) { if (examplesSeen > 0) { pred[i] = sumOfValues.getValue(i) / examplesSeen; } else { pred[i] = 0; -======= - if (examplesSeen > 0) { - for (int i = 0; i < inst.numOutputAttributes(); i++) { - pred[i] = sumOfValues.getValue(i) / examplesSeen; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } return pred; @@ -654,11 +606,8 @@ public class MultitargetPerceptron { protected ISOUPTree tree; // The Perception weights -<<<<<<< HEAD public double[][] weights; -======= - protected double[][] weights; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + // The number of instances contributing to this model protected int instancesSeen = 0; @@ -670,13 +619,6 @@ public String getPurposeString() { public MultitargetPerceptron(ISOUPTree tree, MultitargetPerceptron original) { this.tree = tree; weights = original.weights.clone(); -<<<<<<< HEAD - // TODO check if this is necessary -// for (int i = 0; i < this.tree.getModelContext().numOutputAttributes(); i++) { -// weights[i] = (DoubleVector) original.weights[i].copy(); -// } -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } public MultitargetPerceptron(ISOUPTree tree) { @@ -696,10 +638,7 @@ public void initializeWeights() { weights[i][j] = 2 * tree.classifierRandom.nextDouble() - 1; } } -<<<<<<< HEAD normalizeWeights(); -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } /** @@ -750,10 +689,6 @@ public void normalizeWeights() { } } -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa /** * Output the prediction made by this perceptron on the given instance */ @@ -792,7 +727,6 @@ private double[] denormalizePrediction(double[] normalizedPrediction) { public void getModelDescription(StringBuilder out, int indent) { for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "]"); -<<<<<<< HEAD //if (getModelContext() != null) { //for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { // if (getModelContext().attribute(j).isNumeric()) { @@ -1140,24 +1074,6 @@ public void getModelDescription(StringBuilder out, int indent) { // // } -======= - if (getModelContext() != null) { - for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { - if (getModelContext().attribute(j).isNumeric()) { - out.append((j == 0 || weights[i][j] < 0) ? " " : " + "); - out.append(String.format("%.4f", weights[i][j])); - out.append(" * "); - out.append(getAttributeNameString(j)); - } - } - out.append(" + " + weights[i][getModelContext().numOutputAttributes()]); - } - StringUtils.appendNewline(out); - } - } - } - ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa //endregion ================ CLASSES ================ //region ================ METHODS ================ @@ -1166,27 +1082,17 @@ public void getModelDescription(StringBuilder out, int indent) { public ISOUPTree() {} public String getPurposeString() { -<<<<<<< HEAD - return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; -======= return "Implementation of the iSOUP-Tree algorithm as described by Osojnik et al."; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } public void resetLearningImpl() { treeRoot = null; - leafNodeCount = 0; - splitNodeCount = 0; -<<<<<<< HEAD examplesSeen = 0.0; sumOfValues = new DoubleVector(); sumOfSquares = new DoubleVector(); sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); -======= - maxID = 0; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } public boolean isRandomizable() { @@ -1280,11 +1186,7 @@ public double[] normalizeTargetVector(double[] pred) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0 && examplesSeen > 1) -<<<<<<< HEAD out[i] = (value - average) / sd; -======= - out[i] = (value - average) / (3 * sd); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa else out[i] = 0; } @@ -1300,11 +1202,7 @@ public double normalizeTargetValue(MultiLabelInstance inst, int i) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0) -<<<<<<< HEAD return (value - average) / sd; -======= - return (value - average) / (3 * sd); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa else return 0; } @@ -1318,11 +1216,7 @@ public double normalizeTargetValue(double value, int i) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0) -<<<<<<< HEAD return (value - average) / sd; -======= - return (value - average) / (3 * sd); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa else return 0; } @@ -1350,15 +1244,9 @@ public void trainOnInstanceImpl(MultiLabelInstance inst) { double[] prediction = treeRoot.getPrediction(inst); double[] normalError = getNormalizedError(inst, prediction); -<<<<<<< HEAD processInstance(inst, treeRoot, prediction, normalError, true, false); -======= - //normalError.scaleValues(inst.weight()); - processInstance(inst, treeRoot, prediction, normalError, true, false); - ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa examplesSeen += inst.weight(); for (int i = 0; i < inst.numberOutputTargets(); i++) { sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); @@ -1369,12 +1257,6 @@ public void trainOnInstanceImpl(MultiLabelInstance inst) { sumOfAttrValues.addToValue(i, inst.weight() * inst.valueInputAttribute(i)); sumOfAttrSquares.addToValue(i, inst.weight() * inst.valueInputAttribute(i) * inst.valueInputAttribute(i)); } -<<<<<<< HEAD - - //normalError.scaleValues(inst.weight()); - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } @@ -1475,11 +1357,7 @@ protected LeafNode newLeafNode() { return new LeafNode(this); } -<<<<<<< HEAD public MultitargetPerceptron newLeafModel() { -======= - protected MultitargetPerceptron newLeafModel() { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa return new MultitargetPerceptron(this); } @@ -1489,7 +1367,6 @@ protected MultitargetPerceptron newLeafModel() { protected void checkRoot() { if (treeRoot == null) { treeRoot = newLeafNode(); - leafNodeCount = 1; } } @@ -1556,29 +1433,17 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) } } } -<<<<<<< HEAD - - if (hoeffdingBound < this.tieThresholdOption.getValue() && this.printLogsOption.isSet()) System.out.println("Forced to split due to tie at " + this.examplesSeen); -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } // If the splitting criterion were met, split the current node using the chosen attribute test, and // make two new branches leading to (empty) leaves if (shouldSplit) { -<<<<<<< HEAD - if (node.parent == null && this.printLogsOption.isSet()) { - System.out.println("splitting root node at " + this.examplesSeen); - } -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; SplitNode newSplit = newSplitNode(splitDecision.predicate); newSplit.copyStatistics(node); newSplit.changeDetection = node.changeDetection; newSplit.ID = node.ID; - leafNodeCount--; //System.out.println("Splitting"); //System.out.println(examplesSeen); for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) @@ -1591,7 +1456,6 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) newChild.changeDetection = node.changeDetection; newChild.setParent(newSplit); newSplit.setChild(i, newChild); - leafNodeCount++; } if (parent == null && node.originalNode == null) { treeRoot = newSplit; @@ -1601,8 +1465,6 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) parent.setChild(parentIndex, newSplit); newSplit.setParent(parent); } - - splitNodeCount++; } } diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java index 6cb747894..fc8b2aaea 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java @@ -1,4 +1,3 @@ -<<<<<<< HEAD /* * FIMTDD.java * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia @@ -829,7 +828,7 @@ public void processInstance(Instance inst, Node node, double prediction, double } } - if (false && iNode.changeDetection && !inAlternate) { + if (iNode.changeDetection && !inAlternate) { if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { iNode.initializeAlternateTree(); growthAllowed = false; @@ -926,20 +925,11 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { } } } -// if (hoeffdingBound < this.tieThresholdOption.getValue() && !(secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound)) { -// System.out.println("Forced to split due to tie at " + this.examplesSeen); -// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); -// } } // If the splitting criterion were met, split the current node using the chosen attribute test, and // make two new branches leading to (empty) leaves if (shouldSplit) { -// System.out.println("splitting node"); -// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); -// if (node.parent == null) { -// System.out.println("splitting root node at " + this.examplesSeen); -// } AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; SplitNode newSplit = newSplitNode(splitDecision.splitTest); @@ -989,976 +979,4 @@ public double scalarProduct(DoubleVector u, DoubleVector v) { //endregion --- Processing methods //endregion ================ METHODS ================ -} - -======= -/* - * FIMTDD.java - * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia - * @author Aljaž Osojnik - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ - -package moa.classifiers.trees; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -import com.yahoo.labs.samoa.instances.Instance; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; - -import moa.options.ClassOption; -import moa.AbstractMOAObject; -import moa.classifiers.Regressor; -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.conditionaltests.InstanceConditionalTest; -import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.classifiers.AbstractClassifier; -import moa.core.AutoExpandVector; -import moa.core.DoubleVector; -import moa.core.Measurement; -import moa.core.SizeOf; -import moa.core.StringUtils; - -/* - * Implementation of FIMTDD, regression and model trees for data streams. - */ - -public class FIMTDD extends AbstractClassifier implements Regressor { - - private static final long serialVersionUID = 1L; - - protected Node treeRoot; - - protected int leafNodeCount = 0; - protected int splitNodeCount = 0; - - protected double examplesSeen = 0.0; - protected double sumOfValues = 0.0; - protected double sumOfSquares = 0.0; - - protected DoubleVector sumOfAttrValues = new DoubleVector(); - protected DoubleVector sumOfAttrSquares = new DoubleVector(); - - public int maxID = 0; - - //region ================ OPTIONS ================ - - public ClassOption splitCriterionOption = new ClassOption( - "splitCriterion", 's', "Split criterion to use.", - SplitCriterion.class, "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); - - public IntOption gracePeriodOption = new IntOption( - "gracePeriod", 'g', "Number of instances a leaf should observe between split attempts.", - 200, 0, Integer.MAX_VALUE); - - public FloatOption splitConfidenceOption = new FloatOption( - "splitConfidence", 'c', "Allowed error in split decision, values close to 0 will take long to decide.", - 0.0000001, 0.0, 1.0); - - public FloatOption tieThresholdOption = new FloatOption( - "tieThreshold", 't', "Threshold below which a split will be forced to break ties.", - 0.05, 0.0, 1.0); - - public FloatOption PageHinckleyAlphaOption = new FloatOption( - "PageHinckleyAlpha", 'a', "Alpha value to use in the Page Hinckley change detection tests.", - 0.005, 0.0, 1.0); - - public IntOption PageHinckleyThresholdOption = new IntOption( - "PageHinckleyThreshold", 'h', "Threshold value used in the Page Hinckley change detection tests.", - 50, 0, Integer.MAX_VALUE); - - public FloatOption alternateTreeFadingFactorOption = new FloatOption( - "alternateTreeFadingFactor", 'f', "Fading factor used to decide if an alternate tree should replace an original.", - 0.995, 0.0, 1.0); - - public IntOption alternateTreeTMinOption = new IntOption( - "alternateTreeTMin", 'y', "Tmin value used to decide if an alternate tree should replace an original.", - 150, 0, Integer.MAX_VALUE); - - public IntOption alternateTreeTimeOption = new IntOption( - "alternateTreeTime", 'u', "The number of instances used to decide if an alternate tree should be discarded.", - 1500, 0, Integer.MAX_VALUE); - - public FlagOption regressionTreeOption = new FlagOption( - "regressionTree", 'e', "Build a regression tree instead of a model tree."); - - public FloatOption learningRatioOption = new FloatOption( - "learningRatio", 'l', "Learning ratio to used for training the Perceptrons in the leaves.", - 0.02, 0, 1.00); - - public FloatOption learningRateDecayFactorOption = new FloatOption( - "learningRatioDecayFactor", 'd', "Learning rate decay factor (not used when learning rate is constant).", - 0.001, 0, 1.00); - - public FlagOption learningRatioConstOption = new FlagOption( - "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); - - //endregion ================ OPTIONS ================ - - //region ================ CLASSES ================ - - public abstract static class Node extends AbstractMOAObject { - - private static final long serialVersionUID = 1L; - - public int ID; - - protected FIMTDD tree; - - protected boolean changeDetection = true; - - protected Node parent; - - protected Node alternateTree; - protected Node originalNode; - - // The statistics for this node: - // Number of instances that have reached it - protected double examplesSeen; - // Sum of y values - protected double sumOfValues; - // Sum of squared y values - protected double sumOfSquares; - // Sum of absolute errors - protected double sumOfAbsErrors; // Needed for PH tracking of mean error - - public Node(FIMTDD tree) { - this.tree = tree; - ID = tree.maxID; - } - - public void copyStatistics(Node node) { - examplesSeen = node.examplesSeen; - sumOfValues = node.sumOfValues; - sumOfSquares = node.sumOfSquares; - sumOfAbsErrors = node.sumOfAbsErrors; - } - - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); - } - - /** - * Set the parent node - */ - public void setParent(Node parent) { - this.parent = parent; - } - - /** - * Return the parent node - */ - public Node getParent() { - return parent; - } - - public void disableChangeDetection() { - changeDetection = false; - } - - public void restartChangeDetection() { - changeDetection = true; - } - - public void getDescription(StringBuilder sb, int indent) { - - } - - public double getPrediction(Instance inst) { - return 0; - } - - public void describeSubtree(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, "Leaf"); - } - - public int getLevel() { - Node target = this; - int level = 0; - while (target.getParent() != null) { - if (target.skipInLevelCount()) { - target = target.getParent(); - continue; - } - level = level + 1; - target = target.getParent(); - } - if (target.originalNode == null) { - return level; - } else { - return level + originalNode.getLevel(); - } - } - - public void setChild(int parentBranch, Node node) { - } - - public int getChildIndex(Node child) { - return -1; - } - - public int getNumSubtrees() { - return 1; - } - - protected boolean skipInLevelCount() { - return false; - } - } - - public static class LeafNode extends Node { - - private static final long serialVersionUID = 1L; - - // Perceptron model that carries out the actual learning in each node - public FIMTDDPerceptron learningModel; - - protected AutoExpandVector attributeObservers = new AutoExpandVector(); - - protected double examplesSeenAtLastSplitEvaluation = 0; - - /** - * Create a new LeafNode - */ - public LeafNode(FIMTDD tree) { - super(tree); - if (tree.buildingModelTree()) { - learningModel = tree.newLeafModel(); - } - examplesSeen = 0; - sumOfValues = 0; - sumOfSquares = 0; - sumOfAbsErrors = 0; - } - - public void setChild(int parentBranch, Node node) { - } - - public int getChildIndex(Node child) { - return -1; - } - - public int getNumSubtrees() { - return 1; - } - - protected boolean skipInLevelCount() { - return false; - } - - /** - * Method to learn from an instance that passes the new instance to the perceptron learner, - * and also prevents the class value from being truncated to an int when it is passed to the - * attribute observer - */ - public void learnFromInstance(Instance inst, boolean growthAllowed) { - //The prediction must be calculated here -- it may be different from the tree's prediction due to alternate trees - - // Update the statistics for this node - // number of instances passing through the node - examplesSeen += inst.weight(); - - // sum of y values - sumOfValues += inst.weight() * inst.classValue(); - - // sum of squared y values - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - - // sum of absolute errors - sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - getPrediction(inst)))); - - if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); - FIMTDDNumericAttributeClassObserver obs = attributeObservers.get(i); - if (obs == null) { - // At this stage all nominal attributes are ignored - if (inst.attribute(instAttIndex).isNumeric()) { - obs = tree.newNumericClassObserver(); - this.attributeObservers.set(i, obs); - } - } - if (obs != null) { - obs.observeAttributeClass(inst.value(instAttIndex), inst.classValue(), inst.weight()); - } - } - - if (growthAllowed) { - checkForSplit(tree); - } - } - - /** - * Return the best split suggestions for this node using the given split criteria - */ - public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion) { - - List bestSuggestions = new LinkedList(); - - // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution - double[] nodeSplitDist = new double[] {examplesSeen, sumOfValues, sumOfSquares}; - - for (int i = 0; i < this.attributeObservers.size(); i++) { - FIMTDDNumericAttributeClassObserver obs = this.attributeObservers.get(i); - if (obs != null) { - - // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED - AttributeSplitSuggestion bestSuggestion = null; - if (obs instanceof FIMTDDNumericAttributeClassObserver) { - bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, nodeSplitDist, i, true); - } - - if (bestSuggestion != null) { - bestSuggestions.add(bestSuggestion); - } - } - } - return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); - } - - /** - * Retrieve the class votes using the perceptron learner - */ - public double getPredictionModel(Instance inst) { - return learningModel.prediction(inst); - } - - public double getPredictionTargetMean(Instance inst) { - return (examplesSeen > 0.0) ? sumOfValues / examplesSeen : 0.0; - } - - public double getPrediction(Instance inst) { - return (tree.buildingModelTree()) ? getPredictionModel(inst) : getPredictionTargetMean(inst); - } - - public void checkForSplit(FIMTDD tree) { - // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node - if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { - int index = (parent != null) ? parent.getChildIndex(this) : 0; - tree.attemptToSplit(this, parent, index); - - // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation - examplesSeenAtLastSplitEvaluation = examplesSeen; - } - } - - public void describeSubtree(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, "Leaf "); - if (tree.buildingModelTree()) { - learningModel.getModelDescription(out, 0); - } else { - out.append(tree.getClassNameString() + " = " + String.format("%.4f", (sumOfValues / examplesSeen))); - StringUtils.appendNewline(out); - } - } - } - - public abstract static class InnerNode extends Node { - // The InnerNode and SplitNode design is used for easy extension in ORTO - private static final long serialVersionUID = 1L; - - protected AutoExpandVector children = new AutoExpandVector(); - - // The error values for the Page Hinckley test - // PHmT = the cumulative sum of the errors - // PHMT = the minimum error value seen so far - protected double PHsum = 0; - protected double PHmin = Double.MAX_VALUE; - - // Keep track of the statistics for loss error calculations - protected double lossExamplesSeen; - protected double lossFadedSumOriginal; - protected double lossFadedSumAlternate; - protected double lossNumQiTests; - protected double lossSumQi; - protected double previousWeight = 0; - - public InnerNode(FIMTDD tree) { - super(tree); - } - - public int numChildren() { - return children.size(); - } - - public Node getChild(int index) { - return children.get(index); - } - - public int getChildIndex(Node child) { - return children.indexOf(child); - } - - public void setChild(int index, Node child) { - children.set(index, child); - } - - public void disableChangeDetection() { - changeDetection = false; - for (Node child : children) { - child.disableChangeDetection(); - } - } - - public void restartChangeDetection() { - if (alternateTree == null) { - changeDetection = true; - PHsum = 0; - PHmin = Integer.MAX_VALUE; - for (Node child : children) - child.restartChangeDetection(); - } - } - - /** - * Check to see if the tree needs updating - */ - public boolean PageHinckleyTest(double error, double threshold) { - // Update the cumulative mT sum - PHsum += error; - - // Update the minimum mT value if the new mT is - // smaller than the current minimum - if(PHsum < PHmin) { - PHmin = PHsum; - } - // Return true if the cumulative value - the current minimum is - // greater than the current threshold (in which case we should adapt) - return PHsum - PHmin > threshold; - } - - public void initializeAlternateTree() { - // Start a new alternate tree, beginning with a learning node - alternateTree = tree.newLeafNode(); - alternateTree.originalNode = this; - - // Set up the blank statistics - // Number of instances reaching this node since the alternate tree was started - lossExamplesSeen = 0; - // Faded squared error (original tree) - lossFadedSumOriginal = 0; - // Faded squared error (alternate tree) - lossFadedSumAlternate = 0; - // Number of evaluations of alternate tree - lossNumQiTests = 0; - // Sum of Qi values - lossSumQi = 0; - // Number of examples at last test - previousWeight = 0; - - // Disable the change detection mechanism bellow this node - disableChangeDetection(); - } - } - - public static class SplitNode extends InnerNode { - - private static final long serialVersionUID = 1L; - - protected InstanceConditionalTest splitTest; - - /** - * Create a new SplitNode - * @param tree - */ - public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { - super(tree); - this.splitTest = splitTest; - } - - public int instanceChildIndex(Instance inst) { - return splitTest.branchForInstance(inst); - } - - public Node descendOneStep(Instance inst) { - return children.get(splitTest.branchForInstance(inst)); - } - - public void describeSubtree(StringBuilder out, int indent) { - for (int branch = 0; branch < children.size(); branch++) { - Node child = getChild(branch); - if (child != null) { - StringUtils.appendIndented(out, indent, "if "); - out.append(this.splitTest.describeConditionForBranch(branch, - tree.getModelContext())); - out.append(": "); - StringUtils.appendNewline(out); - child.describeSubtree(out, indent + 2); - } - } - } - - public double getPrediction(Instance inst) { - return children.get(splitTest.branchForInstance(inst)).getPrediction(inst); - } - } - - public class FIMTDDPerceptron implements Serializable { - - private static final long serialVersionUID = 1L; - - protected FIMTDD tree; - - // The Perception weights - protected DoubleVector weightAttribute = new DoubleVector(); - - protected double sumOfValues; - protected double sumOfSquares; - - // The number of instances contributing to this model - protected double instancesSeen = 0; - - // If the model should be reset or not - protected boolean reset; - - public String getPurposeString() { - return "A perceptron regressor as specified by Ikonomovska et al. used for FIMTDD"; - } - - public FIMTDDPerceptron(FIMTDDPerceptron original) { - this.tree = original.tree; - weightAttribute = (DoubleVector) original.weightAttribute.copy(); - reset = false; - } - - public FIMTDDPerceptron(FIMTDD tree) { - this.tree = tree; - reset = true; - } - - - public DoubleVector getWeights() { - return weightAttribute; - } - - /** - * Update the model using the provided instance - */ - public void updatePerceptron(Instance inst) { - - // Initialize perceptron if necessary - if (reset == true) { - reset = false; - weightAttribute = new DoubleVector(); - instancesSeen = 0; - for (int j = 0; j < inst.numAttributes(); j++) { // The last index corresponds to the constant b - weightAttribute.setValue(j, 2 * tree.classifierRandom.nextDouble() - 1); - } - } - - // Update attribute statistics - instancesSeen += inst.weight(); - - // Update weights - double learningRatio = 0.0; - if (tree.learningRatioConstOption.isSet()) { - learningRatio = learningRatioOption.getValue(); - } else { - learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); - } - - sumOfValues += inst.weight() * inst.classValue(); - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - - // Loop for compatibility with bagging methods - for (int i = 0; i < (int) inst.weight(); i++) { - updateWeights(inst, learningRatio); - } - } - - public void updateWeights(Instance inst, double learningRatio) { - // Compute the normalized instance and the delta - DoubleVector normalizedInstance = normalizedInstance(inst); - double normalizedPrediction = prediction(normalizedInstance); - double normalizedValue = tree.normalizeTargetValue(inst.classValue()); - double delta = normalizedValue - normalizedPrediction; - normalizedInstance.scaleValues(delta * learningRatio); - - weightAttribute.addValues(normalizedInstance); - } - - public DoubleVector normalizedInstance(Instance inst) { - // Normalize Instance - DoubleVector normalizedInstance = new DoubleVector(); - for (int j = 0; j < inst.numAttributes() - 1; j++) { - int instAttIndex = modelAttIndexToInstanceAttIndex(j, inst); - double mean = tree.sumOfAttrValues.getValue(j) / tree.examplesSeen; - double sd = computeSD(tree.sumOfAttrSquares.getValue(j), tree.sumOfAttrValues.getValue(j), tree.examplesSeen); - if (inst.attribute(instAttIndex).isNumeric() && tree.examplesSeen > 1 && sd > 0) - normalizedInstance.setValue(j, (inst.value(instAttIndex) - mean) / (3 * sd)); - else - normalizedInstance.setValue(j, 0); - } - if (tree.examplesSeen > 1) - normalizedInstance.setValue(inst.numAttributes() - 1, 1.0); // Value to be multiplied with the constant factor - else - normalizedInstance.setValue(inst.numAttributes() - 1, 0.0); - return normalizedInstance; - } - - /** - * Output the prediction made by this perceptron on the given instance - */ - public double prediction(DoubleVector instanceValues) { - return scalarProduct(weightAttribute, instanceValues); - } - - protected double prediction(Instance inst) { - DoubleVector normalizedInstance = normalizedInstance(inst); - double normalizedPrediction = prediction(normalizedInstance); - return denormalizePrediction(normalizedPrediction, tree); - } - - private double denormalizePrediction(double normalizedPrediction, FIMTDD tree) { - double mean = tree.sumOfValues / tree.examplesSeen; - double sd = computeSD(tree.sumOfSquares, tree.sumOfValues, tree.examplesSeen); - if (examplesSeen > 1) - return normalizedPrediction * sd * 3 + mean; - else - return 0.0; - } - - public void getModelDescription(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, getClassNameString() + " ="); - if (getModelContext() != null) { - for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { - if (getModelContext().attribute(j).isNumeric()) { - out.append((j == 0 || weightAttribute.getValue(j) < 0) ? " " : " + "); - out.append(String.format("%.4f", weightAttribute.getValue(j))); - out.append(" * "); - out.append(getAttributeNameString(j)); - } - } - out.append(" + " + weightAttribute.getValue((getModelContext().numAttributes() - 1))); - } - StringUtils.appendNewline(out); - } - } - - - //endregion ================ CLASSES ================ - - //region ================ METHODS ================ - - // region --- Regressor methods - - public String getPurposeString() { - return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; - } - - public void resetLearningImpl() { - this.treeRoot = null; - this.leafNodeCount = 0; - this.splitNodeCount = 0; - this.maxID = 0; - this.examplesSeen = 0; - this.sumOfValues = 0.0; - this.sumOfSquares = 0.0; - - this.sumOfAttrValues = new DoubleVector(); - this.sumOfAttrSquares = new DoubleVector(); - } - - public boolean isRandomizable() { - return true; - } - - public void getModelDescription(StringBuilder out, int indent) { - if (treeRoot != null) treeRoot.describeSubtree(out, indent); - } - - protected Measurement[] getModelMeasurementsImpl() { - return new Measurement[]{ - new Measurement("tree size (leaves)", this.leafNodeCount) - }; - } - - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); - } - - public double[] getVotesForInstance(Instance inst) { - if (treeRoot == null) { - return new double[] {0}; - } - - double prediction = treeRoot.getPrediction(inst); - - return new double[] {prediction}; - } - - public double normalizeTargetValue(double value) { - if (examplesSeen > 1) { - double sd = Math.sqrt((sumOfSquares - ((sumOfValues * sumOfValues)/examplesSeen))/examplesSeen); - double average = sumOfValues / examplesSeen; - if (sd > 0 && examplesSeen > 1) - return (value - average) / (3 * sd); - else - return 0.0; - } - return 0.0; - } - - public double getNormalizedError(Instance inst, double prediction) { - double normalPrediction = normalizeTargetValue(prediction); - double normalValue = normalizeTargetValue(inst.classValue()); - return Math.abs(normalValue - normalPrediction); - } - - - /** - * Method for updating (training) the model using a new instance - */ - public void trainOnInstanceImpl(Instance inst) { - checkRoot(); - - examplesSeen += inst.weight(); - sumOfValues += inst.weight() * inst.classValue(); - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int aIndex = modelAttIndexToInstanceAttIndex(i, inst); - sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); - sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); - } - - double prediction = treeRoot.getPrediction(inst); - processInstance(inst, treeRoot, prediction, getNormalizedError(inst, prediction), true, false); - } - - public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { - Node currentNode = node; - while (true) { - if (currentNode instanceof LeafNode) { - ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); - break; - } else { - currentNode.examplesSeen += inst.weight(); - currentNode.sumOfAbsErrors += inst.weight() * normalError; - SplitNode iNode = (SplitNode) currentNode; - if (!inAlternate && iNode.alternateTree != null) { - boolean altTree = true; - double lossO = Math.pow(inst.classValue() - prediction, 2); - double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); - - // Loop for compatibility with bagging methods - for (int i = 0; i < inst.weight(); i++) { - iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; - iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; - iNode.lossExamplesSeen++; - - double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - iNode.lossSumQi += Qi; - iNode.lossNumQiTests += 1; - } - double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - - if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { - iNode.previousWeight = iNode.lossExamplesSeen; - if (Qi > 0) { - // Switch the subtrees - Node parent = currentNode.getParent(); - - if (parent != null) { - Node replacementTree = iNode.alternateTree; - parent.setChild(parent.getChildIndex(currentNode), replacementTree); - if (growthAllowed) replacementTree.restartChangeDetection(); - } else { - treeRoot = iNode.alternateTree; - treeRoot.restartChangeDetection(); - } - - currentNode = iNode.alternateTree; - currentNode.originalNode = null; - altTree = false; - } else if ( - (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) - || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() - ) { - // Remove the alternate tree - iNode.alternateTree = null; - if (growthAllowed) iNode.restartChangeDetection(); - altTree = false; - } - } - - if (altTree) { - growthAllowed = false; - processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); - } - } - - if (iNode.changeDetection && !inAlternate) { - if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { - iNode.initializeAlternateTree(); - } - } - if (currentNode instanceof SplitNode) { - currentNode = ((SplitNode) currentNode).descendOneStep(inst); - } - } - } - } - - // endregion --- Regressor methods - - // region --- Object instatiation methods - - protected FIMTDDNumericAttributeClassObserver newNumericClassObserver() { - return new FIMTDDNumericAttributeClassObserver(); - } - - protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { - maxID++; - return new SplitNode(splitTest, this); - } - - protected LeafNode newLeafNode() { - maxID++; - return new LeafNode(this); - } - - protected FIMTDDPerceptron newLeafModel() { - return new FIMTDDPerceptron(this); - } - - //endregion --- Object instatiation methods - - // region --- Processing methods - - protected void checkRoot() { - if (treeRoot == null) { - treeRoot = newLeafNode(); - leafNodeCount = 1; - } - } - - public static double computeHoeffdingBound(double range, double confidence, double n) { - return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); - } - - public boolean buildingModelTree() { - return !regressionTreeOption.isSet(); - } - - protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { - // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); - - // Using this criterion, find the best split per attribute and rank the results - AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); - Arrays.sort(bestSplitSuggestions); - - // Declare a variable to determine if any of the splits should be performed - boolean shouldSplit = false; - - // If only one split was returned, use it - if (bestSplitSuggestions.length < 2) { - shouldSplit = bestSplitSuggestions.length > 0; - } else { // Otherwise, consider which of the splits proposed may be worth trying - - // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, this.splitConfidenceOption.getValue(), node.examplesSeen); - // Determine the top two ranked splitting suggestions - AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - - // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), - // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this - // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and - // splitting should occur. - // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit - // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two - // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { - shouldSplit = true; - } - // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - else { - for (int i = 0; i < node.attributeObservers.size(); i++) { - FIMTDDNumericAttributeClassObserver obs = node.attributeObservers.get(i); - if (obs != null) { - obs.removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); - } - } - } - } - - // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (shouldSplit) { - AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - - SplitNode newSplit = newSplitNode(splitDecision.splitTest); - newSplit.copyStatistics(node); - newSplit.changeDetection = node.changeDetection; - newSplit.ID = node.ID; - leafNodeCount--; - for (int i = 0; i < splitDecision.numSplits(); i++) { - LeafNode newChild = newLeafNode(); - if (buildingModelTree()) { - // Copy the splitting node's perceptron to it's children - newChild.learningModel = new FIMTDDPerceptron((FIMTDDPerceptron) node.learningModel); - - } - newChild.changeDetection = node.changeDetection; - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - leafNodeCount++; - } - if (parent == null && node.originalNode == null) { - treeRoot = newSplit; - } else if (parent == null && node.originalNode != null) { - node.originalNode.alternateTree = newSplit; - } else { - ((SplitNode) parent).setChild(parentIndex, newSplit); - newSplit.setParent(parent); - } - - splitNodeCount++; - } - } - - public double computeSD(double squaredVal, double val, double size) { - if (size > 1) - return Math.sqrt((squaredVal - ((val * val) / size)) / size); - else - return 0.0; - } - - public double scalarProduct(DoubleVector u, DoubleVector v) { - double ret = 0.0; - for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { - ret += u.getValue(i) * v.getValue(i); - } - return ret; - } - //endregion --- Processing methods - - //endregion ================ METHODS ================ -} - ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +} \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index 2745dcc7e..7ab9734db 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -35,16 +35,11 @@ import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.splitcriteria.SplitCriterion; -<<<<<<< HEAD -import moa.classifiers.trees.FIMTDD.InnerNode; -import moa.classifiers.trees.FIMTDD.Node; + import moa.core.AutoExpandVector; import moa.core.Measurement; import moa.core.StringUtils; -======= -import moa.core.AutoExpandVector; -import moa.core.Measurement; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + /* * Implementation of ORTO, option trees for data streams. @@ -127,15 +122,9 @@ public int getNumSubtrees() { public int directionForBestTree() { int d = 0; -<<<<<<< HEAD - double min = Double.MAX_VALUE; - for (int i = 0; i < numChildren(); i++) { - double tmp = getFFRatio(i); -======= double tmp = 0.0, min = Double.MAX_VALUE; for (int i = 0; i < children.size(); i++) { tmp = getFFRatio(i); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (tmp < min) { min = tmp; d = i; @@ -144,38 +133,22 @@ public int directionForBestTree() { return d; } -<<<<<<< HEAD public double getPrediction(Instance inst) { -======= - public double getPrediction(Instance inst, ORTO tree) { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa double[] predictions = new double[numChildren()]; for (int i = 0; i < numChildren(); i++) { predictions[i] = getChild(i).getPrediction(inst); } -<<<<<<< HEAD return aggregate(predictions); } private double aggregate(double[] predictions) { if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average -======= - return aggregate(predictions, tree); - } - - private double aggregate(double[] predictions, ORTO tree) { - if (tree.optionNodeAggregationOption.getChosenIndex() == 0) { // Average ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa double sum = 0.0; for (int i = 0; i < predictions.length; i++) { sum += predictions[i]; } return sum / predictions.length; -<<<<<<< HEAD } else if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 1) { -======= - } else if (tree.optionNodeAggregationOption.getChosenIndex() == 1) { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa int d = directionForBestTree(); return predictions[d]; } else { @@ -190,7 +163,6 @@ public double getFFRatio(int childIndex) { protected boolean skipInLevelCount() { return true; } -<<<<<<< HEAD @Override public void describeSubtree(StringBuilder out, int indent) { @@ -203,8 +175,7 @@ public void describeSubtree(StringBuilder out, int indent) { split.describeSubtree(out, indent + 2); } } -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + } //endregion ================ CLASSES ================ @@ -239,11 +210,7 @@ public void processInstance(Instance inst, Node node, double prediction, double Node currentNode = node; while (true) { if (currentNode instanceof LeafNode) { -<<<<<<< HEAD ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); -======= - ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa break; } else { currentNode.examplesSeen += inst.weight(); @@ -252,11 +219,7 @@ public void processInstance(Instance inst, Node node, double prediction, double if (!inAlternate && iNode.alternateTree != null) { boolean altTree = true; double lossO = Math.pow(inst.classValue() - prediction, 2); -<<<<<<< HEAD double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); -======= - double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { @@ -276,11 +239,7 @@ public void processInstance(Instance inst, Node node, double prediction, double iNode.previousWeight = iNode.lossExamplesSeen; if (Qi > 0) { // Switch the subtrees -<<<<<<< HEAD Node parent = iNode.getParent(); -======= - Node parent = currentNode.parent; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (parent != null) { Node replacementTree = iNode.alternateTree; @@ -290,11 +249,7 @@ public void processInstance(Instance inst, Node node, double prediction, double treeRoot = iNode.alternateTree; treeRoot.restartChangeDetection(); } -<<<<<<< HEAD optionNodeCount += iNode.alternateTree.getNumSubtrees() - iNode.getNumSubtrees(); -======= - optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa removeExcessTrees(); currentNode = iNode.alternateTree; @@ -309,11 +264,7 @@ public void processInstance(Instance inst, Node node, double prediction, double } if (altTree) { growthAllowed = false; // this is the growth of the original tree -<<<<<<< HEAD processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree -======= - processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } else if (currentNode instanceof OptionNode) { // this happens when an option node is switched into the tree for (Node child : ((OptionNode) currentNode).children) { @@ -341,35 +292,23 @@ public void processInstance(Instance inst, Node node, double prediction, double } public void processInstanceOptionNode(Instance inst, OptionNode node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { -<<<<<<< HEAD node.examplesSeen += inst.weight(); node.sumOfAbsErrors += inst.weight() * normalError; -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + if (node.changeDetection) { double error = Math.abs(prediction - inst.classValue()); node.sumOfAbsErrors += error; if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { node.initializeAlternateTree(); -<<<<<<< HEAD growthAllowed = false; -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } for (Node child : node.children) { int index = node.getChildIndex(child); double childPrediction = child.getPrediction(inst); -<<<<<<< HEAD - node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; - node.optionFFSSL[index] = node.optionFFSSL[index] * optionFadingFactorOption.getValue() + Math.pow(childPrediction - inst.classValue(), 2); - } - for (Node child : node.children) { - processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); -======= // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; @@ -379,7 +318,6 @@ public void processInstanceOptionNode(Instance inst, OptionNode node, double pre for (Node child : node.children) { processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } @@ -397,10 +335,6 @@ protected OptionNode newOptionNode() { // region --- Processing methods protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Initialize the split criterion SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); @@ -408,11 +342,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); List acceptedSplits = new LinkedList(); Arrays.sort(bestSplitSuggestions); -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Declare a variable to determine the number of splits to be performed int numSplits = 0; @@ -430,10 +360,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and @@ -445,7 +372,6 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { numSplits = 1; acceptedSplits.add(bestSuggestion); } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { -<<<<<<< HEAD for (int i = 0; i < bestSplitSuggestions.length; i++) { AttributeSplitSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { @@ -456,15 +382,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { } } - -======= - for (AttributeSplitSuggestion suggestion : bestSplitSuggestions) { - if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { - numSplits++; - acceptedSplits.add(suggestion); - } - } ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + } else if (hoeffdingBound < tieThresholdOption.getValue()) { numSplits = 1; acceptedSplits.add(bestSplitSuggestions[0]); @@ -483,11 +401,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (numSplits > 0) { double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); -<<<<<<< HEAD - if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 0) { -======= if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa AttributeSplitSuggestion splitDecision = acceptedSplits.get(0); SplitNode newSplit = newSplitNode(splitDecision.splitTest); for (int i = 0; i < splitDecision.numSplits(); i++) { @@ -498,19 +412,12 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { leafNodeCount--; innerNodeCount++; leafNodeCount += splitDecision.numSplits(); -<<<<<<< HEAD if (parent == null && node.originalNode == null) { treeRoot = newSplit; } else if (parent == null && node.originalNode != null) { node.originalNode.alternateTree = newSplit; } else { parent.setChild(parentIndex, newSplit); -======= - if (parent == null) { - treeRoot = newSplit; - } else { - parent.setChild(parent.getChildIndex(node), newSplit); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa newSplit.setParent(parent); } } else { @@ -544,11 +451,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (parent == null) { treeRoot = optionNode; } else { -<<<<<<< HEAD parent.setChild(parentIndex, optionNode); -======= - parent.setChild(parent.getChildIndex(node), optionNode); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa optionNode.setParent(parent); } @@ -631,8 +534,5 @@ protected void removeExcessTrees() { // endregion --- Option tree methods //endregion ================ METHODS ================ -<<<<<<< HEAD -} -======= } ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index 4202599c6..61f2ee877 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -154,7 +154,6 @@ protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { int secondsElapsed = 0; monitor.setCurrentActivity("Evaluating learner...", -1.0); -<<<<<<< HEAD File dumpFile = this.dumpFileOption.getFile(); PrintStream immediateResultStream = null; if (dumpFile != null) { @@ -208,63 +207,7 @@ protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); } outputPredictionResultStream.println(prediction + "," + sb.toString()); - } -======= - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - //File for output predictions - File outputPredictionFile = this.outputPredictionFileOption.getFile(); - PrintStream outputPredictionResultStream = null; - if (outputPredictionFile != null) { - try { - if (outputPredictionFile.exists()) { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile, true), true); - } else { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open prediction result file: " + outputPredictionFile, ex); - } - } - boolean firstDump = true; - boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); - long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - long lastEvaluateStartTime = evaluateStartTime; - double RAMHours = 0.0; - while (stream.hasMoreInstances() - && ((maxInstances < 0) || (instancesProcessed < maxInstances)) - && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { - Example trainInst = stream.nextInstance(); - Example testInst = (Example) trainInst; //.copy(); - //testInst.setClassMissing(); - //double[] prediction = learner.getVotesForInstance(testInst); - Prediction prediction = learner.getPredictionForInstance(testInst); - // Output prediction - if (outputPredictionFile != null) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { - sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); - } - outputPredictionResultStream.println(prediction + "," + sb.toString()); - } ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + } //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); evaluator.addResult(testInst, prediction); From 5dec8c12eaac8f4785df76b61e4d40a591a13321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:07:34 +0100 Subject: [PATCH 05/33] Additional merging artefacts fixed --- .../MultitargetAttributeClassObserver.java | 15 +++++++++++++++ .../NumericAttributeBinaryTest.java | 4 ---- 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java diff --git a/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java b/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java new file mode 100644 index 000000000..0cfc7acb6 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java @@ -0,0 +1,15 @@ +package moa.classifiers.core.attributeclassobservers; + +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.core.DoubleVector; + +public interface MultitargetAttributeClassObserver extends AttributeClassObserver { + + public void observeAttributeClassVector(double attVal, DoubleVector classVector, double weight); + + public AttributeSplitSuggestion getBestEvaluatedSplitSuggestion( + SplitCriterion criterion, double examlpesSeen, DoubleVector preSplitSums, DoubleVector preSplitSquares, int attIndex, + int numTargets, boolean binaryOnly); + +} diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java index d60ee3af2..87a3f2e0e 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java @@ -52,11 +52,7 @@ public int branchForInstance(Instance inst) { if (inst.isMissing(instAttIndex)) { return -1; } -<<<<<<< HEAD double v = inst.valueInputAttribute(instAttIndex); -======= - double v = inst.valueInputAttribute(instAttIndex); // if the attIndex is not calculated above this is the correct method call ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (v == this.attValue) { return this.equalsPassesTest ? 0 : 1; } From 02d26831ad12964b8c91204bb81c22a5fdd5550b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:09:11 +0100 Subject: [PATCH 06/33] Test commit of everything --- .classpath | 13 ++ .project | 6 + moa/.classpath | 17 +-- moa/.settings/org.eclipse.jdt.core.prefs | 3 + moa/pom.xml | 138 ------------------ .../classifiers/DecisionStumpTutorial.java | 13 +- .../classifiers/multilabel/trees/.gitignore | 1 + moa/src/main/java/moa/evaluation/.gitignore | 2 + weka-package/pom.xml | 53 ------- 9 files changed, 41 insertions(+), 205 deletions(-) create mode 100644 .classpath delete mode 100755 moa/pom.xml create mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore create mode 100644 moa/src/main/java/moa/evaluation/.gitignore delete mode 100644 weka-package/pom.xml diff --git a/.classpath b/.classpath new file mode 100644 index 000000000..dec9f005e --- /dev/null +++ b/.classpath @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/.project b/.project index 76bea900b..56c2846a7 100644 --- a/.project +++ b/.project @@ -5,6 +5,11 @@ + + org.eclipse.jdt.core.javabuilder + + + org.eclipse.m2e.core.maven2Builder @@ -13,5 +18,6 @@ org.eclipse.m2e.core.maven2Nature + org.eclipse.jdt.core.javanature diff --git a/moa/.classpath b/moa/.classpath index 534b5e52f..f5accf223 100644 --- a/moa/.classpath +++ b/moa/.classpath @@ -11,26 +11,21 @@ - - - - - - - - - - - + + + + + + diff --git a/moa/.settings/org.eclipse.jdt.core.prefs b/moa/.settings/org.eclipse.jdt.core.prefs index 60105c1b9..69c31cd49 100644 --- a/moa/.settings/org.eclipse.jdt.core.prefs +++ b/moa/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,8 @@ eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.source=1.6 diff --git a/moa/pom.xml b/moa/pom.xml deleted file mode 100755 index dd44c7979..000000000 --- a/moa/pom.xml +++ /dev/null @@ -1,138 +0,0 @@ - - 4.0.0 - - - nz.ac.waikato.cms.moa - moa-pom - 2015.05-SNAPSHOT - - - moa - jar - - MOA: Massive Online Analysis - - Massive On-line Analysis is an environment for massive data mining. MOA - provides a framework for data stream mining and includes tools for evaluation - and a collection of machine learning algorithms. Related to the WEKA project, - also written in Java, while scaling to more demanding problems. - - http://moa.cms.waikato.ac.nz/ - - University of Waikato, Hamilton, NZ - http://www.waikato.ac.nz/ - - - - GNU General Public License 3.0 - http://www.gnu.org/licenses/gpl-3.0.txt - repo - - - - - - abifet - Albert Bifet - abifet@waikato.ac.nz - - - rkirkby - Richard Kirkby - - - - - - nz.ac.waikato.cms.weka - weka-dev - - - - com.googlecode.sizeofag - sizeofag - - - - junit - junit - test - - - - com.googlecode.java-diff-utils - diffutils - 1.2.1 - test - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.6 - 1.6 - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - - org.codehaus.mojo - license-maven-plugin - - - - org.codehaus.mojo - latex-maven-plugin - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - - license-maven-plugin - - [1.1,) - - add-third-party - - - - - - - - - - - - - - diff --git a/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java b/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java index 8d18b0a9d..0cabab7dc 100644 --- a/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java +++ b/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java @@ -1,11 +1,18 @@ package moa.classifiers; +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; +import moa.classifiers.core.attributeclassobservers.GaussianNumericAttributeClassObserver; +import moa.classifiers.core.attributeclassobservers.NominalAttributeClassObserver; +import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.options.ClassOption; -import moa.options.FlagOption; -import moa.options.IntOption; -import weka.core.Instance; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; + +import com.yahoo.labs.samoa.instances.Instance; public class DecisionStumpTutorial extends AbstractClassifier { diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore b/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore new file mode 100644 index 000000000..8e36d7391 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore @@ -0,0 +1 @@ +/BaselinePerceptron.java diff --git a/moa/src/main/java/moa/evaluation/.gitignore b/moa/src/main/java/moa/evaluation/.gitignore new file mode 100644 index 000000000..48df8b2bf --- /dev/null +++ b/moa/src/main/java/moa/evaluation/.gitignore @@ -0,0 +1,2 @@ +/MultilabelWindowClassificationPerformanceEvaluatorWithMEKAMetrics.java +/MultiTargetWindowRegressionPerformanceEvaluator2.java diff --git a/weka-package/pom.xml b/weka-package/pom.xml deleted file mode 100644 index 6cd73530c..000000000 --- a/weka-package/pom.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - 4.0.0 - - - nz.ac.waikato.cms.moa - moa-pom - 2012.09-SNAPSHOT - - - weka-package - jar - - MOA: WEKA Package - - Massive On-line Analysis is an environment for massive data mining. MOA provides a framework for data stream mining and includes tools for evaluation and a collection of machine learning algorithms. Related to the WEKA project, also written in Java, while scaling to more demanding problems. - This artifact enables you to use MOA from within WEKA. - - http://moa.cms.waikato.ac.nz/ - - University of Waikato, Hamilton, NZ - http://www.waikato.ac.nz/ - - - - GNU General Public License 3 - http://www.gnu.org/licenses/gpl-3.0.txt - repo - - - - - - abifet - Albert Bifet - abifet@waikato.ac.nz - - - fracpete - Peter Reutemann - fracpete@waikato.ac.nz - - - - - - nz.ac.waikato.cms.moa - moa - [${project.version},) - - - From 8e867c37acda33492d7f9853d0d9c0cebadad723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:37:42 +0100 Subject: [PATCH 07/33] Revert "Test commit of everything" This reverts commit 02d26831ad12964b8c91204bb81c22a5fdd5550b. --- .classpath | 13 -- .project | 6 - moa/.classpath | 17 ++- moa/.settings/org.eclipse.jdt.core.prefs | 3 - moa/pom.xml | 138 ++++++++++++++++++ .../classifiers/DecisionStumpTutorial.java | 13 +- .../classifiers/multilabel/trees/.gitignore | 1 - moa/src/main/java/moa/evaluation/.gitignore | 2 - weka-package/pom.xml | 53 +++++++ 9 files changed, 205 insertions(+), 41 deletions(-) delete mode 100644 .classpath create mode 100755 moa/pom.xml delete mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore delete mode 100644 moa/src/main/java/moa/evaluation/.gitignore create mode 100644 weka-package/pom.xml diff --git a/.classpath b/.classpath deleted file mode 100644 index dec9f005e..000000000 --- a/.classpath +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/.project b/.project index 56c2846a7..76bea900b 100644 --- a/.project +++ b/.project @@ -5,11 +5,6 @@ - - org.eclipse.jdt.core.javabuilder - - - org.eclipse.m2e.core.maven2Builder @@ -18,6 +13,5 @@ org.eclipse.m2e.core.maven2Nature - org.eclipse.jdt.core.javanature diff --git a/moa/.classpath b/moa/.classpath index f5accf223..534b5e52f 100644 --- a/moa/.classpath +++ b/moa/.classpath @@ -11,21 +11,26 @@ + + + + + + + + + + + - - - - - - diff --git a/moa/.settings/org.eclipse.jdt.core.prefs b/moa/.settings/org.eclipse.jdt.core.prefs index 69c31cd49..60105c1b9 100644 --- a/moa/.settings/org.eclipse.jdt.core.prefs +++ b/moa/.settings/org.eclipse.jdt.core.prefs @@ -1,8 +1,5 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.source=1.6 diff --git a/moa/pom.xml b/moa/pom.xml new file mode 100755 index 000000000..dd44c7979 --- /dev/null +++ b/moa/pom.xml @@ -0,0 +1,138 @@ + + 4.0.0 + + + nz.ac.waikato.cms.moa + moa-pom + 2015.05-SNAPSHOT + + + moa + jar + + MOA: Massive Online Analysis + + Massive On-line Analysis is an environment for massive data mining. MOA + provides a framework for data stream mining and includes tools for evaluation + and a collection of machine learning algorithms. Related to the WEKA project, + also written in Java, while scaling to more demanding problems. + + http://moa.cms.waikato.ac.nz/ + + University of Waikato, Hamilton, NZ + http://www.waikato.ac.nz/ + + + + GNU General Public License 3.0 + http://www.gnu.org/licenses/gpl-3.0.txt + repo + + + + + + abifet + Albert Bifet + abifet@waikato.ac.nz + + + rkirkby + Richard Kirkby + + + + + + nz.ac.waikato.cms.weka + weka-dev + + + + com.googlecode.sizeofag + sizeofag + + + + junit + junit + test + + + + com.googlecode.java-diff-utils + diffutils + 1.2.1 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + org.codehaus.mojo + license-maven-plugin + + + + org.codehaus.mojo + latex-maven-plugin + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + + license-maven-plugin + + [1.1,) + + add-third-party + + + + + + + + + + + + + + diff --git a/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java b/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java index 0cabab7dc..8d18b0a9d 100644 --- a/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java +++ b/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java @@ -1,18 +1,11 @@ package moa.classifiers; -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.GaussianNumericAttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.NominalAttributeClassObserver; -import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.options.ClassOption; - -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; - -import com.yahoo.labs.samoa.instances.Instance; +import moa.options.FlagOption; +import moa.options.IntOption; +import weka.core.Instance; public class DecisionStumpTutorial extends AbstractClassifier { diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore b/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore deleted file mode 100644 index 8e36d7391..000000000 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/BaselinePerceptron.java diff --git a/moa/src/main/java/moa/evaluation/.gitignore b/moa/src/main/java/moa/evaluation/.gitignore deleted file mode 100644 index 48df8b2bf..000000000 --- a/moa/src/main/java/moa/evaluation/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/MultilabelWindowClassificationPerformanceEvaluatorWithMEKAMetrics.java -/MultiTargetWindowRegressionPerformanceEvaluator2.java diff --git a/weka-package/pom.xml b/weka-package/pom.xml new file mode 100644 index 000000000..6cd73530c --- /dev/null +++ b/weka-package/pom.xml @@ -0,0 +1,53 @@ + + + + 4.0.0 + + + nz.ac.waikato.cms.moa + moa-pom + 2012.09-SNAPSHOT + + + weka-package + jar + + MOA: WEKA Package + + Massive On-line Analysis is an environment for massive data mining. MOA provides a framework for data stream mining and includes tools for evaluation and a collection of machine learning algorithms. Related to the WEKA project, also written in Java, while scaling to more demanding problems. + This artifact enables you to use MOA from within WEKA. + + http://moa.cms.waikato.ac.nz/ + + University of Waikato, Hamilton, NZ + http://www.waikato.ac.nz/ + + + + GNU General Public License 3 + http://www.gnu.org/licenses/gpl-3.0.txt + repo + + + + + + abifet + Albert Bifet + abifet@waikato.ac.nz + + + fracpete + Peter Reutemann + fracpete@waikato.ac.nz + + + + + + nz.ac.waikato.cms.moa + moa + [${project.version},) + + + From 4436a24bb8f615d42331b901d0800047d9f3d389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:37:46 +0100 Subject: [PATCH 08/33] Revert "Additional merging artefacts fixed" This reverts commit 5dec8c12eaac8f4785df76b61e4d40a591a13321. --- .../MultitargetAttributeClassObserver.java | 15 --------------- .../NumericAttributeBinaryTest.java | 4 ++++ 2 files changed, 4 insertions(+), 15 deletions(-) delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java diff --git a/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java b/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java deleted file mode 100644 index 0cfc7acb6..000000000 --- a/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java +++ /dev/null @@ -1,15 +0,0 @@ -package moa.classifiers.core.attributeclassobservers; - -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.core.DoubleVector; - -public interface MultitargetAttributeClassObserver extends AttributeClassObserver { - - public void observeAttributeClassVector(double attVal, DoubleVector classVector, double weight); - - public AttributeSplitSuggestion getBestEvaluatedSplitSuggestion( - SplitCriterion criterion, double examlpesSeen, DoubleVector preSplitSums, DoubleVector preSplitSquares, int attIndex, - int numTargets, boolean binaryOnly); - -} diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java index 87a3f2e0e..d60ee3af2 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java @@ -52,7 +52,11 @@ public int branchForInstance(Instance inst) { if (inst.isMissing(instAttIndex)) { return -1; } +<<<<<<< HEAD double v = inst.valueInputAttribute(instAttIndex); +======= + double v = inst.valueInputAttribute(instAttIndex); // if the attIndex is not calculated above this is the correct method call +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (v == this.attValue) { return this.equalsPassesTest ? 0 : 1; } From 296844e6d6970be9525b3fb6603b58ce33c8746a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:38:13 +0100 Subject: [PATCH 09/33] Revert "Removed merging artefacts" This reverts commit 4e3116ae22afc259caa4f4e7d967ae369aae367c. --- .../samoa/instances/MultiLabelPrediction.java | 5 +- .../LocalMultiTargetClassifier.java | 31 +- .../classifiers/multilabel/meta/MTOzaBag.java | 94 +- .../multilabel/trees/ISOUPTree.java | 144 ++- .../java/moa/classifiers/trees/FIMTDD.java | 986 +++++++++++++++++- .../main/java/moa/classifiers/trees/ORTO.java | 114 +- .../tasks/EvaluatePrequentialMultiTarget.java | 59 +- 7 files changed, 1370 insertions(+), 63 deletions(-) diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index bb9824e9d..838f90c7b 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -32,7 +32,10 @@ public MultiLabelPrediction(int numOutputAttributes) { public MultiLabelPrediction(DoubleVector[] prediction) { this.prediction = prediction; } - + + public MultiLabelPrediction(DoubleVector[] prediction) { + this.prediction = prediction; + } @Override public int numOutputAttributes() { diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 35223d3db..38c82f7e9 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -1,8 +1,12 @@ package moa.classifiers.multilabel; +<<<<<<< HEAD import java.util.ArrayList; +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa import java.util.LinkedList; import java.util.List; +import java.util.Vector; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; @@ -17,14 +21,16 @@ import moa.classifiers.Classifier; import moa.classifiers.MultiLabelClassifier; import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.classifiers.trees.FIMTDD; +import moa.core.DoubleVector; import moa.core.Measurement; +import moa.learners.Learner; import moa.options.ClassOption; public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner implements MultiLabelClassifier, MultiTargetRegressor { - private static final long serialVersionUID = 1L; - public ClassOption classifierOption = new ClassOption( "classifier", 'c', @@ -32,11 +38,17 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner Classifier.class, "moa.classifiers.trees.FIMTDD"); +<<<<<<< HEAD ArrayList classifiers = null; ArrayList headers = null; +======= + LinkedList classifiers = null; + LinkedList headers = null; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa @Override public boolean isRandomizable() { + // TODO Auto-generated method stub return true; } @@ -49,7 +61,11 @@ private InstancesHeader getHeader(int target) { private void makeHeaders() { if (headers == null) { +<<<<<<< HEAD headers = new ArrayList(); +======= + headers = new LinkedList(); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { List attributes = new LinkedList(); List indexValues = new LinkedList(); @@ -79,6 +95,7 @@ private Instance getSTInstance(MultiLabelInstance inst, int target) { @Override public void trainOnInstanceImpl(MultiLabelInstance instance) { + // TODO Auto-generated method stub initializeClassifiers(); for (int j = 0; j < instance.numberOutputTargets(); j++) { @@ -95,6 +112,10 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); for (int j = 0; j < inst.numberOutputTargets(); j++) { Instance STInst = getSTInstance(inst, j); +<<<<<<< HEAD +======= + +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa prediction.setVote(j, 1, classifiers.get(j).getVotesForInstance(STInst)[0]); } return prediction; @@ -110,9 +131,15 @@ public void initializeClassifiers() { this.classifierRandom.setSeed(1234); if (classifiers == null) { makeHeaders(); +<<<<<<< HEAD classifiers = new ArrayList(); for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { Classifier learner = ((Classifier) getPreparedClassOption(this.classifierOption)).copy(); +======= + classifiers = new LinkedList(); + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + Classifier learner = (Classifier) getPreparedClassOption(this.classifierOption); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa classifiers.add(learner); learner.resetLearning(); ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java index bdf2c7ffd..a4c64a809 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java @@ -41,43 +41,41 @@ */ public class MTOzaBag extends OzaBag implements MultiLabelLearner, MultiTargetRegressor { - private static final long serialVersionUID = 1L; - - public MTOzaBag() { - super(); - this.baseLearnerOption = new ClassOption("baseLearner", 'l', - "Classifier to train.", MultiLabelLearner.class, "multilabel.trees.ISOUPTree"); - } - - @Override - public void resetLearningImpl() { - this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; - MultiLabelLearner baseLearner = (MultiLabelLearner) getPreparedClassOption(this.baseLearnerOption); - baseLearner.resetLearning(); - for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i] = baseLearner.copy(); - } - } - - @Override - public void setModelContext(InstancesHeader raw_header) { - - //set the multilabel model context - this.modelContext = raw_header; - - // reset ensemble - this.resetLearningImpl(); - - for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i].setModelContext(raw_header); - this.ensemble[i].resetLearning(); - } - } - - @Override // @note don't need this here - public boolean isRandomizable() { - return true; - } + public MTOzaBag() { + super(); + this.baseLearnerOption = new ClassOption("baseLearner", 'l', + "Classifier to train.", MultiLabelLearner.class, "multilabel.trees.ISOUPTree"); + } + + @Override + public void resetLearningImpl() { + this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; + MultiLabelLearner baseLearner = (MultiLabelLearner) getPreparedClassOption(this.baseLearnerOption); + baseLearner.resetLearning(); + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i] = baseLearner.copy(); + } + } + + @Override + public void setModelContext(InstancesHeader raw_header) { + + //set the multilabel model context + this.modelContext = raw_header; + + // reset ensemble + this.resetLearningImpl(); + + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i].setModelContext(raw_header); + this.ensemble[i].resetLearning(); + } + } + + @Override // @note don't need this here + public boolean isRandomizable() { + return true; + } public Prediction getPredictionForInstance(MultiLabelInstance inst) { DoubleVector[][] predictions = new DoubleVector[this.ensemble.length][getModelContext().numOutputAttributes()]; @@ -95,8 +93,8 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { } return new MultiLabelPrediction(prediction); } - - +<<<<<<< HEAD + public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) { int actual = Math.max(1, Math.min(n, this.ensemble.length)); DoubleVector[][] predictions = new DoubleVector[actual][getModelContext().numOutputAttributes()]; @@ -114,15 +112,17 @@ public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) } return new MultiLabelPrediction(prediction); } - - @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { - trainOnInstanceImpl((Instance) instance); - } - - @Override +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + + @Override + public void trainOnInstanceImpl(MultiLabelInstance instance) { + trainOnInstanceImpl((Instance) instance); + } + + @Override public Prediction getPredictionForInstance(Example example) { return getPredictionForInstance((MultiLabelInstance)example.getData()); } - + } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index 1873b87cf..592a0c5c6 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -66,7 +66,14 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR private static final long serialVersionUID = 1L; +<<<<<<< HEAD public Node treeRoot; +======= + protected Node treeRoot; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + + private int leafNodeCount = 0; + private int splitNodeCount = 0; private double examplesSeen = 0.0; private DoubleVector sumOfValues = new DoubleVector(); @@ -79,6 +86,7 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR //region ================ OPTIONS ================ +<<<<<<< HEAD // public ClassOption splitCriterionOption = new ClassOption( // "splitCriterion", // 's', @@ -87,6 +95,8 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR // "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); // TODO not used at the moment, consider later when the implementation catches up +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa public IntOption gracePeriodOption = new IntOption( "gracePeriod", 'g', @@ -105,6 +115,7 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR "Threshold below which a split will be forced to break ties.", 0.05, 0.0, 1.0); +<<<<<<< HEAD public FloatOption PageHinckleyAlphaOption = new FloatOption( "PageHinckleyAlpha", 'a', @@ -116,6 +127,19 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR 'h', "The threshold value to be used in the Page Hinckley change detection tests.", 50, 0, Integer.MAX_VALUE); +======= +// public FloatOption PageHinckleyAlphaOption = new FloatOption( +// "PageHinckleyAlpha", +// 'a', +// "The alpha value to use in the Page Hinckley change detection tests.", +// 0.005, 0.0, 1.0); +// +// public IntOption PageHinckleyThresholdOption = new IntOption( +// "PageHinckleyThreshold", +// 'h', +// "The threshold value to be used in the Page Hinckley change detection tests.", +// 50, 0, Integer.MAX_VALUE); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa public FloatOption alternateTreeFadingFactorOption = new FloatOption( "alternateTreeFadingFactor", @@ -161,6 +185,15 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR "doNotNormalize", 'n', "Don't normalize."); +<<<<<<< HEAD + + public FlagOption printLogsOption = new FlagOption( + "printLogs", + 'z', + "Print logs."); +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + //endregion ================ OPTIONS ================ @@ -309,11 +342,17 @@ public LeafNode(ISOUPTree tree) { */ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, boolean growthAllowed) { // Update the statistics for this node - +<<<<<<< HEAD + // number of instances passing through the node + double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; + double[] predictionM = getPredictionTargetMean(inst); + +======= double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; double[] predictionM = getPredictionTargetMean(inst); // number of instances passing through the node +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa examplesSeen += inst.weight(); for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { @@ -328,7 +367,10 @@ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, bool errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - inst.valueOutputAttribute(i))); } } - +<<<<<<< HEAD + +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); for (int i = 0; i < inst.numInputAttributes(); i++) { @@ -401,11 +443,17 @@ public double[] getPredictionModel(MultiLabelInstance inst) { public double[] getPredictionTargetMean(MultiLabelInstance inst) { double[] pred = new double[inst.numOutputAttributes()]; +<<<<<<< HEAD for (int i = 0; i < inst.numOutputAttributes(); i++) { if (examplesSeen > 0) { pred[i] = sumOfValues.getValue(i) / examplesSeen; } else { pred[i] = 0; +======= + if (examplesSeen > 0) { + for (int i = 0; i < inst.numOutputAttributes(); i++) { + pred[i] = sumOfValues.getValue(i) / examplesSeen; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } return pred; @@ -606,8 +654,11 @@ public class MultitargetPerceptron { protected ISOUPTree tree; // The Perception weights +<<<<<<< HEAD public double[][] weights; - +======= + protected double[][] weights; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // The number of instances contributing to this model protected int instancesSeen = 0; @@ -619,6 +670,13 @@ public String getPurposeString() { public MultitargetPerceptron(ISOUPTree tree, MultitargetPerceptron original) { this.tree = tree; weights = original.weights.clone(); +<<<<<<< HEAD + // TODO check if this is necessary +// for (int i = 0; i < this.tree.getModelContext().numOutputAttributes(); i++) { +// weights[i] = (DoubleVector) original.weights[i].copy(); +// } +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } public MultitargetPerceptron(ISOUPTree tree) { @@ -638,7 +696,10 @@ public void initializeWeights() { weights[i][j] = 2 * tree.classifierRandom.nextDouble() - 1; } } +<<<<<<< HEAD normalizeWeights(); +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } /** @@ -689,6 +750,10 @@ public void normalizeWeights() { } } +<<<<<<< HEAD + +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa /** * Output the prediction made by this perceptron on the given instance */ @@ -727,6 +792,7 @@ private double[] denormalizePrediction(double[] normalizedPrediction) { public void getModelDescription(StringBuilder out, int indent) { for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "]"); +<<<<<<< HEAD //if (getModelContext() != null) { //for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { // if (getModelContext().attribute(j).isNumeric()) { @@ -1074,6 +1140,24 @@ public void getModelDescription(StringBuilder out, int indent) { // // } +======= + if (getModelContext() != null) { + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + if (getModelContext().attribute(j).isNumeric()) { + out.append((j == 0 || weights[i][j] < 0) ? " " : " + "); + out.append(String.format("%.4f", weights[i][j])); + out.append(" * "); + out.append(getAttributeNameString(j)); + } + } + out.append(" + " + weights[i][getModelContext().numOutputAttributes()]); + } + StringUtils.appendNewline(out); + } + } + } + +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa //endregion ================ CLASSES ================ //region ================ METHODS ================ @@ -1082,17 +1166,27 @@ public void getModelDescription(StringBuilder out, int indent) { public ISOUPTree() {} public String getPurposeString() { +<<<<<<< HEAD + return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; +======= return "Implementation of the iSOUP-Tree algorithm as described by Osojnik et al."; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } public void resetLearningImpl() { treeRoot = null; + leafNodeCount = 0; + splitNodeCount = 0; +<<<<<<< HEAD examplesSeen = 0.0; sumOfValues = new DoubleVector(); sumOfSquares = new DoubleVector(); sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); +======= + maxID = 0; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } public boolean isRandomizable() { @@ -1186,7 +1280,11 @@ public double[] normalizeTargetVector(double[] pred) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0 && examplesSeen > 1) +<<<<<<< HEAD out[i] = (value - average) / sd; +======= + out[i] = (value - average) / (3 * sd); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa else out[i] = 0; } @@ -1202,7 +1300,11 @@ public double normalizeTargetValue(MultiLabelInstance inst, int i) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0) +<<<<<<< HEAD return (value - average) / sd; +======= + return (value - average) / (3 * sd); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa else return 0; } @@ -1216,7 +1318,11 @@ public double normalizeTargetValue(double value, int i) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0) +<<<<<<< HEAD return (value - average) / sd; +======= + return (value - average) / (3 * sd); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa else return 0; } @@ -1244,9 +1350,15 @@ public void trainOnInstanceImpl(MultiLabelInstance inst) { double[] prediction = treeRoot.getPrediction(inst); double[] normalError = getNormalizedError(inst, prediction); +<<<<<<< HEAD processInstance(inst, treeRoot, prediction, normalError, true, false); +======= + //normalError.scaleValues(inst.weight()); + processInstance(inst, treeRoot, prediction, normalError, true, false); + +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa examplesSeen += inst.weight(); for (int i = 0; i < inst.numberOutputTargets(); i++) { sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); @@ -1257,6 +1369,12 @@ public void trainOnInstanceImpl(MultiLabelInstance inst) { sumOfAttrValues.addToValue(i, inst.weight() * inst.valueInputAttribute(i)); sumOfAttrSquares.addToValue(i, inst.weight() * inst.valueInputAttribute(i) * inst.valueInputAttribute(i)); } +<<<<<<< HEAD + + //normalError.scaleValues(inst.weight()); + +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } @@ -1357,7 +1475,11 @@ protected LeafNode newLeafNode() { return new LeafNode(this); } +<<<<<<< HEAD public MultitargetPerceptron newLeafModel() { +======= + protected MultitargetPerceptron newLeafModel() { +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa return new MultitargetPerceptron(this); } @@ -1367,6 +1489,7 @@ public MultitargetPerceptron newLeafModel() { protected void checkRoot() { if (treeRoot == null) { treeRoot = newLeafNode(); + leafNodeCount = 1; } } @@ -1433,17 +1556,29 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) } } } +<<<<<<< HEAD + + if (hoeffdingBound < this.tieThresholdOption.getValue() && this.printLogsOption.isSet()) System.out.println("Forced to split due to tie at " + this.examplesSeen); +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } // If the splitting criterion were met, split the current node using the chosen attribute test, and // make two new branches leading to (empty) leaves if (shouldSplit) { +<<<<<<< HEAD + if (node.parent == null && this.printLogsOption.isSet()) { + System.out.println("splitting root node at " + this.examplesSeen); + } +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; SplitNode newSplit = newSplitNode(splitDecision.predicate); newSplit.copyStatistics(node); newSplit.changeDetection = node.changeDetection; newSplit.ID = node.ID; + leafNodeCount--; //System.out.println("Splitting"); //System.out.println(examplesSeen); for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) @@ -1456,6 +1591,7 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) newChild.changeDetection = node.changeDetection; newChild.setParent(newSplit); newSplit.setChild(i, newChild); + leafNodeCount++; } if (parent == null && node.originalNode == null) { treeRoot = newSplit; @@ -1465,6 +1601,8 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) parent.setChild(parentIndex, newSplit); newSplit.setParent(parent); } + + splitNodeCount++; } } diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java index fc8b2aaea..6cb747894 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java @@ -1,3 +1,4 @@ +<<<<<<< HEAD /* * FIMTDD.java * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia @@ -828,7 +829,7 @@ public void processInstance(Instance inst, Node node, double prediction, double } } - if (iNode.changeDetection && !inAlternate) { + if (false && iNode.changeDetection && !inAlternate) { if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { iNode.initializeAlternateTree(); growthAllowed = false; @@ -925,11 +926,20 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { } } } +// if (hoeffdingBound < this.tieThresholdOption.getValue() && !(secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound)) { +// System.out.println("Forced to split due to tie at " + this.examplesSeen); +// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); +// } } // If the splitting criterion were met, split the current node using the chosen attribute test, and // make two new branches leading to (empty) leaves if (shouldSplit) { +// System.out.println("splitting node"); +// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); +// if (node.parent == null) { +// System.out.println("splitting root node at " + this.examplesSeen); +// } AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; SplitNode newSplit = newSplitNode(splitDecision.splitTest); @@ -979,4 +989,976 @@ public double scalarProduct(DoubleVector u, DoubleVector v) { //endregion --- Processing methods //endregion ================ METHODS ================ -} \ No newline at end of file +} + +======= +/* + * FIMTDD.java + * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia + * @author Aljaž Osojnik + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package moa.classifiers.trees; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import com.yahoo.labs.samoa.instances.Instance; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; + +import moa.options.ClassOption; +import moa.AbstractMOAObject; +import moa.classifiers.Regressor; +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; +import moa.classifiers.core.conditionaltests.InstanceConditionalTest; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.classifiers.AbstractClassifier; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.Measurement; +import moa.core.SizeOf; +import moa.core.StringUtils; + +/* + * Implementation of FIMTDD, regression and model trees for data streams. + */ + +public class FIMTDD extends AbstractClassifier implements Regressor { + + private static final long serialVersionUID = 1L; + + protected Node treeRoot; + + protected int leafNodeCount = 0; + protected int splitNodeCount = 0; + + protected double examplesSeen = 0.0; + protected double sumOfValues = 0.0; + protected double sumOfSquares = 0.0; + + protected DoubleVector sumOfAttrValues = new DoubleVector(); + protected DoubleVector sumOfAttrSquares = new DoubleVector(); + + public int maxID = 0; + + //region ================ OPTIONS ================ + + public ClassOption splitCriterionOption = new ClassOption( + "splitCriterion", 's', "Split criterion to use.", + SplitCriterion.class, "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); + + public IntOption gracePeriodOption = new IntOption( + "gracePeriod", 'g', "Number of instances a leaf should observe between split attempts.", + 200, 0, Integer.MAX_VALUE); + + public FloatOption splitConfidenceOption = new FloatOption( + "splitConfidence", 'c', "Allowed error in split decision, values close to 0 will take long to decide.", + 0.0000001, 0.0, 1.0); + + public FloatOption tieThresholdOption = new FloatOption( + "tieThreshold", 't', "Threshold below which a split will be forced to break ties.", + 0.05, 0.0, 1.0); + + public FloatOption PageHinckleyAlphaOption = new FloatOption( + "PageHinckleyAlpha", 'a', "Alpha value to use in the Page Hinckley change detection tests.", + 0.005, 0.0, 1.0); + + public IntOption PageHinckleyThresholdOption = new IntOption( + "PageHinckleyThreshold", 'h', "Threshold value used in the Page Hinckley change detection tests.", + 50, 0, Integer.MAX_VALUE); + + public FloatOption alternateTreeFadingFactorOption = new FloatOption( + "alternateTreeFadingFactor", 'f', "Fading factor used to decide if an alternate tree should replace an original.", + 0.995, 0.0, 1.0); + + public IntOption alternateTreeTMinOption = new IntOption( + "alternateTreeTMin", 'y', "Tmin value used to decide if an alternate tree should replace an original.", + 150, 0, Integer.MAX_VALUE); + + public IntOption alternateTreeTimeOption = new IntOption( + "alternateTreeTime", 'u', "The number of instances used to decide if an alternate tree should be discarded.", + 1500, 0, Integer.MAX_VALUE); + + public FlagOption regressionTreeOption = new FlagOption( + "regressionTree", 'e', "Build a regression tree instead of a model tree."); + + public FloatOption learningRatioOption = new FloatOption( + "learningRatio", 'l', "Learning ratio to used for training the Perceptrons in the leaves.", + 0.02, 0, 1.00); + + public FloatOption learningRateDecayFactorOption = new FloatOption( + "learningRatioDecayFactor", 'd', "Learning rate decay factor (not used when learning rate is constant).", + 0.001, 0, 1.00); + + public FlagOption learningRatioConstOption = new FlagOption( + "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public abstract static class Node extends AbstractMOAObject { + + private static final long serialVersionUID = 1L; + + public int ID; + + protected FIMTDD tree; + + protected boolean changeDetection = true; + + protected Node parent; + + protected Node alternateTree; + protected Node originalNode; + + // The statistics for this node: + // Number of instances that have reached it + protected double examplesSeen; + // Sum of y values + protected double sumOfValues; + // Sum of squared y values + protected double sumOfSquares; + // Sum of absolute errors + protected double sumOfAbsErrors; // Needed for PH tracking of mean error + + public Node(FIMTDD tree) { + this.tree = tree; + ID = tree.maxID; + } + + public void copyStatistics(Node node) { + examplesSeen = node.examplesSeen; + sumOfValues = node.sumOfValues; + sumOfSquares = node.sumOfSquares; + sumOfAbsErrors = node.sumOfAbsErrors; + } + + public int calcByteSize() { + return (int) SizeOf.fullSizeOf(this); + } + + /** + * Set the parent node + */ + public void setParent(Node parent) { + this.parent = parent; + } + + /** + * Return the parent node + */ + public Node getParent() { + return parent; + } + + public void disableChangeDetection() { + changeDetection = false; + } + + public void restartChangeDetection() { + changeDetection = true; + } + + public void getDescription(StringBuilder sb, int indent) { + + } + + public double getPrediction(Instance inst) { + return 0; + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf"); + } + + public int getLevel() { + Node target = this; + int level = 0; + while (target.getParent() != null) { + if (target.skipInLevelCount()) { + target = target.getParent(); + continue; + } + level = level + 1; + target = target.getParent(); + } + if (target.originalNode == null) { + return level; + } else { + return level + originalNode.getLevel(); + } + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + } + + public static class LeafNode extends Node { + + private static final long serialVersionUID = 1L; + + // Perceptron model that carries out the actual learning in each node + public FIMTDDPerceptron learningModel; + + protected AutoExpandVector attributeObservers = new AutoExpandVector(); + + protected double examplesSeenAtLastSplitEvaluation = 0; + + /** + * Create a new LeafNode + */ + public LeafNode(FIMTDD tree) { + super(tree); + if (tree.buildingModelTree()) { + learningModel = tree.newLeafModel(); + } + examplesSeen = 0; + sumOfValues = 0; + sumOfSquares = 0; + sumOfAbsErrors = 0; + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + + /** + * Method to learn from an instance that passes the new instance to the perceptron learner, + * and also prevents the class value from being truncated to an int when it is passed to the + * attribute observer + */ + public void learnFromInstance(Instance inst, boolean growthAllowed) { + //The prediction must be calculated here -- it may be different from the tree's prediction due to alternate trees + + // Update the statistics for this node + // number of instances passing through the node + examplesSeen += inst.weight(); + + // sum of y values + sumOfValues += inst.weight() * inst.classValue(); + + // sum of squared y values + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + // sum of absolute errors + sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - getPrediction(inst)))); + + if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); + FIMTDDNumericAttributeClassObserver obs = attributeObservers.get(i); + if (obs == null) { + // At this stage all nominal attributes are ignored + if (inst.attribute(instAttIndex).isNumeric()) { + obs = tree.newNumericClassObserver(); + this.attributeObservers.set(i, obs); + } + } + if (obs != null) { + obs.observeAttributeClass(inst.value(instAttIndex), inst.classValue(), inst.weight()); + } + } + + if (growthAllowed) { + checkForSplit(tree); + } + } + + /** + * Return the best split suggestions for this node using the given split criteria + */ + public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion) { + + List bestSuggestions = new LinkedList(); + + // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution + double[] nodeSplitDist = new double[] {examplesSeen, sumOfValues, sumOfSquares}; + + for (int i = 0; i < this.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = this.attributeObservers.get(i); + if (obs != null) { + + // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED + AttributeSplitSuggestion bestSuggestion = null; + if (obs instanceof FIMTDDNumericAttributeClassObserver) { + bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, nodeSplitDist, i, true); + } + + if (bestSuggestion != null) { + bestSuggestions.add(bestSuggestion); + } + } + } + return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); + } + + /** + * Retrieve the class votes using the perceptron learner + */ + public double getPredictionModel(Instance inst) { + return learningModel.prediction(inst); + } + + public double getPredictionTargetMean(Instance inst) { + return (examplesSeen > 0.0) ? sumOfValues / examplesSeen : 0.0; + } + + public double getPrediction(Instance inst) { + return (tree.buildingModelTree()) ? getPredictionModel(inst) : getPredictionTargetMean(inst); + } + + public void checkForSplit(FIMTDD tree) { + // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node + if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { + int index = (parent != null) ? parent.getChildIndex(this) : 0; + tree.attemptToSplit(this, parent, index); + + // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation + examplesSeenAtLastSplitEvaluation = examplesSeen; + } + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf "); + if (tree.buildingModelTree()) { + learningModel.getModelDescription(out, 0); + } else { + out.append(tree.getClassNameString() + " = " + String.format("%.4f", (sumOfValues / examplesSeen))); + StringUtils.appendNewline(out); + } + } + } + + public abstract static class InnerNode extends Node { + // The InnerNode and SplitNode design is used for easy extension in ORTO + private static final long serialVersionUID = 1L; + + protected AutoExpandVector children = new AutoExpandVector(); + + // The error values for the Page Hinckley test + // PHmT = the cumulative sum of the errors + // PHMT = the minimum error value seen so far + protected double PHsum = 0; + protected double PHmin = Double.MAX_VALUE; + + // Keep track of the statistics for loss error calculations + protected double lossExamplesSeen; + protected double lossFadedSumOriginal; + protected double lossFadedSumAlternate; + protected double lossNumQiTests; + protected double lossSumQi; + protected double previousWeight = 0; + + public InnerNode(FIMTDD tree) { + super(tree); + } + + public int numChildren() { + return children.size(); + } + + public Node getChild(int index) { + return children.get(index); + } + + public int getChildIndex(Node child) { + return children.indexOf(child); + } + + public void setChild(int index, Node child) { + children.set(index, child); + } + + public void disableChangeDetection() { + changeDetection = false; + for (Node child : children) { + child.disableChangeDetection(); + } + } + + public void restartChangeDetection() { + if (alternateTree == null) { + changeDetection = true; + PHsum = 0; + PHmin = Integer.MAX_VALUE; + for (Node child : children) + child.restartChangeDetection(); + } + } + + /** + * Check to see if the tree needs updating + */ + public boolean PageHinckleyTest(double error, double threshold) { + // Update the cumulative mT sum + PHsum += error; + + // Update the minimum mT value if the new mT is + // smaller than the current minimum + if(PHsum < PHmin) { + PHmin = PHsum; + } + // Return true if the cumulative value - the current minimum is + // greater than the current threshold (in which case we should adapt) + return PHsum - PHmin > threshold; + } + + public void initializeAlternateTree() { + // Start a new alternate tree, beginning with a learning node + alternateTree = tree.newLeafNode(); + alternateTree.originalNode = this; + + // Set up the blank statistics + // Number of instances reaching this node since the alternate tree was started + lossExamplesSeen = 0; + // Faded squared error (original tree) + lossFadedSumOriginal = 0; + // Faded squared error (alternate tree) + lossFadedSumAlternate = 0; + // Number of evaluations of alternate tree + lossNumQiTests = 0; + // Sum of Qi values + lossSumQi = 0; + // Number of examples at last test + previousWeight = 0; + + // Disable the change detection mechanism bellow this node + disableChangeDetection(); + } + } + + public static class SplitNode extends InnerNode { + + private static final long serialVersionUID = 1L; + + protected InstanceConditionalTest splitTest; + + /** + * Create a new SplitNode + * @param tree + */ + public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { + super(tree); + this.splitTest = splitTest; + } + + public int instanceChildIndex(Instance inst) { + return splitTest.branchForInstance(inst); + } + + public Node descendOneStep(Instance inst) { + return children.get(splitTest.branchForInstance(inst)); + } + + public void describeSubtree(StringBuilder out, int indent) { + for (int branch = 0; branch < children.size(); branch++) { + Node child = getChild(branch); + if (child != null) { + StringUtils.appendIndented(out, indent, "if "); + out.append(this.splitTest.describeConditionForBranch(branch, + tree.getModelContext())); + out.append(": "); + StringUtils.appendNewline(out); + child.describeSubtree(out, indent + 2); + } + } + } + + public double getPrediction(Instance inst) { + return children.get(splitTest.branchForInstance(inst)).getPrediction(inst); + } + } + + public class FIMTDDPerceptron implements Serializable { + + private static final long serialVersionUID = 1L; + + protected FIMTDD tree; + + // The Perception weights + protected DoubleVector weightAttribute = new DoubleVector(); + + protected double sumOfValues; + protected double sumOfSquares; + + // The number of instances contributing to this model + protected double instancesSeen = 0; + + // If the model should be reset or not + protected boolean reset; + + public String getPurposeString() { + return "A perceptron regressor as specified by Ikonomovska et al. used for FIMTDD"; + } + + public FIMTDDPerceptron(FIMTDDPerceptron original) { + this.tree = original.tree; + weightAttribute = (DoubleVector) original.weightAttribute.copy(); + reset = false; + } + + public FIMTDDPerceptron(FIMTDD tree) { + this.tree = tree; + reset = true; + } + + + public DoubleVector getWeights() { + return weightAttribute; + } + + /** + * Update the model using the provided instance + */ + public void updatePerceptron(Instance inst) { + + // Initialize perceptron if necessary + if (reset == true) { + reset = false; + weightAttribute = new DoubleVector(); + instancesSeen = 0; + for (int j = 0; j < inst.numAttributes(); j++) { // The last index corresponds to the constant b + weightAttribute.setValue(j, 2 * tree.classifierRandom.nextDouble() - 1); + } + } + + // Update attribute statistics + instancesSeen += inst.weight(); + + // Update weights + double learningRatio = 0.0; + if (tree.learningRatioConstOption.isSet()) { + learningRatio = learningRatioOption.getValue(); + } else { + learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); + } + + sumOfValues += inst.weight() * inst.classValue(); + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + // Loop for compatibility with bagging methods + for (int i = 0; i < (int) inst.weight(); i++) { + updateWeights(inst, learningRatio); + } + } + + public void updateWeights(Instance inst, double learningRatio) { + // Compute the normalized instance and the delta + DoubleVector normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + double normalizedValue = tree.normalizeTargetValue(inst.classValue()); + double delta = normalizedValue - normalizedPrediction; + normalizedInstance.scaleValues(delta * learningRatio); + + weightAttribute.addValues(normalizedInstance); + } + + public DoubleVector normalizedInstance(Instance inst) { + // Normalize Instance + DoubleVector normalizedInstance = new DoubleVector(); + for (int j = 0; j < inst.numAttributes() - 1; j++) { + int instAttIndex = modelAttIndexToInstanceAttIndex(j, inst); + double mean = tree.sumOfAttrValues.getValue(j) / tree.examplesSeen; + double sd = computeSD(tree.sumOfAttrSquares.getValue(j), tree.sumOfAttrValues.getValue(j), tree.examplesSeen); + if (inst.attribute(instAttIndex).isNumeric() && tree.examplesSeen > 1 && sd > 0) + normalizedInstance.setValue(j, (inst.value(instAttIndex) - mean) / (3 * sd)); + else + normalizedInstance.setValue(j, 0); + } + if (tree.examplesSeen > 1) + normalizedInstance.setValue(inst.numAttributes() - 1, 1.0); // Value to be multiplied with the constant factor + else + normalizedInstance.setValue(inst.numAttributes() - 1, 0.0); + return normalizedInstance; + } + + /** + * Output the prediction made by this perceptron on the given instance + */ + public double prediction(DoubleVector instanceValues) { + return scalarProduct(weightAttribute, instanceValues); + } + + protected double prediction(Instance inst) { + DoubleVector normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + return denormalizePrediction(normalizedPrediction, tree); + } + + private double denormalizePrediction(double normalizedPrediction, FIMTDD tree) { + double mean = tree.sumOfValues / tree.examplesSeen; + double sd = computeSD(tree.sumOfSquares, tree.sumOfValues, tree.examplesSeen); + if (examplesSeen > 1) + return normalizedPrediction * sd * 3 + mean; + else + return 0.0; + } + + public void getModelDescription(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, getClassNameString() + " ="); + if (getModelContext() != null) { + for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { + if (getModelContext().attribute(j).isNumeric()) { + out.append((j == 0 || weightAttribute.getValue(j) < 0) ? " " : " + "); + out.append(String.format("%.4f", weightAttribute.getValue(j))); + out.append(" * "); + out.append(getAttributeNameString(j)); + } + } + out.append(" + " + weightAttribute.getValue((getModelContext().numAttributes() - 1))); + } + StringUtils.appendNewline(out); + } + } + + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + // region --- Regressor methods + + public String getPurposeString() { + return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + this.treeRoot = null; + this.leafNodeCount = 0; + this.splitNodeCount = 0; + this.maxID = 0; + this.examplesSeen = 0; + this.sumOfValues = 0.0; + this.sumOfSquares = 0.0; + + this.sumOfAttrValues = new DoubleVector(); + this.sumOfAttrSquares = new DoubleVector(); + } + + public boolean isRandomizable() { + return true; + } + + public void getModelDescription(StringBuilder out, int indent) { + if (treeRoot != null) treeRoot.describeSubtree(out, indent); + } + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("tree size (leaves)", this.leafNodeCount) + }; + } + + public int calcByteSize() { + return (int) SizeOf.fullSizeOf(this); + } + + public double[] getVotesForInstance(Instance inst) { + if (treeRoot == null) { + return new double[] {0}; + } + + double prediction = treeRoot.getPrediction(inst); + + return new double[] {prediction}; + } + + public double normalizeTargetValue(double value) { + if (examplesSeen > 1) { + double sd = Math.sqrt((sumOfSquares - ((sumOfValues * sumOfValues)/examplesSeen))/examplesSeen); + double average = sumOfValues / examplesSeen; + if (sd > 0 && examplesSeen > 1) + return (value - average) / (3 * sd); + else + return 0.0; + } + return 0.0; + } + + public double getNormalizedError(Instance inst, double prediction) { + double normalPrediction = normalizeTargetValue(prediction); + double normalValue = normalizeTargetValue(inst.classValue()); + return Math.abs(normalValue - normalPrediction); + } + + + /** + * Method for updating (training) the model using a new instance + */ + public void trainOnInstanceImpl(Instance inst) { + checkRoot(); + + examplesSeen += inst.weight(); + sumOfValues += inst.weight() * inst.classValue(); + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int aIndex = modelAttIndexToInstanceAttIndex(i, inst); + sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); + } + + double prediction = treeRoot.getPrediction(inst); + processInstance(inst, treeRoot, prediction, getNormalizedError(inst, prediction), true, false); + } + + public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); + break; + } else { + currentNode.examplesSeen += inst.weight(); + currentNode.sumOfAbsErrors += inst.weight() * normalError; + SplitNode iNode = (SplitNode) currentNode; + if (!inAlternate && iNode.alternateTree != null) { + boolean altTree = true; + double lossO = Math.pow(inst.classValue() - prediction, 2); + double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); + + // Loop for compatibility with bagging methods + for (int i = 0; i < inst.weight(); i++) { + iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + iNode.lossExamplesSeen++; + + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + iNode.lossSumQi += Qi; + iNode.lossNumQiTests += 1; + } + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + + if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + iNode.previousWeight = iNode.lossExamplesSeen; + if (Qi > 0) { + // Switch the subtrees + Node parent = currentNode.getParent(); + + if (parent != null) { + Node replacementTree = iNode.alternateTree; + parent.setChild(parent.getChildIndex(currentNode), replacementTree); + if (growthAllowed) replacementTree.restartChangeDetection(); + } else { + treeRoot = iNode.alternateTree; + treeRoot.restartChangeDetection(); + } + + currentNode = iNode.alternateTree; + currentNode.originalNode = null; + altTree = false; + } else if ( + (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) + || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() + ) { + // Remove the alternate tree + iNode.alternateTree = null; + if (growthAllowed) iNode.restartChangeDetection(); + altTree = false; + } + } + + if (altTree) { + growthAllowed = false; + processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + } + } + + if (iNode.changeDetection && !inAlternate) { + if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + iNode.initializeAlternateTree(); + } + } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).descendOneStep(inst); + } + } + } + } + + // endregion --- Regressor methods + + // region --- Object instatiation methods + + protected FIMTDDNumericAttributeClassObserver newNumericClassObserver() { + return new FIMTDDNumericAttributeClassObserver(); + } + + protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + maxID++; + return new SplitNode(splitTest, this); + } + + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } + + protected FIMTDDPerceptron newLeafModel() { + return new FIMTDDPerceptron(this); + } + + //endregion --- Object instatiation methods + + // region --- Processing methods + + protected void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + leafNodeCount = 1; + } + } + + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } + + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } + + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); + + // Using this criterion, find the best split per attribute and rank the results + AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine if any of the splits should be performed + boolean shouldSplit = false; + + // If only one split was returned, use it + if (bestSplitSuggestions.length < 2) { + shouldSplit = bestSplitSuggestions.length > 0; + } else { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, this.splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { + shouldSplit = true; + } + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + else { + for (int i = 0; i < node.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = node.attributeObservers.get(i); + if (obs != null) { + obs.removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); + } + } + } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (shouldSplit) { + AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + + SplitNode newSplit = newSplitNode(splitDecision.splitTest); + newSplit.copyStatistics(node); + newSplit.changeDetection = node.changeDetection; + newSplit.ID = node.ID; + leafNodeCount--; + for (int i = 0; i < splitDecision.numSplits(); i++) { + LeafNode newChild = newLeafNode(); + if (buildingModelTree()) { + // Copy the splitting node's perceptron to it's children + newChild.learningModel = new FIMTDDPerceptron((FIMTDDPerceptron) node.learningModel); + + } + newChild.changeDetection = node.changeDetection; + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + leafNodeCount++; + } + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + ((SplitNode) parent).setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + + splitNodeCount++; + } + } + + public double computeSD(double squaredVal, double val, double size) { + if (size > 1) + return Math.sqrt((squaredVal - ((val * val) / size)) / size); + else + return 0.0; + } + + public double scalarProduct(DoubleVector u, DoubleVector v) { + double ret = 0.0; + for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { + ret += u.getValue(i) * v.getValue(i); + } + return ret; + } + //endregion --- Processing methods + + //endregion ================ METHODS ================ +} + +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index 7ab9734db..2745dcc7e 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -35,11 +35,16 @@ import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.splitcriteria.SplitCriterion; - +<<<<<<< HEAD +import moa.classifiers.trees.FIMTDD.InnerNode; +import moa.classifiers.trees.FIMTDD.Node; import moa.core.AutoExpandVector; import moa.core.Measurement; import moa.core.StringUtils; - +======= +import moa.core.AutoExpandVector; +import moa.core.Measurement; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa /* * Implementation of ORTO, option trees for data streams. @@ -122,9 +127,15 @@ public int getNumSubtrees() { public int directionForBestTree() { int d = 0; +<<<<<<< HEAD + double min = Double.MAX_VALUE; + for (int i = 0; i < numChildren(); i++) { + double tmp = getFFRatio(i); +======= double tmp = 0.0, min = Double.MAX_VALUE; for (int i = 0; i < children.size(); i++) { tmp = getFFRatio(i); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (tmp < min) { min = tmp; d = i; @@ -133,22 +144,38 @@ public int directionForBestTree() { return d; } +<<<<<<< HEAD public double getPrediction(Instance inst) { +======= + public double getPrediction(Instance inst, ORTO tree) { +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa double[] predictions = new double[numChildren()]; for (int i = 0; i < numChildren(); i++) { predictions[i] = getChild(i).getPrediction(inst); } +<<<<<<< HEAD return aggregate(predictions); } private double aggregate(double[] predictions) { if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average +======= + return aggregate(predictions, tree); + } + + private double aggregate(double[] predictions, ORTO tree) { + if (tree.optionNodeAggregationOption.getChosenIndex() == 0) { // Average +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa double sum = 0.0; for (int i = 0; i < predictions.length; i++) { sum += predictions[i]; } return sum / predictions.length; +<<<<<<< HEAD } else if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 1) { +======= + } else if (tree.optionNodeAggregationOption.getChosenIndex() == 1) { +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa int d = directionForBestTree(); return predictions[d]; } else { @@ -163,6 +190,7 @@ public double getFFRatio(int childIndex) { protected boolean skipInLevelCount() { return true; } +<<<<<<< HEAD @Override public void describeSubtree(StringBuilder out, int indent) { @@ -175,7 +203,8 @@ public void describeSubtree(StringBuilder out, int indent) { split.describeSubtree(out, indent + 2); } } - +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } //endregion ================ CLASSES ================ @@ -210,7 +239,11 @@ public void processInstance(Instance inst, Node node, double prediction, double Node currentNode = node; while (true) { if (currentNode instanceof LeafNode) { +<<<<<<< HEAD ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); +======= + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa break; } else { currentNode.examplesSeen += inst.weight(); @@ -219,7 +252,11 @@ public void processInstance(Instance inst, Node node, double prediction, double if (!inAlternate && iNode.alternateTree != null) { boolean altTree = true; double lossO = Math.pow(inst.classValue() - prediction, 2); +<<<<<<< HEAD double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); +======= + double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { @@ -239,7 +276,11 @@ public void processInstance(Instance inst, Node node, double prediction, double iNode.previousWeight = iNode.lossExamplesSeen; if (Qi > 0) { // Switch the subtrees +<<<<<<< HEAD Node parent = iNode.getParent(); +======= + Node parent = currentNode.parent; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (parent != null) { Node replacementTree = iNode.alternateTree; @@ -249,7 +290,11 @@ public void processInstance(Instance inst, Node node, double prediction, double treeRoot = iNode.alternateTree; treeRoot.restartChangeDetection(); } +<<<<<<< HEAD optionNodeCount += iNode.alternateTree.getNumSubtrees() - iNode.getNumSubtrees(); +======= + optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa removeExcessTrees(); currentNode = iNode.alternateTree; @@ -264,7 +309,11 @@ public void processInstance(Instance inst, Node node, double prediction, double } if (altTree) { growthAllowed = false; // this is the growth of the original tree +<<<<<<< HEAD processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree +======= + processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } else if (currentNode instanceof OptionNode) { // this happens when an option node is switched into the tree for (Node child : ((OptionNode) currentNode).children) { @@ -292,23 +341,35 @@ public void processInstance(Instance inst, Node node, double prediction, double } public void processInstanceOptionNode(Instance inst, OptionNode node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { +<<<<<<< HEAD node.examplesSeen += inst.weight(); node.sumOfAbsErrors += inst.weight() * normalError; - +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (node.changeDetection) { double error = Math.abs(prediction - inst.classValue()); node.sumOfAbsErrors += error; if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { node.initializeAlternateTree(); +<<<<<<< HEAD growthAllowed = false; +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } for (Node child : node.children) { int index = node.getChildIndex(child); double childPrediction = child.getPrediction(inst); +<<<<<<< HEAD + node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; + node.optionFFSSL[index] = node.optionFFSSL[index] * optionFadingFactorOption.getValue() + Math.pow(childPrediction - inst.classValue(), 2); + } + for (Node child : node.children) { + processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); +======= // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; @@ -318,6 +379,7 @@ public void processInstanceOptionNode(Instance inst, OptionNode node, double pre for (Node child : node.children) { processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } @@ -335,6 +397,10 @@ protected OptionNode newOptionNode() { // region --- Processing methods protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { +<<<<<<< HEAD + +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Initialize the split criterion SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); @@ -342,7 +408,11 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); List acceptedSplits = new LinkedList(); Arrays.sort(bestSplitSuggestions); +<<<<<<< HEAD + +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Declare a variable to determine the number of splits to be performed int numSplits = 0; @@ -360,7 +430,10 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - +<<<<<<< HEAD + +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and @@ -372,6 +445,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { numSplits = 1; acceptedSplits.add(bestSuggestion); } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { +<<<<<<< HEAD for (int i = 0; i < bestSplitSuggestions.length; i++) { AttributeSplitSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { @@ -382,7 +456,15 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { } } - + +======= + for (AttributeSplitSuggestion suggestion : bestSplitSuggestions) { + if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { + numSplits++; + acceptedSplits.add(suggestion); + } + } +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } else if (hoeffdingBound < tieThresholdOption.getValue()) { numSplits = 1; acceptedSplits.add(bestSplitSuggestions[0]); @@ -401,7 +483,11 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (numSplits > 0) { double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); +<<<<<<< HEAD + if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 0) { +======= if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa AttributeSplitSuggestion splitDecision = acceptedSplits.get(0); SplitNode newSplit = newSplitNode(splitDecision.splitTest); for (int i = 0; i < splitDecision.numSplits(); i++) { @@ -412,12 +498,19 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { leafNodeCount--; innerNodeCount++; leafNodeCount += splitDecision.numSplits(); +<<<<<<< HEAD if (parent == null && node.originalNode == null) { treeRoot = newSplit; } else if (parent == null && node.originalNode != null) { node.originalNode.alternateTree = newSplit; } else { parent.setChild(parentIndex, newSplit); +======= + if (parent == null) { + treeRoot = newSplit; + } else { + parent.setChild(parent.getChildIndex(node), newSplit); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa newSplit.setParent(parent); } } else { @@ -451,7 +544,11 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (parent == null) { treeRoot = optionNode; } else { +<<<<<<< HEAD parent.setChild(parentIndex, optionNode); +======= + parent.setChild(parent.getChildIndex(node), optionNode); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa optionNode.setParent(parent); } @@ -534,5 +631,8 @@ protected void removeExcessTrees() { // endregion --- Option tree methods //endregion ================ METHODS ================ +<<<<<<< HEAD } - +======= +} +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index 61f2ee877..4202599c6 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -154,6 +154,7 @@ protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { int secondsElapsed = 0; monitor.setCurrentActivity("Evaluating learner...", -1.0); +<<<<<<< HEAD File dumpFile = this.dumpFileOption.getFile(); PrintStream immediateResultStream = null; if (dumpFile != null) { @@ -207,7 +208,63 @@ protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); } outputPredictionResultStream.println(prediction + "," + sb.toString()); - } + } +======= + File dumpFile = this.dumpFileOption.getFile(); + PrintStream immediateResultStream = null; + if (dumpFile != null) { + try { + if (dumpFile.exists()) { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile, true), true); + } else { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open immediate result file: " + dumpFile, ex); + } + } + //File for output predictions + File outputPredictionFile = this.outputPredictionFileOption.getFile(); + PrintStream outputPredictionResultStream = null; + if (outputPredictionFile != null) { + try { + if (outputPredictionFile.exists()) { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile, true), true); + } else { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open prediction result file: " + outputPredictionFile, ex); + } + } + boolean firstDump = true; + boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); + long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + long lastEvaluateStartTime = evaluateStartTime; + double RAMHours = 0.0; + while (stream.hasMoreInstances() + && ((maxInstances < 0) || (instancesProcessed < maxInstances)) + && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { + Example trainInst = stream.nextInstance(); + Example testInst = (Example) trainInst; //.copy(); + //testInst.setClassMissing(); + //double[] prediction = learner.getVotesForInstance(testInst); + Prediction prediction = learner.getPredictionForInstance(testInst); + // Output prediction + if (outputPredictionFile != null) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); + } +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); evaluator.addResult(testInst, prediction); From 562350e5b38ba1128c52425fe49aedb69af80d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Fri, 13 Nov 2015 13:57:24 +0100 Subject: [PATCH 10/33] Updates with the new versions of the algorithms (some code is imported from the 2015.10 prerelease version, so the pom files were updated back to the 2014.04 version) --- Release.key | 19 + moa/pom.xml | 2 +- .../samoa/instances/MultiLabelPrediction.java | 4 - .../NumericAttributeBinaryTest.java | 4 - .../LocalMultiTargetClassifier.java | 34 +- .../AttributeStatisticsObserver.java | 6 +- .../MultiLabelBSTree.java | 6 +- .../MultiLabelNominalAttributeObserver.java | 6 +- .../NominalStatisticsObserver.java | 3 +- .../NumericStatisticsObserver.java | 3 +- .../splitcriteria/ICVarianceReduction.java | 1 - .../MultiLabelSplitCriterion.java | 2 +- .../classifiers/multilabel/meta/MTOzaBag.java | 3 - .../multilabel/trees/ISOUPOptionTree.java | 15 +- .../multilabel/trees/ISOUPTree.java | 1010 ++++---------- .../core/AttributeExpansionSuggestion.java | 3 +- .../multilabel/AMRulesMultiLabelLearner.java | 6 +- .../AMRulesMultiTargetRegressor.java | 2 +- .../multilabel/core/LearningLiteral.java | 10 +- .../core/LearningLiteralRegression.java | 9 +- .../rules/multilabel/core/MultiLabelRule.java | 6 +- .../MultiTargetVarianceRatio.java | 1 + .../java/moa/classifiers/trees/FIMTDD.java | 1156 ++--------------- .../main/java/moa/classifiers/trees/ORTO.java | 113 +- .../tasks/EvaluatePrequentialMultiTarget.java | 59 +- pom.xml | 2 +- weka-package/pom.xml | 2 +- 27 files changed, 422 insertions(+), 2065 deletions(-) create mode 100644 Release.key rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/AttributeStatisticsObserver.java (90%) rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/MultiLabelBSTree.java (96%) rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/MultiLabelNominalAttributeObserver.java (93%) rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/NominalStatisticsObserver.java (56%) rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/NumericStatisticsObserver.java (56%) rename moa/src/main/java/moa/classifiers/{rules => }/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java (85%) rename moa/src/main/java/moa/classifiers/rules/{multilabel => }/core/AttributeExpansionSuggestion.java (95%) diff --git a/Release.key b/Release.key new file mode 100644 index 000000000..549e44194 --- /dev/null +++ b/Release.key @@ -0,0 +1,19 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.5 (GNU/Linux) + +mQGiBE8ySNwRBACKcsg4AceGW7vuOSywcGiiNZg4I8vIzn7zphgj+s6/i2/hs8TQ +TOHy1s3b0f32ani3sBRmTWtgNv8+HSaKSVUcNqqNL+Jy6Pulyao7amGTtvqVKmuz +6ADrbVz0SxWmzTlSctdxK3g3yRSb+vfYrBPrbXNCNB5g9C/uK1uh0fpj1wCgn3MX +GFlZsO3bF7SNqqYlzpV6DM0D/AjnBlxTwRJOA1sLAVSXipLOdkjo00OQ8jgOFDio +oJsqLtsscNGocPCqNRo6QSVQKNs5sfYP2GXWTnPVM5oJI1p6bjuADRE8mneJrJvF +Uc+Mt1MdS6ttF4tVqd5Ncc8LKYQJRn+AtiuxAAayAA35JOslnMM0bqSYMlw4BJTP +8TlPA/4r+k+ucz3cJtM2aaL/ngUdrhmGKfGK7npXA3Ic6FzQo2NlJyKfWjSsR8x+ +oN7tKEpuYxE5fcdbWd3v+4Ypx0LYMgBT1pUgI09AXxrx1cLRZI4yovrvQJgiA4Mh +CZ0eFkJJ1nwQR3NPMj5soar+7d3Ubc2EqkESGm0CgGtjgg+7HrQ6aXN2Om93bkNs +b3VkIE9CUyBQcm9qZWN0IDxpc3Y6b3duQ2xvdWRAYnVpbGQub3BlbnN1c2Uub3Jn +PohmBBMRAgAmBQJU2MJUAhsDBQkJxSl4BgsJCAcDAgQVAggDBBYCAwECHgECF4AA +CgkQl3xDqLpoQiMpOQCggCpaq5yz8C3ckqEr0RkTjICcQYMAnRvjarxoY6iSThDN +7vgxE1Fe8X5EiEYEExECAAYFAk8ySNwACgkQOzARt2udZSPlpwCfQZKNN8Rxx0LE +BF32EYXBdEvkMYYAoIt3lfXL8uwmjvyljzb0JgBQN1cF +=FJ6Q +-----END PGP PUBLIC KEY BLOCK----- diff --git a/moa/pom.xml b/moa/pom.xml index dd44c7979..ec5e36169 100755 --- a/moa/pom.xml +++ b/moa/pom.xml @@ -4,7 +4,7 @@ nz.ac.waikato.cms.moa moa-pom - 2015.05-SNAPSHOT + 2014.04 moa diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index 838f90c7b..7e821ce9f 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -28,10 +28,6 @@ public MultiLabelPrediction(int numOutputAttributes) { for (int i=0; i>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (v == this.attValue) { return this.equalsPassesTest ? 0 : 1; } diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 38c82f7e9..5fce8915c 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -1,12 +1,7 @@ package moa.classifiers.multilabel; -<<<<<<< HEAD import java.util.ArrayList; -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa -import java.util.LinkedList; import java.util.List; -import java.util.Vector; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; @@ -21,11 +16,7 @@ import moa.classifiers.Classifier; import moa.classifiers.MultiLabelClassifier; import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.classifiers.trees.FIMTDD; -import moa.core.DoubleVector; import moa.core.Measurement; -import moa.learners.Learner; import moa.options.ClassOption; public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner @@ -38,17 +29,11 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner Classifier.class, "moa.classifiers.trees.FIMTDD"); -<<<<<<< HEAD ArrayList classifiers = null; ArrayList headers = null; -======= - LinkedList classifiers = null; - LinkedList headers = null; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa @Override public boolean isRandomizable() { - // TODO Auto-generated method stub return true; } @@ -61,14 +46,10 @@ private InstancesHeader getHeader(int target) { private void makeHeaders() { if (headers == null) { -<<<<<<< HEAD headers = new ArrayList(); -======= - headers = new LinkedList(); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { - List attributes = new LinkedList(); - List indexValues = new LinkedList(); + List attributes = new ArrayList(); + List indexValues = new ArrayList(); for (int i = 0; i < getModelContext().numInputAttributes(); i++) { attributes.add(getModelContext().inputAttribute(i)); indexValues.add(i); @@ -95,7 +76,6 @@ private Instance getSTInstance(MultiLabelInstance inst, int target) { @Override public void trainOnInstanceImpl(MultiLabelInstance instance) { - // TODO Auto-generated method stub initializeClassifiers(); for (int j = 0; j < instance.numberOutputTargets(); j++) { @@ -112,10 +92,6 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); for (int j = 0; j < inst.numberOutputTargets(); j++) { Instance STInst = getSTInstance(inst, j); -<<<<<<< HEAD -======= - ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa prediction.setVote(j, 1, classifiers.get(j).getVotesForInstance(STInst)[0]); } return prediction; @@ -131,15 +107,9 @@ public void initializeClassifiers() { this.classifierRandom.setSeed(1234); if (classifiers == null) { makeHeaders(); -<<<<<<< HEAD classifiers = new ArrayList(); for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { Classifier learner = ((Classifier) getPreparedClassOption(this.classifierOption)).copy(); -======= - classifiers = new LinkedList(); - for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { - Classifier learner = (Classifier) getPreparedClassOption(this.classifierOption); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa classifiers.add(learner); learner.resetLearning(); ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/AttributeStatisticsObserver.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/AttributeStatisticsObserver.java similarity index 90% rename from moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/AttributeStatisticsObserver.java rename to moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/AttributeStatisticsObserver.java index e760469e8..34be2f026 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/AttributeStatisticsObserver.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/AttributeStatisticsObserver.java @@ -17,10 +17,10 @@ * along with this program. If not, see . * */ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; -import moa.classifiers.rules.multilabel.core.AttributeExpansionSuggestion; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.core.DoubleVector; import moa.options.OptionHandler; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelBSTree.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java similarity index 96% rename from moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelBSTree.java rename to moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java index 9058f9479..58fd92faa 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelBSTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java @@ -1,13 +1,13 @@ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; import java.io.Serializable; import com.github.javacliparser.IntOption; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.NumericRulePredicate; import moa.classifiers.rules.core.Utils; -import moa.classifiers.rules.multilabel.core.AttributeExpansionSuggestion; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.core.DoubleVector; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelNominalAttributeObserver.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelNominalAttributeObserver.java similarity index 93% rename from moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelNominalAttributeObserver.java rename to moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelNominalAttributeObserver.java index 969f28576..2495b158f 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelNominalAttributeObserver.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelNominalAttributeObserver.java @@ -1,13 +1,13 @@ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.NominalRulePredicate; import moa.classifiers.rules.core.Utils; -import moa.classifiers.rules.multilabel.core.AttributeExpansionSuggestion; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.core.DoubleVector; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NominalStatisticsObserver.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NominalStatisticsObserver.java similarity index 56% rename from moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NominalStatisticsObserver.java rename to moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NominalStatisticsObserver.java index 64ce01864..e52a0cb42 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NominalStatisticsObserver.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NominalStatisticsObserver.java @@ -1,4 +1,5 @@ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; + public interface NominalStatisticsObserver extends AttributeStatisticsObserver { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NumericStatisticsObserver.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NumericStatisticsObserver.java similarity index 56% rename from moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NumericStatisticsObserver.java rename to moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NumericStatisticsObserver.java index 5914dbb15..b899ce1dc 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NumericStatisticsObserver.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NumericStatisticsObserver.java @@ -1,4 +1,5 @@ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; + public interface NumericStatisticsObserver extends AttributeStatisticsObserver { diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java index c3f2299d2..176f3dfd0 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java @@ -5,7 +5,6 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.tasks.TaskMonitor; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion;; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java similarity index 85% rename from moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java rename to moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java index 099748611..cc9247039 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java @@ -1,4 +1,4 @@ -package moa.classifiers.rules.multilabel.core.splitcriteria; +package moa.classifiers.multilabel.core.splitcriteria; import moa.core.DoubleVector; diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java index a4c64a809..2594f61be 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java @@ -93,7 +93,6 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { } return new MultiLabelPrediction(prediction); } -<<<<<<< HEAD public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) { int actual = Math.max(1, Math.min(n, this.ensemble.length)); @@ -112,8 +111,6 @@ public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) } return new MultiLabelPrediction(prediction); } -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa @Override public void trainOnInstanceImpl(MultiLabelInstance instance) { diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java index 93de284a0..a0ce07563 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java @@ -3,15 +3,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.MultiLabelInstance; - -import moa.classifiers.multilabel.trees.ISOUPTree.LeafNode; -import moa.classifiers.multilabel.trees.ISOUPTree.Node; -import moa.classifiers.multilabel.trees.ISOUPTree.SplitNode; -import moa.classifiers.trees.ORTO; -import moa.classifiers.trees.FIMTDD.InnerNode; -import moa.classifiers.trees.ORTO.OptionNode; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; @@ -20,7 +12,6 @@ public class ISOUPOptionTree extends ISOUPTree { private static final long serialVersionUID = 1L; - private int innerNodeCount = 0; private int optionNodeCount = 0; private int numTrees = 1; @@ -62,6 +53,11 @@ public class ISOUPOptionTree extends ISOUPTree { //region ================ CLASSES ================ public static class OptionNode extends InnerNode { + /** + * + */ + private static final long serialVersionUID = 1L; + protected AutoExpandVector optionFFSSL; protected AutoExpandVector optionFFSeen; @@ -152,7 +148,6 @@ public String getPurposeString() { public void resetLearningImpl() { super.resetLearningImpl(); - this.innerNodeCount = 0; this.optionNodeCount = 0; } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index 592a0c5c6..3596120c3 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -41,15 +41,15 @@ import moa.AbstractMOAObject; import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelBSTree; +import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelNominalAttributeObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; import moa.classifiers.multilabel.core.splitcriteria.ICVarianceReduction; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.Predicate; -import moa.classifiers.rules.multilabel.attributeclassobservers.AttributeStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.MultiLabelBSTree; -import moa.classifiers.rules.multilabel.attributeclassobservers.MultiLabelNominalAttributeObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.rules.multilabel.core.AttributeExpansionSuggestion; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; @@ -66,14 +66,7 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR private static final long serialVersionUID = 1L; -<<<<<<< HEAD public Node treeRoot; -======= - protected Node treeRoot; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - - private int leafNodeCount = 0; - private int splitNodeCount = 0; private double examplesSeen = 0.0; private DoubleVector sumOfValues = new DoubleVector(); @@ -86,17 +79,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR //region ================ OPTIONS ================ -<<<<<<< HEAD - // public ClassOption splitCriterionOption = new ClassOption( - // "splitCriterion", - // 's', - // "Split criterion to use.", - // SplitCriterion.class, - // "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); - // TODO not used at the moment, consider later when the implementation catches up - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa public IntOption gracePeriodOption = new IntOption( "gracePeriod", 'g', @@ -115,7 +97,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR "Threshold below which a split will be forced to break ties.", 0.05, 0.0, 1.0); -<<<<<<< HEAD public FloatOption PageHinckleyAlphaOption = new FloatOption( "PageHinckleyAlpha", 'a', @@ -127,19 +108,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR 'h', "The threshold value to be used in the Page Hinckley change detection tests.", 50, 0, Integer.MAX_VALUE); -======= -// public FloatOption PageHinckleyAlphaOption = new FloatOption( -// "PageHinckleyAlpha", -// 'a', -// "The alpha value to use in the Page Hinckley change detection tests.", -// 0.005, 0.0, 1.0); -// -// public IntOption PageHinckleyThresholdOption = new IntOption( -// "PageHinckleyThreshold", -// 'h', -// "The threshold value to be used in the Page Hinckley change detection tests.", -// 50, 0, Integer.MAX_VALUE); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa public FloatOption alternateTreeFadingFactorOption = new FloatOption( "alternateTreeFadingFactor", @@ -185,15 +153,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR "doNotNormalize", 'n', "Don't normalize."); -<<<<<<< HEAD - - public FlagOption printLogsOption = new FlagOption( - "printLogs", - 'z', - "Print logs."); -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - //endregion ================ OPTIONS ================ @@ -342,17 +301,11 @@ public LeafNode(ISOUPTree tree) { */ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, boolean growthAllowed) { // Update the statistics for this node -<<<<<<< HEAD - // number of instances passing through the node - double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; - double[] predictionM = getPredictionTargetMean(inst); -======= double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; double[] predictionM = getPredictionTargetMean(inst); // number of instances passing through the node ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa examplesSeen += inst.weight(); for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { @@ -367,10 +320,7 @@ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, bool errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - inst.valueOutputAttribute(i))); } } -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); for (int i = 0; i < inst.numInputAttributes(); i++) { @@ -443,17 +393,11 @@ public double[] getPredictionModel(MultiLabelInstance inst) { public double[] getPredictionTargetMean(MultiLabelInstance inst) { double[] pred = new double[inst.numOutputAttributes()]; -<<<<<<< HEAD for (int i = 0; i < inst.numOutputAttributes(); i++) { if (examplesSeen > 0) { pred[i] = sumOfValues.getValue(i) / examplesSeen; } else { pred[i] = 0; -======= - if (examplesSeen > 0) { - for (int i = 0; i < inst.numOutputAttributes(); i++) { - pred[i] = sumOfValues.getValue(i) / examplesSeen; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } return pred; @@ -513,7 +457,7 @@ public static abstract class InnerNode extends Node { // Sum of absolute errors protected DoubleVector sumOfAbsErrors = new DoubleVector(); // Needed for PH tracking of mean error - + protected DoubleVector PHsums = new DoubleVector(); protected DoubleVector PHmins = new DoubleVector(); @@ -654,11 +598,7 @@ public class MultitargetPerceptron { protected ISOUPTree tree; // The Perception weights -<<<<<<< HEAD public double[][] weights; -======= - protected double[][] weights; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // The number of instances contributing to this model protected int instancesSeen = 0; @@ -670,13 +610,6 @@ public String getPurposeString() { public MultitargetPerceptron(ISOUPTree tree, MultitargetPerceptron original) { this.tree = tree; weights = original.weights.clone(); -<<<<<<< HEAD - // TODO check if this is necessary -// for (int i = 0; i < this.tree.getModelContext().numOutputAttributes(); i++) { -// weights[i] = (DoubleVector) original.weights[i].copy(); -// } -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } public MultitargetPerceptron(ISOUPTree tree) { @@ -696,10 +629,7 @@ public void initializeWeights() { weights[i][j] = 2 * tree.classifierRandom.nextDouble() - 1; } } -<<<<<<< HEAD normalizeWeights(); -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } /** @@ -708,7 +638,7 @@ public void initializeWeights() { public void updatePerceptron(MultiLabelInstance inst) { // Update attribute statistics instancesSeen += inst.weight(); - + // Update weights double learningRatio = 0.0; if (tree.learningRatioConstOption.isSet()) { @@ -727,7 +657,7 @@ public void updateWeights(MultiLabelInstance inst, double learningRatio) { if (instancesSeen > 1.0) { // Compute the normalized instance and the delta double[] normalizedInput = tree.normalizedInputVector(inst); - double[] normalizedPrediction = prediction(normalizedInput); + double[] normalizedPrediction = prediction(normalizedInput); double[] normalizedTarget = tree.normalizedTargetVector(inst); for (int i = 0; i < inst.numOutputAttributes(); i++){ @@ -750,10 +680,6 @@ public void normalizeWeights() { } } -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa /** * Output the prediction made by this perceptron on the given instance */ @@ -792,372 +718,22 @@ private double[] denormalizePrediction(double[] normalizedPrediction) { public void getModelDescription(StringBuilder out, int indent) { for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "]"); -<<<<<<< HEAD - //if (getModelContext() != null) { - //for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { - // if (getModelContext().attribute(j).isNumeric()) { - // // TODO - // //out.append((j == 0 || weightAttribute.getValue(j) < 0) ? " " : " + "); - // //out.append(String.format("%.4f", weightAttribute.getValue(j))); - // out.append(" * "); - // out.append(getAttributeNameString(j)); - // } - //} - //out.append(" + " + weightAttribute.getValue((getModelContext().numAttributes() - 1))); - //} - } - StringUtils.appendNewline(out); - } - } - - // public class SOPNumericAttributeClassObserver implements MultitargetAttributeClassObserver { - // - // private static final long serialVersionUID = 1L; - // - // protected class Node implements Serializable { - // - // private static final long serialVersionUID = 1L; - // - // // The split point to use - // public double cut_point; - // - // // E-BST statistics - // public double leftCount = 0; - // public double rightCount = 0; - // public DoubleVector leftSums = new DoubleVector(); - // public DoubleVector leftSquares = new DoubleVector(); - // public DoubleVector rightSums = new DoubleVector(); - // public DoubleVector rightSquares = new DoubleVector(); - // - // // Child nodes - // public Node left; - // public Node right; - // - // public Node(double val, DoubleVector labelVector, double weight) { - // cut_point = val; - // leftCount += 1; - // for (int i = 0; i < labelVector.numValues(); i++) { - // leftSums.addToValue(i, labelVector.getValue(i)); - // leftSquares.addToValue(i, labelVector.getValue(i) * labelVector.getValue(i)); - // } - // } - // - // /** - // * Insert a new value into the tree, updating both the sum of values and - // * sum of squared values arrays - // */ - // public void insertValue(double val, DoubleVector labelVector, double weight) { - // - // // If the new value equals the value stored in a node, update - // // the left (<=) node information - // if (val == cut_point) { - // leftCount += 1; - // for (int i = 0; i < labelVector.numValues(); i++) { - // leftSums.addToValue(i, labelVector.getValue(i)); - // leftSquares.addToValue(i, labelVector.getValue(i) * labelVector.getValue(i)); - // } - // } // If the new value is less than the value in a node, update the - // // left distribution and send the value down to the left child node. - // // If no left child exists, create one - // else if (val <= cut_point) { - // - // leftCount += 1; - // for (int i = 0; i < labelVector.numValues(); i++) { - // leftSums.addToValue(i, labelVector.getValue(i)); - // leftSquares.addToValue(i, labelVector.getValue(i) * labelVector.getValue(i)); - // } - // if (left == null) { - // left = new Node(val, labelVector, weight); - // } else { - // left.insertValue(val, labelVector, weight); - // } - // } // If the new value is greater than the value in a node, update the - // // right (>) distribution and send the value down to the right child node. - // // If no right child exists, create one - // else { // val > cut_point - // rightCount += 1; - // for (int i = 0; i < labelVector.numValues(); i++) { - // rightSums.addToValue(i, labelVector.getValue(i)); - // rightSquares.addToValue(i, labelVector.getValue(i) * labelVector.getValue(i)); - // } - // if (right == null) { - // right = new Node(val, labelVector, weight); - // } else { - // right.insertValue(val, labelVector, weight); - // } - // } - // } - // } - // - // // Root node of the E-BST structure for this attribute - // protected Node root = null; - // - // // Global variables for use in the FindBestSplit algorithm - // DoubleVector sumsTotalLeft; - // DoubleVector sumsTotalRight; - // DoubleVector squaresTotalLeft; - // DoubleVector squaresTotalRight; - // double countRightTotal; - // double countLeftTotal; - // - // public void observeAttributeClass(double attVal, double classVal, double weight) { - // // DEPRECATED (used for single-target cases) - // - // // if (Double.isNaN(attVal)) { //Instance.isMissingValue(attVal) - // // } else { - // // if (root == null) { - // // root = new Node(attVal, classVal, weight); - // // } else { - // // root.insertValue(attVal, classVal, weight); - // // } - // // } - // } - // - // public void observeAttributeClass(double attVal, DoubleVector classVector, double weight) { - // if (Double.isNaN(attVal)) { //Instance.isMissingValue(attVal) - // } else { - // if (root == null) { - // root = new Node(attVal, classVector, weight); - // } else { - // root.insertValue(attVal, classVector, weight); - // } - // } - // - // } - // - // public double probabilityOfAttributeValueGivenClass(double attVal, int classVal) { - // // TODO: NaiveBayes broken until implemented - // return 0.0; - // } - // - // @Override - // public AttributeSplitSuggestion getBestEvaluatedSplitSuggestion(SplitCriterion criterion, double examlpesSeen, DoubleVector preSplitSums, DoubleVector preSplitSquares, int numTargets, int attIndex, boolean binaryOnly) { - // // Initialise global variables - // sumsTotalLeft = new DoubleVector(); - // sumsTotalRight = preSplitSums; - // squaresTotalLeft = new DoubleVector(); - // squaresTotalRight = preSplitSquares; - // countLeftTotal = 0; - // countRightTotal = examplesSeen; - // - // // Hardcoded for ICV reduction - // double preSplitVariance = 0; - // for (int i = 0; i < numTargets; i++) { - // preSplitVariance += (preSplitSquares.getValue(i) - examplesSeen * preSplitSums.getValue(i) * preSplitSums.getValue(i)) / examplesSeen; - // } - // - // return searchForBestSplitOption(root, null, preSplitVariance, attIndex, numTargets); - // } - // - // public AttributeSplitSuggestion getBestEvaluatedSplitSuggestion(SplitCriterion criterion, double[] preSplitDist, int attIndex, boolean binaryOnly) { - // // DEPRECATED - // return null; - // } - // - // /** - // * Implementation of the FindBestSplit algorithm from E.Ikonomovska et al. - // */ - // protected AttributeSplitSuggestion searchForBestSplitOption(Node currentNode, AttributeSplitSuggestion currentBestOption, double preSplitVariance, int attIndex, int numTargets) { - // // Return null if the current node is null or we have finished looking through all the possible splits - // if (currentNode == null || countRightTotal == 0.0) { - // return currentBestOption; - // } - // - // if (currentNode.left != null) { - // currentBestOption = searchForBestSplitOption(currentNode.left, currentBestOption, preSplitVariance, attIndex, numTargets); - // } - // - // sumsTotalLeft.addValues(currentNode.leftSums); - // sumsTotalRight.subtractValues(currentNode.leftSums); - // squaresTotalLeft.addValues(currentNode.leftSquares); - // squaresTotalRight.subtractValues(currentNode.leftSquares); - // countLeftTotal += currentNode.leftCount; - // countRightTotal -= currentNode.leftCount; - // - // // double[][] postSplitDists = new double[][]{{countLeftTotal, sumTotalLeft, sumSqTotalLeft}, {countRightTotal, sumTotalRight, sumSqTotalRight}}; - // // double[] preSplitDist = new double[]{(countLeftTotal + countRightTotal), (sumTotalLeft + sumTotalRight), (sumSqTotalLeft + sumSqTotalRight)}; - // // double merit = criterion.getMeritOfSplit(preSplitDist, postSplitDists); - // - // double postSplitVariance = 0; - // for (int i = 0; i < numTargets; i++) { - // postSplitVariance += (squaresTotalLeft.getValue(i) - examplesSeen * sumsTotalLeft.getValue(i) * sumsTotalLeft.getValue(i)) / countLeftTotal; - // postSplitVariance += (squaresTotalRight.getValue(i) - examplesSeen * sumsTotalRight.getValue(i) * sumsTotalRight.getValue(i)) / countRightTotal; - // } - // - // double merit = preSplitVariance - postSplitVariance; - // - // if ((currentBestOption == null) || (merit > currentBestOption.merit)) { - // currentBestOption = new AttributeSplitSuggestion( - // new NumericAttributeBinaryTest(attIndex, - // currentNode.cut_point, true), new double[0][0], merit); - // - // } - // - // if (currentNode.right != null) { - // currentBestOption = searchForBestSplitOption(currentNode.right, currentBestOption, preSplitVariance, attIndex, numTargets); - // } - // - // sumsTotalLeft.subtractValues(currentNode.leftSums); - // sumsTotalRight.addValues(currentNode.leftSums); - // squaresTotalLeft.subtractValues(currentNode.leftSquares); - // squaresTotalRight.addValues(currentNode.leftSquares); - // countLeftTotal -= currentNode.leftCount; - // countRightTotal += currentNode.leftCount; - // - // return currentBestOption; - // } - // - // /** - // * A method to remove all nodes in the E-BST in which it and all it's - // * children represent 'bad' split points - // */ - // public void removeBadSplits(SplitCriterion criterion, double lastCheckRatio, double lastCheckSDR, double lastCheckE, int numTargets) { - // removeBadSplitNodes(criterion, root, lastCheckRatio, lastCheckSDR, lastCheckE, numTargets); - // } - // - // /** - // * Recursive method that first checks all of a node's children before - // * deciding if it is 'bad' and may be removed - // */ - // private boolean removeBadSplitNodes(SplitCriterion criterion, Node currentNode, double lastCheckRatio, double lastCheckSDR, double lastCheckE, int numTargets) { - // boolean isBad = false; - // - // if (currentNode == null) { - // return true; - // } - // - // if (currentNode.left != null) { - // isBad = removeBadSplitNodes(criterion, currentNode.left, lastCheckRatio, lastCheckSDR, lastCheckE, numTargets); - // } - // - // if (currentNode.right != null && isBad) { - // isBad = removeBadSplitNodes(criterion, currentNode.left, lastCheckRatio, lastCheckSDR, lastCheckE, numTargets); - // } - // - // if (isBad) { - // - // double preSplitVariance = 0; - // for (int i = 0; i < numTargets; i++) { - // preSplitVariance += (currentNode.leftSquares.getValue(i) + currentNode.rightSquares.getValue(i) - examplesSeen * - // (currentNode.leftSums.getValue(i) + currentNode.rightSums.getValue(i)) * (currentNode.leftSums.getValue(i) + currentNode.rightSums.getValue(i))) / examplesSeen; - // } - // - // double postSplitVariance = 0; - // for (int i = 0; i < numTargets; i++) { - // postSplitVariance += (currentNode.leftSquares.getValue(i) - currentNode.leftCount * currentNode.leftSums.getValue(i) * currentNode.leftSums.getValue(i)) / currentNode.leftCount; - // postSplitVariance += (currentNode.rightSquares.getValue(i) - currentNode.rightCount * currentNode.rightSums.getValue(i) * currentNode.rightSums.getValue(i)) / currentNode.rightCount; - // } - // - // - // // double[][] postSplitDists = new double[][]{{currentNode.leftStatistics.getValue(0), currentNode.leftStatistics.getValue(1), currentNode.leftStatistics.getValue(2)}, {currentNode.rightStatistics.getValue(0), currentNode.rightStatistics.getValue(1), currentNode.rightStatistics.getValue(2)}}; - // // double[] preSplitDist = new double[]{(currentNode.leftStatistics.getValue(0) + currentNode.rightStatistics.getValue(0)), (currentNode.leftStatistics.getValue(1) + currentNode.rightStatistics.getValue(1)), (currentNode.leftStatistics.getValue(2) + currentNode.rightStatistics.getValue(2))}; - // // double merit = criterion.getMeritOfSplit(preSplitDist, postSplitDists); - // double merit = preSplitVariance - postSplitVariance; - // - // if ((merit / lastCheckSDR) < (lastCheckRatio - (2 * lastCheckE))) { - // currentNode = null; - // return true; - // } - // } - // - // return false; - // } - // - // @Override - // public void getDescription(StringBuilder sb, int indent) { - // // TODO Auto-generated method stub - // } - // - // protected void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { - // // TODO Auto-generated method stub - // } - // - // @Override - // public void observeAttributeClass(double attVal, int classVal, - // double weight) { - // // TODO Auto-generated method stub - // - // } - // - // @Override - // public void observeAttributeTarget(double attVal, double target) { - // // TODO Auto-generated method stub - // - // } - // - // @Override - // public String getPurposeString() { - // // TODO Auto-generated method stub - // return null; - // } - // - // @Override - // public Options getOptions() { - // // TODO Auto-generated method stub - // return null; - // } - // - // @Override - // public void prepareForUse() { - // // TODO Auto-generated method stub - // - // } - // - // @Override - // public void prepareForUse(TaskMonitor monitor, - // ObjectRepository repository) { - // // TODO Auto-generated method stub - // - // } - // - // @Override - // public OptionHandler copy() { - // // TODO Auto-generated method stub - // return null; - // } - // - // @Override - // public String getCLICreationString(Class expectedType) { - // // TODO Auto-generated method stub - // return null; - // } - // - // @Override - // public int measureByteSize() { - // // TODO Auto-generated method stub - // return 0; - // } - // - // - // - // @Override - // public void observeAttributeClassVector(double attVal, - // DoubleVector classVector, double weight) { - // // TODO Auto-generated method stub - // - // } - // - // - // } - -======= if (getModelContext() != null) { - for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { - if (getModelContext().attribute(j).isNumeric()) { - out.append((j == 0 || weights[i][j] < 0) ? " " : " + "); - out.append(String.format("%.4f", weights[i][j])); - out.append(" * "); - out.append(getAttributeNameString(j)); - } - } - out.append(" + " + weights[i][getModelContext().numOutputAttributes()]); + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + if (getModelContext().attribute(j).isNumeric()) { + out.append((j == 0 || weights[i][j] < 0) ? " " : " + "); + out.append(String.format("%.4f", weights[i][j])); + out.append(" * "); + out.append(getAttributeNameString(j)); + } + } + out.append(" + " + weights[i][getModelContext().numOutputAttributes()]); } StringUtils.appendNewline(out); } } } ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa //endregion ================ CLASSES ================ //region ================ METHODS ================ @@ -1166,27 +742,17 @@ public void getModelDescription(StringBuilder out, int indent) { public ISOUPTree() {} public String getPurposeString() { -<<<<<<< HEAD - return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; -======= return "Implementation of the iSOUP-Tree algorithm as described by Osojnik et al."; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } public void resetLearningImpl() { treeRoot = null; - leafNodeCount = 0; - splitNodeCount = 0; -<<<<<<< HEAD examplesSeen = 0.0; sumOfValues = new DoubleVector(); sumOfSquares = new DoubleVector(); sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); -======= - maxID = 0; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } public boolean isRandomizable() { @@ -1280,11 +846,7 @@ public double[] normalizeTargetVector(double[] pred) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0 && examplesSeen > 1) -<<<<<<< HEAD out[i] = (value - average) / sd; -======= - out[i] = (value - average) / (3 * sd); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa else out[i] = 0; } @@ -1300,11 +862,7 @@ public double normalizeTargetValue(MultiLabelInstance inst, int i) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0) -<<<<<<< HEAD return (value - average) / sd; -======= - return (value - average) / (3 * sd); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa else return 0; } @@ -1318,11 +876,7 @@ public double normalizeTargetValue(double value, int i) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0) -<<<<<<< HEAD return (value - average) / sd; -======= - return (value - average) / (3 * sd); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa else return 0; } @@ -1344,283 +898,249 @@ public double[] getNormalizedError(MultiLabelInstance inst, double[] prediction) /** * Method for updating (training) the model using a new instance */ - public void trainOnInstanceImpl(MultiLabelInstance inst) { - if (inst.weight() > 0) { - checkRoot(); - - double[] prediction = treeRoot.getPrediction(inst); - double[] normalError = getNormalizedError(inst, prediction); -<<<<<<< HEAD - - processInstance(inst, treeRoot, prediction, normalError, true, false); - -======= - //normalError.scaleValues(inst.weight()); - processInstance(inst, treeRoot, prediction, normalError, true, false); - ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - examplesSeen += inst.weight(); - for (int i = 0; i < inst.numberOutputTargets(); i++) { - sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); - sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); - } - - for (int i = 0; i < inst.numInputAttributes(); i++) { - sumOfAttrValues.addToValue(i, inst.weight() * inst.valueInputAttribute(i)); - sumOfAttrSquares.addToValue(i, inst.weight() * inst.valueInputAttribute(i) * inst.valueInputAttribute(i)); - } -<<<<<<< HEAD - - //normalError.scaleValues(inst.weight()); - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - } - } - - public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { - Node currentNode = node; - while (true) { - if (currentNode instanceof LeafNode) { - ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); - break; - } else { - currentNode.examplesSeen += inst.weight(); - //currentNode.sumOfAbsErrors.addValues(normalError); - // SplitNode iNode = (SplitNode) currentNode; - // if (!inAlternate && iNode.alternateTree != null) { - // boolean altTree = true; - // double lossO = Math.pow(inst.valueOutputAttribute() - prediction, 2); - // double lossA = Math.pow(inst.valueOutputAttribute() - iNode.alternateTree.getPrediction(inst), 2); - // - // iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; - // iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; - // iNode.lossExamplesSeen++; - // - // double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - // double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - // iNode.lossSumQi += Qi; - // iNode.lossNumQiTests += 1; - // double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - // - // if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { - // iNode.previousWeight = iNode.lossExamplesSeen; - // if (Qi > 0) { - // SplitNode parent = currentNode.getParent(); - // - // if (parent != null) { - // Node replacementTree = iNode.alternateTree; - // parent.setChild(parent.getChildIndex(currentNode), replacementTree); - // if (growthAllowed) replacementTree.restartChangeDetection(); - // } else { - // treeRoot = iNode.alternateTree; - // treeRoot.restartChangeDetection(); - // } - // - // currentNode = iNode.alternateTree; - // altTree = false; - // } else if ( - // (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) - // || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() - // ) { - // iNode.alternateTree = null; - // if (growthAllowed) iNode.restartChangeDetection(); - // altTree = false; - // } - // } - // - // if (altTree) { - // growthAllowed = false; - // processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); - // } - // } - - // if (iNode.changeDetection && !inAlternate) { - // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { - // iNode.initializeAlternateTree(this); - // } - // } - if (currentNode instanceof SplitNode) { - currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); - } else { // if the replaced alternate tree is just a leaf node - ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); - break; - } - } - } - } - - //region --- Object instatiation methods - - protected NumericStatisticsObserver newNumericClassObserver() { - return new MultiLabelBSTree(); - } - - public NominalStatisticsObserver newNominalClassObserver() { - return new MultiLabelNominalAttributeObserver(); - } - - // protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { - // maxID++; - // return new SplitNode(splitTest, this); - // } - - protected SplitNode newSplitNode(Predicate predicate) { - maxID++; - return new SplitNode(predicate, this); - } - - protected LeafNode newLeafNode() { - maxID++; - return new LeafNode(this); - } - -<<<<<<< HEAD - public MultitargetPerceptron newLeafModel() { -======= - protected MultitargetPerceptron newLeafModel() { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - return new MultitargetPerceptron(this); - } - - //endregion --- Object instatiation methods - - //region --- Processing methods - protected void checkRoot() { - if (treeRoot == null) { - treeRoot = newLeafNode(); - leafNodeCount = 1; - } - } - - public static double computeHoeffdingBound(double range, double confidence, double n) { - return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); - } - - public boolean buildingModelTree() { - return !regressionTreeOption.isSet(); - } - - public boolean normalize() { - return !doNotNormalizeOption.isSet(); - } - - protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) { - //System.out.println("Evaluating splits"); - //System.out.println(examplesSeen); - // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - MultiLabelSplitCriterion splitCriterion = new ICVarianceReduction(); - - // Using this criterion, find the best split per attribute and rank the results - AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option - Arrays.sort(bestSplitSuggestions); - - // Declare a variable to determine if any of the splits should be performed - boolean shouldSplit = false; - - // If only one split was returned, use it - if (bestSplitSuggestions.length < 2) { - shouldSplit = bestSplitSuggestions.length > 0; - } else { // Otherwise, consider which of the splits proposed may be worth trying - - // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); - // Determine the top two ranked splitting suggestions - AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - - // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), - // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this - // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and - // splitting should occur. - // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit - // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two - // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - //System.out.print(hoeffdingBound); - //System.out.print(" "); - ///System.out.println(secondBestSuggestion.merit / bestSuggestion.merit); - if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { - shouldSplit = true; - } - // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - else { - // TODO pruning is currently disabled - for (int i = 0; i < node.attributeObservers.size(); i++) { - AttributeStatisticsObserver obs = node.attributeObservers.get(i); - if (obs != null) { - if (getModelContext().attribute(i).isNumeric()); - //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); - if (getModelContext().attribute(i).isNominal()); - // TODO nominal class observers - } - } - } -<<<<<<< HEAD - - if (hoeffdingBound < this.tieThresholdOption.getValue() && this.printLogsOption.isSet()) System.out.println("Forced to split due to tie at " + this.examplesSeen); -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - } - - // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (shouldSplit) { -<<<<<<< HEAD - if (node.parent == null && this.printLogsOption.isSet()) { - System.out.println("splitting root node at " + this.examplesSeen); - } -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa - AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - - SplitNode newSplit = newSplitNode(splitDecision.predicate); - newSplit.copyStatistics(node); - newSplit.changeDetection = node.changeDetection; - newSplit.ID = node.ID; - leafNodeCount--; - //System.out.println("Splitting"); - //System.out.println(examplesSeen); - for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) - LeafNode newChild = newLeafNode(); - if (buildingModelTree()) { - // Copy the splitting node's perceptron to it's children - newChild.learningModel = new MultitargetPerceptron(this, (MultitargetPerceptron) node.learningModel); - - } - newChild.changeDetection = node.changeDetection; - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - leafNodeCount++; - } - if (parent == null && node.originalNode == null) { - treeRoot = newSplit; - } else if (parent == null && node.originalNode != null) { - node.originalNode.alternateTree = newSplit; - } else { - parent.setChild(parentIndex, newSplit); - newSplit.setParent(parent); - } - - splitNodeCount++; - } - } - - public double computeSD(double squaredVal, double val, double size) { - if (size > 1) - return Math.sqrt((squaredVal - ((val * val) / size)) / size); - else - return 0.0; - } - - public static double scalarProduct(DoubleVector u, DoubleVector v) { - double ret = 0.0; - for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { - ret += u.getValue(i) * v.getValue(i); - } - return ret; - } - //endregion --- Processing methods - - //endregion ================ METHODS ================ + public void trainOnInstanceImpl(MultiLabelInstance inst) { + if (inst.weight() > 0) { + checkRoot(); + + double[] prediction = treeRoot.getPrediction(inst); + double[] normalError = getNormalizedError(inst, prediction); + + processInstance(inst, treeRoot, prediction, normalError, true, false); + + examplesSeen += inst.weight(); + for (int i = 0; i < inst.numberOutputTargets(); i++) { + sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); + sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); + } + + for (int i = 0; i < inst.numInputAttributes(); i++) { + sumOfAttrValues.addToValue(i, inst.weight() * inst.valueInputAttribute(i)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.valueInputAttribute(i) * inst.valueInputAttribute(i)); + } + } + } + + public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } else { + currentNode.examplesSeen += inst.weight(); + //currentNode.sumOfAbsErrors.addValues(normalError); + // SplitNode iNode = (SplitNode) currentNode; + // if (!inAlternate && iNode.alternateTree != null) { + // boolean altTree = true; + // double lossO = Math.pow(inst.valueOutputAttribute() - prediction, 2); + // double lossA = Math.pow(inst.valueOutputAttribute() - iNode.alternateTree.getPrediction(inst), 2); + // + // iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + // iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + // iNode.lossExamplesSeen++; + // + // double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + // double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // iNode.lossSumQi += Qi; + // iNode.lossNumQiTests += 1; + // double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // + // if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + // iNode.previousWeight = iNode.lossExamplesSeen; + // if (Qi > 0) { + // SplitNode parent = currentNode.getParent(); + // + // if (parent != null) { + // Node replacementTree = iNode.alternateTree; + // parent.setChild(parent.getChildIndex(currentNode), replacementTree); + // if (growthAllowed) replacementTree.restartChangeDetection(); + // } else { + // treeRoot = iNode.alternateTree; + // treeRoot.restartChangeDetection(); + // } + // + // currentNode = iNode.alternateTree; + // altTree = false; + // } else if ( + // (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) + // || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() + // ) { + // iNode.alternateTree = null; + // if (growthAllowed) iNode.restartChangeDetection(); + // altTree = false; + // } + // } + // + // if (altTree) { + // growthAllowed = false; + // processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + // } + // } + + // if (iNode.changeDetection && !inAlternate) { + // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + // iNode.initializeAlternateTree(this); + // } + // } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); + } else { // if the replaced alternate tree is just a leaf node + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } + } + } + } + + //region --- Object instatiation methods + + protected NumericStatisticsObserver newNumericClassObserver() { + return new MultiLabelBSTree(); + } + + public NominalStatisticsObserver newNominalClassObserver() { + return new MultiLabelNominalAttributeObserver(); + } + + // protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + // maxID++; + // return new SplitNode(splitTest, this); + // } + + protected SplitNode newSplitNode(Predicate predicate) { + maxID++; + return new SplitNode(predicate, this); + } + + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } + + public MultitargetPerceptron newLeafModel() { + return new MultitargetPerceptron(this); + } + + //endregion --- Object instatiation methods + + //region --- Processing methods + protected void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + } + } + + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } + + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } + + public boolean normalize() { + return !doNotNormalizeOption.isSet(); + } + + protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) { + //System.out.println("Evaluating splits"); + //System.out.println(examplesSeen); + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + MultiLabelSplitCriterion splitCriterion = new ICVarianceReduction(); + + // Using this criterion, find the best split per attribute and rank the results + AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine if any of the splits should be performed + boolean shouldSplit = false; + + // If only one split was returned, use it + if (bestSplitSuggestions.length < 2) { + shouldSplit = bestSplitSuggestions.length > 0; + } else { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + //System.out.print(hoeffdingBound); + //System.out.print(" "); + ///System.out.println(secondBestSuggestion.merit / bestSuggestion.merit); + if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { + shouldSplit = true; + } + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + else { + // TODO pruning is currently disabled + for (int i = 0; i < node.attributeObservers.size(); i++) { + AttributeStatisticsObserver obs = node.attributeObservers.get(i); + if (obs != null) { + if (getModelContext().attribute(i).isNumeric()); + //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); + if (getModelContext().attribute(i).isNominal()); + // TODO nominal class observers + } + } + } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (shouldSplit) { + AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + + SplitNode newSplit = newSplitNode(splitDecision.predicate); + newSplit.copyStatistics(node); + newSplit.changeDetection = node.changeDetection; + newSplit.ID = node.ID; + for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) + LeafNode newChild = newLeafNode(); + if (buildingModelTree()) { + // Copy the splitting node's perceptron to it's children + newChild.learningModel = new MultitargetPerceptron(this, (MultitargetPerceptron) node.learningModel); + + } + newChild.changeDetection = node.changeDetection; + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + parent.setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + } + } + + public double computeSD(double squaredVal, double val, double size) { + if (size > 1) + return Math.sqrt((squaredVal - ((val * val) / size)) / size); + else + return 0.0; + } + + public static double scalarProduct(DoubleVector u, DoubleVector v) { + double ret = 0.0; + for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { + ret += u.getValue(i) * v.getValue(i); + } + return ret; + } + //endregion --- Processing methods + + //endregion ================ METHODS ================ } diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/AttributeExpansionSuggestion.java b/moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java similarity index 95% rename from moa/src/main/java/moa/classifiers/rules/multilabel/core/AttributeExpansionSuggestion.java rename to moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java index b39b52ba0..a1e24bbb6 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/AttributeExpansionSuggestion.java +++ b/moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java @@ -17,10 +17,9 @@ * along with this program. If not, see . * */ -package moa.classifiers.rules.multilabel.core; +package moa.classifiers.rules.core; import moa.AbstractMOAObject; -import moa.classifiers.rules.core.Predicate; import moa.core.DoubleVector; /** diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java index 8014b5e20..2672f58f5 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java @@ -36,13 +36,13 @@ import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiLabelLearner; import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; import moa.classifiers.rules.core.anomalydetection.OddsRatioScore; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; import moa.classifiers.rules.multilabel.core.MultiLabelRule; import moa.classifiers.rules.multilabel.core.MultiLabelRuleSet; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.core.voting.MultiLabelVote; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java index 5b192f525..146a6be85 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java @@ -3,9 +3,9 @@ import moa.classifiers.MultiLabelLearner; import moa.classifiers.MultiTargetRegressor; import moa.classifiers.Regressor; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.core.MultiLabelRule; import moa.classifiers.rules.multilabel.core.MultiLabelRuleRegression; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.core.voting.InverseErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java index a2765587b..4a8a18ccf 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java @@ -11,16 +11,18 @@ import com.yahoo.labs.samoa.instances.MultiLabelInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; + import moa.classifiers.MultiLabelLearner; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.attributeclassobservers.NumericAttributeClassObserver; import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; -import moa.classifiers.rules.multilabel.attributeclassobservers.AttributeStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.errormeasurers.AbstractMultiTargetErrorMeasurer; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java index fb96cae96..26ae4e0d9 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java @@ -15,11 +15,12 @@ import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.driftdetection.ChangeDetector; import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.Utils; -import moa.classifiers.rules.multilabel.attributeclassobservers.AttributeStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.functions.AMRulesFunction; import moa.core.AutoExpandVector; import moa.core.DoubleVector; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java index 9312ce86a..6bd641395 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java @@ -14,13 +14,13 @@ import moa.classifiers.core.conditionaltests.InstanceConditionalTest; import moa.classifiers.core.conditionaltests.NumericAttributeBinaryTest; import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.core.RuleActiveLearningNode; import moa.classifiers.rules.core.RuleSplitNode; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; import moa.classifiers.rules.core.conditionaltests.NumericAttributeBinaryRulePredicate; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; import moa.core.StringUtils; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiTargetVarianceRatio.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiTargetVarianceRatio.java index c9a3a9904..4f64f7c44 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiTargetVarianceRatio.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiTargetVarianceRatio.java @@ -1,5 +1,6 @@ package moa.classifiers.rules.multilabel.core.splitcriteria; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.core.Utils; import moa.core.DoubleVector; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java index 6cb747894..02bd090fd 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java @@ -1,997 +1,3 @@ -<<<<<<< HEAD -/* - * FIMTDD.java - * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia - * @author Aljaž Osojnik - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ - -package moa.classifiers.trees; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -import com.yahoo.labs.samoa.instances.Instance; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; - -import moa.options.ClassOption; -import moa.AbstractMOAObject; -import moa.classifiers.Regressor; -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.conditionaltests.InstanceConditionalTest; -import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.classifiers.AbstractClassifier; -import moa.core.AutoExpandVector; -import moa.core.DoubleVector; -import moa.core.Measurement; -import moa.core.SizeOf; -import moa.core.StringUtils; - -/* - * Implementation of FIMTDD, regression and model trees for data streams. - */ - -public class FIMTDD extends AbstractClassifier implements Regressor { - - private static final long serialVersionUID = 1L; - - protected Node treeRoot; - - protected int leafNodeCount = 0; - protected int splitNodeCount = 0; - - protected double examplesSeen = 0.0; - protected double sumOfValues = 0.0; - protected double sumOfSquares = 0.0; - - protected DoubleVector sumOfAttrValues = new DoubleVector(); - protected DoubleVector sumOfAttrSquares = new DoubleVector(); - - public int maxID = 0; - - //region ================ OPTIONS ================ - - public ClassOption splitCriterionOption = new ClassOption( - "splitCriterion", 's', "Split criterion to use.", - SplitCriterion.class, "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); - - public IntOption gracePeriodOption = new IntOption( - "gracePeriod", 'g', "Number of instances a leaf should observe between split attempts.", - 200, 0, Integer.MAX_VALUE); - - public FloatOption splitConfidenceOption = new FloatOption( - "splitConfidence", 'c', "Allowed error in split decision, values close to 0 will take long to decide.", - 0.0000001, 0.0, 1.0); - - public FloatOption tieThresholdOption = new FloatOption( - "tieThreshold", 't', "Threshold below which a split will be forced to break ties.", - 0.05, 0.0, 1.0); - - public FloatOption PageHinckleyAlphaOption = new FloatOption( - "PageHinckleyAlpha", 'a', "Alpha value to use in the Page Hinckley change detection tests.", - 0.005, 0.0, 1.0); - - public IntOption PageHinckleyThresholdOption = new IntOption( - "PageHinckleyThreshold", 'h', "Threshold value used in the Page Hinckley change detection tests.", - 50, 0, Integer.MAX_VALUE); - - public FloatOption alternateTreeFadingFactorOption = new FloatOption( - "alternateTreeFadingFactor", 'f', "Fading factor used to decide if an alternate tree should replace an original.", - 0.995, 0.0, 1.0); - - public IntOption alternateTreeTMinOption = new IntOption( - "alternateTreeTMin", 'y', "Tmin value used to decide if an alternate tree should replace an original.", - 150, 0, Integer.MAX_VALUE); - - public IntOption alternateTreeTimeOption = new IntOption( - "alternateTreeTime", 'u', "The number of instances used to decide if an alternate tree should be discarded.", - 1500, 0, Integer.MAX_VALUE); - - public FlagOption regressionTreeOption = new FlagOption( - "regressionTree", 'e', "Build a regression tree instead of a model tree."); - - public FloatOption learningRatioOption = new FloatOption( - "learningRatio", 'l', "Learning ratio to used for training the Perceptrons in the leaves.", - 0.003, 0, 1.00); - - public FloatOption learningRateDecayFactorOption = new FloatOption( - "learningRatioDecayFactor", 'd', "Learning rate decay factor (not used when learning rate is constant).", - 0.001, 0, 1.00); - - public FlagOption learningRatioConstOption = new FlagOption( - "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); - - //endregion ================ OPTIONS ================ - - //region ================ CLASSES ================ - - public abstract static class Node extends AbstractMOAObject { - - private static final long serialVersionUID = 1L; - - public int ID; - - protected FIMTDD tree; - - protected boolean changeDetection = true; - - protected Node parent; - - protected Node alternateTree; - protected Node originalNode; - - // The statistics for this node: - // Number of instances that have reached it - protected double examplesSeen; - // Sum of y values - protected double sumOfValues; - // Sum of squared y values - protected double sumOfSquares; - // Sum of absolute errors - protected double sumOfAbsErrors; // Needed for PH tracking of mean error - - public Node(FIMTDD tree) { - this.tree = tree; - ID = tree.maxID; - } - - public void copyStatistics(Node node) { - examplesSeen = node.examplesSeen; - sumOfValues = node.sumOfValues; - sumOfSquares = node.sumOfSquares; - sumOfAbsErrors = node.sumOfAbsErrors; - } - - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); - } - - /** - * Set the parent node - */ - public void setParent(Node parent) { - this.parent = parent; - } - - /** - * Return the parent node - */ - public Node getParent() { - return parent; - } - - public void disableChangeDetection() { - changeDetection = false; - } - - public void restartChangeDetection() { - changeDetection = true; - } - - public void getDescription(StringBuilder sb, int indent) { - - } - - public double getPrediction(Instance inst) { - return 0; - } - - public void describeSubtree(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, "Leaf"); - } - - public int getLevel() { - Node target = this; - int level = 0; - while (target.getParent() != null) { - if (target.skipInLevelCount()) { - target = target.getParent(); - continue; - } - level = level + 1; - target = target.getParent(); - } - if (target.originalNode == null) { - return level; - } else { - return level + originalNode.getLevel(); - } - } - - public void setChild(int parentBranch, Node node) { - } - - public int getChildIndex(Node child) { - return -1; - } - - public int getNumSubtrees() { - return 1; - } - - protected boolean skipInLevelCount() { - return false; - } - } - - public static class LeafNode extends Node { - - private static final long serialVersionUID = 1L; - - public double errorModel = 0.0; - public double errorTargetMean = 0.0; - - // Perceptron model that carries out the actual learning in each node - public FIMTDDPerceptron learningModel; - - protected AutoExpandVector attributeObservers = new AutoExpandVector(); - - protected double examplesSeenAtLastSplitEvaluation = 0; - - /** - * Create a new LeafNode - */ - public LeafNode(FIMTDD tree) { - super(tree); - if (tree.buildingModelTree()) { - learningModel = tree.newLeafModel(); - } - examplesSeen = 0; - sumOfValues = 0; - sumOfSquares = 0; - sumOfAbsErrors = 0; - } - - public void setChild(int parentBranch, Node node) { - } - - public int getChildIndex(Node child) { - return -1; - } - - public int getNumSubtrees() { - return 1; - } - - protected boolean skipInLevelCount() { - return false; - } - - /** - * Method to learn from an instance that passes the new instance to the perceptron learner, - * and also prevents the class value from being truncated to an int when it is passed to the - * attribute observer - */ - public void learnFromInstance(Instance inst, boolean growthAllowed, double prediction) { - //The prediction must be calculated here -- it may be different from the tree's prediction due to alternate trees - - // Update the statistics for this node - // number of instances passing through the node - examplesSeen += inst.weight(); - - // sum of y values - sumOfValues += inst.weight() * inst.classValue(); - - // sum of squared y values - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - - // sum of absolute errors - sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - prediction))); - - if (tree.buildingModelTree()) { - double predictionModel = getPredictionModel(inst); - double predictionTargetMean = getPredictionTargetMean(inst); - - errorModel = errorModel * 0.95 + Math.abs(predictionModel - inst.classValue()); - errorTargetMean = errorTargetMean * 0.95 + Math.abs(predictionTargetMean - inst.classValue()); - - learningModel.updatePerceptron(inst); - } - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); - FIMTDDNumericAttributeClassObserver obs = attributeObservers.get(i); - if (obs == null) { - // At this stage all nominal attributes are ignored - if (inst.attribute(instAttIndex).isNumeric()) { - obs = tree.newNumericClassObserver(); - this.attributeObservers.set(i, obs); - } - } - if (obs != null) { - obs.observeAttributeClass(inst.value(instAttIndex), inst.classValue(), inst.weight()); - } - } - - if (growthAllowed) { - checkForSplit(); - } - } - - /** - * Return the best split suggestions for this node using the given split criteria - */ - public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion) { - - List bestSuggestions = new LinkedList(); - - // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution - double[] nodeSplitDist = new double[] {examplesSeen, sumOfValues, sumOfSquares}; - - for (int i = 0; i < this.attributeObservers.size(); i++) { - FIMTDDNumericAttributeClassObserver obs = this.attributeObservers.get(i); - if (obs != null) { - - // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED - AttributeSplitSuggestion bestSuggestion = null; - if (obs instanceof FIMTDDNumericAttributeClassObserver) { - bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, nodeSplitDist, i, true); - } - - if (bestSuggestion != null) { - bestSuggestions.add(bestSuggestion); - } - } - } - return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); - } - - /** - * Retrieve the class votes using the perceptron learner - */ - public double getPredictionModel(Instance inst) { - return learningModel.prediction(inst); - } - - public double getPredictionTargetMean(Instance inst) { - return (examplesSeen > 0.0) ? sumOfValues / examplesSeen : 0.0; - } - - public double getPrediction(Instance inst) { - if (tree.buildingModelTree()) { - //return getPredictionModel(inst); - return (errorModel < errorTargetMean) ? getPredictionModel(inst) : getPredictionTargetMean(inst); - } else - return getPredictionTargetMean(inst); - } - - public void checkForSplit() { - // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node - if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { - int index = (parent != null) ? parent.getChildIndex(this) : 0; - tree.attemptToSplit(this, parent, index); - - // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation - examplesSeenAtLastSplitEvaluation = examplesSeen; - } - } - - public void describeSubtree(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, "Leaf "); - if (tree.buildingModelTree()) { - learningModel.getModelDescription(out, 0); - } else { - out.append(tree.getClassNameString() + " = " + String.format("%.4f", sumOfValues / examplesSeen)); - StringUtils.appendNewline(out); - } - } - } - - public abstract static class InnerNode extends Node { - // The InnerNode and SplitNode design is used for easy extension in ORTO - private static final long serialVersionUID = 1L; - - protected AutoExpandVector children = new AutoExpandVector(); - - // The error values for the Page Hinckley test - // PHmT = the cumulative sum of the errors - // PHMT = the minimum error value seen so far - protected double PHsum = 0; - protected double PHmin = Double.MAX_VALUE; - - // Keep track of the statistics for loss error calculations - protected double lossExamplesSeen; - protected double lossFadedSumOriginal; - protected double lossFadedSumAlternate; - protected double lossNumQiTests; - protected double lossSumQi; - protected double previousWeight = 0; - - public InnerNode(FIMTDD tree) { - super(tree); - } - - public int numChildren() { - return children.size(); - } - - public Node getChild(int index) { - return children.get(index); - } - - public int getChildIndex(Node child) { - return children.indexOf(child); - } - - public void setChild(int index, Node child) { - children.set(index, child); - } - - public void disableChangeDetection() { - changeDetection = false; - for (Node child : children) { - child.disableChangeDetection(); - } - } - - public void restartChangeDetection() { - if (alternateTree == null) { - changeDetection = true; - PHsum = 0; - PHmin = Integer.MAX_VALUE; - for (Node child : children) - child.restartChangeDetection(); - } - } - - /** - * Check to see if the tree needs updating - */ - public boolean PageHinckleyTest(double error, double threshold) { - // Update the cumulative mT sum - PHsum += error; - - // Update the minimum mT value if the new mT is - // smaller than the current minimum - if(PHsum < PHmin) { - PHmin = PHsum; - } - // Return true if the cumulative value - the current minimum is - // greater than the current threshold (in which case we should adapt) - return PHsum - PHmin > threshold; - } - - public void initializeAlternateTree() { - // Start a new alternate tree, beginning with a learning node - alternateTree = tree.newLeafNode(); - alternateTree.originalNode = this; - - // Set up the blank statistics - // Number of instances reaching this node since the alternate tree was started - lossExamplesSeen = 0; - // Faded squared error (original tree) - lossFadedSumOriginal = 0; - // Faded squared error (alternate tree) - lossFadedSumAlternate = 0; - // Number of evaluations of alternate tree - lossNumQiTests = 0; - // Sum of Qi values - lossSumQi = 0; - // Number of examples at last test - previousWeight = 0; - - // Disable the change detection mechanism bellow this node - disableChangeDetection(); - } - } - - public static class SplitNode extends InnerNode { - - private static final long serialVersionUID = 1L; - - protected InstanceConditionalTest splitTest; - - /** - * Create a new SplitNode - * @param tree - */ - public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { - super(tree); - this.splitTest = splitTest; - } - - public int instanceChildIndex(Instance inst) { - return splitTest.branchForInstance(inst); - } - - public Node descendOneStep(Instance inst) { - return children.get(splitTest.branchForInstance(inst)); - } - - public void describeSubtree(StringBuilder out, int indent) { - for (int branch = 0; branch < children.size(); branch++) { - Node child = getChild(branch); - if (child != null) { - StringUtils.appendIndented(out, indent, "if "); - out.append(this.splitTest.describeConditionForBranch(branch, - tree.getModelContext())); - out.append(": "); - StringUtils.appendNewline(out); - child.describeSubtree(out, indent + 2); - } - } - } - - public double getPrediction(Instance inst) { - return children.get(splitTest.branchForInstance(inst)).getPrediction(inst); - } - } - - public class FIMTDDPerceptron implements Serializable { - - private static final long serialVersionUID = 1L; - - protected FIMTDD tree; - - // The Perception weights - protected double[] weightAttribute; - - // The number of instances contributing to this model - protected double instancesSeen = 0; - - public String getPurposeString() { - return "A perceptron regressor as specified by Ikonomovska et al. used for FIMTDD"; - } - - public FIMTDDPerceptron(FIMTDDPerceptron original) { - this.tree = original.tree; - weightAttribute = original.weightAttribute.clone(); - } - - public FIMTDDPerceptron(FIMTDD tree) { - this.tree = tree; - initializeWeights(); - - } - - public void initializeWeights() { - weightAttribute = new double[tree.getModelContext().numInputAttributes()+1]; - instancesSeen = 0; - for (int j = 0; j < tree.getModelContext().numInputAttributes()+1; j++) { - // The last index corresponds to the constant b - weightAttribute[j] = 2 * tree.classifierRandom.nextDouble() - 1; - } - normalizeWeights(); - } - - /** - * Update the model using the provided instance - */ - public void updatePerceptron(Instance inst) { - - // Update attribute statistics - instancesSeen += inst.weight(); - - // Update weights - double learningRatio = 0.0; - if (tree.learningRatioConstOption.isSet()) { - learningRatio = learningRatioOption.getValue(); - } else { - learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); - } - - // Loop for compatibility with bagging methods - for (int i = 0; i < (int) inst.weight(); i++) { - updateWeights(inst, learningRatio); - } - - } - - public void updateWeights(Instance inst, double learningRatio) { - // Compute the normalized instance and the delta - double[] normalizedInstance = normalizedInstance(inst); - double normalizedPrediction = prediction(normalizedInstance); - double normalizedValue = tree.normalizeTargetValue(inst.classValue()); - double delta = normalizedValue - normalizedPrediction; - for (int i = 0; i < weightAttribute.length; i++) { - weightAttribute[i] += delta * learningRatio * normalizedInstance[i]; - } - - normalizeWeights(); - } - - public void normalizeWeights() { - double sum = 0; - for (int i = 0; i < this.weightAttribute.length; i++) - sum += Math.abs(weightAttribute[i]); - for (int i = 0; i < this.weightAttribute.length; i++) - weightAttribute[i] /= sum; - } - - public double[] normalizedInstance(Instance inst) { - // Normalize Instance - double[] normalizedInstance = new double[inst.numInputAttributes()+1]; - for (int j = 0; j < inst.numInputAttributes(); j++) { - double mean = tree.sumOfAttrValues.getValue(j) / tree.examplesSeen; - double sd = computeSD(tree.sumOfAttrSquares.getValue(j), tree.sumOfAttrValues.getValue(j), tree.examplesSeen); - if (inst.inputAttribute(j).isNumeric() && tree.examplesSeen > 1 && sd > 0.0000001) - normalizedInstance[j] = (inst.valueInputAttribute(j) - mean) / (sd); - else - normalizedInstance[j] = 0; - } - normalizedInstance[inst.numInputAttributes()] = tree.examplesSeen > 1 ? 1 : 0; // Value to be multiplied with the constant factor - return normalizedInstance; - } - - /** - * Output the prediction made by this perceptron on the given instance - */ - public double prediction(double[] instanceValues) { - double ret = 0; - for (int i = 0; i < instanceValues.length; i++) - ret += instanceValues[i] * weightAttribute[i]; - return ret; - } - - protected double prediction(Instance inst) { - double[] normalizedInstance = normalizedInstance(inst); - double normalizedPrediction = prediction(normalizedInstance); - return denormalizePrediction(normalizedPrediction); - } - - private double denormalizePrediction(double normalizedPrediction) { - double mean = tree.sumOfValues / tree.examplesSeen; - double sd = computeSD(tree.sumOfSquares, tree.sumOfValues, tree.examplesSeen); - if (examplesSeen > 1) - return normalizedPrediction * sd + mean; - else - return 0.0; - } - - public void getModelDescription(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, getClassNameString() + " ="); - if (getModelContext() != null) { - for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { - if (getModelContext().attribute(j).isNumeric()) { - out.append((j == 0 || weightAttribute[j] < 0) ? " " : " + "); - out.append(String.format("%.4f", weightAttribute[j])); - out.append(" * "); - out.append(getAttributeNameString(j)); - } - } - out.append(" + " + weightAttribute[getModelContext().numInputAttributes()]); - } - StringUtils.appendNewline(out); - } - } - - - //endregion ================ CLASSES ================ - - //region ================ METHODS ================ - - // region --- Regressor methods - - public String getPurposeString() { - return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; - } - - public void resetLearningImpl() { - this.treeRoot = null; - this.leafNodeCount = 0; - this.splitNodeCount = 0; - this.maxID = 0; - this.examplesSeen = 0; - this.sumOfValues = 0.0; - this.sumOfSquares = 0.0; - - this.sumOfAttrValues = new DoubleVector(); - this.sumOfAttrSquares = new DoubleVector(); - } - - public boolean isRandomizable() { - return true; - } - - public void getModelDescription(StringBuilder out, int indent) { - if (treeRoot != null) treeRoot.describeSubtree(out, indent); - } - - protected Measurement[] getModelMeasurementsImpl() { - return new Measurement[]{ - new Measurement("tree size (leaves)", this.leafNodeCount) - }; - } - - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); - } - - public double[] getVotesForInstance(Instance inst) { - if (treeRoot == null) { - return new double[] {0}; - } - - double prediction = treeRoot.getPrediction(inst); - - return new double[] {prediction}; - } - - public double normalizeTargetValue(double value) { - if (examplesSeen > 1) { - double sd = Math.sqrt((sumOfSquares - ((sumOfValues * sumOfValues)/examplesSeen))/examplesSeen); - double average = sumOfValues / examplesSeen; - if (sd > 0 && examplesSeen > 1) - return (value - average) / sd; - else - return 0.0; - } - return 0.0; - } - - public double getNormalizedError(Instance inst, double prediction) { - double normalPrediction = normalizeTargetValue(prediction); - double normalValue = normalizeTargetValue(inst.classValue()); - return Math.abs(normalValue - normalPrediction); - } - - - /** - * Method for updating (training) the model using a new instance - */ - public void trainOnInstanceImpl(Instance inst) { - checkRoot(); - - double prediction = treeRoot.getPrediction(inst); - double normalError = getNormalizedError(inst, prediction); - - processInstance(inst, treeRoot, prediction, normalError, true, false); - - examplesSeen += inst.weight(); - sumOfValues += inst.weight() * inst.classValue(); - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int aIndex = modelAttIndexToInstanceAttIndex(i, inst); - sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); - sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); - } - - - } - - public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { - Node currentNode = node; - while (true) { - if (currentNode instanceof LeafNode) { - ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); - break; - } else { - currentNode.examplesSeen += inst.weight(); - currentNode.sumOfAbsErrors += inst.weight() * normalError; - InnerNode iNode = (InnerNode) currentNode; - if (!inAlternate && iNode.alternateTree != null) { - boolean altTree = true; - double lossO = Math.pow(inst.classValue() - prediction, 2); - double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); - - // Loop for compatibility with bagging methods - for (int i = 0; i < inst.weight(); i++) { - iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; - iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; - iNode.lossExamplesSeen++; - - double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - iNode.lossSumQi += Qi; - iNode.lossNumQiTests += 1; - } - double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - - if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { - iNode.previousWeight = iNode.lossExamplesSeen; - if (Qi > 0) { - // Switch the subtrees - Node parent = iNode.getParent(); - - if (parent != null) { - Node replacementTree = iNode.alternateTree; - parent.setChild(parent.getChildIndex(iNode), replacementTree); - if (growthAllowed) replacementTree.restartChangeDetection(); - } else { - treeRoot = iNode.alternateTree; - treeRoot.restartChangeDetection(); - } - - currentNode = iNode.alternateTree; - currentNode.originalNode = null; - altTree = false; - } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { - // Remove the alternate tree - iNode.alternateTree = null; - if (growthAllowed) iNode.restartChangeDetection(); - altTree = false; - } - } - - if (altTree) { - growthAllowed = false; - processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); - } - } - - if (false && iNode.changeDetection && !inAlternate) { - if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { - iNode.initializeAlternateTree(); - growthAllowed = false; - } - } - if (currentNode instanceof SplitNode) { - currentNode = ((SplitNode) currentNode).descendOneStep(inst); - } - } - } - } - - // endregion --- Regressor methods - - // region --- Object instatiation methods - - protected FIMTDDNumericAttributeClassObserver newNumericClassObserver() { - return new FIMTDDNumericAttributeClassObserver(); - } - - protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { - maxID++; - return new SplitNode(splitTest, this); - } - - protected LeafNode newLeafNode() { - maxID++; - return new LeafNode(this); - } - - protected FIMTDDPerceptron newLeafModel() { - return new FIMTDDPerceptron(this); - } - - //endregion --- Object instatiation methods - - // region --- Processing methods - - protected void checkRoot() { - if (treeRoot == null) { - treeRoot = newLeafNode(); - leafNodeCount = 1; - } - } - - public static double computeHoeffdingBound(double range, double confidence, double n) { - return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); - } - - public boolean buildingModelTree() { - return !regressionTreeOption.isSet(); - } - - protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { - - // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); - - // Using this criterion, find the best split per attribute and rank the results - AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); - Arrays.sort(bestSplitSuggestions); - - // Declare a variable to determine if any of the splits should be performed - boolean shouldSplit = false; - - // If only one split was returned, use it - if (bestSplitSuggestions.length < 2) { - shouldSplit = bestSplitSuggestions.length > 0; - } else { // Otherwise, consider which of the splits proposed may be worth trying - - // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, this.splitConfidenceOption.getValue(), node.examplesSeen); - // Determine the top two ranked splitting suggestions - AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - - // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), - // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this - // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and - // splitting should occur. - // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit - // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two - // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { - shouldSplit = true; - } - // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - else { - for (int i = 0; i < node.attributeObservers.size(); i++) { - FIMTDDNumericAttributeClassObserver obs = node.attributeObservers.get(i); - if (obs != null) { - obs.removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); - } - } - } -// if (hoeffdingBound < this.tieThresholdOption.getValue() && !(secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound)) { -// System.out.println("Forced to split due to tie at " + this.examplesSeen); -// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); -// } - } - - // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (shouldSplit) { -// System.out.println("splitting node"); -// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); -// if (node.parent == null) { -// System.out.println("splitting root node at " + this.examplesSeen); -// } - AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - - SplitNode newSplit = newSplitNode(splitDecision.splitTest); - newSplit.copyStatistics(node); - newSplit.changeDetection = node.changeDetection; - newSplit.ID = node.ID; - leafNodeCount--; - for (int i = 0; i < splitDecision.numSplits(); i++) { - LeafNode newChild = newLeafNode(); - if (buildingModelTree()) { - // Copy the splitting node's perceptron to it's children - newChild.learningModel = new FIMTDDPerceptron((FIMTDDPerceptron) node.learningModel); - - } - newChild.changeDetection = node.changeDetection; - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - leafNodeCount++; - } - if (parent == null && node.originalNode == null) { - treeRoot = newSplit; - } else if (parent == null && node.originalNode != null) { - node.originalNode.alternateTree = newSplit; - } else { - ((SplitNode) parent).setChild(parentIndex, newSplit); - newSplit.setParent(parent); - } - - splitNodeCount++; - } - } - - public double computeSD(double squaredVal, double val, double size) { - if (size > 1) - return Math.sqrt((squaredVal - ((val * val) / size)) / size); - else - return 0.0; - } - - public double scalarProduct(DoubleVector u, DoubleVector v) { - double ret = 0.0; - for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { - ret += u.getValue(i) * v.getValue(i); - } - return ret; - } - //endregion --- Processing methods - - //endregion ================ METHODS ================ -} - -======= /* * FIMTDD.java * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia @@ -1103,7 +109,7 @@ public class FIMTDD extends AbstractClassifier implements Regressor { public FloatOption learningRatioOption = new FloatOption( "learningRatio", 'l', "Learning ratio to used for training the Perceptrons in the leaves.", - 0.02, 0, 1.00); + 0.003, 0, 1.00); public FloatOption learningRateDecayFactorOption = new FloatOption( "learningRatioDecayFactor", 'd', "Learning rate decay factor (not used when learning rate is constant).", @@ -1229,6 +235,9 @@ public static class LeafNode extends Node { private static final long serialVersionUID = 1L; + public double errorModel = 0.0; + public double errorTargetMean = 0.0; + // Perceptron model that carries out the actual learning in each node public FIMTDDPerceptron learningModel; @@ -1270,7 +279,7 @@ protected boolean skipInLevelCount() { * and also prevents the class value from being truncated to an int when it is passed to the * attribute observer */ - public void learnFromInstance(Instance inst, boolean growthAllowed) { + public void learnFromInstance(Instance inst, boolean growthAllowed, double prediction) { //The prediction must be calculated here -- it may be different from the tree's prediction due to alternate trees // Update the statistics for this node @@ -1284,9 +293,17 @@ public void learnFromInstance(Instance inst, boolean growthAllowed) { sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); // sum of absolute errors - sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - getPrediction(inst)))); - - if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); + sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - prediction))); + + if (tree.buildingModelTree()) { + double predictionModel = getPredictionModel(inst); + double predictionTargetMean = getPredictionTargetMean(inst); + + errorModel = errorModel * 0.95 + Math.abs(predictionModel - inst.classValue()); + errorTargetMean = errorTargetMean * 0.95 + Math.abs(predictionTargetMean - inst.classValue()); + + learningModel.updatePerceptron(inst); + } for (int i = 0; i < inst.numAttributes() - 1; i++) { int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); @@ -1304,7 +321,7 @@ public void learnFromInstance(Instance inst, boolean growthAllowed) { } if (growthAllowed) { - checkForSplit(tree); + checkForSplit(); } } @@ -1348,10 +365,14 @@ public double getPredictionTargetMean(Instance inst) { } public double getPrediction(Instance inst) { - return (tree.buildingModelTree()) ? getPredictionModel(inst) : getPredictionTargetMean(inst); + if (tree.buildingModelTree()) { + //return getPredictionModel(inst); + return (errorModel < errorTargetMean) ? getPredictionModel(inst) : getPredictionTargetMean(inst); + } else + return getPredictionTargetMean(inst); } - public void checkForSplit(FIMTDD tree) { + public void checkForSplit() { // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { int index = (parent != null) ? parent.getChildIndex(this) : 0; @@ -1367,7 +388,7 @@ public void describeSubtree(StringBuilder out, int indent) { if (tree.buildingModelTree()) { learningModel.getModelDescription(out, 0); } else { - out.append(tree.getClassNameString() + " = " + String.format("%.4f", (sumOfValues / examplesSeen))); + out.append(tree.getClassNameString() + " = " + String.format("%.4f", sumOfValues / examplesSeen)); StringUtils.appendNewline(out); } } @@ -1520,52 +541,41 @@ public class FIMTDDPerceptron implements Serializable { protected FIMTDD tree; // The Perception weights - protected DoubleVector weightAttribute = new DoubleVector(); - - protected double sumOfValues; - protected double sumOfSquares; + protected double[] weightAttribute; // The number of instances contributing to this model protected double instancesSeen = 0; - // If the model should be reset or not - protected boolean reset; - public String getPurposeString() { return "A perceptron regressor as specified by Ikonomovska et al. used for FIMTDD"; } public FIMTDDPerceptron(FIMTDDPerceptron original) { this.tree = original.tree; - weightAttribute = (DoubleVector) original.weightAttribute.copy(); - reset = false; + weightAttribute = original.weightAttribute.clone(); } public FIMTDDPerceptron(FIMTDD tree) { this.tree = tree; - reset = true; - } - + initializeWeights(); - public DoubleVector getWeights() { - return weightAttribute; } + public void initializeWeights() { + weightAttribute = new double[tree.getModelContext().numInputAttributes()+1]; + instancesSeen = 0; + for (int j = 0; j < tree.getModelContext().numInputAttributes()+1; j++) { + // The last index corresponds to the constant b + weightAttribute[j] = 2 * tree.classifierRandom.nextDouble() - 1; + } + normalizeWeights(); + } + /** * Update the model using the provided instance */ public void updatePerceptron(Instance inst) { - // Initialize perceptron if necessary - if (reset == true) { - reset = false; - weightAttribute = new DoubleVector(); - instancesSeen = 0; - for (int j = 0; j < inst.numAttributes(); j++) { // The last index corresponds to the constant b - weightAttribute.setValue(j, 2 * tree.classifierRandom.nextDouble() - 1); - } - } - // Update attribute statistics instancesSeen += inst.weight(); @@ -1577,63 +587,70 @@ public void updatePerceptron(Instance inst) { learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); } - sumOfValues += inst.weight() * inst.classValue(); - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - // Loop for compatibility with bagging methods for (int i = 0; i < (int) inst.weight(); i++) { updateWeights(inst, learningRatio); } + } public void updateWeights(Instance inst, double learningRatio) { // Compute the normalized instance and the delta - DoubleVector normalizedInstance = normalizedInstance(inst); + double[] normalizedInstance = normalizedInstance(inst); double normalizedPrediction = prediction(normalizedInstance); double normalizedValue = tree.normalizeTargetValue(inst.classValue()); double delta = normalizedValue - normalizedPrediction; - normalizedInstance.scaleValues(delta * learningRatio); + for (int i = 0; i < weightAttribute.length; i++) { + weightAttribute[i] += delta * learningRatio * normalizedInstance[i]; + } - weightAttribute.addValues(normalizedInstance); + normalizeWeights(); + } + + public void normalizeWeights() { + double sum = 0; + for (int i = 0; i < this.weightAttribute.length; i++) + sum += Math.abs(weightAttribute[i]); + for (int i = 0; i < this.weightAttribute.length; i++) + weightAttribute[i] /= sum; } - public DoubleVector normalizedInstance(Instance inst) { + public double[] normalizedInstance(Instance inst) { // Normalize Instance - DoubleVector normalizedInstance = new DoubleVector(); - for (int j = 0; j < inst.numAttributes() - 1; j++) { - int instAttIndex = modelAttIndexToInstanceAttIndex(j, inst); + double[] normalizedInstance = new double[inst.numInputAttributes()+1]; + for (int j = 0; j < inst.numInputAttributes(); j++) { double mean = tree.sumOfAttrValues.getValue(j) / tree.examplesSeen; double sd = computeSD(tree.sumOfAttrSquares.getValue(j), tree.sumOfAttrValues.getValue(j), tree.examplesSeen); - if (inst.attribute(instAttIndex).isNumeric() && tree.examplesSeen > 1 && sd > 0) - normalizedInstance.setValue(j, (inst.value(instAttIndex) - mean) / (3 * sd)); + if (inst.inputAttribute(j).isNumeric() && tree.examplesSeen > 1 && sd > 0.0000001) + normalizedInstance[j] = (inst.valueInputAttribute(j) - mean) / (sd); else - normalizedInstance.setValue(j, 0); + normalizedInstance[j] = 0; } - if (tree.examplesSeen > 1) - normalizedInstance.setValue(inst.numAttributes() - 1, 1.0); // Value to be multiplied with the constant factor - else - normalizedInstance.setValue(inst.numAttributes() - 1, 0.0); + normalizedInstance[inst.numInputAttributes()] = tree.examplesSeen > 1 ? 1 : 0; // Value to be multiplied with the constant factor return normalizedInstance; } /** * Output the prediction made by this perceptron on the given instance */ - public double prediction(DoubleVector instanceValues) { - return scalarProduct(weightAttribute, instanceValues); + public double prediction(double[] instanceValues) { + double ret = 0; + for (int i = 0; i < instanceValues.length; i++) + ret += instanceValues[i] * weightAttribute[i]; + return ret; } protected double prediction(Instance inst) { - DoubleVector normalizedInstance = normalizedInstance(inst); + double[] normalizedInstance = normalizedInstance(inst); double normalizedPrediction = prediction(normalizedInstance); - return denormalizePrediction(normalizedPrediction, tree); + return denormalizePrediction(normalizedPrediction); } - private double denormalizePrediction(double normalizedPrediction, FIMTDD tree) { + private double denormalizePrediction(double normalizedPrediction) { double mean = tree.sumOfValues / tree.examplesSeen; double sd = computeSD(tree.sumOfSquares, tree.sumOfValues, tree.examplesSeen); if (examplesSeen > 1) - return normalizedPrediction * sd * 3 + mean; + return normalizedPrediction * sd + mean; else return 0.0; } @@ -1643,13 +660,13 @@ public void getModelDescription(StringBuilder out, int indent) { if (getModelContext() != null) { for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { if (getModelContext().attribute(j).isNumeric()) { - out.append((j == 0 || weightAttribute.getValue(j) < 0) ? " " : " + "); - out.append(String.format("%.4f", weightAttribute.getValue(j))); + out.append((j == 0 || weightAttribute[j] < 0) ? " " : " + "); + out.append(String.format("%.4f", weightAttribute[j])); out.append(" * "); out.append(getAttributeNameString(j)); } } - out.append(" + " + weightAttribute.getValue((getModelContext().numAttributes() - 1))); + out.append(" + " + weightAttribute[getModelContext().numInputAttributes()]); } StringUtils.appendNewline(out); } @@ -1712,7 +729,7 @@ public double normalizeTargetValue(double value) { double sd = Math.sqrt((sumOfSquares - ((sumOfValues * sumOfValues)/examplesSeen))/examplesSeen); double average = sumOfValues / examplesSeen; if (sd > 0 && examplesSeen > 1) - return (value - average) / (3 * sd); + return (value - average) / sd; else return 0.0; } @@ -1732,6 +749,11 @@ public double getNormalizedError(Instance inst, double prediction) { public void trainOnInstanceImpl(Instance inst) { checkRoot(); + double prediction = treeRoot.getPrediction(inst); + double normalError = getNormalizedError(inst, prediction); + + processInstance(inst, treeRoot, prediction, normalError, true, false); + examplesSeen += inst.weight(); sumOfValues += inst.weight() * inst.classValue(); sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); @@ -1742,20 +764,19 @@ public void trainOnInstanceImpl(Instance inst) { sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); } - double prediction = treeRoot.getPrediction(inst); - processInstance(inst, treeRoot, prediction, getNormalizedError(inst, prediction), true, false); + } public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { Node currentNode = node; while (true) { if (currentNode instanceof LeafNode) { - ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); break; } else { currentNode.examplesSeen += inst.weight(); currentNode.sumOfAbsErrors += inst.weight() * normalError; - SplitNode iNode = (SplitNode) currentNode; + InnerNode iNode = (InnerNode) currentNode; if (!inAlternate && iNode.alternateTree != null) { boolean altTree = true; double lossO = Math.pow(inst.classValue() - prediction, 2); @@ -1779,11 +800,11 @@ public void processInstance(Instance inst, Node node, double prediction, double iNode.previousWeight = iNode.lossExamplesSeen; if (Qi > 0) { // Switch the subtrees - Node parent = currentNode.getParent(); + Node parent = iNode.getParent(); if (parent != null) { Node replacementTree = iNode.alternateTree; - parent.setChild(parent.getChildIndex(currentNode), replacementTree); + parent.setChild(parent.getChildIndex(iNode), replacementTree); if (growthAllowed) replacementTree.restartChangeDetection(); } else { treeRoot = iNode.alternateTree; @@ -1793,10 +814,7 @@ public void processInstance(Instance inst, Node node, double prediction, double currentNode = iNode.alternateTree; currentNode.originalNode = null; altTree = false; - } else if ( - (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) - || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() - ) { + } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { // Remove the alternate tree iNode.alternateTree = null; if (growthAllowed) iNode.restartChangeDetection(); @@ -1813,6 +831,7 @@ public void processInstance(Instance inst, Node node, double prediction, double if (iNode.changeDetection && !inAlternate) { if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { iNode.initializeAlternateTree(); + growthAllowed = false; } } if (currentNode instanceof SplitNode) { @@ -1864,8 +883,9 @@ public boolean buildingModelTree() { } protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); + SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); // Using this criterion, find the best split per attribute and rank the results AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); @@ -1911,7 +931,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { // make two new branches leading to (empty) leaves if (shouldSplit) { AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - + SplitNode newSplit = newSplitNode(splitDecision.splitTest); newSplit.copyStatistics(node); newSplit.changeDetection = node.changeDetection; @@ -1959,6 +979,4 @@ public double scalarProduct(DoubleVector u, DoubleVector v) { //endregion --- Processing methods //endregion ================ METHODS ================ -} - ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +} \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index 2745dcc7e..2f7ca3d52 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -35,16 +35,11 @@ import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.splitcriteria.SplitCriterion; -<<<<<<< HEAD -import moa.classifiers.trees.FIMTDD.InnerNode; -import moa.classifiers.trees.FIMTDD.Node; + import moa.core.AutoExpandVector; import moa.core.Measurement; import moa.core.StringUtils; -======= -import moa.core.AutoExpandVector; -import moa.core.Measurement; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + /* * Implementation of ORTO, option trees for data streams. @@ -127,15 +122,9 @@ public int getNumSubtrees() { public int directionForBestTree() { int d = 0; -<<<<<<< HEAD - double min = Double.MAX_VALUE; - for (int i = 0; i < numChildren(); i++) { - double tmp = getFFRatio(i); -======= double tmp = 0.0, min = Double.MAX_VALUE; for (int i = 0; i < children.size(); i++) { tmp = getFFRatio(i); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (tmp < min) { min = tmp; d = i; @@ -144,38 +133,22 @@ public int directionForBestTree() { return d; } -<<<<<<< HEAD public double getPrediction(Instance inst) { -======= - public double getPrediction(Instance inst, ORTO tree) { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa double[] predictions = new double[numChildren()]; for (int i = 0; i < numChildren(); i++) { predictions[i] = getChild(i).getPrediction(inst); } -<<<<<<< HEAD return aggregate(predictions); } private double aggregate(double[] predictions) { if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average -======= - return aggregate(predictions, tree); - } - - private double aggregate(double[] predictions, ORTO tree) { - if (tree.optionNodeAggregationOption.getChosenIndex() == 0) { // Average ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa double sum = 0.0; for (int i = 0; i < predictions.length; i++) { sum += predictions[i]; } return sum / predictions.length; -<<<<<<< HEAD } else if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 1) { -======= - } else if (tree.optionNodeAggregationOption.getChosenIndex() == 1) { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa int d = directionForBestTree(); return predictions[d]; } else { @@ -190,7 +163,6 @@ public double getFFRatio(int childIndex) { protected boolean skipInLevelCount() { return true; } -<<<<<<< HEAD @Override public void describeSubtree(StringBuilder out, int indent) { @@ -203,8 +175,7 @@ public void describeSubtree(StringBuilder out, int indent) { split.describeSubtree(out, indent + 2); } } -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + } //endregion ================ CLASSES ================ @@ -239,11 +210,7 @@ public void processInstance(Instance inst, Node node, double prediction, double Node currentNode = node; while (true) { if (currentNode instanceof LeafNode) { -<<<<<<< HEAD ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); -======= - ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa break; } else { currentNode.examplesSeen += inst.weight(); @@ -252,11 +219,7 @@ public void processInstance(Instance inst, Node node, double prediction, double if (!inAlternate && iNode.alternateTree != null) { boolean altTree = true; double lossO = Math.pow(inst.classValue() - prediction, 2); -<<<<<<< HEAD double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); -======= - double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { @@ -276,11 +239,7 @@ public void processInstance(Instance inst, Node node, double prediction, double iNode.previousWeight = iNode.lossExamplesSeen; if (Qi > 0) { // Switch the subtrees -<<<<<<< HEAD Node parent = iNode.getParent(); -======= - Node parent = currentNode.parent; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (parent != null) { Node replacementTree = iNode.alternateTree; @@ -290,11 +249,7 @@ public void processInstance(Instance inst, Node node, double prediction, double treeRoot = iNode.alternateTree; treeRoot.restartChangeDetection(); } -<<<<<<< HEAD optionNodeCount += iNode.alternateTree.getNumSubtrees() - iNode.getNumSubtrees(); -======= - optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa removeExcessTrees(); currentNode = iNode.alternateTree; @@ -309,11 +264,7 @@ public void processInstance(Instance inst, Node node, double prediction, double } if (altTree) { growthAllowed = false; // this is the growth of the original tree -<<<<<<< HEAD processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree -======= - processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } else if (currentNode instanceof OptionNode) { // this happens when an option node is switched into the tree for (Node child : ((OptionNode) currentNode).children) { @@ -341,35 +292,23 @@ public void processInstance(Instance inst, Node node, double prediction, double } public void processInstanceOptionNode(Instance inst, OptionNode node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { -<<<<<<< HEAD node.examplesSeen += inst.weight(); node.sumOfAbsErrors += inst.weight() * normalError; -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + if (node.changeDetection) { double error = Math.abs(prediction - inst.classValue()); node.sumOfAbsErrors += error; if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { node.initializeAlternateTree(); -<<<<<<< HEAD growthAllowed = false; -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } for (Node child : node.children) { int index = node.getChildIndex(child); double childPrediction = child.getPrediction(inst); -<<<<<<< HEAD - node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; - node.optionFFSSL[index] = node.optionFFSSL[index] * optionFadingFactorOption.getValue() + Math.pow(childPrediction - inst.classValue(), 2); - } - for (Node child : node.children) { - processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); -======= // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; @@ -379,7 +318,6 @@ public void processInstanceOptionNode(Instance inst, OptionNode node, double pre for (Node child : node.children) { processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } @@ -397,10 +335,6 @@ protected OptionNode newOptionNode() { // region --- Processing methods protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Initialize the split criterion SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); @@ -408,11 +342,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); List acceptedSplits = new LinkedList(); Arrays.sort(bestSplitSuggestions); -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Declare a variable to determine the number of splits to be performed int numSplits = 0; @@ -430,10 +360,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and @@ -445,7 +372,6 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { numSplits = 1; acceptedSplits.add(bestSuggestion); } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { -<<<<<<< HEAD for (int i = 0; i < bestSplitSuggestions.length; i++) { AttributeSplitSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { @@ -456,15 +382,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { } } - -======= - for (AttributeSplitSuggestion suggestion : bestSplitSuggestions) { - if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { - numSplits++; - acceptedSplits.add(suggestion); - } - } ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + } else if (hoeffdingBound < tieThresholdOption.getValue()) { numSplits = 1; acceptedSplits.add(bestSplitSuggestions[0]); @@ -483,11 +401,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (numSplits > 0) { double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); -<<<<<<< HEAD - if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 0) { -======= if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa AttributeSplitSuggestion splitDecision = acceptedSplits.get(0); SplitNode newSplit = newSplitNode(splitDecision.splitTest); for (int i = 0; i < splitDecision.numSplits(); i++) { @@ -498,19 +412,12 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { leafNodeCount--; innerNodeCount++; leafNodeCount += splitDecision.numSplits(); -<<<<<<< HEAD if (parent == null && node.originalNode == null) { treeRoot = newSplit; } else if (parent == null && node.originalNode != null) { node.originalNode.alternateTree = newSplit; } else { parent.setChild(parentIndex, newSplit); -======= - if (parent == null) { - treeRoot = newSplit; - } else { - parent.setChild(parent.getChildIndex(node), newSplit); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa newSplit.setParent(parent); } } else { @@ -544,11 +451,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (parent == null) { treeRoot = optionNode; } else { -<<<<<<< HEAD parent.setChild(parentIndex, optionNode); -======= - parent.setChild(parent.getChildIndex(node), optionNode); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa optionNode.setParent(parent); } @@ -631,8 +534,4 @@ protected void removeExcessTrees() { // endregion --- Option tree methods //endregion ================ METHODS ================ -<<<<<<< HEAD -} -======= } ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index 4202599c6..61f2ee877 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -154,7 +154,6 @@ protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { int secondsElapsed = 0; monitor.setCurrentActivity("Evaluating learner...", -1.0); -<<<<<<< HEAD File dumpFile = this.dumpFileOption.getFile(); PrintStream immediateResultStream = null; if (dumpFile != null) { @@ -208,63 +207,7 @@ protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); } outputPredictionResultStream.println(prediction + "," + sb.toString()); - } -======= - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - //File for output predictions - File outputPredictionFile = this.outputPredictionFileOption.getFile(); - PrintStream outputPredictionResultStream = null; - if (outputPredictionFile != null) { - try { - if (outputPredictionFile.exists()) { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile, true), true); - } else { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open prediction result file: " + outputPredictionFile, ex); - } - } - boolean firstDump = true; - boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); - long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - long lastEvaluateStartTime = evaluateStartTime; - double RAMHours = 0.0; - while (stream.hasMoreInstances() - && ((maxInstances < 0) || (instancesProcessed < maxInstances)) - && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { - Example trainInst = stream.nextInstance(); - Example testInst = (Example) trainInst; //.copy(); - //testInst.setClassMissing(); - //double[] prediction = learner.getVotesForInstance(testInst); - Prediction prediction = learner.getPredictionForInstance(testInst); - // Output prediction - if (outputPredictionFile != null) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { - sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); - } - outputPredictionResultStream.println(prediction + "," + sb.toString()); - } ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa + } //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); evaluator.addResult(testInst, prediction); diff --git a/pom.xml b/pom.xml index 052fa8916..2320c5ec3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ nz.ac.waikato.cms.moa moa-pom pom - 2012.09-SNAPSHOT + 2014.04 MOA: meta-package diff --git a/weka-package/pom.xml b/weka-package/pom.xml index 6cd73530c..693727f08 100644 --- a/weka-package/pom.xml +++ b/weka-package/pom.xml @@ -6,7 +6,7 @@ nz.ac.waikato.cms.moa moa-pom - 2012.09-SNAPSHOT + 2014.04 weka-package From 483366b26ca357ec80022ba6bb3966199aaf9d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Wed, 23 Mar 2016 11:06:20 +0100 Subject: [PATCH 11/33] Intermediary commit for multi-label changes --- .../labs/samoa/instances/ArffLoader.java | 15 +- .../yahoo/labs/samoa/instances/Attribute.java | 594 ++++++++++-------- .../samoa/instances/AttributeStructure.java | 7 + .../labs/samoa/instances/DAGStructure.java | 86 +++ .../instances/HierarhicalInstanceImpl.java | 452 +++++++++++++ .../yahoo/labs/samoa/instances/Instance.java | 11 + .../labs/samoa/instances/InstanceImpl.java | 14 +- .../samoa/instances/InstanceInformation.java | 9 + .../labs/samoa/instances/InstancesHeader.java | 4 + .../com/yahoo/labs/samoa/instances/Range.java | 4 +- ...lInstance.java => StructuredInstance.java} | 4 +- .../moa/classifiers/AbstractClassifier.java | 11 +- .../AbstractMultiLabelLearner.java | 10 +- .../moa/classifiers/MultiLabelLearner.java | 6 +- .../java/moa/classifiers/meta/OzaBag.java | 2 +- .../LocalMultiTargetClassifier.java | 8 +- .../multilabel/MEKAClassifier.java | 10 +- .../multilabel/MajorityLabelset.java | 6 +- .../multilabel/MultilabelHoeffdingTree.java | 8 +- .../splitcriteria/ICVarianceReduction.java | 1 - .../WeightedICVarianceReduction.java | 46 ++ .../classifiers/multilabel/meta/MLOzaBag.java | 8 +- .../multilabel/meta/MLOzaBagAdwin.java | 8 +- .../classifiers/multilabel/meta/MTOzaBag.java | 40 +- .../multilabel/trees/ISOUPOptionTree.java | 319 +++++++++- .../multilabel/trees/ISOUPTree.java | 195 ++++-- .../BasicMultiTargetRegressor.java | 8 +- .../functions/MultiTargetNoChange.java | 6 +- .../rules/core/NominalRulePredicate.java | 15 +- .../rules/core/NumericRulePredicate.java | 16 +- .../moa/classifiers/rules/core/Predicate.java | 2 + .../AbstractAnomalyDetector.java | 4 +- .../AnomalinessRatioScore.java | 4 +- .../anomalydetection/AnomalyDetector.java | 4 +- .../anomalydetection/NoAnomalyDetection.java | 4 +- .../core/anomalydetection/OddsRatioScore.java | 4 +- .../NominalAttributeBinaryRulePredicate.java | 9 + .../NumericAttributeBinaryRulePredicate.java | 7 + .../rules/functions/Perceptron.java | 2 +- .../multilabel/AMRulesMultiLabelLearner.java | 10 +- .../multilabel/core/LearningLiteral.java | 12 +- .../core/LearningLiteralRegression.java | 4 +- .../rules/multilabel/core/MultiLabelRule.java | 12 +- .../AbstractMultiLabelErrorMeasurer.java | 4 +- .../AbstractMultiTargetErrorMeasurer.java | 4 +- .../MultiLabelErrorMeasurer.java | 4 +- .../AdaptiveMultiTargetRegressor.java | 6 +- .../meta/MultiLabelRandomAMRules.java | 6 +- .../java/moa/classifiers/trees/FIMTDD.java | 37 +- .../main/java/moa/classifiers/trees/ORTO.java | 6 +- .../BasicMultiTargetPerformanceEvaluator.java | 4 +- ...tWindowRegressionPerformanceEvaluator.java | 4 +- ...dowClassificationPerformanceEvaluator.java | 4 +- .../main/java/moa/streams/ArffFileStream.java | 9 +- 54 files changed, 1568 insertions(+), 521 deletions(-) create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/AttributeStructure.java create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/DAGStructure.java create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java rename moa/src/main/java/com/yahoo/labs/samoa/instances/{MultiLabelInstance.java => StructuredInstance.java} (87%) create mode 100644 moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/WeightedICVarianceReduction.java diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java index 124b1d5d6..a6bddce59 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java @@ -352,10 +352,6 @@ private InstanceInformation getHeader() { //commented JD //this.range.setUpper(10000); //TO DO: Create a new range object with isInRange that does not need the upper limit String relation = "file stream"; - //System.out.println("RELATION " + relation); - //inputAttributes = new ArrayList(); - //outputAttributes = new ArrayList(); - //ArrayList auxAttributes = new ArrayList();//JD int numAttributes = 0; try { @@ -405,6 +401,17 @@ private InstanceInformation getHeader() { }*/ auxAttributes.add(new Attribute(name, attributeLabels)); numAttributes++; + } else if (streamTokenizer.sval != null && streamTokenizer.sval.toUpperCase() == "HIERARCHICAL") { + streamTokenizer.nextToken(); + DAGStructure attributeStructure = new DAGStructure(); + if (streamTokenizer.ttype == '{') { + while(streamTokenizer.ttype == '}') { + streamTokenizer.nextToken(); + System.out.println(streamTokenizer.sval); + } + + } + } else { // Add attribute //commented JD diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java index 941616a73..54e6c21dc 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java @@ -25,279 +25,323 @@ */ public class Attribute implements Serializable { - /** The keyword used to denote the start of an arff attribute declaration */ - public final static String ARFF_ATTRIBUTE = "@attribute"; - - /** A keyword used to denote a numeric attribute */ - public final static String ARFF_ATTRIBUTE_INTEGER = "integer"; - - /** A keyword used to denote a numeric attribute */ - public final static String ARFF_ATTRIBUTE_REAL = "real"; - - /** A keyword used to denote a numeric attribute */ - public final static String ARFF_ATTRIBUTE_NUMERIC = "numeric"; - - /** The keyword used to denote a string attribute */ - public final static String ARFF_ATTRIBUTE_STRING = "string"; - - /** The keyword used to denote a date attribute */ - public final static String ARFF_ATTRIBUTE_DATE = "date"; - - /** The keyword used to denote a relation-valued attribute */ - public final static String ARFF_ATTRIBUTE_RELATIONAL = "relational"; - - /** The keyword used to denote the end of the declaration of a subrelation */ - public final static String ARFF_END_SUBRELATION = "@end"; - - /** Strings longer than this will be stored compressed. */ - private static final int STRING_COMPRESS_THRESHOLD = 200; - - /** - * The is nominal. - */ - protected boolean isNominal; - - /** - * The is numeric. - */ - protected boolean isNumeric; - - /** - * The is date. - */ - protected boolean isDate; - - /** - * Date format specification for date attributes - */ - protected SimpleDateFormat m_DateFormat; - - /** - * The name. - */ - protected String name; - - /** - * The attribute values. - */ - protected List attributeValues; - - /** - * Gets the attribute values. - * - * @return the attribute values - */ - public List getAttributeValues() { - return attributeValues; - } - - /** - * The index. - */ - protected int index; - - /** - * Instantiates a new attribute. - * - * @param string the string - */ - public Attribute(String string) { - this.name = string; - this.isNumeric = true; - } - - /** - * Instantiates a new attribute. - * - * @param attributeName the attribute name - * @param attributeValues the attribute values - */ - public Attribute(String attributeName, List attributeValues) { - this.name = attributeName; - this.attributeValues = attributeValues; - this.isNominal = true; - } - - /** - * Instantiates a new attribute. - * - * @param attributeName the attribute name - * @param dateFormat the format of the date used - */ - public Attribute(String attributeName, String dateFormat) { - this.name = attributeName; - this.index = -1; - this.valuesStringAttribute = null; - this.isDate = true; - - if (dateFormat != null) { - m_DateFormat = new SimpleDateFormat(dateFormat); - } else { - m_DateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - } - } - - /** - * Instantiates a new attribute. - */ - public Attribute() { - this(""); - } - - /** - * Checks if is nominal. - * - * @return true, if is nominal - */ - public boolean isNominal() { - return this.isNominal; - } - - /** - * Name. - * - * @return the string - */ - public String name() { - return this.name; - } - - /** - * Value. - * - * @param value the value - * @return the string - */ - public String value(int value) { - return attributeValues.get(value); - } - - /** - * Checks if is numeric. - * - * @return true, if is numeric - */ - public boolean isNumeric() { - return isNumeric; - } - - /** - * Num values. - * - * @return the int - */ - public int numValues() { - if (isNumeric()) { - return 0; - } else { - return attributeValues.size(); - } - } - - /** - * Index. - * - * @return the int - */ - public int index() { //RuleClassifier - return this.index; - } - - /** - * Format date. - * - * @param value the value - * @return the string - */ - String formatDate(double value) { - return this.m_DateFormat.format(new Date((long) value)); - } - - /** - * Checks if is date. - * - * @return true, if is date - */ - boolean isDate() { - return isDate; - } - - /** - * The values string attribute. - */ - private Map valuesStringAttribute; - - /** - * Index of value. - * - * @param value the value - * @return the int - */ - public final int indexOfValue(String value) { - - if (isNominal() == false) { - return -1; - } - if (this.valuesStringAttribute == null) { - this.valuesStringAttribute = new HashMap(); - int count = 0; - for (String stringValue : attributeValues) { - this.valuesStringAttribute.put(stringValue, count); - count++; - } - } - Integer val = (Integer) this.valuesStringAttribute.get(value); - if (val == null) { - return -1; - } else { - return val.intValue(); - } - } - - /** - * Returns a description of this attribute in ARFF format. Quotes - * strings if they contain whitespace characters, or if they - * are a question mark. - * - * @return a description of this attribute as a string - */ - public final String toString() { - - StringBuffer text = new StringBuffer(); - - text.append(ARFF_ATTRIBUTE).append(" ").append(Utils.quote(this.name())).append(" "); - - if (this.isNominal){ - text.append('{'); - Enumeration enu = enumerateValues(); - while (enu.hasMoreElements()) { - text.append(Utils.quote((String) enu.nextElement())); - if (enu.hasMoreElements()) - text.append(','); - } - text.append('}'); - } else if (this.isNumeric){ - text.append(ARFF_ATTRIBUTE_NUMERIC); - } else if (this.isDate){ - text.append(ARFF_ATTRIBUTE_DATE).append(" ").append(Utils.quote(m_DateFormat.toPattern())); - } else{ - text.append("UNKNOW"); - } - - return text.toString(); - } - - /** - * Returns an enumeration of all the attribute's values if the - * attribute is nominal, null otherwise. - * - * @return enumeration of all the attribute's values - */ - public final /*@ pure @*/ Enumeration enumerateValues() { - - if (this.isNominal()) { - return Collections.enumeration(this.attributeValues); - } - return null; - } + /** The keyword used to denote the start of an arff attribute declaration */ + public final static String ARFF_ATTRIBUTE = "@attribute"; + + /** A keyword used to denote a numeric attribute */ + public final static String ARFF_ATTRIBUTE_INTEGER = "integer"; + + /** A keyword used to denote a numeric attribute */ + public final static String ARFF_ATTRIBUTE_REAL = "real"; + + /** A keyword used to denote a numeric attribute */ + public final static String ARFF_ATTRIBUTE_NUMERIC = "numeric"; + + /** The keyword used to denote a string attribute */ + public final static String ARFF_ATTRIBUTE_STRING = "string"; + + /** The keyword used to denote a date attribute */ + public final static String ARFF_ATTRIBUTE_DATE = "date"; + + /** The keyword used to denote a (nominal) hierarchical attribute */ + public final static String ARFF_ATTRIBUTE_HIERARCHICAL = "hierarchical"; + + /** The keyword used to denote a relation-valued attribute */ + public final static String ARFF_ATTRIBUTE_RELATIONAL = "relational"; + + /** The keyword used to denote the end of the declaration of a subrelation */ + public final static String ARFF_END_SUBRELATION = "@end"; + + /** Strings longer than this will be stored compressed. */ + private static final int STRING_COMPRESS_THRESHOLD = 200; + + /** + * The is nominal. + */ + protected boolean isNominal; + + /** + * The is numeric. + */ + protected boolean isNumeric; + + /** + * The is date. + */ + protected boolean isDate; + + /** + * The is hierarchical. + */ + protected boolean isHierarchical; + + /** + * Date format specification for date attributes + */ + protected SimpleDateFormat m_DateFormat; + + /** + * The name. + */ + protected String name; + + /** + * The attribute values. + */ + protected List attributeValues; + + /** + * The attribute structure. + */ + protected AttributeStructure attributeStructure; + + /** + * Gets the attribute values. + * + * @return the attribute values + */ + public List getAttributeValues() { + return attributeValues; + } + + /** + * The index. + */ + protected int index; + + /** + * Instantiates a new attribute. + * + * @param string the string + */ + public Attribute(String string) { + this.name = string; + this.isNumeric = true; + } + + /** + * Instantiates a new attribute. + * + * @param attributeName the attribute name + * @param attributeValues the attribute values + */ + public Attribute(String attributeName, List attributeValues) { + this.name = attributeName; + this.attributeValues = attributeValues; + this.isNominal = true; + } + + /** + * Instantiates a new attribute. + * + * @param attributeName the attribute name + * @param dateFormat the format of the date used + */ + public Attribute(String attributeName, String dateFormat) { + this.name = attributeName; + this.index = -1; + this.valuesStringAttribute = null; + this.isDate = true; + + if (dateFormat != null) { + m_DateFormat = new SimpleDateFormat(dateFormat); + } else { + m_DateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + } + } + + /** + * Instantiates a new attribute. + * + * @param attributeName the attribute name + * @param attributeValues the attribute values + * @param attributeStructure the attribute structure + */ + public Attribute(String attributeName, List attributeValues, AttributeStructure attributeStructure) { + this.name = attributeName; + this.attributeValues = attributeValues; + this.attributeStructure = attributeStructure; + this.isHierarchical = true; + } + /** + * Instantiates a new attribute. + */ + public Attribute() { + this(""); + } + + /** + * Checks if is nominal. + * + * @return true, if is nominal + */ + public boolean isNominal() { + return this.isNominal; + } + + /** + * Name. + * + * @return the string + */ + public String name() { + return this.name; + } + + /** + * Value. + * + * @param value the value + * @return the string + */ + public String value(int value) { + return attributeValues.get(value); + } + + /** + * Checks if is numeric. + * + * @return true, if is numeric + */ + public boolean isNumeric() { + return isNumeric; + } + + /** + * Num values. + * + * @return the int + */ + public int numValues() { + if (isNumeric()) { + return 0; + } else { + return attributeValues.size(); + } + } + + /** + * Checks if is hierarchical. + * + * @return true, if is hierarchical + */ + public boolean isHierarchical() { + return this.isHierarchical; + } + + + /** + * Index. + * + * @return the int + */ + public int index() { //RuleClassifier + return this.index; + } + + /** + * Format date. + * + * @param value the value + * @return the string + */ + String formatDate(double value) { + return this.m_DateFormat.format(new Date((long) value)); + } + + /** + * Checks if is date. + * + * @return true, if is date + */ + boolean isDate() { + return isDate; + } + + /** + * The values string attribute. + */ + private Map valuesStringAttribute; + + /** + * Index of value. + * + * @param value the value + * @return the int + */ + public final int indexOfValue(String value) { + + if (!isNominal()) { + return -1; + } + // TODO check how this affects hierarchies + if (this.valuesStringAttribute == null) { + this.valuesStringAttribute = new HashMap(); + int count = 0; + for (String stringValue : attributeValues) { + this.valuesStringAttribute.put(stringValue, count); + count++; + } + } + Integer val = (Integer) this.valuesStringAttribute.get(value); + if (val == null) { + return -1; + } else { + return val.intValue(); + } + } + + /** + * Returns a description of this attribute in ARFF format. Quotes + * strings if they contain whitespace characters, or if they + * are a question mark. + * + * @return a description of this attribute as a string + */ + public final String toString() { + + StringBuffer text = new StringBuffer(); + + text.append(ARFF_ATTRIBUTE).append(" ").append(Utils.quote(this.name())).append(" "); + + if (this.isNominal){ + text.append('{'); + Enumeration enu = enumerateValues(); + while (enu.hasMoreElements()) { + text.append(Utils.quote((String) enu.nextElement())); + if (enu.hasMoreElements()) + text.append(','); + } + text.append('}'); + } else if (this.isNumeric){ + text.append(ARFF_ATTRIBUTE_NUMERIC); + } else if (this.isDate){ + text.append(ARFF_ATTRIBUTE_DATE).append(" ").append(Utils.quote(m_DateFormat.toPattern())); + } else if (this.isHierarchical) { + text.append(ARFF_ATTRIBUTE_HIERARCHICAL).append(" "); + + text.append("{"); + // TODO output hierarchy + text.append("}"); + + } else { + text.append("UNKNOW"); + } + + return text.toString(); + } + + /** + * Returns an enumeration of all the attribute's values if the + * attribute is nominal, null otherwise. + * + * @return enumeration of all the attribute's values + */ + public final /*@ pure @*/ Enumeration enumerateValues() { + + if (this.isNominal()) { + return Collections.enumeration(this.attributeValues); + } + return null; + } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributeStructure.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributeStructure.java new file mode 100644 index 000000000..afcd53e38 --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributeStructure.java @@ -0,0 +1,7 @@ +package com.yahoo.labs.samoa.instances; + +import java.io.Serializable; + +public interface AttributeStructure extends Serializable { + +} diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/DAGStructure.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/DAGStructure.java new file mode 100644 index 000000000..b26cd433c --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/DAGStructure.java @@ -0,0 +1,86 @@ +package com.yahoo.labs.samoa.instances; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DAGStructure implements AttributeStructure { + public Node root; + + public Map nodes; + + public int type; + + public static int HIERARCHY_TYPE = 0; + public static int DAG_TYPE = 1; + + public DAGStructure() { + this.type = DAGStructure.HIERARCHY_TYPE; + this.nodes = new HashMap(); + this.root = null; + } + + public boolean hasNode(String description) { + return nodes.containsKey(description); + } + + public void addNode(String description) { + nodes.put(description, new Node(description)); + } + + public void addChild(String parent, String child) { + Node p = nodes.get(parent); + Node c = nodes.get(child); + p.addChild(c); + c.addAncestor(p); + if (c.ancestors.size() > 1) { + this.type = DAGStructure.DAG_TYPE; + } + } + + public void setRoot(String description) { + if (this.nodes.containsKey(description)) { + this.root = this.nodes.get(description); + } + } + + public class Node { + public String description; + + public List ancestors; + public List children; + + public Node(String description) { + this.description = description; + this.ancestors = new ArrayList(); + this.children = new ArrayList(); + } + + public void addAncestor(Node ancestor) { + this.ancestors.add(ancestor); + } + + public void addChild(Node child) { + this.ancestors.add(child); + } + + public boolean isRoot() { + // Should only be called when the structure is built + return this.ancestors.isEmpty(); + } + + public double getLevel() { + // Check how this is done when a DAG is used instead of a hierarchy + if (this.isRoot()) return 0; + else { + double total = Integer.MAX_VALUE; + for (Node ancestor : this.ancestors) { + total = total + ancestor.getLevel(); + } + return total / ancestors.size() + 1; + } + } + } + +} diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java new file mode 100644 index 000000000..c9ed7728c --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java @@ -0,0 +1,452 @@ +/* + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package com.yahoo.labs.samoa.instances; + +import moa.AbstractMOAObject; + +/** + * The Class InstanceImpl. + * + * @author abifet + */ +public class HierarhicalInstanceImpl implements StructuredInstance { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * The weight. + */ + protected double weight; + + /** + * The instance data. + */ + protected InstanceData instanceData; + + /** + * The instance information. + */ + protected InstancesHeader instanceHeader; + + /** + * Instantiates a new instance. + * + * @param inst the inst + */ + public HierarhicalInstanceImpl(HierarhicalInstanceImpl inst) { + this.weight = inst.weight; + this.instanceData = inst.instanceData.copy(); + this.instanceHeader = inst.instanceHeader; + } + + //Dense + /** + * Instantiates a new instance. + * + * @param weight the weight + * @param res the res + */ + public HierarhicalInstanceImpl(double weight, double[] res) { + this.weight = weight; + this.instanceData = new DenseInstanceData(res); + } + + //Sparse + /** + * Instantiates a new instance. + * + * @param weight the weight + * @param attributeValues the attribute values + * @param indexValues the index values + * @param numberAttributes the number attributes + */ + public HierarhicalInstanceImpl(double weight, double[] attributeValues, int[] indexValues, int numberAttributes) { + this.weight = weight; + this.instanceData = new SparseInstanceData(attributeValues, indexValues, numberAttributes); + } + + /** + * Instantiates a new instance. + * + * @param weight the weight + * @param instanceData the instance data + */ + public HierarhicalInstanceImpl(double weight, InstanceData instanceData) { + this.weight = weight; + this.instanceData = instanceData; + } + + /** + * Instantiates a new instance. + * + * @param numAttributes the num attributes + */ + public HierarhicalInstanceImpl(int numAttributes) { + this.instanceData = new DenseInstanceData(new double[numAttributes]); //JD + this.weight = 1; + } + + /** + * Weight. + * + * @return the double + */ + @Override + public double weight() { + return weight; + } + + /** + * Sets the weight. + * + * @param weight the new weight + */ + @Override + public void setWeight(double weight) { + this.weight = weight; + } + + /** + * Attribute. + * + * @param instAttIndex the inst att index + * @return the attribute + */ + @Override + public Attribute attribute(int instAttIndex) { + return this.instanceHeader.attribute(instAttIndex); + } + + /** + * Delete attribute at. + * + * @param i the i + */ + @Override + public void deleteAttributeAt(int i) { + //throw new UnsupportedOperationException("Not yet implemented"); + this.instanceData.deleteAttributeAt(i); + } + + /** + * Insert attribute at. + * + * @param i the i + */ + @Override + public void insertAttributeAt(int i) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * Num attributes. + * + * @return the int + */ + @Override + public int numAttributes() { + return this.instanceData.numAttributes(); + } + + /** + * Value. + * + * @param instAttIndex the inst att index + * @return the double + */ + @Override + public double value(int instAttIndex) { + return this.instanceData.value(instAttIndex); + } + + /** + * Checks if is missing. + * + * @param instAttIndex the inst att index + * @return true, if is missing + */ + @Override + public boolean isMissing(int instAttIndex) { + return this.instanceData.isMissing(instAttIndex); + } + + /** + * Num values. + * + * @return the int + */ + @Override + public int numValues() { + return this.instanceData.numValues(); + } + + /** + * Index. + * + * @param i the i + * @return the int + */ + @Override + public int index(int i) { + return this.instanceData.index(i); + } + + /** + * Value sparse. + * + * @param i the i + * @return the double + */ + @Override + public double valueSparse(int i) { + return this.instanceData.valueSparse(i); + } + + /** + * Checks if is missing sparse. + * + * @param p the p + * @return true, if is missing sparse + */ + @Override + public boolean isMissingSparse(int p) { + return this.instanceData.isMissingSparse(p); + } + + /** + * Value. + * + * @param attribute the attribute + * @return the double + */ + @Override + public double value(Attribute attribute) { + return value(attribute.index()); + + } + + /** + * String value. + * + * @param i the i + * @return the string + */ + @Override + public String stringValue(int i) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * To double array. + * + * @return the double[] + */ + @Override + public double[] toDoubleArray() { + return this.instanceData.toDoubleArray(); + } + + /** + * Sets the value. + * + * @param numAttribute the num attribute + * @param d the d + */ + @Override + public void setValue(int numAttribute, double d) { + this.instanceData.setValue(numAttribute, d); + } + + /** + * Class value. + * + * @return the double + */ + @Override + public double classValue() { + return this.instanceData.value(classIndex()); + } + + /** + * Class index. + * + * @return the int + */ + @Override + public int classIndex() { + int classIndex = instanceHeader.classIndex(); + return classIndex != Integer.MAX_VALUE ? classIndex : 0; + } + + /** + * Num classes. + * + * @return the int + */ + @Override + public int numClasses() { + return this.instanceHeader.numClasses(); + } + + /** + * Class is missing. + * + * @return true, if successful + */ + @Override + public boolean classIsMissing() { + return this.instanceData.isMissing(classIndex()); + } + + /** + * Class attribute. + * + * @return the attribute + */ + @Override + public Attribute classAttribute() { + return this.instanceHeader.attribute(classIndex()); + } + + /** + * Sets the class value. + * + * @param d the new class value + */ + @Override + public void setClassValue(double d) { + this.setValue(classIndex(), d); + } + + /** + * Copy. + * + * @return the instance + */ + @Override + public Instance copy() { + HierarhicalInstanceImpl inst = new HierarhicalInstanceImpl(this); + return inst; + } + + /** + * Dataset. + * + * @return the instances + */ + @Override + public Instances dataset() { + return this.instanceHeader; + } + + /** + * Sets the dataset. + * + * @param dataset the new dataset + */ + @Override + public void setDataset(Instances dataset) { + this.instanceHeader = new InstancesHeader(dataset); + } + + /** + * Adds the sparse values. + * + * @param indexValues the index values + * @param attributeValues the attribute values + * @param numberAttributes the number attributes + */ + @Override + public void addSparseValues(int[] indexValues, double[] attributeValues, int numberAttributes) { + this.instanceData = new SparseInstanceData(attributeValues, indexValues, numberAttributes); //??? + } + + /** + * Text representation of a InstanceImpl. + */ + @Override + public String toString() { + double[] aux = this.instanceData.toDoubleArray(); + StringBuilder str = new StringBuilder(); + for (int i = 0; i < aux.length; i++) { + str.append(aux[i]).append(" "); + } + + return str.toString(); + } + + @Override + public int numInputAttributes() { + return this.instanceHeader.numInputAttributes(); + } + + @Override + public int numOutputAttributes() { + return numberOutputTargets(); + } + + @Override + public int numberOutputTargets() { + return this.instanceHeader.numOutputAttributes(); + } + + @Override + public double classValue(int instAttIndex) { + return valueOutputAttribute(instAttIndex); + } + + @Override + public void setClassValue(int indexClass, double valueAttribute) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + this.instanceData.setValue(instanceInformation.outputAttributeIndex(indexClass), valueAttribute); + + } + + @Override + public Attribute outputAttribute(int outputIndex) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + return instanceInformation.outputAttribute(outputIndex); + } + + @Override + public Attribute inputAttribute(int attributeIndex) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + return instanceInformation.inputAttribute(attributeIndex); + } + + @Override + public double valueInputAttribute(int attributeIndex) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + return this.instanceData.value(instanceInformation.inputAttributeIndex(attributeIndex)); + } + + @Override + public double valueOutputAttribute(int attributeIndex) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + return this.instanceData.value(instanceInformation.outputAttributeIndex(attributeIndex)); + } + + public int structureType() { + return Instance.STRUCTURE_TYPE_HIERARHICAL; + } + + public AttributeStructure getStructure() { + return this.instanceHeader.getInstanceStructure(); + } +} \ No newline at end of file diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java index 1780a9d11..dbf315738 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java @@ -17,6 +17,8 @@ import java.io.Serializable; +import moa.AbstractMOAObject; + /** * The Interface Instance. * @@ -24,6 +26,11 @@ */ public interface Instance extends Serializable { + public static int STRUCTURE_TYPE_SINGLE_TARGET = 0; + public static int STRUCTURE_TYPE_MULTI_TARGET = 1; + public static int STRUCTURE_TYPE_TIME_SERIES = 2; + public static int STRUCTURE_TYPE_HIERARHICAL = 3; + /** * Gets the weight of the instance. * @@ -287,5 +294,9 @@ public interface Instance extends Serializable { * @return the value */ public double valueOutputAttribute(int attributeIndex); + + public int structureType(); + + public AttributeStructure getStructure(); } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java index 50403eb20..16acdac54 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java @@ -15,12 +15,14 @@ */ package com.yahoo.labs.samoa.instances; +import moa.AbstractMOAObject; + /** * The Class InstanceImpl. * * @author abifet */ -public class InstanceImpl implements MultiLabelInstance { +public class InstanceImpl implements StructuredInstance { /** * The weight. @@ -434,4 +436,12 @@ public double valueOutputAttribute(int attributeIndex) { InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); return this.instanceData.value(instanceInformation.outputAttributeIndex(attributeIndex)); } -} + + public int structureType() { + return (numOutputAttributes() > 1) ? Instance.STRUCTURE_TYPE_MULTI_TARGET : Instance.STRUCTURE_TYPE_SINGLE_TARGET; + } + + public AttributeStructure getStructure() { + return null; + } +} \ No newline at end of file diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java index dd59d6f27..7a8aae816 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java @@ -18,6 +18,8 @@ import java.io.Serializable; import java.util.List; +import moa.AbstractMOAObject; + /** * The Class InstanceInformation. * @@ -31,6 +33,8 @@ public class InstanceInformation implements Serializable { protected String relationName; protected AttributesInformation attributesInformation; + + protected AttributeStructure structure = null; /** * The class index. @@ -58,6 +62,7 @@ public Attribute outputAttribute(int w) { public InstanceInformation(InstanceInformation chunk) { this.relationName = chunk.relationName; this.attributesInformation = chunk.attributesInformation; + this.structure = chunk.structure; this.classIndex = chunk.classIndex; } @@ -212,5 +217,9 @@ public void setAttributes(List v, List indexValues) { this.attributesInformation.setAttributes(v,indexValues); } + + public AttributeStructure getStructure() { + return this.structure; + } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java index 687bb9705..ed53007d0 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java @@ -113,4 +113,8 @@ public int numOutputAttributes() { public InstanceInformation getInstanceInformation() { return this.instanceInformation; } + + public AttributeStructure getInstanceStructure() { + return this.instanceInformation.getStructure(); + } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java index dfdf3dba9..ab27c38fb 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java @@ -15,7 +15,9 @@ */ package com.yahoo.labs.samoa.instances; -public class Range { +import java.io.Serializable; + +public class Range implements Serializable { //Only works for ranges "start-end" private int start = 0; diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelInstance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java similarity index 87% rename from moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelInstance.java rename to moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java index 0978bd332..279d6baed 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelInstance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java @@ -16,12 +16,12 @@ package com.yahoo.labs.samoa.instances; /** - * The Interface MultiLabelInstance. + * The Interface StructuredInstance. * * @author abifet */ -public interface MultiLabelInstance extends Instance { +public interface StructuredInstance extends Instance { } \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/AbstractClassifier.java b/moa/src/main/java/moa/classifiers/AbstractClassifier.java index 9511a24f6..ee1c01c47 100644 --- a/moa/src/main/java/moa/classifiers/AbstractClassifier.java +++ b/moa/src/main/java/moa/classifiers/AbstractClassifier.java @@ -85,14 +85,15 @@ public AbstractClassifier() { } @Override - public void prepareForUseImpl(TaskMonitor monitor, - ObjectRepository repository) { + public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { if (this.randomSeedOption != null) { this.randomSeed = this.randomSeedOption.getValue(); } - if (!trainingHasStarted()) { - resetLearning(); - } + + // resetLearning should not be called if the classifier has not yet received the context +// if (!trainingHasStarted()) { +// resetLearning(); +// } } diff --git a/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java b/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java index 641228cf0..3fefdd9ce 100644 --- a/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java @@ -2,7 +2,7 @@ import moa.core.Example; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; public abstract class AbstractMultiLabelLearner extends AbstractClassifier implements MultiLabelLearner { @@ -13,11 +13,11 @@ public abstract class AbstractMultiLabelLearner extends AbstractClassifier imple private static final long serialVersionUID = 1L; @Override - abstract public void trainOnInstanceImpl(MultiLabelInstance instance); + abstract public void trainOnInstanceImpl(StructuredInstance instance); @Override public void trainOnInstanceImpl(Instance instance) { - trainOnInstanceImpl((MultiLabelInstance) instance); + trainOnInstanceImpl((StructuredInstance) instance); } @Override @@ -27,10 +27,10 @@ public Prediction getPredictionForInstance(Example example) { @Override public Prediction getPredictionForInstance(Instance inst) { - return getPredictionForInstance((MultiLabelInstance) inst); + return getPredictionForInstance((StructuredInstance) inst); } - abstract public Prediction getPredictionForInstance(MultiLabelInstance inst); + abstract public Prediction getPredictionForInstance(StructuredInstance inst); @Override public double[] getVotesForInstance(Instance inst) { diff --git a/moa/src/main/java/moa/classifiers/MultiLabelLearner.java b/moa/src/main/java/moa/classifiers/MultiLabelLearner.java index b42a37085..ee875ee60 100644 --- a/moa/src/main/java/moa/classifiers/MultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/MultiLabelLearner.java @@ -1,12 +1,12 @@ package moa.classifiers; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; public interface MultiLabelLearner extends Classifier{ - public void trainOnInstanceImpl(MultiLabelInstance instance); + public void trainOnInstanceImpl(StructuredInstance instance); - public Prediction getPredictionForInstance(MultiLabelInstance instance); + public Prediction getPredictionForInstance(StructuredInstance instance); } diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBag.java b/moa/src/main/java/moa/classifiers/meta/OzaBag.java index d7c935590..9ca3dd639 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBag.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBag.java @@ -70,9 +70,9 @@ public String getPurposeString() { public void resetLearningImpl() { this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); - baseLearner.resetLearning(); for (int i = 0; i < this.ensemble.length; i++) { this.ensemble[i] = baseLearner.copy(); + } } diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 5fce8915c..4c78071f9 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -7,7 +7,7 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -64,7 +64,7 @@ private void makeHeaders() { } } - private Instance getSTInstance(MultiLabelInstance inst, int target) { + private Instance getSTInstance(StructuredInstance inst, int target) { double[] instanceData = new double[getModelContext().numInputAttributes() + 1]; for (int i = 0; i < inst.numInputAttributes(); i++) instanceData[i] = inst.valueInputAttribute(i); @@ -75,7 +75,7 @@ private Instance getSTInstance(MultiLabelInstance inst, int target) { } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { initializeClassifiers(); for (int j = 0; j < instance.numberOutputTargets(); j++) { @@ -86,7 +86,7 @@ public void trainOnInstanceImpl(MultiLabelInstance instance) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance inst) { + public Prediction getPredictionForInstance(StructuredInstance inst) { initializeClassifiers(); MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); diff --git a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java index 88881ce21..bc44ab3f7 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java @@ -24,7 +24,7 @@ import moa.classifiers.meta.WEKAClassifier; import com.yahoo.labs.samoa.instances.InstancesHeader; import weka.classifiers.UpdateableClassifier; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; @@ -87,12 +87,12 @@ public void setModelContext(InstancesHeader raw_header) { @Override public void trainOnInstanceImpl(Instance instance) { - trainOnInstanceImpl((MultiLabelInstance) instance); + trainOnInstanceImpl((StructuredInstance) instance); } @Override - public void trainOnInstanceImpl(MultiLabelInstance samoaInstance) { + public void trainOnInstanceImpl(StructuredInstance samoaInstance) { weka.core.Instance inst = this.instanceConverter.wekaInstance(samoaInstance); //System.out.println(""+m_L); // <-- this is correct //System.out.println(""+inst.classIndex()); // <--- this one is wrong @@ -130,11 +130,11 @@ public double[] getVotesForInstance(Instance samoaInstance) { @Override public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance((MultiLabelInstance)example.getData()); + return getPredictionForInstance((StructuredInstance)example.getData()); } @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { double[] predictionArray = this.getVotesForInstance(instance); diff --git a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java index 039c0834e..c83ddbde6 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java @@ -24,7 +24,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.Measurement; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import moa.classifiers.AbstractMultiLabelLearner; @@ -91,13 +91,13 @@ public void resetLearningImpl() { } @Override - public void trainOnInstanceImpl(MultiLabelInstance x) { + public void trainOnInstanceImpl(StructuredInstance x) { updateCount(x, m_L); } @Override //public double[] getVotesForInstance(Instance x) { - public Prediction getPredictionForInstance(MultiLabelInstance x){ + public Prediction getPredictionForInstance(StructuredInstance x){ System.out.println("-------- start MC vote ---------------"); int L = x.numOutputAttributes(); //x.classIndex() + 1; diff --git a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java index 934eae252..aaaa1b6d8 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java @@ -28,7 +28,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import java.util.LinkedList; @@ -65,11 +65,11 @@ public void setModelContext(InstancesHeader raw_header) { @Override public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance((MultiLabelInstance)example.getData()); + return getPredictionForInstance((StructuredInstance)example.getData()); } @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { double[] predictionArray = this.getVotesForInstance(instance); @@ -232,7 +232,7 @@ public double[] getVotesForInstance(Instance inst) { @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { trainOnInstanceImpl((Instance) instance); } diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java index 176f3dfd0..24f9839b0 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java @@ -1,6 +1,5 @@ package moa.classifiers.multilabel.core.splitcriteria; -import moa.classifiers.rules.core.Utils; import moa.core.DoubleVector; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/WeightedICVarianceReduction.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/WeightedICVarianceReduction.java new file mode 100644 index 000000000..9d5d181ea --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/WeightedICVarianceReduction.java @@ -0,0 +1,46 @@ +package moa.classifiers.multilabel.core.splitcriteria; + +import moa.core.DoubleVector; +import moa.core.ObjectRepository; +import moa.tasks.TaskMonitor; + +/** + * Weighted intra cluster variance reduction split criterion + * @author Aljaž Osojnik + * + */ + +public class WeightedICVarianceReduction extends ICVarianceReduction { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public DoubleVector weights; + + public WeightedICVarianceReduction(DoubleVector targetWeights) { + super(); + this.weights = targetWeights; + } + + @Override + public double getMeritOfSplit(DoubleVector[] preSplitDist, DoubleVector[][] postSplitDists) { + double error=0; + int numOutputs=preSplitDist.length; + for (int i=0; i example) { - return getPredictionForInstance((MultiLabelInstance)example.getData()); + return getPredictionForInstance((StructuredInstance)example.getData()); } @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { double[] predictionArray = this.getVotesForInstance(instance); diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MLOzaBagAdwin.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MLOzaBagAdwin.java index 43c008713..65e25b533 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/MLOzaBagAdwin.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MLOzaBagAdwin.java @@ -25,7 +25,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.MiscUtils; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import moa.classifiers.MultiLabelLearner; @@ -156,17 +156,17 @@ public double[] getVotesForInstance(Instance x) { } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { trainOnInstanceImpl((Instance) instance); } @Override public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance((MultiLabelInstance) example.getData()); + return getPredictionForInstance((StructuredInstance) example.getData()); } @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { double[] predictionArray = this.getVotesForInstance(instance); diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java index 2594f61be..b4675887f 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java @@ -21,7 +21,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -41,7 +41,12 @@ */ public class MTOzaBag extends OzaBag implements MultiLabelLearner, MultiTargetRegressor { - public MTOzaBag() { + /** + * + */ + private static final long serialVersionUID = 1L; + + public MTOzaBag() { super(); this.baseLearnerOption = new ClassOption("baseLearner", 'l', "Classifier to train.", MultiLabelLearner.class, "multilabel.trees.ISOUPTree"); @@ -51,23 +56,9 @@ public MTOzaBag() { public void resetLearningImpl() { this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; MultiLabelLearner baseLearner = (MultiLabelLearner) getPreparedClassOption(this.baseLearnerOption); - baseLearner.resetLearning(); + baseLearner.setModelContext(this.modelContext); for (int i = 0; i < this.ensemble.length; i++) { this.ensemble[i] = baseLearner.copy(); - } - } - - @Override - public void setModelContext(InstancesHeader raw_header) { - - //set the multilabel model context - this.modelContext = raw_header; - - // reset ensemble - this.resetLearningImpl(); - - for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i].setModelContext(raw_header); this.ensemble[i].resetLearning(); } } @@ -77,14 +68,15 @@ public boolean isRandomizable() { return true; } - public Prediction getPredictionForInstance(MultiLabelInstance inst) { - DoubleVector[][] predictions = new DoubleVector[this.ensemble.length][getModelContext().numOutputAttributes()]; + public Prediction getPredictionForInstance(StructuredInstance inst) { + int numTargets = getModelContext().numOutputAttributes(); + DoubleVector[][] predictions = new DoubleVector[this.ensemble.length][numTargets]; for (int i = 0; i < this.ensemble.length; i++) { Prediction basePrediction = this.ensemble[i].getPredictionForInstance(inst); predictions[i] = ((MultiLabelPrediction) basePrediction).getPrediction(); } - DoubleVector[] prediction = new DoubleVector[getModelContext().numOutputAttributes()]; - for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + DoubleVector[] prediction = new DoubleVector[numTargets]; + for (int j = 0; j < numTargets; j++) { prediction[j] = new DoubleVector(); for (int i = 0; i < this.ensemble.length; i++) { prediction[j].addValues(predictions[i][j]); @@ -94,7 +86,7 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { return new MultiLabelPrediction(prediction); } - public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) { + public Prediction getPredictionForInstanceUsingN(StructuredInstance inst, int n) { int actual = Math.max(1, Math.min(n, this.ensemble.length)); DoubleVector[][] predictions = new DoubleVector[actual][getModelContext().numOutputAttributes()]; for (int i = 0; i < actual; i++) { @@ -113,13 +105,13 @@ public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { trainOnInstanceImpl((Instance) instance); } @Override public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance((MultiLabelInstance)example.getData()); + return getPredictionForInstance((StructuredInstance)example.getData()); } } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java index a0ce07563..da8fdadd3 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java @@ -1,12 +1,31 @@ package moa.classifiers.multilabel.trees; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Stack; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; + +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.ICVarianceReduction; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.multilabel.core.splitcriteria.WeightedICVarianceReduction; +import moa.classifiers.multilabel.trees.ISOUPTree.LeafNode; +import moa.classifiers.multilabel.trees.ISOUPTree.MultitargetPerceptron; +import moa.classifiers.multilabel.trees.ISOUPTree.Node; +import moa.classifiers.multilabel.trees.ISOUPTree.SplitNode; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; +import moa.classifiers.trees.FIMTDD.InnerNode; +import moa.classifiers.trees.ORTO.OptionNode; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; +import moa.core.StringUtils; public class ISOUPOptionTree extends ISOUPTree { @@ -15,7 +34,7 @@ public class ISOUPOptionTree extends ISOUPTree { private int optionNodeCount = 0; private int numTrees = 1; - + //region ================ OPTIONS ================ public IntOption maxTreesOption = new IntOption( @@ -38,7 +57,7 @@ public class ISOUPOptionTree extends ISOUPTree { public MultiChoiceOption optionNodeAggregationOption = new MultiChoiceOption( "optionNodeAggregation", - 'o', + 'p', "The aggregation method used to combine predictions in option nodes.", new String[]{"average", "bestTree"}, new String[]{"Average", "Best tree"}, 0); @@ -51,16 +70,16 @@ public class ISOUPOptionTree extends ISOUPTree { //endregion ================ OPTIONS ================ //region ================ CLASSES ================ - + public static class OptionNode extends InnerNode { /** * */ private static final long serialVersionUID = 1L; - + protected AutoExpandVector optionFFSSL; protected AutoExpandVector optionFFSeen; - + public OptionNode(ISOUPTree tree) { super(tree); } @@ -77,7 +96,7 @@ public void resetFF() { } } } - + public int getNumSubtrees() { int num = 0; for (Node child : children) { @@ -85,15 +104,15 @@ public int getNumSubtrees() { } return num; } - - public double[] getPrediction(MultiLabelInstance inst) { + + public double[] getPrediction(StructuredInstance inst) { double[][] predictions = new double[numChildren()][tree.getModelContext().numOutputAttributes()]; for (int i = 0; i < numChildren(); i++) { predictions[i] = getChild(i).getPrediction(inst); } return aggregate(predictions); } - + private double[] aggregate(double[][] predictions) { if (((ISOUPOptionTree) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average double[] sums = new double[tree.getModelContext().numOutputAttributes()]; @@ -111,7 +130,7 @@ private double[] aggregate(double[][] predictions) { return new double[] {}; } } - + public int directionForBestTree() { int d = 0; double min = Double.MAX_VALUE; @@ -128,22 +147,34 @@ public int directionForBestTree() { } return d; } - + public double getFFRatio(int childIndex, int targetIndex) { return optionFFSSL.get(childIndex).getValue(targetIndex) / optionFFSeen.get(childIndex).getValue(targetIndex); } - + protected boolean skipInLevelCount() { return true; } + + public void describeSubtree(StringBuilder out, int indent) { + for (int branch = 0; branch < children.size(); branch++) { + Node child = getChild(branch); + if (child != null) { + StringUtils.appendIndented(out, indent, "option"); + out.append(branch); + StringUtils.appendNewline(out); + child.describeSubtree(out, indent + 2); + } + } + } } - + //endregion ================ CLASSES ================ - + //region ================ METHODS ================ - + public String getPurposeString() { - return "Implementation of the ORTO tree as described by Ikonomovska et al."; + return "Implementation of the iSOUPOptionTree"; } public void resetLearningImpl() { @@ -151,7 +182,7 @@ public void resetLearningImpl() { this.optionNodeCount = 0; } - + protected Measurement[] getModelMeasurementsImpl() { return new Measurement[]{ new Measurement("number of subtrees", this.numTrees), @@ -159,9 +190,18 @@ protected Measurement[] getModelMeasurementsImpl() { //new Measurement("tree size (leaves)", this.leafNodeCount), new Measurement("number of option nodes", this.optionNodeCount),}; } - + + // region --- Object instantiation methods + + protected OptionNode newOptionNode() { + maxID++; + return new OptionNode(this); + } + + // endregion --- Object instantiation methods + @Override - public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + public void processInstance(StructuredInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { if (node instanceof OptionNode) { processInstanceOptionNode(inst, (OptionNode) node, prediction, normalError, growthAllowed, inAlternate); } else { @@ -225,7 +265,7 @@ public void processInstance(MultiLabelInstance inst, Node node, double[] predict // break; // } // } - + // if (iNode.changeDetection && !inAlternate) { // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { // iNode.initializeAlternateTree(); @@ -240,18 +280,18 @@ public void processInstance(MultiLabelInstance inst, Node node, double[] predict } } } - + } - - public void processInstanceOptionNode(MultiLabelInstance inst, OptionNode node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { -// if (node.changeDetection) { -// double error = Math.abs(prediction - inst.classValue()); -// node.sumOfAbsErrors += error; -// -// if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { -// node.initializeAlternateTree(); -// } -// } + + public void processInstanceOptionNode(StructuredInstance inst, OptionNode node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + // if (node.changeDetection) { + // double error = Math.abs(prediction - inst.classValue()); + // node.sumOfAbsErrors += error; + // + // if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + // node.initializeAlternateTree(); + // } + // } for (Node child : node.children) { int i = node.getChildIndex(child); @@ -266,7 +306,220 @@ public void processInstanceOptionNode(MultiLabelInstance inst, OptionNode node, processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); } } - + //endregion ================ METHODS ================ + protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) { + //System.out.println("Evaluating splits"); + //System.out.println(examplesSeen); + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + MultiLabelSplitCriterion splitCriterion = new WeightedICVarianceReduction(targetWeights); + + // Using this criterion, find the best split per attribute and rank the results + AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option + List acceptedSplits = new LinkedList(); + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine the number of splits to be performed + int numSplits = 0; + + // If only one split was returned, use it + if (bestSplitSuggestions.length == 1) { + numSplits = 1; + acceptedSplits.add(bestSplitSuggestions[0]); + } else if (bestSplitSuggestions.length > 1) { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + //System.out.print(hoeffdingBound); + //System.out.print(" "); + ///System.out.println(secondBestSuggestion.merit / bestSuggestion.merit); + if (secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) { + numSplits = 1; + acceptedSplits.add(bestSuggestion); + } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { + for (int i = 0; i < bestSplitSuggestions.length; i++) { + AttributeExpansionSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; + if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { + numSplits++; + acceptedSplits.add(suggestion); + } else { + break; + } + } + + } else if (hoeffdingBound < this.tieThresholdOption.getValue()) { + numSplits = 1; + acceptedSplits.add(bestSuggestion); + } + else { + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + // TODO pruning is currently disabled + for (int i = 0; i < node.attributeObservers.size(); i++) { + AttributeStatisticsObserver obs = node.attributeObservers.get(i); + if (obs != null) { + if (getModelContext().attribute(i).isNumeric()); + //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); + if (getModelContext().attribute(i).isNominal()); + // TODO nominal class observers + } + } + } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (numSplits > 0) { + double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); + log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); + + if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { + AttributeExpansionSuggestion splitDecision = acceptedSplits.get(0); + SplitNode newSplit = newSplitNode(splitDecision.getPredicate()); + newSplit.ID = node.ID; + + for (int i = 0; i < 2 /* TODO Hardcoded for Predicate class */; i++) { + LeafNode newChild = newLeafNode(); + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + //leafNodeCount--; + //innerNodeCount++; + //leafNodeCount += splitDecision.numSplits(); + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + parent.setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + } else { + + OptionNode optionNode = newOptionNode(); + optionNode.ID = node.ID; + + //leafNodeCount--; + int j = 0; + + for (AttributeExpansionSuggestion splitDecision : acceptedSplits) { + if (j > optionFactor || maxTreesOption.getValue() - numTrees <= 0) { + break; + } + SplitNode newSplit = newSplitNode(splitDecision.getPredicate()); + for (int i = 0; i < 2 /* TODO Hardcoded for Predicate class */; i++) { + LeafNode newChild = newLeafNode(); + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + + //leafNodeCount += splitDecision.numSplits(); + //innerNodeCount++; + numTrees++; + + newSplit.setParent(optionNode); + optionNode.setChild(j, newSplit); + j++; + } + + //innerNodeCount++; + optionNodeCount++; + + if (parent == null) { + treeRoot = optionNode; + } else { + parent.setChild(parentIndex, optionNode); + optionNode.setParent(parent); + } + + optionNode.resetFF(); + } + } + } + + // region --- Option tree methods + protected Node findWorstOption() { + Stack stack = new Stack(); + stack.add(treeRoot); + + double ratio = Double.MIN_VALUE; + Node out = null; + + while (!stack.empty()) { + Node node = stack.pop(); + if (node.getParent() instanceof OptionNode) { + OptionNode myParent = (OptionNode) node.getParent(); + int nodeIndex = myParent.getChildIndex(node); + DoubleVector nodeRatios = new DoubleVector(); + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + nodeRatios.setValue(i, myParent.getFFRatio(nodeIndex, i)); + } + double nodeRatio = nodeRatios.sumOfValues() / nodeRatios.numValues(); + + if (nodeRatio > ratio) { + ratio = nodeRatio; + out = node; + } + } + if (node instanceof InnerNode) { + for (Node child : ((InnerNode) node).children) { + stack.add(child); + } + } + } + + return out; + } + + protected void removeExcessTrees() { + while (numTrees > maxTreesOption.getValue()) { + Node option = findWorstOption(); + OptionNode parent = (OptionNode) option.parent; + int index = parent.getChildIndex(option); + + if (parent.children.size() == 2) { + parent.children.remove(index); + for (Node chld : parent.children) { + chld.parent = parent.parent; + parent.parent.setChild(parent.parent.getChildIndex(parent), chld); + } + } else { + AutoExpandVector children = new AutoExpandVector(); + AutoExpandVector optionFFSSL = new AutoExpandVector(); + AutoExpandVector optionFFSeen = new AutoExpandVector(); + + int seen = 0; + + for (int i = 0; i < parent.children.size() - 1; i++) { + if (parent.getChild(i) != option) { + children.add(parent.getChild(i)); + optionFFSSL.set(i, parent.optionFFSSL.get(i + seen)); + optionFFSeen.set(i, parent.optionFFSeen.get(i + seen)); + } else { + seen = 1; + } + } + + parent.children = children; + parent.optionFFSSL = optionFFSSL; + parent.optionFFSeen = optionFFSeen; + + assert parent.children.size() == parent.optionFFSSL.size(); + } + numTrees--; + } + } + } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index 3596120c3..853405dd8 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -26,15 +26,23 @@ package moa.classifiers.multilabel.trees; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.Vector; +import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -46,8 +54,8 @@ import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelNominalAttributeObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.multilabel.core.splitcriteria.ICVarianceReduction; import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.multilabel.core.splitcriteria.WeightedICVarianceReduction; import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.Predicate; import moa.core.AutoExpandVector; @@ -57,18 +65,18 @@ import moa.core.StringUtils; /** - * iSOUPTrees class for structured output prediction. + * iSOUPTree class for structured output prediction. * * @author Aljaž Osojnik (aljaz.osojnik@ijs.si) * @version $Revision: 1 $ */ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetRegressor { - + private static final long serialVersionUID = 1L; public Node treeRoot; - private double examplesSeen = 0.0; + protected double examplesSeen = 0.0; private DoubleVector sumOfValues = new DoubleVector(); private DoubleVector sumOfSquares = new DoubleVector(); @@ -76,6 +84,10 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR private DoubleVector sumOfAttrSquares = new DoubleVector(); public int maxID = 0; + + private BufferedWriter writer; + + public DoubleVector targetWeights; //region ================ OPTIONS ================ @@ -154,6 +166,13 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR 'n', "Don't normalize."); + public FlagOption randomForestBaseModelOption = new FlagOption( + "randomForestBaseModel", + 'z', + "Use the learner as a base model in a random forest."); + + public FileOption weightFile = new FileOption("targetWeightFile", 'w', "File with the weights of the targets.", null, null, false); + //endregion ================ OPTIONS ================ //region ================ CLASSES ================ @@ -169,7 +188,7 @@ public abstract static class Node extends AbstractMOAObject { protected ISOUPTree tree; // The parent of this particular node - protected SplitNode parent; + protected InnerNode parent; protected Node alternateTree; protected Node originalNode; @@ -191,6 +210,7 @@ public abstract static class Node extends AbstractMOAObject { public Node(ISOUPTree tree) { this.tree = tree; + this.ID = tree.maxID; } public void copyStatistics(Node node) { @@ -206,7 +226,7 @@ public int calcByteSize() { /** * Set the parent node */ - public void setParent(SplitNode parent) { + public void setParent(InnerNode parent) { this.parent = parent; } @@ -227,10 +247,10 @@ public void restartChangeDetection() { public void getDescription(StringBuilder sb, int i) {} - public double[] getPrediction(MultiLabelInstance inst) { + public double[] getPrediction(StructuredInstance inst) { return null; } - + public void describeSubtree(StringBuilder out, int indent) { StringUtils.appendIndented(out, indent, "Leaf"); } @@ -278,6 +298,8 @@ public static class LeafNode extends Node { public DoubleVector errorP = new DoubleVector(); public DoubleVector errorM = new DoubleVector(); + + public List inputIndexes = null; protected double examplesSeenAtLastSplitEvaluation = 0; @@ -289,17 +311,38 @@ public LeafNode(ISOUPTree tree) { if (tree.buildingModelTree()) { learningModel = tree.newLeafModel(); } + initializeInputIndexes(); examplesSeen = 0; sumOfValues = new DoubleVector(); sumOfSquares = new DoubleVector(); } + public void initializeInputIndexes() { + List indexes = new Vector(); + int numAttrs = tree.getModelContext().numInputAttributes(); + for (int i = 0; i < numAttrs; i++) { + indexes.add(i, i); + } + if (tree.buildingRandomForestTree()) { + // Select the first sqrt(n) attribute indexes + for (int i = 0; i < Math.ceil(Math.sqrt(numAttrs)); i++) { + int swap = i + tree.classifierRandom.nextInt(numAttrs - i); + int temp = indexes.get(i); + indexes.set(i, indexes.get(swap)); + indexes.set(swap, temp); + } + inputIndexes = indexes.subList(0, (int) Math.ceil(Math.sqrt(numAttrs))); + } else { + inputIndexes = indexes; + } + } + /** * Method to learn from an instance that passes the new instance to the perceptron learner, * and also prevents the class value from being truncated to an int when it is passed to the * attribute observer */ - public void learnFromInstance(MultiLabelInstance inst, double[] prediction, boolean growthAllowed) { + public void learnFromInstance(StructuredInstance inst, double[] prediction, boolean growthAllowed) { // Update the statistics for this node double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; @@ -323,7 +366,7 @@ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, bool if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); - for (int i = 0; i < inst.numInputAttributes(); i++) { + for (int i : inputIndexes) { AttributeStatisticsObserver obs = attributeObservers.get(i); if (obs == null) { // At this stage all nominal attributes are ignored @@ -362,7 +405,7 @@ public AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCri List bestSuggestions = new LinkedList(); - for (int i = 0; i < attributeObservers.size(); i++) { + for (int i : inputIndexes) { AttributeStatisticsObserver obs = attributeObservers.get(i); if (obs != null) { DoubleVector[] preSplitStatistics = new DoubleVector[tree.getModelContext().numOutputAttributes()]; @@ -387,11 +430,11 @@ public AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCri /** * Retrieve the class votes using the perceptron learner */ - public double[] getPredictionModel(MultiLabelInstance inst) { + public double[] getPredictionModel(StructuredInstance inst) { return learningModel.prediction(inst); } - public double[] getPredictionTargetMean(MultiLabelInstance inst) { + public double[] getPredictionTargetMean(StructuredInstance inst) { double[] pred = new double[inst.numOutputAttributes()]; for (int i = 0; i < inst.numOutputAttributes(); i++) { if (examplesSeen > 0) { @@ -403,7 +446,7 @@ public double[] getPredictionTargetMean(MultiLabelInstance inst) { return pred; } - public double[] getPrediction(MultiLabelInstance inst) { + public double[] getPrediction(StructuredInstance inst) { if (tree.buildingModelTree()) { double[] predictionP = getPredictionModel(inst); double[] predictionM = getPredictionTargetMean(inst); @@ -438,11 +481,14 @@ public void checkForSplit() { } public void describeSubtree(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, "Leaf "); + StringUtils.appendIndented(out, indent, "Leaf"); + StringUtils.appendNewline(out); + if (tree.buildingModelTree()) { - learningModel.getModelDescription(out, 0); + learningModel.getModelDescription(out, indent + 2); } else { //out.append(tree.getClassNameString() + " = " + String.format("%.4f", (sumOfValues / examplesSeen))); + out.append("Leaf node"); StringUtils.appendNewline(out); } } @@ -567,7 +613,7 @@ public SplitNode(Predicate predicate, ISOUPTree tree) { ID = tree.maxID; } - public int instanceChildIndex(MultiLabelInstance inst) { + public int instanceChildIndex(StructuredInstance inst) { return (predicate.evaluate(inst)) ? 0 : 1; } @@ -577,7 +623,7 @@ public void describeSubtree(StringBuilder out, int indent) { if (child != null) { if (branch == 0) { StringUtils.appendIndented(out, indent, "if "); - this.predicate.getDescription(out, 0); + this.predicate.getDescription(out, 0, tree.getModelContext()); } else { StringUtils.appendIndented(out, indent, "else"); } @@ -588,7 +634,7 @@ public void describeSubtree(StringBuilder out, int indent) { } } - public double[] getPrediction(MultiLabelInstance inst) { + public double[] getPrediction(StructuredInstance inst) { return children.get(predicate.evaluate(inst) ? 0 : 1).getPrediction(inst); } } @@ -635,7 +681,7 @@ public void initializeWeights() { /** * Update the model using the provided instance */ - public void updatePerceptron(MultiLabelInstance inst) { + public void updatePerceptron(StructuredInstance inst) { // Update attribute statistics instancesSeen += inst.weight(); @@ -653,7 +699,7 @@ public void updatePerceptron(MultiLabelInstance inst) { } } - public void updateWeights(MultiLabelInstance inst, double learningRatio) { + public void updateWeights(StructuredInstance inst, double learningRatio) { if (instancesSeen > 1.0) { // Compute the normalized instance and the delta double[] normalizedInput = tree.normalizedInputVector(inst); @@ -694,7 +740,7 @@ public double[] prediction(double[] instanceValues) { return out; } - private double[] prediction(MultiLabelInstance inst) { + private double[] prediction(StructuredInstance inst) { double[] normalizedInput = tree.normalizedInputVector(inst); double[] normalizedPrediction = prediction(normalizedInput); return denormalizePrediction(normalizedPrediction); @@ -716,18 +762,18 @@ private double[] denormalizePrediction(double[] normalizedPrediction) { } public void getModelDescription(StringBuilder out, int indent) { - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { - StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "]"); - if (getModelContext() != null) { - for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { - if (getModelContext().attribute(j).isNumeric()) { - out.append((j == 0 || weights[i][j] < 0) ? " " : " + "); - out.append(String.format("%.4f", weights[i][j])); + if (getModelContext() != null) { + for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "] ="); + for (int j = 0; j < getModelContext().numInputAttributes(); j++) { + if (getModelContext().inputAttribute(j).isNumeric()) { + out.append((j == 0 && weights[i][j] >= 0) ? " " : (weights[i][j] < 0) ? " - " : " + "); + out.append(String.format("%.4f", Math.abs(weights[i][j]))); out.append(" * "); - out.append(getAttributeNameString(j)); + out.append(getModelContext().inputAttribute(j).name()); } } - out.append(" + " + weights[i][getModelContext().numOutputAttributes()]); + out.append((weights[i][getModelContext().numInputAttributes()] < 0 ? " - " : " + ") + String.format("%.4f", Math.abs(weights[i][getModelContext().numInputAttributes()]))); } StringUtils.appendNewline(out); } @@ -739,7 +785,9 @@ public void getModelDescription(StringBuilder out, int indent) { //region ================ METHODS ================ // Regressor methods - public ISOUPTree() {} + public ISOUPTree() { + super(); + } public String getPurposeString() { return "Implementation of the iSOUP-Tree algorithm as described by Osojnik et al."; @@ -753,8 +801,19 @@ public void resetLearningImpl() { sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); + loadWeights(); } + public void loadWeights() { + targetWeights = new DoubleVector(); + try { + List lines = Files.readAllLines(Paths.get(weightFile.getValue()), Charset.defaultCharset()); + for (int i = 0 ; i < lines.size(); i++) targetWeights.setValue(i, Double.valueOf(lines.get(i))); + } catch (Exception e) { + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) targetWeights.setValue(i, 1.0); + } + } + public boolean isRandomizable() { return true; } @@ -762,7 +821,7 @@ public boolean isRandomizable() { public void getModelDescription(StringBuilder out, int indent) { if (treeRoot != null) treeRoot.describeSubtree(out, indent); } - + protected Measurement[] getModelMeasurementsImpl() { return new Measurement[]{ //new Measurement("tree size (nodes)", this.leafNodeCount + this.splitNodeCount), @@ -778,7 +837,7 @@ public int calcByteSize() { return size; } - public Prediction getPredictionForInstance(MultiLabelInstance inst) { + public Prediction getPredictionForInstance(StructuredInstance inst) { checkRoot(); double[] predictionVector = treeRoot.getPrediction(inst); MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); @@ -788,7 +847,7 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { return prediction; } - public double[] normalizedInputVector(MultiLabelInstance inst) { + public double[] normalizedInputVector(StructuredInstance inst) { // Normalize Instance double[] normalizedInput = new double[inst.numInputAttributes()+1]; if (normalize()) { @@ -818,7 +877,7 @@ public double[] normalizedInputVector(MultiLabelInstance inst) { return normalizedInput; } - public double[] normalizedTargetVector(MultiLabelInstance inst) { + public double[] normalizedTargetVector(StructuredInstance inst) { double[] out = new double[getModelContext().numOutputAttributes()]; if (normalize()) { for (int i = 0; i < inst.numOutputAttributes(); i++) { @@ -855,7 +914,7 @@ public double[] normalizeTargetVector(double[] pred) { } - public double normalizeTargetValue(MultiLabelInstance inst, int i) { + public double normalizeTargetValue(StructuredInstance inst, int i) { if (normalize()) { if (examplesSeen > 1) { double value = inst.valueOutputAttribute(i); @@ -884,7 +943,7 @@ public double normalizeTargetValue(double value, int i) { } else return value; } - public double[] getNormalizedError(MultiLabelInstance inst, double[] prediction) { + public double[] getNormalizedError(StructuredInstance inst, double[] prediction) { double[] normalPrediction = normalizeTargetVector(prediction); double[] normalValue = normalizedTargetVector(inst); double[] out = new double[getModelContext().numOutputAttributes()]; @@ -898,7 +957,7 @@ public double[] getNormalizedError(MultiLabelInstance inst, double[] prediction) /** * Method for updating (training) the model using a new instance */ - public void trainOnInstanceImpl(MultiLabelInstance inst) { + public void trainOnInstanceImpl(StructuredInstance inst) { if (inst.weight() > 0) { checkRoot(); @@ -920,7 +979,7 @@ public void trainOnInstanceImpl(MultiLabelInstance inst) { } } - public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + public void processInstance(StructuredInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { Node currentNode = node; while (true) { if (currentNode instanceof LeafNode) { @@ -1031,22 +1090,24 @@ protected void checkRoot() { } public static double computeHoeffdingBound(double range, double confidence, double n) { - return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); + return Math.sqrt(((range * range) * Math.log(1 / confidence)) / (2.0 * n)); } public boolean buildingModelTree() { return !regressionTreeOption.isSet(); } + + public boolean buildingRandomForestTree() { + return randomForestBaseModelOption.isSet(); + } public boolean normalize() { return !doNotNormalizeOption.isSet(); } - protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) { - //System.out.println("Evaluating splits"); - //System.out.println(examplesSeen); + protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) { // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - MultiLabelSplitCriterion splitCriterion = new ICVarianceReduction(); + MultiLabelSplitCriterion splitCriterion = new WeightedICVarianceReduction(targetWeights); // Using this criterion, find the best split per attribute and rank the results AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option @@ -1054,7 +1115,6 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) // Declare a variable to determine if any of the splits should be performed boolean shouldSplit = false; - // If only one split was returned, use it if (bestSplitSuggestions.length < 2) { shouldSplit = bestSplitSuggestions.length > 0; @@ -1074,9 +1134,6 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - //System.out.print(hoeffdingBound); - //System.out.print(" "); - ///System.out.println(secondBestSuggestion.merit / bestSuggestion.merit); if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { shouldSplit = true; } @@ -1101,9 +1158,11 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; SplitNode newSplit = newSplitNode(splitDecision.predicate); + newSplit.ID = node.ID; newSplit.copyStatistics(node); newSplit.changeDetection = node.changeDetection; newSplit.ID = node.ID; + log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) LeafNode newChild = newLeafNode(); if (buildingModelTree()) { @@ -1126,7 +1185,7 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) } } - public double computeSD(double squaredVal, double val, double size) { + public double computeSD(double squaredVal, double val, double size) { if (size > 1) return Math.sqrt((squaredVal - ((val * val) / size)) / size); else @@ -1141,6 +1200,38 @@ public static double scalarProduct(DoubleVector u, DoubleVector v) { return ret; } //endregion --- Processing methods - + + public void initWriter(String filename) { + try { + writer = new BufferedWriter(new FileWriter(filename)); + writer.write(""); + writer.close(); + writer = new BufferedWriter(new FileWriter(filename, true)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void closeWriter() { + try { + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + writer = null; + + } + + public void log(String s) { + if (writer != null) { + try { + writer.write(s + "\n"); + writer.flush(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + //endregion ================ METHODS ================ } diff --git a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java index 56c3985a5..93c1c94a1 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java @@ -16,7 +16,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -47,7 +47,7 @@ public void resetLearningImpl() { } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { if (this.hasStarted == false){ this.ensemble = new Classifier[instance.numberOutputTargets()]; Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); @@ -65,7 +65,7 @@ public void trainOnInstanceImpl(MultiLabelInstance instance) { protected InstancesHeader[] header; - protected Instance transformInstance(MultiLabelInstance inst, int outputIndex) { + protected Instance transformInstance(StructuredInstance inst, int outputIndex) { if (header == null) { this.header = new InstancesHeader[this.ensemble.length]; } @@ -128,7 +128,7 @@ public void getModelDescription(StringBuilder out, int indent) { @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { Prediction prediction=null; if (this.hasStarted){ prediction=new MultiLabelPrediction(ensemble.length); diff --git a/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java b/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java index 0f61f4e73..9f08ed855 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java +++ b/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java @@ -4,7 +4,7 @@ import com.yahoo.labs.samoa.instances.DenseInstanceData; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -37,7 +37,7 @@ public void resetLearningImpl() { } @Override - public void trainOnInstanceImpl(MultiLabelInstance inst) { + public void trainOnInstanceImpl(StructuredInstance inst) { int numOutputs = inst.numberOutputTargets(); Prediction prediction = new MultiLabelPrediction(numOutputs); @@ -65,7 +65,7 @@ public boolean isRandomizable() { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance inst) { + public Prediction getPredictionForInstance(StructuredInstance inst) { //return (lastSeenClasses!=null) ? this.lastSeenClasses : new MultiLabelPrediction(); return (lastSeenClasses!=null) ? this.lastSeenClasses : null; } diff --git a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java index 8d835fb5a..fb5505ef7 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java @@ -1,7 +1,8 @@ package moa.classifiers.rules.core; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; import moa.core.StringUtils; @@ -23,10 +24,10 @@ public NominalRulePredicate(int inputAttributeIndex, double attributeValue, bool } @Override public boolean evaluate(Instance instance){ - return evaluate((MultiLabelInstance) instance); + return evaluate((StructuredInstance) instance); } - public boolean evaluate(MultiLabelInstance instance) { + public boolean evaluate(StructuredInstance instance) { if (instance.isMissing(inputAttributeIndex)) { return false; } @@ -68,5 +69,11 @@ public int getAttributeIndex() { public boolean isEqualOrLess() { return isEqual; } - + @Override + public void getDescription(StringBuilder sb, int indent, InstancesHeader header) { + if(isEqual) + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, inputAttributeIndex) + " == " + attributeValue); + else + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, inputAttributeIndex) + " <> " + attributeValue); + } } diff --git a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java index 6084fbae6..8387610c0 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java @@ -1,7 +1,8 @@ package moa.classifiers.rules.core; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; import moa.core.StringUtils; @@ -23,10 +24,10 @@ public NumericRulePredicate(int inputAttributeIndex, double attributeValue, bool } @Override public boolean evaluate(Instance instance){ - return evaluate((MultiLabelInstance) instance); + return evaluate((StructuredInstance) instance); } - public boolean evaluate(MultiLabelInstance instance) { + public boolean evaluate(StructuredInstance instance) { if (instance.isMissing(inputAttributeIndex)) { return false; } @@ -69,5 +70,14 @@ public boolean isEqualOrLess() { return isEqualOrLower; } + public double getAttributeValue() { + return attributeValue; + } + @Override + public void getDescription(StringBuilder sb, int indent, InstancesHeader header) { + if(isEqualOrLower) + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, inputAttributeIndex) + " <= " + attributeValue); + else + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, inputAttributeIndex) + " > " + attributeValue); } } diff --git a/moa/src/main/java/moa/classifiers/rules/core/Predicate.java b/moa/src/main/java/moa/classifiers/rules/core/Predicate.java index f7f120d5d..75517efc3 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/Predicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/Predicate.java @@ -20,6 +20,7 @@ package moa.classifiers.rules.core; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; public interface Predicate { @@ -28,5 +29,6 @@ public interface Predicate { public int getAttributeIndex(); public boolean isEqualOrLess(); public void getDescription(StringBuilder sb, int indent); + public void getDescription(StringBuilder sb, int indent, InstancesHeader header); } diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java index dea1adf2c..13a4f85ba 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java @@ -1,7 +1,7 @@ package moa.classifiers.rules.core.anomalydetection; import moa.options.AbstractOptionHandler; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; public abstract class AbstractAnomalyDetector extends AbstractOptionHandler implements AnomalyDetector { @@ -12,7 +12,7 @@ public abstract class AbstractAnomalyDetector extends AbstractOptionHandler impl private static final long serialVersionUID = 1L; @Override - public abstract boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance); + public abstract boolean updateAndCheckAnomalyDetection(StructuredInstance instance); @Override public AnomalyDetector copy() { diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java index 211fbbc29..9297ebe1e 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java @@ -11,7 +11,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; public class AnomalinessRatioScore extends AbstractAnomalyDetector { @@ -54,7 +54,7 @@ public class AnomalinessRatioScore extends AbstractAnomalyDetector { @Override - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance) { boolean isAnomaly=false; if(probabilityFunction==null){ weightSeen=0.0; diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalyDetector.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalyDetector.java index f4d4647d7..6e9361842 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalyDetector.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalyDetector.java @@ -1,5 +1,5 @@ package moa.classifiers.rules.core.anomalydetection; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.options.OptionHandler; @@ -18,7 +18,7 @@ public interface AnomalyDetector extends OptionHandler { * * @return true if anomaly is detected and false otherwise */ - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance); + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance); @Override diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java index e7e44a113..722f15dfa 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java @@ -2,7 +2,7 @@ import moa.core.ObjectRepository; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; public class NoAnomalyDetection extends AbstractAnomalyDetector{ @@ -17,7 +17,7 @@ public void getDescription(StringBuilder sb, int indent) { } @Override - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance) { return false; } diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java index 08d846ea9..53cc8556c 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java @@ -11,7 +11,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; public class OddsRatioScore extends AbstractAnomalyDetector { @@ -48,7 +48,7 @@ public class OddsRatioScore extends AbstractAnomalyDetector { private ProbabilityFunction probabilityFunction; @Override - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance) { boolean isAnomaly=false; if(probabilityFunction==null){ weightSeen=0.0; diff --git a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java index 49a82a67d..df2405a5a 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java @@ -20,6 +20,7 @@ package moa.classifiers.rules.core.conditionaltests; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.core.conditionaltests.NominalAttributeBinaryTest; import moa.classifiers.rules.core.Predicate; @@ -78,6 +79,14 @@ public int getAttributeIndex() { public boolean isEqualOrLess() { return state; } + + @Override + public void getDescription(StringBuilder sb, int indent, InstancesHeader header) { + if(state) + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, attIndex) + " = " + attValue); + else + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, attIndex) + " <> " + attValue); + } } diff --git a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java index 90560586b..37650e7ca 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java @@ -169,4 +169,11 @@ public boolean isEqualOrLess() { return state; } + @Override + public void getDescription(StringBuilder sb, int indent, InstancesHeader header) { + String compareChar = (operator == 0) ? "=" : (operator == 1) ? "<=" : ">"; + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, attIndex) + compareChar + attValue); + } + + } diff --git a/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java b/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java index 45ae75b74..a5e48b1a8 100644 --- a/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java +++ b/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java @@ -25,7 +25,7 @@ import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.classifiers.AbstractClassifier; import moa.classifiers.Regressor; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java index 2672f58f5..44a24ae5f 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java @@ -55,7 +55,7 @@ import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; @@ -147,7 +147,7 @@ public AMRulesMultiLabelLearner(double attributesPercentage) { @Override - public Prediction getPredictionForInstance(MultiLabelInstance inst) { + public Prediction getPredictionForInstance(StructuredInstance inst) { /*MultiLabelVote vote=getVotes(inst); if(vote!=null) return vote.getVote(); @@ -166,7 +166,7 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { * returns the prediction of the instance. * Called in WeightedRandomRules */ - public ErrorWeightedVoteMultiLabel getVotes(MultiLabelInstance instance) { + public ErrorWeightedVoteMultiLabel getVotes(StructuredInstance instance) { ErrorWeightedVoteMultiLabel errorWeightedVote=newErrorWeightedVote(); //DoubleVector combinedVote = new DoubleVector(); debug("Test",3); @@ -237,7 +237,7 @@ public boolean isRandomizable(){ private double numInstances; //Just for statistics @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { /** * AMRules Algorithm * @@ -398,7 +398,7 @@ protected void debug(String string, int level) { } } - protected void VerboseToConsole(MultiLabelInstance inst) { + protected void VerboseToConsole(StructuredInstance inst) { if(VerbosityOption.getValue()>=5){ System.out.println(); System.out.println("I) Dataset: "+inst.dataset().getRelationName()); diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java index 4a8a18ccf..9c179d2f6 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java @@ -8,7 +8,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -95,9 +95,9 @@ public LearningLiteral(int [] outputsToLearn){ this.outputsToLearn=outputsToLearn.clone(); } - abstract public void trainOnInstance(MultiLabelInstance instance); + abstract public void trainOnInstance(StructuredInstance instance); - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { if (learner!=null) return learner.getPredictionForInstance(instance); else @@ -107,7 +107,7 @@ public Prediction getPredictionForInstance(MultiLabelInstance instance) { public abstract boolean tryToExpand(double splitConfidence, double tieThresholdOption); - public boolean updateAndCheckChange(MultiLabelInstance instance) { + public boolean updateAndCheckChange(StructuredInstance instance) { boolean hasChanged=false; if (hasStarted){ if (changeDetectors==null){ @@ -133,7 +133,7 @@ public boolean updateAndCheckChange(MultiLabelInstance instance) { protected abstract double[] getNormalizedErrors(Prediction prediction, Instance inst); - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance) { if(hasStarted) return anomalyDetector.updateAndCheckAnomalyDetection(instance); else @@ -239,7 +239,7 @@ public void setAttributesPercentage(double attributesPercentage) { this.attributesPercentage=attributesPercentage; } - protected void initializeAttibutesMask(MultiLabelInstance inst) { + protected void initializeAttibutesMask(StructuredInstance inst) { int numInputAttributes=inst.numInputAttributes(); int numAttributesSelected=(int)Math.round(numInputAttributes*attributesPercentage/100); diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java index 26ae4e0d9..f9e2c5c82 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java @@ -2,7 +2,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; import java.util.Arrays; @@ -157,7 +157,7 @@ private AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCr } @Override - public void trainOnInstance(MultiLabelInstance instance) { + public void trainOnInstance(StructuredInstance instance) { if (attributesMask==null) initializeAttibutesMask(instance); diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java index 6bd641395..0fb2aba8b 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Random; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; import moa.AbstractMOAObject; @@ -63,7 +63,7 @@ public void setRuleNumberID(int ruleNumberID) { this.ruleNumberID = ruleNumberID; } - public boolean isCovering(MultiLabelInstance inst) { + public boolean isCovering(StructuredInstance inst) { boolean isCovering = true; for (Literal l : literalList) { if (l.evaluate(inst) == false) { @@ -90,15 +90,15 @@ public void getDescription(StringBuilder out, int indent) { StringUtils.appendNewline(out); } - public boolean updateChangeDetection(MultiLabelInstance instance) { + public boolean updateChangeDetection(StructuredInstance instance) { return this.learningLiteral.updateAndCheckChange(instance); } - public boolean updateAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAnomalyDetection(StructuredInstance instance) { return this.learningLiteral.updateAndCheckAnomalyDetection(instance); } - public void trainOnInstance(MultiLabelInstance instance) { + public void trainOnInstance(StructuredInstance instance) { learningLiteral.trainOnInstance(instance); } @@ -114,7 +114,7 @@ public LearningLiteral getLearningNode() { return learningLiteral.getErrors(); } - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { return learningLiteral.getPredictionForInstance(instance); } diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java index ddcad8f6c..b96ddd2a7 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java @@ -5,7 +5,7 @@ import moa.tasks.TaskMonitor; import com.github.javacliparser.FloatOption; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; public abstract class AbstractMultiLabelErrorMeasurer extends AbstractOptionHandler implements MultiTargetErrorMeasurer{ @@ -27,7 +27,7 @@ public void addPrediction(Prediction prediction, Prediction trueClass){ addPrediction(prediction, trueClass); } - abstract public void addPrediction(Prediction prediction, MultiLabelInstance inst); + abstract public void addPrediction(Prediction prediction, StructuredInstance inst); abstract public double getCurrentError(); diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java index 97ee491ac..5b2bc3be8 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java @@ -1,6 +1,6 @@ package moa.classifiers.rules.multilabel.errormeasurers; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -11,7 +11,7 @@ public abstract class AbstractMultiTargetErrorMeasurer extends AbstractMultiLabe */ private static final long serialVersionUID = 1L; - public void addPrediction(Prediction prediction, MultiLabelInstance inst){ + public void addPrediction(Prediction prediction, StructuredInstance inst){ int numOutputs=inst.numberOutputTargets(); Prediction trueClass= new MultiLabelPrediction(numOutputs); for (int i=0; i= tree.gracePeriodOption.getValue()) { int index = (parent != null) ? parent.getChildIndex(this) : 0; - tree.attemptToSplit(this, parent, index); + tree.attemptToSplit(this, parent, index, inst, prediction); // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation examplesSeenAtLastSplitEvaluation = examplesSeen; @@ -553,6 +552,7 @@ public String getPurposeString() { public FIMTDDPerceptron(FIMTDDPerceptron original) { this.tree = original.tree; weightAttribute = original.weightAttribute.clone(); + instancesSeen = original.instancesSeen / 2; } public FIMTDDPerceptron(FIMTDD tree) { @@ -742,6 +742,18 @@ public double getNormalizedError(Instance inst, double prediction) { return Math.abs(normalValue - normalPrediction); } + + public void updateStatistics(Instance inst) { + examplesSeen += inst.weight(); + sumOfValues += inst.weight() * inst.classValue(); + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int aIndex = modelAttIndexToInstanceAttIndex(i, inst); + sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); + } + } /** * Method for updating (training) the model using a new instance @@ -754,16 +766,7 @@ public void trainOnInstanceImpl(Instance inst) { processInstance(inst, treeRoot, prediction, normalError, true, false); - examplesSeen += inst.weight(); - sumOfValues += inst.weight() * inst.classValue(); - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int aIndex = modelAttIndexToInstanceAttIndex(i, inst); - sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); - sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); - } - + updateStatistics(inst); } @@ -867,7 +870,7 @@ protected FIMTDDPerceptron newLeafModel() { // region --- Processing methods - protected void checkRoot() { + public void checkRoot() { if (treeRoot == null) { treeRoot = newLeafNode(); leafNodeCount = 1; @@ -882,7 +885,7 @@ public boolean buildingModelTree() { return !regressionTreeOption.isSet(); } - protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex, Instance inst, double prediction) { // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index 2f7ca3d52..5c48c0e21 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -334,7 +334,7 @@ protected OptionNode newOptionNode() { // region --- Processing methods - protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex, Instance inst, double prediction) { // Initialize the split criterion SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); @@ -380,12 +380,10 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { } else { break; } - } - } else if (hoeffdingBound < tieThresholdOption.getValue()) { numSplits = 1; - acceptedSplits.add(bestSplitSuggestions[0]); + acceptedSplits.add(bestSuggestion); } else { // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer for (int i = 0; i < node.attributeObservers.size(); i++) { AttributeClassObserver obs = node.attributeObservers.get(i); diff --git a/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java index aec992e29..5b87a670b 100644 --- a/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java @@ -27,7 +27,7 @@ import com.yahoo.labs.samoa.instances.DenseInstanceData; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; /** @@ -59,7 +59,7 @@ public void reset() { @Override public void addResult(Example example, Prediction prediction) { - MultiLabelInstance inst = (MultiLabelInstance) example.getData(); + StructuredInstance inst = (StructuredInstance) example.getData(); if (numberOutputs == 0) { numberOutputs = inst.numberOutputTargets(); } diff --git a/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java index 2b43a72a6..24d45642d 100644 --- a/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java @@ -30,7 +30,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; /** @@ -152,7 +152,7 @@ public void prepareForUseImpl(TaskMonitor monitor, @Override public void addResult(Example testInst, Prediction prediction) { - MultiLabelInstance inst=(MultiLabelInstance) testInst.getData(); + StructuredInstance inst=(StructuredInstance) testInst.getData(); double weight = inst.weight(); if (numberOutputs == 0) { numberOutputs = inst.numberOutputTargets(); diff --git a/moa/src/main/java/moa/evaluation/MultilabelWindowClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/MultilabelWindowClassificationPerformanceEvaluator.java index b1374ff95..b26c131c0 100644 --- a/moa/src/main/java/moa/evaluation/MultilabelWindowClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/MultilabelWindowClassificationPerformanceEvaluator.java @@ -25,7 +25,7 @@ import moa.core.Example; import moa.core.Measurement; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; /** @@ -110,7 +110,7 @@ public void addResult(Example example, double[] p_y) { @Override public void addResult(Example example, Prediction prediction) { - MultiLabelInstance inst = (MultiLabelInstance) example.getData(); + StructuredInstance inst = (StructuredInstance) example.getData(); if (inst.weight() > 0.0) { int numberOutputs = inst.numOutputAttributes(); if (numberOutputs <= 1) { diff --git a/moa/src/main/java/moa/streams/ArffFileStream.java b/moa/src/main/java/moa/streams/ArffFileStream.java index c701d431d..408c6d2da 100644 --- a/moa/src/main/java/moa/streams/ArffFileStream.java +++ b/moa/src/main/java/moa/streams/ArffFileStream.java @@ -41,8 +41,7 @@ * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * @version $Revision: 7 $ */ -public class ArffFileStream extends AbstractOptionHandler implements - InstanceStream { +public class ArffFileStream extends AbstractOptionHandler implements InstanceStream { @Override public String getPurposeString() { @@ -82,8 +81,7 @@ public ArffFileStream(String arffFileName, int classIndex) { } @Override - public void prepareForUseImpl(TaskMonitor monitor, - ObjectRepository repository) { + public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { restart(); } @@ -127,8 +125,7 @@ public void restart() { InputStream fileStream = new FileInputStream(this.arffFileOption.getFile()); this.fileProgressMonitor = new InputStreamProgressMonitor( fileStream); - this.fileReader = new BufferedReader(new InputStreamReader( - this.fileProgressMonitor)); + this.fileReader = new BufferedReader(new InputStreamReader(this.fileProgressMonitor)); int classIndex = this.classIndexOption.getValue(); this.instances = new Instances(this.fileReader, 1, classIndex); if (classIndex < 0) { From 60b81db2af688ed40ee2a837addc3ae2ba666a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Thu, 24 Mar 2016 13:16:58 +0100 Subject: [PATCH 12/33] Instance, InstanceHeader, ArffReader, etc. rework --- .../labs/samoa/instances/ArffLoader.java | 147 ++-- .../instances/HierarhicalInstanceImpl.java | 452 ------------ .../yahoo/labs/samoa/instances/Instance.java | 12 +- .../labs/samoa/instances/InstanceImpl.java | 17 +- .../samoa/instances/InstanceInformation.java | 127 ++-- .../yahoo/labs/samoa/instances/Instances.java | 542 -------------- .../labs/samoa/instances/InstancesHeader.java | 674 ++++++++++++++++-- .../instances/MultiTargetArffLoader.java | 43 +- .../com/yahoo/labs/samoa/instances/Range.java | 1 + .../SamoaToWekaInstanceConverter.java | 4 +- .../samoa/instances/StructuredInstance.java | 3 + .../WekaToSamoaInstanceConverter.java | 12 +- .../moa/classifiers/AbstractClassifier.java | 20 +- .../bayes/NaiveBayesMultinomial.java | 4 +- .../InstanceConditionalTest.java | 3 +- .../NominalAttributeBinaryTest.java | 1 + .../NominalAttributeMultiwayTest.java | 1 + .../NumericAttributeBinaryTest.java | 1 + .../main/java/moa/classifiers/lazy/kNN.java | 9 +- .../java/moa/classifiers/lazy/kNNwithPAW.java | 4 +- .../classifiers/lazy/kNNwithPAWandADWIN.java | 4 +- .../neighboursearch/DistanceFunction.java | 6 +- .../neighboursearch/EuclideanDistance.java | 6 +- .../lazy/neighboursearch/KDTree.java | 22 +- .../lazy/neighboursearch/LinearNNSearch.java | 10 +- .../NearestNeighbourSearch.java | 12 +- .../neighboursearch/NormalizableDistance.java | 10 +- .../kdtrees/KDTreeNodeSplitter.java | 8 +- .../kdtrees/KMeansInpiredMethod.java | 8 +- .../main/java/moa/classifiers/meta/ADACC.java | 6 +- .../meta/AccuracyUpdatedEnsemble.java | 8 +- .../meta/AccuracyWeightedEnsemble.java | 16 +- .../moa/classifiers/meta/RandomRules.java | 4 +- .../meta/TemporallyAugmentedClassifier.java | 8 +- .../moa/classifiers/meta/WEKAClassifier.java | 2 +- .../LocalMultiTargetClassifier.java | 1 + .../multilabel/MEKAClassifier.java | 8 +- .../multilabel/MajorityLabelset.java | 4 +- .../multilabel/MultilabelHoeffdingTree.java | 9 +- .../multilabel/meta/OzaBagAdwinML.java | 6 +- .../classifiers/multilabel/meta/OzaBagML.java | 6 +- .../multilabel/trees/ISOUPTree.java | 5 + .../BasicMultiTargetRegressor.java | 4 +- .../rules/core/NominalRulePredicate.java | 1 + .../rules/core/NumericRulePredicate.java | 1 + .../NominalAttributeBinaryRulePredicate.java | 1 + .../NumericAttributeBinaryRulePredicate.java | 1 + .../rules/meta/RandomAMRulesOld.java | 1 - .../moa/clusterers/AbstractClusterer.java | 4 +- .../main/java/moa/clusterers/Clusterer.java | 2 +- moa/src/main/java/moa/clusterers/CobWeb.java | 14 +- .../clusterers/WekaClusteringAlgorithm.java | 10 +- .../moa/core/MultilabelInstancesHeader.java | 4 +- moa/src/main/java/moa/core/SizeOf.java | 2 +- .../core/utils/AttributeDefinitionUtil.java | 121 ++++ .../main/java/moa/core/utils/Converter.java | 8 +- .../BasicMultiLabelPerformanceEvaluator.java | 4 +- .../visualization/RunOutlierVisualizer.java | 4 +- .../moa/gui/visualization/RunVisualizer.java | 4 +- .../moa/gui/visualization/WekaExplorer.java | 4 +- .../main/java/moa/streams/ArffFileStream.java | 55 +- .../moa/streams/CachedInstancesStream.java | 6 +- .../moa/streams/ConceptDriftRealStream.java | 13 +- .../java/moa/streams/ConceptDriftStream.java | 3 +- .../main/java/moa/streams/ExampleStream.java | 3 +- .../main/java/moa/streams/FilteredStream.java | 3 +- .../java/moa/streams/MultiFilteredStream.java | 2 +- .../moa/streams/MultiLabelFilteredStream.java | 4 +- .../streams/MultiTargetArffFileStream.java | 290 ++++---- .../moa/streams/clustering/FileStream.java | 43 +- .../clustering/RandomRBFGeneratorEvents.java | 4 +- .../streams/clustering/SimpleCSVStream.java | 6 +- .../moa/streams/filters/AddNoiseFilter.java | 3 +- .../java/moa/streams/filters/RBFFilter.java | 7 +- .../java/moa/streams/filters/ReLUFilter.java | 6 +- .../RemoveDiscreteAttributeFilter.java | 4 +- .../filters/ReplacingMissingValuesFilter.java | 1 + .../filters/SelectAttributesFilter.java | 16 +- .../streams/generators/AgrawalGenerator.java | 4 +- .../generators/HyperplaneGenerator.java | 4 +- .../moa/streams/generators/LEDGenerator.java | 4 +- .../streams/generators/LEDGeneratorDrift.java | 1 + .../generators/RandomRBFGenerator.java | 4 +- .../generators/RandomTreeGenerator.java | 4 +- .../moa/streams/generators/SEAGenerator.java | 4 +- .../streams/generators/STAGGERGenerator.java | 4 +- .../streams/generators/WaveformGenerator.java | 4 +- .../generators/WaveformGeneratorDrift.java | 1 + .../cd/AbstractConceptDriftGenerator.java | 4 +- .../multilabel/MetaMultilabelGenerator.java | 7 +- .../multilabel/MultilabelArffFileStream.java | 4 +- .../java/moa/tasks/CacheShuffledStream.java | 4 +- .../moa/tasks/EvaluateInterleavedChunks.java | 4 +- .../tasks/EvaluatePeriodicHeldOutTest.java | 4 +- .../instances/MultiTargetArffLoaderTest.java | 31 +- .../AbstractClassifierTestCase.java | 14 +- .../filters/SelectAttributesFilterTest.java | 4 +- 97 files changed, 1358 insertions(+), 1657 deletions(-) delete mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java delete mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/Instances.java create mode 100644 moa/src/main/java/moa/core/utils/AttributeDefinitionUtil.java diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java index a6bddce59..c427141d8 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java @@ -20,10 +20,13 @@ import java.io.Reader; import java.io.StreamTokenizer; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import moa.core.utils.AttributeDefinitionUtil; + /** * The Class ArffLoader. Loads an Arff file with sparse or dense format. */ @@ -41,8 +44,9 @@ public class ArffLoader { */ protected StreamTokenizer streamTokenizer; + /** - * Instantiates a new arff loader. + * Instantiates a new arff loader. Constructor for backwards compatibility. * * @param reader the reader * @param size the size @@ -50,39 +54,43 @@ public class ArffLoader { */ public ArffLoader(Reader reader, int size, int classAttribute) { // size is not used - this(reader); - if (classAttribute < 0) { - this.instanceInformation.setClassIndex(this.instanceInformation.numAttributes() - 1); - //System.out.print(this.instanceInformation.classIndex()); - } else if (classAttribute > 0) { - this.instanceInformation.setClassIndex(classAttribute - 1); - } + this(reader,String.valueOf(classAttribute)); } - protected Range range; /** * Instantiates a new arff loader. * * @param reader the reader - * @param range - * @param size the size - * @param classAttribute the class attribute + * @param outputDefinition the string definition of output attributes + * @param inputDefinition the string definition of input attributes */ - public ArffLoader(Reader reader) { - this(reader, null); + public ArffLoader(Reader reader, String outputDefinition, String inputDefinition) { + BufferedReader br = new BufferedReader(reader); + + //Init streamTokenizer + streamTokenizer = new StreamTokenizer(br); + streamTokenizer.resetSyntax(); + streamTokenizer.whitespaceChars(0, ' '); + streamTokenizer.wordChars(' ' + 1, '\u00FF'); + streamTokenizer.whitespaceChars(',', ','); + streamTokenizer.commentChar('%'); + streamTokenizer.quoteChar('"'); + streamTokenizer.quoteChar('\''); + streamTokenizer.ordinaryChar('{'); + streamTokenizer.ordinaryChar('}'); + streamTokenizer.eolIsSignificant(true); + + this.instanceInformation = this.getHeader(outputDefinition, inputDefinition); } /** * Instantiates a new arff loader. * * @param reader the reader - * @param range - * @param size the size - * @param classAttribute the class attribute + * @param outputDefinition the string definition of output attributes (others are taken as inputs) */ - public ArffLoader(Reader reader, Range range) { - this.range = range; + public ArffLoader(Reader reader, String outputDefinition) { BufferedReader br = new BufferedReader(reader); //Init streamTokenizer @@ -98,23 +106,9 @@ public ArffLoader(Reader reader, Range range) { streamTokenizer.ordinaryChar('}'); streamTokenizer.eolIsSignificant(true); - this.instanceInformation = this.getHeader(); - - if (range != null) { //is MultiLabel - this.instanceInformation.setRangeOutputIndices(range); - } - - } - - /** - * Gets the structure. - * - * @return the structure - */ - public InstanceInformation getStructure() { - return this.instanceInformation; + this.instanceInformation = this.getHeader(outputDefinition, AttributeDefinitionUtil.nonIgnoredDefinition); } - + /** * Reads instance. It detects if it is dense or sparse. * @@ -144,7 +138,6 @@ public Instance readInstance() { */ public Instance readInstanceDense() { Instance instance = newDenseInstance(this.instanceInformation.numAttributes()); - //System.out.println(this.instanceInformation.numAttributes()); int numAttribute = 0; try { while (numAttribute == 0 && streamTokenizer.ttype != StreamTokenizer.TT_EOF) { @@ -196,7 +189,7 @@ protected void setValue(Instance instance, int numAttribute, double value, boole valueAttribute = value; //System.out.println(value +"/"+valueAttribute+" "); } - if (this.instanceInformation.classIndex() == numAttribute) { + if (this.instanceInformation.numOutputAttributes() == 1 && this.instanceInformation.classIndex() == numAttribute) { setClassValue(instance, valueAttribute); //System.out.println(value +"<"+this.instanceInformation.classIndex()+">"); } else { @@ -219,17 +212,11 @@ private Instance readInstanceSparse() { ArrayList attributeValues = new ArrayList(); List indexValues = new ArrayList(); try { - //while (streamTokenizer.ttype != StreamTokenizer.TT_EOF) { - streamTokenizer.nextToken(); // Remove the '{' char //For each line while (streamTokenizer.ttype != StreamTokenizer.TT_EOL && streamTokenizer.ttype != StreamTokenizer.TT_EOF) { while (streamTokenizer.ttype != '}') { //For each item - //streamTokenizer.nextToken(); - //while (streamTokenizer.ttype != '}'){ - //System.out.println(streamTokenizer.nval +"-"+ streamTokenizer.sval); - //numAttribute = (int) streamTokenizer.nval; if (streamTokenizer.ttype == StreamTokenizer.TT_NUMBER) { numAttribute = (int) streamTokenizer.nval; } else { @@ -342,25 +329,20 @@ private Instance readDenseInstanceSparse() { } return instance; } - - //protected List inputAttributes; - // protected List outputAttributes; protected List auxAttributes; - private InstanceInformation getHeader() { - //commented JD - //this.range.setUpper(10000); //TO DO: Create a new range object with isInRange that does not need the upper limit + private InstanceInformation getHeader(String outputDefinition, String inputDefinition) { String relation = "file stream"; auxAttributes = new ArrayList();//JD int numAttributes = 0; + List inputIndexes = new ArrayList(); + List outputIndexes = new ArrayList(); try { streamTokenizer.nextToken(); while (streamTokenizer.ttype != StreamTokenizer.TT_EOF) { //For each line - //if (streamTokenizer.ttype == '@') { if (streamTokenizer.ttype == StreamTokenizer.TT_WORD && streamTokenizer.sval.startsWith("@") == true) { - //streamTokenizer.nextToken(); String token = streamTokenizer.sval.toUpperCase(); if (token.startsWith("@RELATION")) { streamTokenizer.nextToken(); @@ -369,13 +351,11 @@ private InstanceInformation getHeader() { } else if (token.startsWith("@ATTRIBUTE")) { streamTokenizer.nextToken(); String name = streamTokenizer.sval; - //System.out.println("* " + name); if (name == null) { name = Double.toString(streamTokenizer.nval); } streamTokenizer.nextToken(); String type = streamTokenizer.sval; - // System.out.println("* " + name + ":" + type + " "); if (streamTokenizer.ttype == '{') { streamTokenizer.nextToken(); List attributeLabels = new ArrayList(); @@ -391,35 +371,21 @@ private InstanceInformation getHeader() { streamTokenizer.nextToken(); } - // System.out.println(); - //attributes.add(new Attribute(name, attributeLabels)); - //commented JD - /* if (this.range.isInRange(numAttribute)) { - outputAttributes.add(new Attribute(name, attributeLabels)); - } else { - inputAttributes.add(new Attribute(name, attributeLabels)); - }*/ auxAttributes.add(new Attribute(name, attributeLabels)); numAttributes++; - } else if (streamTokenizer.sval != null && streamTokenizer.sval.toUpperCase() == "HIERARCHICAL") { - streamTokenizer.nextToken(); - DAGStructure attributeStructure = new DAGStructure(); - if (streamTokenizer.ttype == '{') { - while(streamTokenizer.ttype == '}') { - streamTokenizer.nextToken(); - System.out.println(streamTokenizer.sval); - } - - } - +// } else if (streamTokenizer.sval != null && streamTokenizer.sval.toUpperCase() == "HIERARCHICAL") { +// streamTokenizer.nextToken(); +// DAGStructure attributeStructure = new DAGStructure(); +// if (streamTokenizer.ttype == '{') { +// while(streamTokenizer.ttype != '}') { +// streamTokenizer.nextToken(); +// System.out.println(streamTokenizer.sval); +// } +// +// } +// } else { - // Add attribute - //commented JD - /*if (this.range.isInRange(numAttribute)) { - outputAttributes.add(new Attribute(name)); - } else { - inputAttributes.add(new Attribute(name)); - }*/ + auxAttributes.add(new Attribute(name)); numAttributes++; } @@ -432,29 +398,16 @@ private InstanceInformation getHeader() { } streamTokenizer.nextToken(); } - if (range != null) { - this.range.setUpper(numAttributes); - } - /*if (range==null) //is single-target. All instances should go to inputAtrributes (see setClassIndex(int) from InstanceInformation ) - inputAttributes=auxAttributes; - else//is multi-target - { - this.range.setUpper(numAttribute); - for (int i=0; i outputIndexes; + protected List inputIndexes; + + public Attribute inputAttribute(int w) { return this.attributesInformation.attribute(inputAttributeIndex(w)); } @@ -54,6 +47,8 @@ public Attribute outputAttribute(int w) { return this.attributesInformation.attribute(outputAttributeIndex(w)); } + + /** * Instantiates a new instance information. * @@ -61,9 +56,9 @@ public Attribute outputAttribute(int w) { */ public InstanceInformation(InstanceInformation chunk) { this.relationName = chunk.relationName; + this.outputIndexes = chunk.outputIndexes; + this.inputIndexes = chunk.inputIndexes; this.attributesInformation = chunk.attributesInformation; - this.structure = chunk.structure; - this.classIndex = chunk.classIndex; } /** @@ -72,16 +67,38 @@ public InstanceInformation(InstanceInformation chunk) { * @param st the st * @param v the v */ - public InstanceInformation(String st, List input) { + public InstanceInformation(String st, List attributes, List outputIndexes, List inputIndexes) { + this.relationName = st; + this.outputIndexes = outputIndexes; + this.inputIndexes = inputIndexes; + this.attributesInformation = new AttributesInformation(attributes, attributes.size()); + } + + public InstanceInformation(String st, List input, List indexes) { this.relationName = st; - this.attributesInformation = new AttributesInformation(input, input.size()); + this.outputIndexes = new ArrayList(); + this.inputIndexes = new ArrayList(); + this.attributesInformation = new AttributesInformation(input, indexes, indexes.size()); } + public InstanceInformation(String st, List input) { + this.relationName = st; + this.outputIndexes = new ArrayList(); + this.inputIndexes = new ArrayList(); + List indexes = new ArrayList(); + for (int i = 0; i < input.size(); i++) { + indexes.add(i); + } + this.attributesInformation = new AttributesInformation(input, indexes, indexes.size()); + } + /** * Instantiates a new instance information. */ public InstanceInformation() { this.relationName = null; + this.inputIndexes = null; + this.outputIndexes = null; this.attributesInformation = null; } @@ -104,15 +121,16 @@ public String getRelationName() { * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#classIndex() */ public int classIndex() { - return this.classIndex; + if (this.outputIndexes.size() > 1) + throw new UnsupportedOperationException("This instance has multiple output attributes."); + return this.outputIndexes.get(0); } - /* (non-Javadoc) - * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#setClassIndex(int) - */ - public void setClassIndex(int classIndex) { - this.classIndex = classIndex; + public void setClassIndex(int index) { + this.outputIndexes = new ArrayList(); + this.outputIndexes.add(index); } + /* (non-Javadoc) * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#classAttribute() @@ -163,63 +181,48 @@ public void setAttributes(List v) { } public int inputAttributeIndex(int index) { - int ret = 0; - if (classIndex == Integer.MAX_VALUE) {//Multi Label - if(index index ? index : index + 1; - } - return ret; + // Returns actual instance attribute index! + return inputIndexes.get(index); } - public int outputAttributeIndex(int attributeIndex) { - int ret = 0; - if (classIndex == Integer.MAX_VALUE) {//Multi Label - ret=attributeIndex+range.getStart(); //JD - Range should be a "block" - } else { //Single Label - ret = classIndex; - } - return ret; + public int outputAttributeIndex(int index) { + // Returns actual instance attribute index! + return outputIndexes.get(index); } public int numInputAttributes() { - int ret = 0; - if (classIndex == Integer.MAX_VALUE) {//Multi Label - ret=this.numAttributes()-range.getSelectionLength(); //JD - } else { //Single Label - ret = this.numAttributes() - 1; - } - return ret; + return inputIndexes.size(); } public int numOutputAttributes() { - int ret = 0; - if (classIndex == Integer.MAX_VALUE) {//Multi Label - ret=range.getSelectionLength(); //JD - } else { //Single Label - ret = 1; - } - return ret; - } - public void setRangeOutputIndices(Range range) { - this.setClassIndex(Integer.MAX_VALUE); - this.range = range; + return outputIndexes.size(); } public void setAttributes(List v, List indexValues) { if(this.attributesInformation==null) this.attributesInformation= new AttributesInformation(); this.attributesInformation.setAttributes(v,indexValues); - + } + + public void setOutputIndexes(List outputIndexes) { + this.outputIndexes = outputIndexes; } - public AttributeStructure getStructure() { - return this.structure; + public void setInputIndexes(List inputIndexes) { + this.inputIndexes = inputIndexes; + } + + /** + * Sets all non-output attributes as input attributes. + */ + public void setInputIndexes() { + this.inputIndexes = new ArrayList(); + for (int i = 0; i < attributesInformation.indexValues.size(); i++) { + if (!outputIndexes.contains(attributesInformation.indexValues.get(i))) { + inputIndexes.add(attributesInformation.indexValues.get(i)); + } + } } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instances.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instances.java deleted file mode 100644 index 7a52cead0..000000000 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instances.java +++ /dev/null @@ -1,542 +0,0 @@ -/* - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ -package com.yahoo.labs.samoa.instances; - -import java.io.Reader; -import java.io.Serializable; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import moa.core.Utils; - -/** - * The Class Instances. - * - * @author abifet - */ -public class Instances implements Serializable { - - /** The keyword used to denote the start of an arff header */ - public final static String ARFF_RELATION = "@relation"; - - /** The keyword used to denote the start of the arff data section */ - public final static String ARFF_DATA = "@data"; - - private static final long serialVersionUID = 8110510475535581577L; - /** - * The instance information. - */ - protected InstanceInformation instanceInformation; - /** - * The instances. - */ - protected List instances; - - /** - * The arff. - */ - protected ArffLoader arff; - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - */ - public Instances(Instances chunk) { - this(chunk, chunk.numInstances()); - chunk.copyInstances(0, this, chunk.numInstances()); - } - - /** - * Instantiates a new instances. - */ - public Instances() { - } - - /** - * Instantiates a new instances. - * - * @param reader the reader - * @param size the size - * @param classAttribute the class attribute - */ - public Instances(Reader reader, int size, int classAttribute) { - arff = new ArffLoader(reader, 0, classAttribute); - this.instanceInformation = arff.getStructure(); - this.instances = new ArrayList(); - } - - /** - * Instantiates a new instances. - * - * @param reader the reader - * @param range - */ - public Instances(Reader reader, Range range) { - this.arff = new MultiTargetArffLoader(reader, range); - this.instanceInformation = arff.getStructure(); - this.instances = new ArrayList(); - } - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - * @param capacity the capacity - */ - public Instances(Instances chunk, int capacity) { - this.instanceInformation = chunk.instanceInformation(); - if (capacity < 0) { - capacity = 0; - } - this.instances = new ArrayList(capacity); - } - - /** - * Instantiates a new instances. - * - * @param st the st - * @param v the v - * @param capacity the capacity - */ - public Instances(String st, List v, int capacity) { - this.instanceInformation = new InstanceInformation(st, v); - } - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - * @param first the first instance - * @param toCopy the j - */ - public Instances(Instances chunk, int first, int toCopy) { - - this(chunk, toCopy); - - if ((first < 0) || ((first + toCopy) > chunk.numInstances())) { - throw new IllegalArgumentException("Parameters first and/or toCopy out " - + "of range"); - } - chunk.copyInstances(first, this, toCopy); - } - - /** - * Instantiates a new instances. - * - * @param st the st - * @param capacity the capacity - */ - public Instances(StringReader st, int capacity) { - this.instances = new ArrayList(capacity); - } - - //Information Instances - /** - * Sets the relation name. - * - * @param string the new relation name - */ - public void setRelationName(String string) { - this.instanceInformation.setRelationName(string); - } - - /** - * Gets the relation name. - * - * @return the relation name - */ - public String getRelationName() { - return this.instanceInformation.getRelationName(); - } - - /** - * Class index. - * - * @return the int - */ - public int classIndex() { - return this.instanceInformation.classIndex(); - } - - /** - * Sets the class index. - * - * @param classIndex the new class index - */ - public void setClassIndex(int classIndex) { - this.instanceInformation.setClassIndex(classIndex); - } - - /** - * Class attribute. - * - * @return the attribute - */ - public Attribute classAttribute() { - return this.instanceInformation.classAttribute(); - } - - /** - * Num attributes. - * - * @return the int - */ - public int numAttributes() { - return this.instanceInformation.numAttributes(); - } - - /** - * Attribute. - * - * @param w the w - * @return the attribute - */ - public Attribute attribute(int w) { - return this.instanceInformation.attribute(w); - } - - /** - * Num classes. - * - * @return the int - */ - public int numClasses() { - return this.instanceInformation.numClasses(); - } - - /** - * Delete attribute at. - * - * @param integer the integer - */ - public void deleteAttributeAt(Integer integer) { - this.instanceInformation.deleteAttributeAt(integer); - } - - /** - * Insert attribute at. - * - * @param attribute the attribute - * @param i the i - */ - public void insertAttributeAt(Attribute attribute, int i) { - if (this.instanceInformation==null) - this.instanceInformation= new InstanceInformation(); - this.instanceInformation.insertAttributeAt(attribute, i); - } - - //List of Instances - /** - * Instance. - * - * @param num the num - * @return the instance - */ - public Instance instance(int num) { - return this.instances.get(num); - } - - /** - * Num instances. - * - * @return the int - */ - public int numInstances() { - return this.instances.size(); - } - - /** - * Adds the. - * - * @param inst the inst - */ - public void add(Instance inst) { - this.instances.add(inst.copy()); - } - - /** - * Randomize. - * - * @param random the random - */ - public void randomize(Random random) { - for (int j = numInstances() - 1; j > 0; j--) { - swap(j, random.nextInt(j + 1)); - } - } - - /** - * Stratify. - * - * @param numFolds the num folds - */ - public void stratify(int numFolds) { - - if (classAttribute().isNominal()) { - - // sort by class - int index = 1; - while (index < numInstances()) { - Instance instance1 = instance(index - 1); - for (int j = index; j < numInstances(); j++) { - Instance instance2 = instance(j); - if ((instance1.classValue() == instance2.classValue()) - || (instance1.classIsMissing() - && instance2.classIsMissing())) { - swap(index, j); - index++; - } - } - index++; - } - stratStep(numFolds); - } - } - - protected void stratStep(int numFolds) { - ArrayList newVec = new ArrayList(this.instances.size()); - int start = 0, j; - - // create stratified batch - while (newVec.size() < numInstances()) { - j = start; - while (j < numInstances()) { - newVec.add(instance(j)); - j = j + numFolds; - } - start++; - } - this.instances = newVec; - } - - /** - * Train cv. - * - * @param numFolds the num folds - * @param numFold - * @param n the n - * @param random the random - * @return the instances - */ - public Instances trainCV(int numFolds, int numFold, Random random) { - Instances train = trainCV(numFolds, numFold); - train.randomize(random); - return train; - } - - public Instances trainCV(int numFolds, int numFold) { - int numInstForFold, first, offset; - Instances train; - - numInstForFold = numInstances() / numFolds; - if (numFold < numInstances() % numFolds) { - numInstForFold++; - offset = numFold; - } else { - offset = numInstances() % numFolds; - } - train = new Instances(this, numInstances() - numInstForFold); - first = numFold * (numInstances() / numFolds) + offset; - copyInstances(0, train, first); - copyInstances(first + numInstForFold, train, - numInstances() - first - numInstForFold); - return train; - } - - protected void copyInstances(int from, Instances dest, int num) { - for (int i = 0; i < num; i++) { - dest.add(instance(from + i)); - } - } - - /** - * Test cv. - * - * @param numFolds the num folds - * @param numFold the num fold - * @return the instances - */ - public Instances testCV(int numFolds, int numFold) { - - int numInstForFold, first, offset; - Instances test; - - numInstForFold = numInstances() / numFolds; - if (numFold < numInstances() % numFolds) { - numInstForFold++; - offset = numFold; - } else { - offset = numInstances() % numFolds; - } - test = new Instances(this, numInstForFold); - first = numFold * (numInstances() / numFolds) + offset; - copyInstances(first, test, numInstForFold); - return test; - } - - /* public Instances dataset() { - throw new UnsupportedOperationException("Not yet implemented"); - }*/ - /** - * Mean or mode. - * - * @param j the j - * @return the double - */ - public double meanOrMode(int j) { - throw new UnsupportedOperationException("Not yet implemented"); //CobWeb - } - - /** - * Read instance. - * - * @param fileReader the file reader - * @return true, if successful - */ - public boolean readInstance(Reader fileReader) { - - //ArffReader arff = new ArffReader(reader, this, m_Lines, 1); - Instance inst = arff.readInstance(); - if (inst != null) { - inst.setDataset(this); - add(inst); - return true; - } else { - return false; - } - } - - /** - * Delete. - */ - public void delete() { - this.instances = new ArrayList(); - } - - /** - * Delete. - */ - public void delete(int index) { - this.instances.remove(index); - } - - - /** - * Swap. - * - * @param i the i - * @param j the j - */ - public void swap(int i, int j) { - Instance in = instances.get(i); - instances.set(i, instances.get(j)); - instances.set(j, in); - } - - /** - * Instance information. - * - * @return the instance information - */ - private InstanceInformation instanceInformation() { - return this.instanceInformation; - } - - public Attribute attribute(String name) { - - for (int i = 0; i < numAttributes(); i++) { - if (attribute(i).name().equals(name)) { - return attribute(i); - } - } - return null; - } - - public int size() { - return this.numInstances(); - } - - public void set(int i, Instance inst) { - this.instances.set(i, inst); - } - - public Instance get(int k) { - return this.instance(k); - } - - public void setRangeOutputIndices(Range range) { - this.instanceInformation.setRangeOutputIndices(range); - - } - - public void setAttributes(List v) { - if(this.instanceInformation==null) - this.instanceInformation= new InstanceInformation(); - this.instanceInformation.setAttributes(v); - } - - public void setAttributes(List v, List indexValues) { - if(this.instanceInformation==null) - this.instanceInformation= new InstanceInformation(); - this.instanceInformation.setAttributes(v, indexValues); - } - - /** - * Returns the dataset as a string in ARFF format. Strings - * are quoted if they contain whitespace characters, or if they - * are a question mark. - * - * @return the dataset in ARFF format as a string - */ - public String toString() { - - StringBuffer text = new StringBuffer(); - - text.append(ARFF_RELATION).append(" "). - append(Utils.quote( this.instanceInformation.getRelationName())).append("\n\n"); - for (int i = 0; i < numAttributes(); i++) { - text.append(attribute(i).toString()).append("\n"); - } - text.append("\n").append(ARFF_DATA).append("\n"); - - text.append(stringWithoutHeader()); - return text.toString(); - } - - /** - * Returns the instances in the dataset as a string in ARFF format. Strings - * are quoted if they contain whitespace characters, or if they - * are a question mark. - * - * @return the dataset in ARFF format as a string - */ - protected String stringWithoutHeader() { - - StringBuffer text = new StringBuffer(); - - for (int i = 0; i < numInstances(); i++) { - text.append(instance(i)); - if (i < numInstances() - 1) { - text.append('\n'); - } - } - return text.toString(); - - } - -} diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java index 6086fa888..421cbb74e 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java @@ -15,116 +15,642 @@ */ package com.yahoo.labs.samoa.instances; +import java.io.Reader; +import java.io.Serializable; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.junit.experimental.theories.Theories; + +import moa.core.Utils; + /** - * Class for storing the header or context of a data stream. It allows to know - * the number of attributes and classes. + * The Class Instances. * - * @version $Revision: 7 $ + * @author abifet */ -public class InstancesHeader extends Instances { +public class InstancesHeader implements Serializable { + /** The keyword used to denote the start of an arff header */ + public final static String ARFF_RELATION = "@relation"; + + /** The keyword used to denote the start of the arff data section */ + public final static String ARFF_DATA = "@data"; + private static final long serialVersionUID = 1L; - public InstancesHeader(Instances i) { - super(i, 0); + /** + * The instance information. + */ + protected InstanceInformation instanceInformation; + /** + * The instances. + */ + protected List instances; + + /** + * The arff. + */ + protected ArffLoader arff; + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + */ + public InstancesHeader(InstancesHeader chunk) { + this(chunk, chunk.numInstances()); + chunk.copyInstances(0, this, chunk.numInstances()); } + /** + * Instantiates a new instances. + */ public InstancesHeader() { - super(); } - public static String getClassNameString(InstancesHeader context) { - if (context == null) { - return "[class]"; - } - return "[class:" + context.classAttribute().name() + "]"; + /** + * Instantiates a new instances. + * + * @param reader the reader + * @param size the size + * @param classAttribute the class attribute + */ + public InstancesHeader(Reader reader, int size, int classAttribute) { + arff = new ArffLoader(reader, String.valueOf(classAttribute)); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); } - public static String getClassLabelString(InstancesHeader context, - int classLabelIndex) { - if ((context == null) || (classLabelIndex >= context.numClasses())) { - return ""; + public InstancesHeader(Reader reader, String outputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + public InstancesHeader(Reader reader, String outputDefinition, String inputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + public InstancesHeader(Reader reader, int size, String outputDefinition, String inputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + /** + * Instantiates a new instances. + * + * @param reader the reader + * @param range + */ +// public Instances(Reader reader, Range range) { +// this.arff = new MultiTargetArffLoader(reader, range); +// this.instanceInformation = arff.getStructure(); +// this.instances = new ArrayList(); +// } + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + * @param capacity the capacity + */ + public InstancesHeader(InstancesHeader chunk, int capacity) { + this.instanceInformation = chunk.instanceInformation(); + if (capacity < 0) { + capacity = 0; } - return ""; + this.instances = new ArrayList(capacity); } - // is impervious to class index changes - attIndex is true attribute index - // regardless of class position - public static String getAttributeNameString(InstancesHeader context, - int attIndex) { - if ((context == null) || (attIndex >= context.numAttributes())) { - return "[att " + (attIndex + 1) + "]"; + /** + * Instantiates a new instances. + * + * @param st the st + * @param v the v + * @param capacity the capacity + */ + public InstancesHeader(String st, List v, int capacity) { + this.instanceInformation = new InstanceInformation(st, v); + } + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + * @param first the first instance + * @param toCopy the j + */ + public InstancesHeader(InstancesHeader chunk, int first, int toCopy) { + + this(chunk, toCopy); + + if ((first < 0) || ((first + toCopy) > chunk.numInstances())) { + throw new IllegalArgumentException("Parameters first and/or toCopy out " + + "of range"); } - int instAttIndex = attIndex < context.classIndex() ? attIndex - : attIndex + 1; - return "[att " + (attIndex + 1) + ":" - + context.attribute(instAttIndex).name() + "]"; + chunk.copyInstances(first, this, toCopy); + } + + /** + * Instantiates a new instances. + * + * @param st the st + * @param capacity the capacity + */ + public InstancesHeader(StringReader st, int capacity) { + this.instances = new ArrayList(capacity); + } + + //Information Instances + /** + * Sets the relation name. + * + * @param string the new relation name + */ + public void setRelationName(String string) { + this.instanceInformation.setRelationName(string); } - public static String getInputAttributeNameString(InstancesHeader context, - int attIndex) { - if ((context == null) || (attIndex >= context.numInputAttributes())) { - return "[att " + (attIndex + 1) + "]"; + /** + * Gets the relation name. + * + * @return the relation name + */ + public String getRelationName() { + return this.instanceInformation.getRelationName(); + } + + /** + * Class index. + * + * @return the int + */ + public int classIndex() { + return this.instanceInformation.classIndex(); + } + + /** + * Sets the class index. Also sets all other attributes as input attributes for backward compatibility. + * + * @param classIndex the new class index + */ + public void setClassIndex(int classIndex) { + this.instanceInformation.setClassIndex(classIndex); + this.instanceInformation.setInputIndexes(); + } + + public void setOutputIndexes(List outputIndexes) { + this.instanceInformation.setOutputIndexes(outputIndexes); + } + + public void setInputIndexes(List inputIndexes) { + this.instanceInformation.setInputIndexes(inputIndexes); + } + + /** + * Sets all non-output attributes as input attributes. + */ + public void setInputIndexes() { + this.instanceInformation.setInputIndexes(); + } + + /** + * Class attribute. + * + * @return the attribute + */ + public Attribute classAttribute() { + return this.instanceInformation.classAttribute(); + } + + /** + * Num attributes. + * + * @return the int + */ + public int numAttributes() { + return this.instanceInformation.numAttributes(); + } + + /** + * Attribute. + * + * @param w the w + * @return the attribute + */ + public Attribute attribute(int w) { + return this.instanceInformation.attribute(w); + } + + /** + * Num classes. + * + * @return the int + */ + public int numClasses() { + return this.instanceInformation.numClasses(); + } + + /** + * Delete attribute at. + * + * @param integer the integer + */ + public void deleteAttributeAt(Integer integer) { + this.instanceInformation.deleteAttributeAt(integer); + } + + /** + * Insert attribute at. + * + * @param attribute the attribute + * @param i the i + */ + public void insertAttributeAt(Attribute attribute, int i) { + if (this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.insertAttributeAt(attribute, i); + } + + //List of Instances + /** + * Instance. + * + * @param num the num + * @return the instance + */ + public Instance instance(int num) { + return this.instances.get(num); + } + + /** + * Num instances. + * + * @return the int + */ + public int numInstances() { + return this.instances.size(); + } + + /** + * Adds the. + * + * @param inst the inst + */ + public void add(Instance inst) { + this.instances.add(inst.copy()); + } + + /** + * Randomize. + * + * @param random the random + */ + public void randomize(Random random) { + for (int j = numInstances() - 1; j > 0; j--) { + swap(j, random.nextInt(j + 1)); } - int instAttIndex = attIndex; - return "[att " + (attIndex + 1) + ":" - + context.inputAttribute(instAttIndex).name() + "]"; - } - - // is impervious to class index changes - attIndex is true attribute index - // regardless of class position - public static String getNominalValueString(InstancesHeader context, - int attIndex, int valIndex) { - if (context != null) { - int instAttIndex = attIndex < context.classIndex() ? attIndex - : attIndex + 1; - if ((instAttIndex < context.numAttributes()) - && (valIndex < context.attribute(instAttIndex).numValues())) { - return "{val " + (valIndex + 1) + ":" - + context.attribute(instAttIndex).value(valIndex) + "}"; + } + + /** + * Stratify. + * + * @param numFolds the num folds + */ + public void stratify(int numFolds) { + + if (classAttribute().isNominal()) { + + // sort by class + int index = 1; + while (index < numInstances()) { + Instance instance1 = instance(index - 1); + for (int j = index; j < numInstances(); j++) { + Instance instance2 = instance(j); + if ((instance1.classValue() == instance2.classValue()) + || (instance1.classIsMissing() + && instance2.classIsMissing())) { + swap(index, j); + index++; + } + } + index++; } + stratStep(numFolds); } - return "{val " + (valIndex + 1) + "}"; - } - - // is impervious to class index changes - attIndex is true attribute index - // regardless of class position - public static String getNumericValueString(InstancesHeader context, - int attIndex, double value) { - if (context != null) { - int instAttIndex = attIndex < context.classIndex() ? attIndex - : attIndex + 1; - if (instAttIndex < context.numAttributes()) { - if (context.attribute(instAttIndex).isDate()) { - return context.attribute(instAttIndex).formatDate(value); - } + } + + protected void stratStep(int numFolds) { + ArrayList newVec = new ArrayList(this.instances.size()); + int start = 0, j; + + // create stratified batch + while (newVec.size() < numInstances()) { + j = start; + while (j < numInstances()) { + newVec.add(instance(j)); + j = j + numFolds; } + start++; + } + this.instances = newVec; + } + + /** + * Train cv. + * + * @param numFolds the num folds + * @param numFold + * @param n the n + * @param random the random + * @return the instances + */ + public InstancesHeader trainCV(int numFolds, int numFold, Random random) { + InstancesHeader train = trainCV(numFolds, numFold); + train.randomize(random); + return train; + } + + public InstancesHeader trainCV(int numFolds, int numFold) { + int numInstForFold, first, offset; + InstancesHeader train; + + numInstForFold = numInstances() / numFolds; + if (numFold < numInstances() % numFolds) { + numInstForFold++; + offset = numFold; + } else { + offset = numInstances() % numFolds; + } + train = new InstancesHeader(this, numInstances() - numInstForFold); + first = numFold * (numInstances() / numFolds) + offset; + copyInstances(0, train, first); + copyInstances(first + numInstForFold, train, + numInstances() - first - numInstForFold); + return train; + } + + protected void copyInstances(int from, InstancesHeader dest, int num) { + for (int i = 0; i < num; i++) { + dest.add(instance(from + i)); + } + } + + /** + * Test cv. + * + * @param numFolds the num folds + * @param numFold the num fold + * @return the instances + */ + public InstancesHeader testCV(int numFolds, int numFold) { + + int numInstForFold, first, offset; + InstancesHeader test; + + numInstForFold = numInstances() / numFolds; + if (numFold < numInstances() % numFolds) { + numInstForFold++; + offset = numFold; + } else { + offset = numInstances() % numFolds; } - return Double.toString(value); + test = new InstancesHeader(this, numInstForFold); + first = numFold * (numInstances() / numFolds) + offset; + copyInstances(first, test, numInstForFold); + return test; } - public Attribute inputAttribute(int w) { - return this.instanceInformation.inputAttribute(w); + /* public Instances dataset() { + throw new UnsupportedOperationException("Not yet implemented"); + }*/ + /** + * Mean or mode. + * + * @param j the j + * @return the double + */ + public double meanOrMode(int j) { + throw new UnsupportedOperationException("Not yet implemented"); //CobWeb } - public Attribute outputAttribute(int w) { - return this.instanceInformation.outputAttribute(w); + /** + * Read instance. + * + * @param fileReader the file reader + * @return true, if successful + */ + public boolean readInstance(Reader fileReader) { + + //ArffReader arff = new ArffReader(reader, this, m_Lines, 1); + Instance inst = arff.readInstance(); + if (inst != null) { + inst.setDataset(this); + add(inst); + return true; + } else { + return false; + } } - public int numInputAttributes() { - return this.instanceInformation.numInputAttributes(); + /** + * Delete. + */ + public void delete() { + this.instances = new ArrayList(); + } + + /** + * Delete. + */ + public void delete(int index) { + this.instances.remove(index); } - public int numOutputAttributes() { - return this.instanceInformation.numOutputAttributes(); + + /** + * Swap. + * + * @param i the i + * @param j the j + */ + public void swap(int i, int j) { + Instance in = instances.get(i); + instances.set(i, instances.get(j)); + instances.set(j, in); } - public InstanceInformation getInstanceInformation() { + /** + * Instance information. + * + * @return the instance information + */ + private InstanceInformation instanceInformation() { return this.instanceInformation; } + + public Attribute attribute(String name) { + + for (int i = 0; i < numAttributes(); i++) { + if (attribute(i).name().equals(name)) { + return attribute(i); + } + } + return null; + } + + public int size() { + return this.numInstances(); + } + + public void set(int i, Instance inst) { + this.instances.set(i, inst); + } + + public Instance get(int k) { + return this.instance(k); + } + +// public void setRangeOutputIndices(Range range) { +// this.instanceInformation.setRangeOutputIndices(range); +// +// } + + public void setAttributes(List v) { + if(this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.setAttributes(v); + } + + public void setAttributes(List v, List indexValues) { + if(this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.setAttributes(v, indexValues); + } + + /** + * Returns the dataset as a string in ARFF format. Strings + * are quoted if they contain whitespace characters, or if they + * are a question mark. + * + * @return the dataset in ARFF format as a string + */ + public String toString() { + + StringBuffer text = new StringBuffer(); + + text.append(ARFF_RELATION).append(" "). + append(Utils.quote( this.instanceInformation.getRelationName())).append("\n\n"); + for (int i = 0; i < numAttributes(); i++) { + text.append(attribute(i).toString()).append("\n"); + } + text.append("\n").append(ARFF_DATA).append("\n"); + + text.append(stringWithoutHeader()); + return text.toString(); + } + + /** + * Returns the instances in the dataset as a string in ARFF format. Strings + * are quoted if they contain whitespace characters, or if they + * are a question mark. + * + * @return the dataset in ARFF format as a string + */ + protected String stringWithoutHeader() { - public AttributeStructure getInstanceStructure() { - return this.instanceInformation.getStructure(); + StringBuffer text = new StringBuffer(); + + for (int i = 0; i < numInstances(); i++) { + text.append(instance(i)); + if (i < numInstances() - 1) { + text.append('\n'); + } } + return text.toString(); + + } + + public Attribute inputAttribute(int w) { + return this.instanceInformation.inputAttribute(w); + } + + public Attribute outputAttribute(int w) { + return this.instanceInformation.outputAttribute(w); + } + + public int numInputAttributes() { + return this.instanceInformation.numInputAttributes(); + } + + public int numOutputAttributes() { + return this.instanceInformation.numOutputAttributes(); + } + + public InstanceInformation getInstanceInformation() { + return this.instanceInformation; + } + + public static String getClassNameString(InstancesHeader context) { + if (context == null) { + return "[class]"; + } + return "[class:" + context.classAttribute().name() + "]"; + } + + public static String getClassLabelString(InstancesHeader context, int classLabelIndex) { + if ((context == null) || (classLabelIndex >= context.numClasses())) { + return ""; + } + return ""; + } + + public static String getAttributeNameString(InstancesHeader context, int attIndex) { + if ((context == null) || (attIndex >= context.numAttributes())) { + return "[att " + (attIndex + 1) + "]"; + } + return "[att " + (attIndex + 1) + ":" + + context.attribute(attIndex).name() + "]"; + } + + public static String getInputAttributeNameString(InstancesHeader context, int attIndex) { + if ((context == null) || (attIndex >= context.numInputAttributes())) { + return "[att " + (attIndex + 1) + "]"; + } + return "[att " + (attIndex + 1) + ":" + + context.inputAttribute(attIndex).name() + "]"; + } + + public static String getNominalValueString(InstancesHeader context, int attIndex, int valIndex) { + if (context != null) { + if ((attIndex < context.numInputAttributes()) + && (valIndex < context.inputAttribute(attIndex).numValues())) { + return "{val " + (valIndex + 1) + ":" + + context.inputAttribute(attIndex).value(valIndex) + "}"; + } + } + return "{val " + (valIndex + 1) + "}"; + } + + public static String getNumericValueString(InstancesHeader context, int attIndex, double value) { + if (context != null) { + int instAttIndex = attIndex < context.classIndex() ? attIndex + : attIndex + 1; + if (instAttIndex < context.numAttributes()) { + if (context.attribute(instAttIndex).isDate()) { + return context.attribute(instAttIndex).formatDate(value); + } + } + } + return Double.toString(value); + } + + } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoader.java index fc7392e68..a0a4b0b48 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoader.java @@ -19,24 +19,31 @@ public class MultiTargetArffLoader extends ArffLoader { - public MultiTargetArffLoader(Reader reader) { - super(reader); - } + public MultiTargetArffLoader(Reader reader, String outputDefinition, String inputDefinition) { + super(reader, outputDefinition, inputDefinition); + // TODO Auto-generated constructor stub + } - public MultiTargetArffLoader(Reader reader, Range range) { - super(reader, range); - } - - @Override - protected Instance newSparseInstance(double d, double[] res) { - return new SparseInstance(d, res); // TODO - } - - @Override - protected Instance newDenseInstance(int numAttributes) { - // numAttributes is this.instanceInformation.numAttributes() - this.range.setUpper(numAttributes); - return new DenseInstance(numAttributes); - } +// DEPRECATED + +// public MultiTargetArffLoader(Reader reader) { +// super(reader); +// } +// +// public MultiTargetArffLoader(Reader reader, Range range) { +// super(reader, range); +// } +// +// @Override +// protected Instance newSparseInstance(double d, double[] res) { +// return new SparseInstance(d, res); // TODO +// } +// +// @Override +// protected Instance newDenseInstance(int numAttributes) { +// // numAttributes is this.instanceInformation.numAttributes() +// this.range.setUpper(numAttributes); +// return new DenseInstance(numAttributes); +// } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java index ab27c38fb..d02e5fbbc 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java @@ -1,3 +1,4 @@ + /* * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/SamoaToWekaInstanceConverter.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/SamoaToWekaInstanceConverter.java index f94851d93..3ef342875 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/SamoaToWekaInstanceConverter.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/SamoaToWekaInstanceConverter.java @@ -77,7 +77,7 @@ public weka.core.Instance wekaInstance(Instance inst) { * @param instances the instances * @return the weka.core. instances */ - public weka.core.Instances wekaInstances(Instances instances) { + public weka.core.Instances wekaInstances(InstancesHeader instances) { weka.core.Instances wekaInstances = wekaInstancesInformation(instances); //We assume that we have only one WekaInstanceInformation for SamoaToWekaInstanceConverter this.wekaInstanceInformation = wekaInstances; @@ -93,7 +93,7 @@ public weka.core.Instances wekaInstances(Instances instances) { * @param instances the instances * @return the weka.core. instances */ - public weka.core.Instances wekaInstancesInformation(Instances instances) { + public weka.core.Instances wekaInstancesInformation(InstancesHeader instances) { weka.core.Instances wekaInstances; ArrayList attInfo = new ArrayList(); for (int i = 0; i < instances.numAttributes(); i++) { diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java index 279d6baed..9867f74ca 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java @@ -19,6 +19,9 @@ * The Interface StructuredInstance. * * @author abifet + * + * A placeholder for structured instances. + * */ public interface StructuredInstance extends Instance { diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/WekaToSamoaInstanceConverter.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/WekaToSamoaInstanceConverter.java index f49d7397d..1937f6274 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/WekaToSamoaInstanceConverter.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/WekaToSamoaInstanceConverter.java @@ -26,7 +26,7 @@ */ public class WekaToSamoaInstanceConverter implements Serializable{ - protected Instances samoaInstanceInformation; + protected InstancesHeader samoaInstanceInformation; /** * Samoa instance from weka instance. @@ -65,8 +65,8 @@ public Instance samoaInstance(weka.core.Instance inst) { * @param instances the instances * @return the instances */ - public Instances samoaInstances(weka.core.Instances instances) { - Instances samoaInstances = samoaInstancesInformation(instances); + public InstancesHeader samoaInstances(weka.core.Instances instances) { + InstancesHeader samoaInstances = samoaInstancesInformation(instances); //We assume that we have only one samoaInstanceInformation for WekaToSamoaInstanceConverter this.samoaInstanceInformation = samoaInstances; for (int i = 0; i < instances.numInstances(); i++) { @@ -81,13 +81,13 @@ public Instances samoaInstances(weka.core.Instances instances) { * @param instances the instances * @return the instances */ - public Instances samoaInstancesInformation(weka.core.Instances instances) { - Instances samoaInstances; + public InstancesHeader samoaInstancesInformation(weka.core.Instances instances) { + InstancesHeader samoaInstances; List attInfo = new ArrayList(); for (int i = 0; i < instances.numAttributes(); i++) { attInfo.add(samoaAttribute(i, instances.attribute(i))); } - samoaInstances = new Instances(instances.relationName(), attInfo, 0); + samoaInstances = new InstancesHeader(instances.relationName(), attInfo, 0); samoaInstances.setClassIndex(instances.classIndex()); return samoaInstances; } diff --git a/moa/src/main/java/moa/classifiers/AbstractClassifier.java b/moa/src/main/java/moa/classifiers/AbstractClassifier.java index ee1c01c47..fb8daca38 100644 --- a/moa/src/main/java/moa/classifiers/AbstractClassifier.java +++ b/moa/src/main/java/moa/classifiers/AbstractClassifier.java @@ -44,7 +44,7 @@ import com.yahoo.labs.samoa.instances.DenseInstanceData; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -68,7 +68,7 @@ public String getPurposeString() { protected int randomSeed = 1; /** Option for randomizable learners to change the random seed */ - protected IntOption randomSeedOption; + public IntOption randomSeedOption; /** Random Generator used in randomizable learners */ public Random classifierRandom; @@ -91,9 +91,9 @@ public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) } // resetLearning should not be called if the classifier has not yet received the context -// if (!trainingHasStarted()) { -// resetLearning(); -// } + if (!trainingHasStarted()) { + resetLearning(); + } } @@ -120,7 +120,7 @@ public Prediction getPredictionForInstance(Instance inst){ @Override public void setModelContext(InstancesHeader ih) { - if ((ih != null) && (ih.classIndex() < 0)) { + if ((ih != null) && (ih.numOutputAttributes() < 1)) { throw new IllegalArgumentException( "Context for a classifier must include a class to learn"); } @@ -131,6 +131,10 @@ public void setModelContext(InstancesHeader ih) { "New context is not compatible with existing model"); } this.modelContext = ih; + this.modelContextSet(); + } + + public void modelContextSet() { } @Override @@ -170,7 +174,7 @@ public void resetLearning() { public void trainOnInstance(Instance inst) { boolean isTraining = (inst.weight() > 0.0); if (this instanceof SemiSupervisedLearner == false && - inst.classIsMissing() == true){ + inst.missingOutputs() == true){ isTraining = false; } if (isTraining) { @@ -430,7 +434,7 @@ protected static int modelAttIndexToInstanceAttIndex(int index, * @return the index of the attribute in the instances */ protected static int modelAttIndexToInstanceAttIndex(int index, - Instances insts) { + InstancesHeader insts) { return insts.classIndex() > index ? index : index + 1; } } diff --git a/moa/src/main/java/moa/classifiers/bayes/NaiveBayesMultinomial.java b/moa/src/main/java/moa/classifiers/bayes/NaiveBayesMultinomial.java index 523e8d6c8..5e474770e 100644 --- a/moa/src/main/java/moa/classifiers/bayes/NaiveBayesMultinomial.java +++ b/moa/src/main/java/moa/classifiers/bayes/NaiveBayesMultinomial.java @@ -28,7 +28,7 @@ import moa.core.StringUtils; import moa.core.Utils; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Class for building and using a multinomial Naive @@ -77,7 +77,7 @@ public String getPurposeString() { /** * copy of header information for use in toString method */ - protected Instances m_headerInfo; + protected InstancesHeader m_headerInfo; /** * number of class values diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/InstanceConditionalTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/InstanceConditionalTest.java index fad4d9a30..9d5160136 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/InstanceConditionalTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/InstanceConditionalTest.java @@ -20,8 +20,9 @@ package moa.classifiers.core.conditionaltests; import moa.AbstractMOAObject; -import com.yahoo.labs.samoa.instances.InstancesHeader; + import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Abstract conditional test for instances to use to split nodes in Hoeffding trees. diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeBinaryTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeBinaryTest.java index 73498ff6b..519ec6a42 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeBinaryTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeBinaryTest.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Nominal binary conditional test for instances to use to split nodes in Hoeffding trees. diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeMultiwayTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeMultiwayTest.java index 003cf416c..a0dd5ff7b 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeMultiwayTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeMultiwayTest.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Nominal multi way conditional test for instances to use to split nodes in Hoeffding trees. diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java index d8cb5e8c3..597a7c07f 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Numeric binary conditional test for instances to use to split nodes in Hoeffding trees. diff --git a/moa/src/main/java/moa/classifiers/lazy/kNN.java b/moa/src/main/java/moa/classifiers/lazy/kNN.java index da99909e9..1cf765b1d 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNN.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNN.java @@ -24,7 +24,6 @@ import moa.classifiers.lazy.neighboursearch.NearestNeighbourSearch; import moa.core.Measurement; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; @@ -62,12 +61,12 @@ public String getPurposeString() { return "kNN: special."; } - protected Instances window; + protected InstancesHeader window; @Override public void setModelContext(InstancesHeader context) { try { - this.window = new Instances(context,0); //new StringReader(context.toString()) + this.window = new InstancesHeader(context,0); //new StringReader(context.toString()) this.window.setClassIndex(context.classIndex()); } catch(Exception e) { System.err.println("Error: no Model Context available."); @@ -86,7 +85,7 @@ public void trainOnInstanceImpl(Instance inst) { if (inst.classValue() > C) C = (int)inst.classValue(); if (this.window == null) { - this.window = new Instances(inst.dataset()); + this.window = new InstancesHeader(inst.dataset()); } if (this.limitOption.getValue() <= this.window.numInstances()) { this.window.delete(0); @@ -106,7 +105,7 @@ public double[] getVotesForInstance(Instance inst) { search.setInstances(this.window); } if (this.window.numInstances()>0) { - Instances neighbours = search.kNearestNeighbours(inst,Math.min(kOption.getValue(),this.window.numInstances())); + InstancesHeader neighbours = search.kNearestNeighbours(inst,Math.min(kOption.getValue(),this.window.numInstances())); for(int i = 0; i < neighbours.numInstances(); i++) { v[(int)neighbours.instance(i).classValue()]++; } diff --git a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java index 9d7103053..6b78777a3 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java @@ -19,7 +19,7 @@ import moa.classifiers.core.driftdetection.ADWIN; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * k Nearest Neighbor ADAPTIVE with PAW.

@@ -57,7 +57,7 @@ public void trainOnInstanceImpl(Instance inst) { C = (int) inst.classValue(); } if (this.window == null) { - this.window = new Instances(inst.dataset()); + this.window = new InstancesHeader(inst.dataset()); } for (int i = 0; i < this.window.size(); i++) { diff --git a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java index 1ff1b2412..65e9266ed 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java @@ -20,7 +20,7 @@ import java.util.ArrayList; import moa.classifiers.core.driftdetection.ADWIN; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * k Nearest Neighbor ADAPTIVE with ADWIN+PAW.

@@ -67,7 +67,7 @@ public void trainOnInstanceImpl(Instance inst) { } // ADWIN if (this.window == null) { - this.window = new Instances(inst.dataset()); + this.window = new InstancesHeader(inst.dataset()); } if (this.timeStamp == null) { diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/DistanceFunction.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/DistanceFunction.java index 9df3b3a4c..ef0723941 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/DistanceFunction.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/DistanceFunction.java @@ -22,7 +22,7 @@ package moa.classifiers.lazy.neighboursearch; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Interface for any class that can compute and return distances between two @@ -38,14 +38,14 @@ public interface DistanceFunction { * * @param insts the instances to use */ - public void setInstances(Instances insts); + public void setInstances(InstancesHeader insts); /** * returns the instances currently set. * * @return the current instances */ - public Instances getInstances(); + public InstancesHeader getInstances(); /** * Sets the range of attributes to use in the calculation of the distance. diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/EuclideanDistance.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/EuclideanDistance.java index f21197d81..ac9743bbc 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/EuclideanDistance.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/EuclideanDistance.java @@ -22,7 +22,7 @@ package moa.classifiers.lazy.neighboursearch; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** @@ -92,7 +92,7 @@ public EuclideanDistance() { * * @param data the instances the distance function should work on */ - public EuclideanDistance(Instances data) { + public EuclideanDistance(InstancesHeader data) { super(data); } @@ -195,7 +195,7 @@ public double getMiddle(double[] ranges) { * @return the index of the closest point * @throws Exception if something goes wrong */ - public int closestPoint(Instance instance, Instances allPoints, + public int closestPoint(Instance instance, InstancesHeader allPoints, int[] pointList) throws Exception { double minDist = Integer.MAX_VALUE; int bestPoint = 0; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java index 3a44f2b70..b3b6d7a0d 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java @@ -27,7 +27,7 @@ import moa.classifiers.lazy.neighboursearch.kdtrees.KDTreeNodeSplitter; import moa.classifiers.lazy.neighboursearch.kdtrees.SlidingMidPointOfWidestSide; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; @@ -151,7 +151,7 @@ public KDTree() { * @param insts The instances/points on which the BallTree * should be built on. */ - public KDTree(Instances insts) { + public KDTree(InstancesHeader insts) { super(insts); } @@ -166,7 +166,7 @@ public KDTree(Instances insts) { * @param instances The instances to build the tree on * @throws Exception if something goes wrong */ - protected void buildKDTree(Instances instances) throws Exception { + protected void buildKDTree(InstancesHeader instances) throws Exception { checkMissing(instances); if (m_EuclideanDistance == null) @@ -325,13 +325,13 @@ protected void findNearestNeighbours(Instance target, KDTreeNode node, int k, * one neighbours at the kth boundary). * @throws Exception if the nearest neighbour could not be found. */ - public Instances kNearestNeighbours(Instance target, int k) throws Exception { + public InstancesHeader kNearestNeighbours(Instance target, int k) throws Exception { checkMissing(target); MyHeap heap = new MyHeap(k); findNearestNeighbours(target, m_Root, k, heap, 0.0); - Instances neighbours = new Instances(m_Instances, (heap.size() + heap + InstancesHeader neighbours = new InstancesHeader(m_Instances, (heap.size() + heap .noOfKthNearest())); m_DistanceList = new double[heap.size() + heap.noOfKthNearest()]; int[] indices = new int[heap.size() + heap.noOfKthNearest()]; @@ -399,7 +399,7 @@ public double[] getDistances() throws Exception { * @throws Exception If some error occurs while * building the KDTree */ - public void setInstances(Instances instances) throws Exception { + public void setInstances(InstancesHeader instances) throws Exception { super.setInstances(instances); buildKDTree(instances); } @@ -527,7 +527,7 @@ public void addInstanceInfo(Instance instance) { * @param instances the instances to check * @throws Exception if missing values are encountered */ - protected void checkMissing(Instances instances) throws Exception { + protected void checkMissing(InstancesHeader instances) throws Exception { for (int i = 0; i < instances.numInstances(); i++) { Instance ins = instances.instance(i); for (int j = 0; j < ins.numValues(); j++) { @@ -698,7 +698,7 @@ public void setMeasurePerformance(boolean measurePerformance) { * @throws Exception If there is some problem * assigning instances to centers. */ - public void centerInstances(Instances centers, int[] assignments, double pc) + public void centerInstances(InstancesHeader centers, int[] assignments, double pc) throws Exception { int[] centList = new int[centers.numInstances()]; @@ -719,7 +719,7 @@ public void centerInstances(Instances centers, int[] assignments, double pc) * @throws Exception If there is some problem assigning * instances to centers. */ - protected void determineAssignments(KDTreeNode node, Instances centers, + protected void determineAssignments(KDTreeNode node, InstancesHeader centers, int[] candidates, int[] assignments, double pc) throws Exception { // reduce number of owners for current hyper rectangle @@ -752,7 +752,7 @@ protected void determineAssignments(KDTreeNode node, Instances centers, * @return list of owners * @throws Exception If some problem occurs in refining. */ - protected int[] refineOwners(KDTreeNode node, Instances centers, + protected int[] refineOwners(KDTreeNode node, InstancesHeader centers, int[] candidates) throws Exception { int[] owners = new int[candidates.length]; @@ -907,7 +907,7 @@ protected boolean candidateIsFullOwner(KDTreeNode node, Instance candidate, * @param assignments index list of last assignments * @throws Exception If there is error assigning the instances. */ - public void assignSubToCenters(KDTreeNode node, Instances centers, + public void assignSubToCenters(KDTreeNode node, InstancesHeader centers, int[] centList, int[] assignments) throws Exception { // todo: undecided situations int numCent = centList.length; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/LinearNNSearch.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/LinearNNSearch.java index 59b1f07bb..3c51f26c5 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/LinearNNSearch.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/LinearNNSearch.java @@ -22,7 +22,7 @@ import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; //import weka.core.Option; //import weka.core.RevisionUtils; //import weka.core.Utils; @@ -73,7 +73,7 @@ public LinearNNSearch() { * * @param insts the instances to use */ - public LinearNNSearch(Instances insts) { + public LinearNNSearch(InstancesHeader insts) { super(insts); m_DistanceFunction.setInstances(insts); } @@ -143,7 +143,7 @@ public Instance nearestNeighbour(Instance target) throws Exception { * @return the k nearest neighbors * @throws Exception if the neighbours could not be found. */ - public Instances kNearestNeighbours(Instance target, int kNN) throws Exception { + public InstancesHeader kNearestNeighbours(Instance target, int kNN) throws Exception { //debug boolean print=false; @@ -182,7 +182,7 @@ else if(distance == temp.distance) { } } - Instances neighbours = new Instances(m_Instances, (heap.size()+heap.noOfKthNearest())); + InstancesHeader neighbours = new InstancesHeader(m_Instances, (heap.size()+heap.noOfKthNearest())); m_Distances = new double[heap.size()+heap.noOfKthNearest()]; int [] indices = new int[heap.size()+heap.noOfKthNearest()]; int i=1; MyHeapElement h; @@ -240,7 +240,7 @@ public double[] getDistances() throws Exception { * training set. * @throws Exception if setting of instances fails */ - public void setInstances(Instances insts) throws Exception { + public void setInstances(InstancesHeader insts) throws Exception { m_Instances = insts; m_DistanceFunction.setInstances(insts); } diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java index 5b8402c35..ddefd58ae 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java @@ -22,7 +22,7 @@ import java.io.Serializable; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Abstract class for nearest neighbour search. All algorithms (classes) that @@ -482,7 +482,7 @@ public NeighborNode getLast() { } /** The neighbourhood of instances to find neighbours in. */ - protected Instances m_Instances; + protected InstancesHeader m_Instances; /** The number of neighbours to find. */ protected int m_kNN; @@ -504,7 +504,7 @@ public NearestNeighbourSearch() { * * @param insts The set of instances that constitute the neighbourhood. */ - public NearestNeighbourSearch(Instances insts) { + public NearestNeighbourSearch(InstancesHeader insts) { this(); m_Instances = insts; } @@ -592,7 +592,7 @@ public boolean getMeasurePerformance() { * @return the k nearest neighbors * @throws Exception if the neighbours could not be found. */ - public abstract Instances kNearestNeighbours(Instance target, int k) throws Exception; + public abstract InstancesHeader kNearestNeighbours(Instance target, int k) throws Exception; /** * Returns the distances of the k nearest neighbours. The kNearestNeighbours @@ -629,7 +629,7 @@ public void addInstanceInfo(Instance ins) { * @param insts the instances to use * @throws Exception if setting fails */ - public void setInstances(Instances insts) throws Exception { + public void setInstances(InstancesHeader insts) throws Exception { m_Instances = insts; } @@ -638,7 +638,7 @@ public void setInstances(Instances insts) throws Exception { * * @return the current instances */ - public Instances getInstances() { + public InstancesHeader getInstances() { return m_Instances; } diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java index 0c815a686..7800a8576 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java @@ -23,7 +23,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Represents the abstract ancestor for normalizable distance functions, like @@ -48,7 +48,7 @@ public abstract class NormalizableDistance public static final int R_WIDTH = 2; /** the instances used internally. */ - protected Instances m_Data = null; + protected InstancesHeader m_Data = null; /** True if normalization is turned off (default false).*/ protected boolean m_DontNormalize = false; @@ -78,7 +78,7 @@ public NormalizableDistance() { * * @param data the instances the distance function should work on */ - public NormalizableDistance(Instances data) { + public NormalizableDistance(InstancesHeader data) { setInstances(data); } @@ -230,7 +230,7 @@ protected void initializeAttributeIndices() { * * @param insts the instances to use */ - public void setInstances(Instances insts) { + public void setInstances(InstancesHeader insts) { m_Data = insts; invalidate(); } @@ -240,7 +240,7 @@ public void setInstances(Instances insts) { * * @return the current instances */ - public Instances getInstances() { + public InstancesHeader getInstances() { return m_Data; } diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java index 431cfd972..f69760c9f 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java @@ -25,7 +25,7 @@ import java.util.Vector; import moa.classifiers.lazy.neighboursearch.EuclideanDistance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Class that splits up a KDTreeNode. @@ -37,7 +37,7 @@ public abstract class KDTreeNodeSplitter implements Serializable { /** The instances that'll be used for tree construction. */ - protected Instances m_Instances; + protected InstancesHeader m_Instances; /** The distance function used for building the tree. */ protected EuclideanDistance m_EuclideanDistance; @@ -78,7 +78,7 @@ public KDTreeNodeSplitter() { * @param e The EuclideanDistance object that is used * in tree contruction. */ - public KDTreeNodeSplitter(int[] instList, Instances insts, EuclideanDistance e) { + public KDTreeNodeSplitter(int[] instList, InstancesHeader insts, EuclideanDistance e) { m_InstList = instList; m_Instances = insts; m_EuclideanDistance = e; @@ -155,7 +155,7 @@ public abstract void splitNode(KDTreeNode node, int numNodesCreated, * to be) built. * @param inst The training instances. */ - public void setInstances(Instances inst) { + public void setInstances(InstancesHeader inst) { m_Instances = inst; } diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java index 6e19a86a0..6d834c9be 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java @@ -21,7 +21,7 @@ package moa.classifiers.lazy.neighboursearch.kdtrees; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** @@ -227,7 +227,7 @@ public void splitNode(KDTreeNode node, int numNodesCreated, * that should be partitioned. * @return the index of the middle element */ - protected static int partition(Instances insts, int[] index, int attidx, int l, int r) { + protected static int partition(InstancesHeader insts, int[] index, int attidx, int l, int r) { double pivot = insts.instance(index[(l + r) / 2]).value(attidx); int help; @@ -270,7 +270,7 @@ protected static int partition(Instances insts, int[] index, int attidx, int l, * @param right The end index of the portion of the master index * array that needs to be sorted. */ - protected static void quickSort(Instances insts, int[] indices, int attidx, int left, int right) { + protected static void quickSort(InstancesHeader insts, int[] indices, int attidx, int left, int right) { if (left < right) { int middle = partition(insts, indices, attidx, left, right); @@ -295,7 +295,7 @@ protected static void quickSort(Instances insts, int[] indices, int attidx, int * @throws Exception If the indices of the instances * are not in sorted order. */ - private static void checkSort(Instances insts, int[] indices, int attidx, + private static void checkSort(InstancesHeader insts, int[] indices, int attidx, int start, int end) throws Exception { for(int i=start+1; i<=end; i++) { if( insts.instance(indices[i-1]).value(attidx) > diff --git a/moa/src/main/java/moa/classifiers/meta/ADACC.java b/moa/src/main/java/moa/classifiers/meta/ADACC.java index 3c000f353..8aa324af8 100644 --- a/moa/src/main/java/moa/classifiers/meta/ADACC.java +++ b/moa/src/main/java/moa/classifiers/meta/ADACC.java @@ -23,7 +23,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.Classifier; import moa.core.Measurement; @@ -74,7 +74,7 @@ public String getPurposeString() { /** * Last chunk of data of size (tau_size) to compute the stability index */ - protected Instances recentChunk; + protected InstancesHeader recentChunk; /** * Threshold values for the stability index and concept equivalence */ @@ -112,7 +112,7 @@ protected void initVariables(){ public void trainOnInstanceImpl(Instance inst) { if (recentChunk == null) - recentChunk = new Instances(this.getModelContext()); + recentChunk = new InstancesHeader(this.getModelContext()); if (recentChunk.size() < this.tau_size) recentChunk.add(inst); diff --git a/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java index c017c5fe7..f9764fa19 100644 --- a/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java @@ -29,7 +29,7 @@ import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * The revised version of the Accuracy Updated Ensemble as proposed by @@ -94,7 +94,7 @@ public class AccuracyUpdatedEnsemble extends AbstractClassifier { /** * Current chunk of instances. */ - protected Instances currentChunk; + protected InstancesHeader currentChunk; @Override public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { @@ -247,7 +247,7 @@ protected double computeMseR() { * @param chunk chunk of examples * @return the computed error. */ - protected double computeMse(Classifier learner, Instances chunk) { + protected double computeMse(Classifier learner, InstancesHeader chunk) { double mse_i = 0; double f_ci; @@ -348,7 +348,7 @@ private int getPoorestClassifierIndex() { */ private void initVariables() { if (this.currentChunk == null) { - this.currentChunk = new Instances(this.getModelContext()); + this.currentChunk = new InstancesHeader(this.getModelContext()); } if (this.classDistributions == null) { diff --git a/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java index ddcd76d70..df7e6fea1 100644 --- a/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java @@ -30,7 +30,7 @@ import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.Utils; /** @@ -119,7 +119,7 @@ public int compare(double[] o1, double[] o2) { protected Classifier candidateClassifier; - protected Instances currentChunk; + protected InstancesHeader currentChunk; @Override public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { @@ -168,7 +168,7 @@ public void trainOnInstanceImpl(Instance inst) { */ private void initVariables() { if (this.currentChunk == null) { - this.currentChunk = new Instances(this.getModelContext()); + this.currentChunk = new InstancesHeader(this.getModelContext()); } if (this.classDistributions == null) { @@ -243,18 +243,18 @@ protected void processChunk() { * @param useMseR Determines whether to use the MSEr threshold. * @return Candidate classifier weight. */ - protected double computeCandidateWeight(Classifier candidate, Instances chunk, int numFolds) { + protected double computeCandidateWeight(Classifier candidate, InstancesHeader chunk, int numFolds) { double candidateWeight = 0.0; Random random = new Random(1); - Instances randData = new Instances(chunk); + InstancesHeader randData = new InstancesHeader(chunk); randData.randomize(random); if (randData.classAttribute().isNominal()) { randData.stratify(numFolds); } for (int n = 0; n < numFolds; n++) { - Instances train = randData.trainCV(numFolds, n, random); - Instances test = randData.testCV(numFolds, n); + InstancesHeader train = randData.trainCV(numFolds, n, random); + InstancesHeader test = randData.testCV(numFolds, n); Classifier learner = candidate.copy(); @@ -282,7 +282,7 @@ protected double computeCandidateWeight(Classifier candidate, Instances chunk, i * @param useMseR Determines whether to use the MSEr threshold. * @return The given classifier's weight. */ - protected double computeWeight(Classifier learner, Instances chunk) { + protected double computeWeight(Classifier learner, InstancesHeader chunk) { double mse_i = 0; double mse_r = 0; diff --git a/moa/src/main/java/moa/classifiers/meta/RandomRules.java b/moa/src/main/java/moa/classifiers/meta/RandomRules.java index 694b8b37e..e170e1ef7 100644 --- a/moa/src/main/java/moa/classifiers/meta/RandomRules.java +++ b/moa/src/main/java/moa/classifiers/meta/RandomRules.java @@ -25,7 +25,7 @@ import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.AbstractClassifier; @@ -174,7 +174,7 @@ protected Instance transformInstance(Instance inst, int classifierIndex) { //System.out.println("Number of attributes: "+this.numAttributes+ ","+inst.numAttributes()); //JD System.out.println("Number of attributes: "+this.numAttributes+ ","+(inst.numAttributes()-1)); attributes.addElement(inst.classAttribute()); - this.dataset[ensembleIndex] = new InstancesHeader(new Instances( + this.dataset[ensembleIndex] = new InstancesHeader(new InstancesHeader( getCLICreationString(InstanceStream.class), attributes, 0)); this.dataset[ensembleIndex].setClassIndex(this.numAttributes); this.ensemble[ensembleIndex].setModelContext(this.dataset[ensembleIndex]); diff --git a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java index 5fe182cc2..eac49168d 100644 --- a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java @@ -33,7 +33,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Include labels of previous instances into the training data @@ -65,7 +65,7 @@ public String getPurposeString() { protected double[] oldLabels; - protected Instances header; + protected InstancesHeader header; public FlagOption labelDelayOption = new FlagOption("labelDelay", 'd', "Labels arrive with Delay. Use predictions instead of true Labels."); @@ -97,7 +97,7 @@ public void addOldLabel(double newPrediction) { } } - public void initHeader(Instances dataset) { + public void initHeader(InstancesHeader dataset) { int numLabels = this.numOldLabelsOption.getValue(); Attribute target = dataset.classAttribute(); @@ -124,7 +124,7 @@ public void initHeader(Instances dataset) { attrs.add(newAttribute); } } - this.header = new Instances("extended_" + dataset.getRelationName(), attrs, 0); + this.header = new InstancesHeader("extended_" + dataset.getRelationName(), attrs, 0); this.header.setClassIndex(numLabels + dataset.classIndex()); } diff --git a/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java b/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java index 13bb3e338..d9ac321c8 100644 --- a/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java @@ -27,7 +27,7 @@ import weka.classifiers.Classifier; import weka.classifiers.UpdateableClassifier; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; /** diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 4c78071f9..070665e55 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -7,6 +7,7 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; diff --git a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java index 7691b603f..96e8f09ac 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java @@ -30,10 +30,10 @@ import weka.classifiers.Classifier; import weka.classifiers.UpdateableClassifier; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; @@ -90,7 +90,7 @@ public void resetLearningImpl() { } @Override - public void trainOnInstanceImpl(MultiLabelInstance samoaInstance) { + public void trainOnInstanceImpl(StructuredInstance samoaInstance) { // Convert Samoa instance to Weka instance (as used in Meka) L = samoaInstance.numberOutputTargets(); @@ -146,7 +146,7 @@ public double[] getVotesForInstance(Instance samoaInstance) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance samoaInstance) { + public Prediction getPredictionForInstance(StructuredInstance samoaInstance) { MultiLabelPrediction prediction = new MultiLabelPrediction(L); diff --git a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java index c7eded5ed..135f8f88e 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java @@ -60,7 +60,7 @@ public void resetLearningImpl() { } @Override - public void trainOnInstanceImpl(MultiLabelInstance x) { + public void trainOnInstanceImpl(StructuredInstance x) { int L = x.numberOutputTargets(); MultiLabelPrediction y = new MultiLabelPrediction(L); @@ -80,7 +80,7 @@ public void trainOnInstanceImpl(MultiLabelInstance x) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance x){ + public Prediction getPredictionForInstance(StructuredInstance x){ if (this.majorityLabelset == null) { int L = x.numberOutputTargets(); diff --git a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java index b6c793eb9..1801eba28 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java @@ -27,7 +27,6 @@ import moa.core.StringUtils; import moa.core.utils.Converter; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; @@ -181,11 +180,11 @@ protected void deactivateLearningNode(ActiveLearningNode toDeactivate, @Override public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance((MultiLabelInstance)example.getData()); + return getPredictionForInstance((StructuredInstance)example.getData()); } @Override - public Prediction getPredictionForInstance(MultiLabelInstance inst){ + public Prediction getPredictionForInstance(StructuredInstance inst){ if (this.treeRoot != null) { FoundNode foundNode = this.treeRoot.filterInstanceToLeaf(inst, null, -1); @@ -209,12 +208,12 @@ public void trainOnInstance(Instance inst) { boolean isTraining = (inst.weight() > 0.0); if (isTraining) { this.trainingWeightSeenByModel += inst.weight(); - trainOnInstanceImpl((MultiLabelInstance) inst); + trainOnInstanceImpl((StructuredInstance) inst); } } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { trainOnInstanceImpl((Instance) instance); } diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagAdwinML.java b/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagAdwinML.java index d07673f02..a94b89b6f 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagAdwinML.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagAdwinML.java @@ -25,7 +25,7 @@ import moa.core.InstanceExample; import moa.core.MiscUtils; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import moa.classifiers.MultiLabelLearner; @@ -84,7 +84,7 @@ public void trainOnInstanceImpl(Instance inst) { } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { trainOnInstanceImpl((Instance) instance); } @@ -101,7 +101,7 @@ public double[] getVotesForInstance(Instance inst) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { return getPredictionForInstance((new InstanceExample(instance))); } diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagML.java b/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagML.java index 66c9c470a..20acefa4e 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagML.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagML.java @@ -22,7 +22,7 @@ import moa.classifiers.meta.OzaBag; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import moa.classifiers.MultiLabelLearner; @@ -43,7 +43,7 @@ public class OzaBagML extends OzaBag implements MultiLabelLearner, MultiTargetRe //Training @Override - public void trainOnInstanceImpl(MultiLabelInstance inst) { + public void trainOnInstanceImpl(StructuredInstance inst) { trainOnInstanceImpl((Instance) inst); } @@ -119,7 +119,7 @@ public static double[] compileVotes(Classifier h[], Instance inst) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { return getPredictionForInstance((new InstanceExample(instance))); } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index 853405dd8..b7d54bb4a 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -801,6 +801,11 @@ public void resetLearningImpl() { sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); + + } + + @Override + public void modelContextSet() { loadWeights(); } diff --git a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java index 93c1c94a1..edad24332 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java @@ -14,7 +14,7 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; @@ -77,7 +77,7 @@ protected Instance transformInstance(StructuredInstance inst, int outputIndex) { } //System.out.println("Number of attributes: "+this.numAttributes+ ","+inst.numAttributes()); attributes.addElement(inst.outputAttribute(outputIndex)); - this.header[outputIndex] = new InstancesHeader(new Instances( + this.header[outputIndex] = new InstancesHeader(new InstancesHeader( getCLICreationString(InstanceStream.class), attributes, 0)); this.header[outputIndex].setClassIndex(attributes.size()-1); this.ensemble[outputIndex].setModelContext(this.header[outputIndex]); diff --git a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java index fb5505ef7..7e5febe56 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java @@ -2,6 +2,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java index 8387610c0..a6b313c12 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java @@ -2,6 +2,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java index df2405a5a..93d962149 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.core.conditionaltests.NominalAttributeBinaryTest; import moa.classifiers.rules.core.Predicate; diff --git a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java index 37650e7ca..ff4c0c350 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.core.conditionaltests.InstanceConditionalBinaryTest; import moa.classifiers.rules.core.Predicate; diff --git a/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java b/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java index b860ad10e..8828c1d84 100644 --- a/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java +++ b/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java @@ -29,7 +29,6 @@ import com.github.javacliparser.MultiChoiceOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.AbstractClassifier; diff --git a/moa/src/main/java/moa/clusterers/AbstractClusterer.java b/moa/src/main/java/moa/clusterers/AbstractClusterer.java index db3a2a8a4..a8f23f48e 100644 --- a/moa/src/main/java/moa/clusterers/AbstractClusterer.java +++ b/moa/src/main/java/moa/clusterers/AbstractClusterer.java @@ -34,7 +34,7 @@ import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public abstract class AbstractClusterer extends AbstractOptionHandler implements Clusterer { @@ -286,7 +286,7 @@ protected static int modelAttIndexToInstanceAttIndex(int index, } protected static int modelAttIndexToInstanceAttIndex(int index, - Instances insts) { + InstancesHeader insts) { return insts.classIndex() > index ? index : index + 1; } diff --git a/moa/src/main/java/moa/clusterers/Clusterer.java b/moa/src/main/java/moa/clusterers/Clusterer.java index 36bdbf79c..b018b421f 100644 --- a/moa/src/main/java/moa/clusterers/Clusterer.java +++ b/moa/src/main/java/moa/clusterers/Clusterer.java @@ -21,11 +21,11 @@ import moa.MOAObject; import moa.cluster.Clustering; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.Measurement; import moa.gui.AWTRenderable; import moa.options.OptionHandler; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; public interface Clusterer extends MOAObject, OptionHandler, AWTRenderable { diff --git a/moa/src/main/java/moa/clusterers/CobWeb.java b/moa/src/main/java/moa/clusterers/CobWeb.java index c6c451098..03e34a5f9 100644 --- a/moa/src/main/java/moa/clusterers/CobWeb.java +++ b/moa/src/main/java/moa/clusterers/CobWeb.java @@ -30,7 +30,7 @@ import com.github.javacliparser.IntOption; import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import weka.core.AttributeStats; import weka.experiment.Stats; import weka.filters.unsupervised.attribute.Add; @@ -73,7 +73,7 @@ private class CNode implements Serializable { /** * Instances at this node */ - protected Instances m_clusterInstances = null; + protected InstancesHeader m_clusterInstances = null; /** * Children of this node */ @@ -107,7 +107,7 @@ public CNode(int numAttributes, Instance leafInstance) { if (m_clusterInstances == null) { //System.out.println(leafInstance.numAttributes()+"-"+leafInstance.value(0)+"-"+leafInstance.value(1)+"-"+leafInstance.value(2)); //System.out.println(leafInstance.numAttributes()+"-"+leafInstance.attribute(0).type()+"-"+leafInstance.attribute(1).type()+"-"+leafInstance.attribute(2).type()); - m_clusterInstances = new Instances(leafInstance.dataset(), 1); + m_clusterInstances = new InstancesHeader(leafInstance.dataset(), 1); } m_clusterInstances.add(leafInstance); updateStats(leafInstance, false); @@ -122,7 +122,7 @@ protected void addInstance(Instance newInstance) { // Add the instance to this cluster if (m_clusterInstances == null) { - m_clusterInstances = new Instances(newInstance.dataset(), 1); + m_clusterInstances = new InstancesHeader(newInstance.dataset(), 1); m_clusterInstances.add(newInstance); updateStats(newInstance, false); return; @@ -196,7 +196,7 @@ private double cuScoreForBestTwoMerged(CNode merged, double mergedCU = -Double.MAX_VALUE; // consider merging the best and second // best. - merged.m_clusterInstances = new Instances(m_clusterInstances, 1); + merged.m_clusterInstances = new InstancesHeader(m_clusterInstances, 1); merged.addChildNode(a); merged.addChildNode(b); @@ -620,11 +620,11 @@ protected String dumpData() { //throws Exception { // construct instances string with cluster numbers attached CNode tempNode = new CNode(m_numAttributes); - tempNode.m_clusterInstances = new Instances(m_clusterInstances, 1); + tempNode.m_clusterInstances = new InstancesHeader(m_clusterInstances, 1); for (int i = 0; i < m_children.size(); i++) { tempNode.addChildNode((CNode) m_children.elementAt(i)); } - Instances tempInst = tempNode.m_clusterInstances; + InstancesHeader tempInst = tempNode.m_clusterInstances; tempNode = null; Add af = new Add(); diff --git a/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java b/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java index 774e675dc..978290119 100644 --- a/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java +++ b/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java @@ -33,7 +33,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; import weka.core.Utils; @@ -52,7 +52,7 @@ public class WekaClusteringAlgorithm extends AbstractClusterer { private Class[] clustererClasses; - private Instances instances; + private InstancesHeader instances; private weka.clusterers.AbstractClusterer clusterer; @@ -136,7 +136,7 @@ public Clustering getClusteringResult() { clusterer.buildClusterer(wekaInstances); int numClusters = clusterer.numberOfClusters(); - Instances dataset = getDataset(instances.numAttributes(), numClusters); + InstancesHeader dataset = getDataset(instances.numAttributes(), numClusters); List newInstances = new ArrayList() ; //Instances(dataset); for (int i = 0; i < wekaInstances.numInstances(); i++) { @@ -159,7 +159,7 @@ public Clustering getClusteringResult() { return clustering; } - public Instances getDataset(int numdim, int numclass) { + public InstancesHeader getDataset(int numdim, int numclass) { FastVector attributes = new FastVector(); for (int i = 0; i < numdim; i++) { attributes.addElement(new Attribute("att" + (i + 1))); @@ -173,7 +173,7 @@ public Instances getDataset(int numdim, int numclass) { attributes.addElement(new Attribute("class", classLabels)); } - Instances myDataset = new Instances("horizion", attributes, 0); + InstancesHeader myDataset = new InstancesHeader("horizion", attributes, 0); if (numclass > 0) { myDataset.setClassIndex(myDataset.numAttributes() - 1); } diff --git a/moa/src/main/java/moa/core/MultilabelInstancesHeader.java b/moa/src/main/java/moa/core/MultilabelInstancesHeader.java index cc7e57c59..b8dc3b3c2 100644 --- a/moa/src/main/java/moa/core/MultilabelInstancesHeader.java +++ b/moa/src/main/java/moa/core/MultilabelInstancesHeader.java @@ -19,7 +19,7 @@ */ package moa.core; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; /** @@ -33,7 +33,7 @@ public class MultilabelInstancesHeader extends InstancesHeader { private int m_NumLabels = -1; - public MultilabelInstancesHeader(Instances i, int numLabels) { + public MultilabelInstancesHeader(InstancesHeader i, int numLabels) { super(i); m_NumLabels = numLabels; } diff --git a/moa/src/main/java/moa/core/SizeOf.java b/moa/src/main/java/moa/core/SizeOf.java index 6e7b4e168..ff3def4c8 100644 --- a/moa/src/main/java/moa/core/SizeOf.java +++ b/moa/src/main/java/moa/core/SizeOf.java @@ -34,7 +34,7 @@ public class SizeOf { protected static Boolean m_Present; /** - * Checks whteher the agent is present. + * Checks whether the agent is present. * * @return true if the agent is present, false otherwise */ diff --git a/moa/src/main/java/moa/core/utils/AttributeDefinitionUtil.java b/moa/src/main/java/moa/core/utils/AttributeDefinitionUtil.java new file mode 100644 index 000000000..a47df6c0d --- /dev/null +++ b/moa/src/main/java/moa/core/utils/AttributeDefinitionUtil.java @@ -0,0 +1,121 @@ +package moa.core.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class AttributeDefinitionUtil { + //public static String definitionTotal = "(!?-?[0-9]+?)|(!?[0-9]+?-[0-9]+?)|(!?-?[0-9]+?~-?[0-9]+?)"; + + public static String nonIgnoredDefinition = "0"; + + public static String definitionSingle = "-?[0-9]+?"; + public static String definitionPositiveRange = "-?[0-9]+?-[0-9]+?"; + public static String definitionArbitraryRange = "-?[0-9]+?~-?[0-9]+?"; + + public static String getDefinitionTotal() { + return "(!?" + definitionSingle + ")|" + "(!?" + definitionPositiveRange + ")|" + "(!?" + definitionArbitraryRange + ")"; + } + + public static List parseDefinition(String definition, int numAttributes, List ignoredAttributes) { + List ret = new ArrayList(); + if (Pattern.matches(definitionArbitraryRange, definition)) { + String[] split = definition.split("~"); + int start = Integer.valueOf(split[0]); + int end = Integer.valueOf(split[1]); + if (start < 0) { + start = numAttributes + start + 1; // + 1 for so that -1 maps to last attribute + } + if (end < 0) { + end = numAttributes + end + 1; // + 1 for so that -1 maps to last attribute + } + start = Math.max(0, start); + end = Math.max(0, end); + if (start == end) { + System.err.println("[Warning] Strage attribute range definition '" + definition + "', start equals end"); + } + Integer i = start; + if (start <= end) + while(i <= end) { + if (!ignoredAttributes.contains(i - 1)) ret.add(i - 1); + i++; + } + else + System.err.println("[Warning] Strage attribute range definition '" + definition + "', end smaller of start, ignoring..."); + } else if (Pattern.matches(definitionPositiveRange, definition)) { + String[] split = definition.split("-"); + int start = Integer.valueOf(split[0]); + int end = Integer.valueOf(split[1]); + if (start == 0 || end == 0) { + throw new UnsupportedOperationException("Attribute definition range error - start or end equals 0: " + definition); + } + if (start == end) { + System.err.println("[Warning] Strage attribute range definition '" + definition + "', start equals end"); + } + Integer i = start; + if (start <= end) + while(i <= end) { + if (!ignoredAttributes.contains(i - 1)) ret.add(i - 1); + i++; + } + else + System.err.println("[Warning] Strage attribute range definition '" + definition + "', end smaller of start, ignoring..."); + } else if (Pattern.matches(definitionSingle, definition)) { + int index = Integer.valueOf(definition); + if (index == 0) { + // Add all non-ignored attributes + for (Integer i = 0; i < numAttributes; i++) + if (!ignoredAttributes.contains(i)) ret.add(i); + } else { + if (index < 0){ + index = numAttributes + index + 1; + if (index <= 0) { + throw new UnsupportedOperationException("Attribute definition range error - negative index overflows the number of attributes: " + definition); + } + } + if (!ignoredAttributes.contains(index - 1)) ret.add(index - 1); + } + } + return ret; + } + + public static List parseAttributeDefinition(String attributeDefinition, int numAttributes, List ignoredAttributes) { + List ret = new ArrayList(); + if (ignoredAttributes == null) ignoredAttributes = new ArrayList(); + if (attributeDefinition != "") { + String[] definitions = attributeDefinition.split("[,;]"); + Pattern definitionsPattern = Pattern.compile(getDefinitionTotal()); + for (int i = 0; i < definitions.length; i++) { + String definition = definitions[i]; + boolean negative = false; + if (definition.isEmpty()) { + continue; + } + if (!definitionsPattern.matcher(definition).matches()) throw new UnsupportedOperationException("The attribute definition '" + definition + "' is not recognised."); + + if (definition.startsWith("!")) { + definition = definition.substring(1); + negative = true; + } + + List candidates = parseDefinition(definition, numAttributes, ignoredAttributes); + if (negative) { + for (Integer j : candidates) { + if (ret.contains(j)) ret.remove(j); + } + } else { + for (Integer j : candidates) { + if (!ret.contains(j)) ret.add(j); + } + } + } + } else { + // Add all non-ignored attributes (this is the default behavior for input attributes) + for (Integer i = 0; i < numAttributes; i++) + if (!ignoredAttributes.contains(i)) ret.add(i); + } + return ret; + } + + +} diff --git a/moa/src/main/java/moa/core/utils/Converter.java b/moa/src/main/java/moa/core/utils/Converter.java index 3e3110557..a3f976c38 100755 --- a/moa/src/main/java/moa/core/utils/Converter.java +++ b/moa/src/main/java/moa/core/utils/Converter.java @@ -23,7 +23,7 @@ import java.util.List; import moa.AbstractMOAObject; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Converter. This class can be used to convert a multi-label instance into a @@ -34,7 +34,7 @@ */ public class Converter extends AbstractMOAObject { - protected Instances m_InstancesTemplate = null; + protected InstancesHeader m_InstancesTemplate = null; protected int m_L = -1; @@ -49,8 +49,8 @@ public Converter(int n) { m_L = n; } - public Instances createTemplate(Instances i) { - this.m_InstancesTemplate = new Instances(i, 0, 0); + public InstancesHeader createTemplate(InstancesHeader i) { + this.m_InstancesTemplate = new InstancesHeader(i, 0, 0); return this.m_InstancesTemplate; } diff --git a/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java index 6f677c93c..33e6b18d1 100644 --- a/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java @@ -24,7 +24,7 @@ import moa.core.Measurement; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; /** @@ -57,7 +57,7 @@ public void reset() { @Override public void addResult(Example example, Prediction y) { - MultiLabelInstance x = (MultiLabelInstance) example.getData(); + StructuredInstance x = (StructuredInstance) example.getData(); if (L == 0) { L = x.numberOutputTargets(); diff --git a/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java b/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java index 380b31204..ce611e1ba 100644 --- a/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java +++ b/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java @@ -59,7 +59,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public class RunOutlierVisualizer implements Runnable, ActionListener, ClusterEventListener{ /** the pause interval, being read from the gui at startup */ @@ -646,7 +646,7 @@ public void weka() { for(int i = 0; i < dims; i++) attributes.addElement( new Attribute("att" + i) ); - Instances instances = new Instances("trainset",attributes,0); + InstancesHeader instances = new InstancesHeader("trainset",attributes,0); for(int c = 0; c < wekaClustering.size(); c++){ Cluster cluster = wekaClustering.get(c); diff --git a/moa/src/main/java/moa/gui/visualization/RunVisualizer.java b/moa/src/main/java/moa/gui/visualization/RunVisualizer.java index e95cb7551..1e08cab18 100644 --- a/moa/src/main/java/moa/gui/visualization/RunVisualizer.java +++ b/moa/src/main/java/moa/gui/visualization/RunVisualizer.java @@ -52,7 +52,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import moa.core.FastVector; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public class RunVisualizer implements Runnable, ActionListener, ClusterEventListener{ @@ -606,7 +606,7 @@ public void weka() { for(int i = 0; i < dims; i++) attributes.addElement( new Attribute("att" + i) ); - Instances instances = new Instances("trainset",attributes,0); + InstancesHeader instances = new InstancesHeader("trainset",attributes,0); for(int c = 0; c < wekaClustering.size(); c++){ Cluster cluster = wekaClustering.get(c); diff --git a/moa/src/main/java/moa/gui/visualization/WekaExplorer.java b/moa/src/main/java/moa/gui/visualization/WekaExplorer.java index 7825f5433..cfc1d5254 100644 --- a/moa/src/main/java/moa/gui/visualization/WekaExplorer.java +++ b/moa/src/main/java/moa/gui/visualization/WekaExplorer.java @@ -36,7 +36,7 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; @@ -46,7 +46,7 @@ public class WekaExplorer { /** for monitoring the Memory consumption */ private static Memory m_Memory = new Memory(true); - public WekaExplorer(Instances instances) { + public WekaExplorer(InstancesHeader instances) { //weka.core.logging.Logger.log(weka.core.logging.Logger.Level.INFO, "Logging started"); try { javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); diff --git a/moa/src/main/java/moa/streams/ArffFileStream.java b/moa/src/main/java/moa/streams/ArffFileStream.java index 408c6d2da..5d0d10ef9 100644 --- a/moa/src/main/java/moa/streams/ArffFileStream.java +++ b/moa/src/main/java/moa/streams/ArffFileStream.java @@ -21,7 +21,8 @@ import com.github.javacliparser.FileOption; import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instances; +import com.github.javacliparser.StringOption; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import java.io.BufferedReader; import java.io.FileInputStream; @@ -41,7 +42,7 @@ * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * @version $Revision: 7 $ */ -public class ArffFileStream extends AbstractOptionHandler implements InstanceStream { +public class ArffFileStream extends AbstractOptionHandler implements InstanceStream, MultiTargetInstanceStream { @Override public String getPurposeString() { @@ -53,13 +54,26 @@ public String getPurposeString() { public FileOption arffFileOption = new FileOption("arffFile", 'f', "ARFF file to load.", null, "arff", false); - public IntOption classIndexOption = new IntOption( - "classIndex", - 'c', - "Class index of data. 0 for none or -1 for last attribute in file.", - -1, -1, Integer.MAX_VALUE); +// public IntOption classIndexOption = new IntOption( +// "classIndex", +// 'c', +// "Class index of data. 0 for none or -1 for last attribute in file.", +// -1, -1, Integer.MAX_VALUE); + + public StringOption outputIndexesOption = new StringOption( + "outputIndexes", + 'c', + "Indices of output (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges.", + "-1"); + + public StringOption inputIndexesOption = new StringOption( + "inputIndexes", + 'i', + "Indices of input (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges. Leave blank for all non-output attributes.", + ""); - protected Instances instances; + + protected InstancesHeader instances; protected Reader fileReader; @@ -76,7 +90,22 @@ public ArffFileStream() { public ArffFileStream(String arffFileName, int classIndex) { this.arffFileOption.setValue(arffFileName); - this.classIndexOption.setValue(classIndex); + this.outputIndexesOption.setValue(Integer.toString(classIndex)); + this.inputIndexesOption.setValue(""); + restart(); + } + + + public ArffFileStream(String arffFileName, String outputIndexes) { + this.arffFileOption.setValue(arffFileName); + this.outputIndexesOption.setValue(outputIndexes); + restart(); + } + + public ArffFileStream(String arffFileName, String outputIndexes, String inputIndexes) { + this.arffFileOption.setValue(arffFileName); + this.outputIndexesOption.setValue(outputIndexes); + this.inputIndexesOption.setValue(inputIndexes); restart(); } @@ -126,13 +155,7 @@ public void restart() { this.fileProgressMonitor = new InputStreamProgressMonitor( fileStream); this.fileReader = new BufferedReader(new InputStreamReader(this.fileProgressMonitor)); - int classIndex = this.classIndexOption.getValue(); - this.instances = new Instances(this.fileReader, 1, classIndex); - if (classIndex < 0) { - this.instances.setClassIndex(this.instances.numAttributes() - 1); - } else if (this.classIndexOption.getValue() > 0) { - this.instances.setClassIndex(this.classIndexOption.getValue() - 1); - } + this.instances = new InstancesHeader(this.fileReader, 1, this.outputIndexesOption.getValue(), this.inputIndexesOption.getValue()); this.numInstancesRead = 0; this.lastInstanceRead = null; this.hitEndOfFile = !readNextInstanceFromFile(); diff --git a/moa/src/main/java/moa/streams/CachedInstancesStream.java b/moa/src/main/java/moa/streams/CachedInstancesStream.java index 4faa60832..bb618fac8 100644 --- a/moa/src/main/java/moa/streams/CachedInstancesStream.java +++ b/moa/src/main/java/moa/streams/CachedInstancesStream.java @@ -23,7 +23,7 @@ import moa.core.InstanceExample; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator for representing a stream that is cached in memory. @@ -38,11 +38,11 @@ public class CachedInstancesStream extends AbstractMOAObject implements private static final long serialVersionUID = 1L; - protected Instances toStream; + protected InstancesHeader toStream; protected int streamPos; - public CachedInstancesStream(Instances toStream) { + public CachedInstancesStream(InstancesHeader toStream) { this.toStream = toStream; } diff --git a/moa/src/main/java/moa/streams/ConceptDriftRealStream.java b/moa/src/main/java/moa/streams/ConceptDriftRealStream.java index fd7b8c313..46c30398a 100644 --- a/moa/src/main/java/moa/streams/ConceptDriftRealStream.java +++ b/moa/src/main/java/moa/streams/ConceptDriftRealStream.java @@ -23,13 +23,16 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import java.util.ArrayList; +import java.util.List; import java.util.Random; import moa.core.InstanceExample; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; +import moa.core.utils.AttributeDefinitionUtil; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; import com.github.javacliparser.FloatOption; @@ -111,8 +114,8 @@ public void prepareForUseImpl(TaskMonitor monitor, } // generate header - Instances first = this.inputStream.getHeader(); - Instances second = this.driftStream.getHeader(); + InstancesHeader first = this.inputStream.getHeader(); + InstancesHeader second = this.driftStream.getHeader(); FastVector newAttributes = new FastVector(); for (int i = 0; i < first.numAttributes() - 1; i++) { newAttributes.addElement(first.attribute(i)); @@ -130,9 +133,11 @@ public void prepareForUseImpl(TaskMonitor monitor, } newAttributes.addElement(classLabels); - this.streamHeader = new InstancesHeader(new Instances( + this.streamHeader = new InstancesHeader(new InstancesHeader( getCLICreationString(InstanceStream.class), newAttributes, 0)); this.streamHeader.setClassIndex(this.streamHeader.numAttributes() - 1); + // TODO adapt for multi-target streaming + this.streamHeader.setInputIndexes(); restart(); } diff --git a/moa/src/main/java/moa/streams/ConceptDriftStream.java b/moa/src/main/java/moa/streams/ConceptDriftStream.java index c0775b447..19ff13c49 100644 --- a/moa/src/main/java/moa/streams/ConceptDriftStream.java +++ b/moa/src/main/java/moa/streams/ConceptDriftStream.java @@ -22,8 +22,6 @@ import java.util.Random; import moa.core.Example; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; @@ -31,6 +29,7 @@ import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator that adds concept drift to examples in a stream. diff --git a/moa/src/main/java/moa/streams/ExampleStream.java b/moa/src/main/java/moa/streams/ExampleStream.java index f5e9ec500..20877597a 100644 --- a/moa/src/main/java/moa/streams/ExampleStream.java +++ b/moa/src/main/java/moa/streams/ExampleStream.java @@ -21,8 +21,9 @@ import moa.MOAObject; import moa.core.Example; -import com.yahoo.labs.samoa.instances.InstancesHeader; + import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Interface representing a data stream of examples. diff --git a/moa/src/main/java/moa/streams/FilteredStream.java b/moa/src/main/java/moa/streams/FilteredStream.java index 1eb0803a5..6cf072f88 100644 --- a/moa/src/main/java/moa/streams/FilteredStream.java +++ b/moa/src/main/java/moa/streams/FilteredStream.java @@ -19,8 +19,9 @@ */ package moa.streams; -import moa.core.Example; import com.yahoo.labs.samoa.instances.InstancesHeader; + +import moa.core.Example; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/streams/MultiFilteredStream.java b/moa/src/main/java/moa/streams/MultiFilteredStream.java index 6e35c4994..befa684b6 100644 --- a/moa/src/main/java/moa/streams/MultiFilteredStream.java +++ b/moa/src/main/java/moa/streams/MultiFilteredStream.java @@ -21,7 +21,6 @@ import moa.core.Example; import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; @@ -31,6 +30,7 @@ import moa.streams.filters.StreamFilter; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Class for representing a stream that is filtered. diff --git a/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java b/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java index d63b0e451..f7c8bdf79 100644 --- a/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java +++ b/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java @@ -19,6 +19,8 @@ */ package moa.streams; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; @@ -29,8 +31,6 @@ import moa.streams.filters.StreamFilter; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.InstancesHeader; - /** * Class for representing a stream that is filtered. * diff --git a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java index 4eb9dbff0..80e2ae84f 100644 --- a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java +++ b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java @@ -20,7 +20,7 @@ package moa.streams; import com.github.javacliparser.FileOption; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import java.io.BufferedReader; import java.io.FileInputStream; @@ -41,149 +41,151 @@ * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * @version $Revision: 7 $ */ -public class MultiTargetArffFileStream extends AbstractOptionHandler implements +public class MultiTargetArffFileStream extends ArffFileStream implements MultiTargetInstanceStream { - @Override - public String getPurposeString() { - return "A stream read from an ARFF file."; - } - - private static final long serialVersionUID = 1L; - - public FileOption arffFileOption = new FileOption("arffFile", 'f', - "ARFF file to load.", null, "arff", false); - - public RangeOption outputAttributesOption = new RangeOption( - "outputAttributes", - 'c', - "Output attributes: n for first n attributes, -n for last n attributes For example, 2 for the two first attributes, -2 for the two last attributes.", - "-1"); - - protected Instances instances; - - protected Reader fileReader; - - protected boolean hitEndOfFile; - - protected InstanceExample lastInstanceRead; - - protected int numInstancesRead; - - protected InputStreamProgressMonitor fileProgressMonitor; - - public MultiTargetArffFileStream() { - } - - // jesse - public MultiTargetArffFileStream(String arffFileName, String classIndices) { - this.arffFileOption.setValue(arffFileName); - this.outputAttributesOption.setValue(classIndices); - restart(); - } - - /* - public ArffFileStream(String arffFileName, int classIndex) { - this.arffFileOption.setValue(arffFileName); - this.outputAttributesOption.setValue(classIndex); - restart(); - } - */ - - @Override - public void prepareForUseImpl(TaskMonitor monitor, - ObjectRepository repository) { - restart(); - } - - @Override - public InstancesHeader getHeader() { - return new InstancesHeader(this.instances); - } - - @Override - public long estimatedRemainingInstances() { - double progressFraction = this.fileProgressMonitor.getProgressFraction(); - if ((progressFraction > 0.0) && (this.numInstancesRead > 0)) { - return (long) ((this.numInstancesRead / progressFraction) - this.numInstancesRead); - } - return -1; - } - - @Override - public boolean hasMoreInstances() { - return !this.hitEndOfFile; - } - - @Override - public InstanceExample nextInstance() { - InstanceExample prevInstance = this.lastInstanceRead; - this.hitEndOfFile = !readNextInstanceFromFile(); - return prevInstance; - } - - @Override - public boolean isRestartable() { - return true; - } - - @Override - public void restart() { - try { - if (this.fileReader != null) { - this.fileReader.close(); - } - InputStream fileStream = new FileInputStream(this.arffFileOption.getFile()); - this.fileProgressMonitor = new InputStreamProgressMonitor( - fileStream); - this.fileReader = new BufferedReader(new InputStreamReader( - this.fileProgressMonitor)); - // jesse ----- - /*int cs[] = this.outputAttributesOption.getRange(); - if (cs.length == 1) { - // single label - int c = cs[0]; - this.instances = new Instances(this.fileReader, 1, c); - if (c < 0) { - this.instances.setClassIndex(this.instances.numAttributes() - 1); - } else if (c > 0) { - this.instances.setClassIndex(c - 1); - } - } - else {*/ - // multi-label since cs[] contains _multipe_ class indices, e.g., cs[] = {9,10,11} - // what to do here? - this.instances = new Instances(this.fileReader, this.outputAttributesOption.getRange()); - //} - this.numInstancesRead = 0; - this.lastInstanceRead = null; - this.hitEndOfFile = !readNextInstanceFromFile(); - } catch (IOException ioe) { - throw new RuntimeException("ArffFileStream restart failed.", ioe); - } - } - - protected boolean readNextInstanceFromFile() { - try { - if (this.instances.readInstance(this.fileReader)) { - this.lastInstanceRead = new InstanceExample(this.instances.instance(0)); - this.instances.delete(); // keep instances clean - this.numInstancesRead++; - return true; - } - if (this.fileReader != null) { - this.fileReader.close(); - this.fileReader = null; - } - return false; - } catch (IOException ioe) { - throw new RuntimeException( - "ArffFileStream failed to read instance from stream.", ioe); - } - } - - @Override - public void getDescription(StringBuilder sb, int indent) { - // TODO Auto-generated method stub - } + // deprecated + +// @Override +// public String getPurposeString() { +// return "A stream read from an ARFF file."; +// } +// +// private static final long serialVersionUID = 1L; +// +// public FileOption arffFileOption = new FileOption("arffFile", 'f', +// "ARFF file to load.", null, "arff", false); +// +// public RangeOption outputAttributesOption = new RangeOption( +// "outputAttributes", +// 'c', +// "Output attributes: n for first n attributes, -n for last n attributes For example, 2 for the two first attributes, -2 for the two last attributes.", +// "-1"); +// +// protected Instances instances; +// +// protected Reader fileReader; +// +// protected boolean hitEndOfFile; +// +// protected InstanceExample lastInstanceRead; +// +// protected int numInstancesRead; +// +// protected InputStreamProgressMonitor fileProgressMonitor; +// +// public MultiTargetArffFileStream() { +// } +// +// // jesse +// public MultiTargetArffFileStream(String arffFileName, String classIndices) { +// this.arffFileOption.setValue(arffFileName); +// this.outputAttributesOption.setValue(classIndices); +// restart(); +// } +// +// /* +// public ArffFileStream(String arffFileName, int classIndex) { +// this.arffFileOption.setValue(arffFileName); +// this.outputAttributesOption.setValue(classIndex); +// restart(); +// } +// */ +// +// @Override +// public void prepareForUseImpl(TaskMonitor monitor, +// ObjectRepository repository) { +// restart(); +// } +// +// @Override +// public InstancesHeader getHeader() { +// return new InstancesHeader(this.instances); +// } +// +// @Override +// public long estimatedRemainingInstances() { +// double progressFraction = this.fileProgressMonitor.getProgressFraction(); +// if ((progressFraction > 0.0) && (this.numInstancesRead > 0)) { +// return (long) ((this.numInstancesRead / progressFraction) - this.numInstancesRead); +// } +// return -1; +// } +// +// @Override +// public boolean hasMoreInstances() { +// return !this.hitEndOfFile; +// } +// +// @Override +// public InstanceExample nextInstance() { +// InstanceExample prevInstance = this.lastInstanceRead; +// this.hitEndOfFile = !readNextInstanceFromFile(); +// return prevInstance; +// } +// +// @Override +// public boolean isRestartable() { +// return true; +// } +// +// @Override +// public void restart() { +// try { +// if (this.fileReader != null) { +// this.fileReader.close(); +// } +// InputStream fileStream = new FileInputStream(this.arffFileOption.getFile()); +// this.fileProgressMonitor = new InputStreamProgressMonitor( +// fileStream); +// this.fileReader = new BufferedReader(new InputStreamReader( +// this.fileProgressMonitor)); +// // jesse ----- +// /*int cs[] = this.outputAttributesOption.getRange(); +// if (cs.length == 1) { +// // single label +// int c = cs[0]; +// this.instances = new Instances(this.fileReader, 1, c); +// if (c < 0) { +// this.instances.setClassIndex(this.instances.numAttributes() - 1); +// } else if (c > 0) { +// this.instances.setClassIndex(c - 1); +// } +// } +// else {*/ +// // multi-label since cs[] contains _multipe_ class indices, e.g., cs[] = {9,10,11} +// // what to do here? +// this.instances = new Instances(this.fileReader, this.outputAttributesOption.getRange()); +// //} +// this.numInstancesRead = 0; +// this.lastInstanceRead = null; +// this.hitEndOfFile = !readNextInstanceFromFile(); +// } catch (IOException ioe) { +// throw new RuntimeException("ArffFileStream restart failed.", ioe); +// } +// } +// +// protected boolean readNextInstanceFromFile() { +// try { +// if (this.instances.readInstance(this.fileReader)) { +// this.lastInstanceRead = new InstanceExample(this.instances.instance(0)); +// this.instances.delete(); // keep instances clean +// this.numInstancesRead++; +// return true; +// } +// if (this.fileReader != null) { +// this.fileReader.close(); +// this.fileReader = null; +// } +// return false; +// } catch (IOException ioe) { +// throw new RuntimeException( +// "ArffFileStream failed to read instance from stream.", ioe); +// } +// } +// +// @Override +// public void getDescription(StringBuilder sb, int indent) { +// // TODO Auto-generated method stub +// } } diff --git a/moa/src/main/java/moa/streams/clustering/FileStream.java b/moa/src/main/java/moa/streams/clustering/FileStream.java index 9b122de65..7ef557add 100644 --- a/moa/src/main/java/moa/streams/clustering/FileStream.java +++ b/moa/src/main/java/moa/streams/clustering/FileStream.java @@ -43,10 +43,12 @@ import com.github.javacliparser.IntOption; import com.github.javacliparser.ListOption; import com.github.javacliparser.Option; +import com.github.javacliparser.StringOption; + import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public class FileStream extends ClusteringStream{ @@ -63,12 +65,24 @@ public String getPurposeString() { public FileOption arffFileOption = new FileOption("arffFile", 'f', "ARFF file to load.", defaultfile, "arff", false); - public IntOption classIndexOption = new IntOption( - "classIndex", - 'c', - "Class index of data. 0 for none or -1 for last attribute in file.", - -1, -1, Integer.MAX_VALUE); - +// public IntOption classIndexOption = new IntOption( +// "classIndex", +// 'c', +// "Class index of data. 0 for none or -1 for last attribute in file.", +// -1, -1, Integer.MAX_VALUE); + + public StringOption outputIndicesOption = new StringOption( + "outputIndices", + 'c', + "Indices of output (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges.", + "-1"); + + public StringOption inputIndicesOption = new StringOption( + "outputIndices", + 'i', + "Indices of input (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges. Leave blank for all non-output attributes.", + ""); + public FlagOption normalizeOption = new FlagOption("normalize", 'n', "Numerical data will be normalized to 0-1 " + @@ -90,7 +104,7 @@ public String getPurposeString() { - protected Instances instances; + protected InstancesHeader instances; protected Reader fileReader; @@ -104,7 +118,7 @@ public String getPurposeString() { private Integer[] removeAttributes = null; - private Instances filteredDataset = null; + private InstancesHeader filteredDataset = null; private ArrayList valuesMinMaxDiff = null; @@ -155,12 +169,7 @@ public void restart() { InputStream fileStream = new FileInputStream(arffFileOption.getFile()); fileProgressMonitor = new InputStreamProgressMonitor(fileStream); fileReader = new BufferedReader(new InputStreamReader(fileProgressMonitor)); - instances = new Instances(fileReader, 1, this.classIndexOption.getValue()); - if (classIndexOption.getValue() < 0) { - instances.setClassIndex(instances.numAttributes() - 1); - } else if (classIndexOption.getValue() > 0) { - instances.setClassIndex(classIndexOption.getValue() - 1); - } + instances = new InstancesHeader(fileReader, 1, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); //use hashset to delete duplicates and attributes numbers that aren't valid @@ -206,7 +215,7 @@ public void restart() { } //create filtered dataset - filteredDataset = new Instances(instances); + filteredDataset = new InstancesHeader(instances); for (int i = removeAttributes.length-1; i >= 0 ; i--) { filteredDataset.deleteAttributeAt(removeAttributes[i]); if(true){ @@ -278,7 +287,7 @@ protected ArrayList readMinMaxDiffValues(HashSet ignoredAttri InputStream fileStream = new FileInputStream(arffFileOption.getFile()); InputStreamProgressMonitor fileProgressMonitor = new InputStreamProgressMonitor(fileStream); Reader fileReader = new BufferedReader(new InputStreamReader(fileProgressMonitor)); - Instances instances = new Instances(fileReader, 1, this.classIndexOption.getValue()); + InstancesHeader instances = new InstancesHeader(fileReader, 1, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); valuesMinMaxDiff = new ArrayList(); for (int i = 0; i < instances.numAttributes()-ignoredAttributes.size(); i++) { diff --git a/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java b/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java index 4ade99a71..84b15eebc 100644 --- a/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java +++ b/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java @@ -47,7 +47,7 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public class RandomRBFGeneratorEvents extends ClusteringStream { @@ -510,7 +510,7 @@ protected void generateHeader() { // 2013/06/02: Noise label if (noiseLevelOption.getValue() > 0) classLabels.add("noise"); // The last label = "noise" attributes.add(new Attribute("class", classLabels)); - streamHeader = new InstancesHeader(new Instances(getCLICreationString(InstanceStream.class), attributes, 0)); + streamHeader = new InstancesHeader(new InstancesHeader(getCLICreationString(InstanceStream.class), attributes, 0)); streamHeader.setClassIndex(streamHeader.numAttributes() - 1); } diff --git a/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java b/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java index d554e0eaf..fe46621be 100644 --- a/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java +++ b/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java @@ -33,7 +33,7 @@ import com.github.javacliparser.StringOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.InputStreamProgressMonitor; @@ -61,7 +61,7 @@ public class SimpleCSVStream extends ClusteringStream { public FlagOption classIndexOption = new FlagOption("classIndex", 'c', "Last attribute is class index."); - protected Instances dataset; + protected InstancesHeader dataset; protected BufferedReader fileReader; @@ -252,7 +252,7 @@ public void restart() { ArrayList classLabels = new ArrayList(); classLabels.add("0"); attributes.add(new Attribute("class", classLabels)); - this.dataset = new Instances(csvFileOption.getFile().getName(), + this.dataset = new InstancesHeader(csvFileOption.getFile().getName(), attributes, 0); this.dataset.setClassIndex(this.numAttributes - 1); numAttsOption = new IntOption("numAtts", 'a', "", diff --git a/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java b/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java index 3caa94559..c7968e479 100644 --- a/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java +++ b/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java @@ -25,10 +25,11 @@ import moa.core.DoubleVector; import moa.core.GaussianEstimator; import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Filter for adding random noise to examples in a stream. diff --git a/moa/src/main/java/moa/streams/filters/RBFFilter.java b/moa/src/main/java/moa/streams/filters/RBFFilter.java index 4b9901d83..bf90b324c 100644 --- a/moa/src/main/java/moa/streams/filters/RBFFilter.java +++ b/moa/src/main/java/moa/streams/filters/RBFFilter.java @@ -11,7 +11,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Range; @@ -88,7 +88,7 @@ private void initialize(Instance instance) { } // initialize instance space - Instances ds = new Instances(); + InstancesHeader ds = new InstancesHeader(); List v = new ArrayList(h); List indexValues = new ArrayList(h); @@ -101,9 +101,6 @@ private void initialize(Instance instance) { ds.setAttributes(v,indexValues); - Range r= new Range("start-end"); - //r.setUpper(h); - ds.setRangeOutputIndices(r); dataset=(new InstancesHeader(ds)); dataset.setClassIndex(h); System.out.println(""+dataset); diff --git a/moa/src/main/java/moa/streams/filters/ReLUFilter.java b/moa/src/main/java/moa/streams/filters/ReLUFilter.java index f50c6ac60..3f6eb7f55 100644 --- a/moa/src/main/java/moa/streams/filters/ReLUFilter.java +++ b/moa/src/main/java/moa/streams/filters/ReLUFilter.java @@ -11,7 +11,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Range; @@ -99,7 +99,7 @@ private void initialize(Instance instance) { } // initialize instance space - Instances ds = new Instances(); + InstancesHeader ds = new InstancesHeader(); List v = new ArrayList(H); List indexValues = new ArrayList(H); @@ -112,8 +112,6 @@ private void initialize(Instance instance) { ds.setAttributes(v,indexValues); - Range r= new Range("start-end"); - ds.setRangeOutputIndices(r); dataset=(new InstancesHeader(ds)); dataset.setClassIndex(H); diff --git a/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java b/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java index fa80d5230..f2143f080 100644 --- a/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java +++ b/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java @@ -25,7 +25,7 @@ import moa.streams.InstanceStream; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SparseInstance; import moa.core.FastVector; @@ -74,7 +74,7 @@ public InstanceExample nextInstance() { } attributes.addElement(inst.classAttribute()); numericAttributes.add(inst.classIndex()); - this.streamHeader = new InstancesHeader(new Instances( + this.streamHeader = new InstancesHeader(new InstancesHeader( getCLICreationString(InstanceStream.class), attributes, 0)); this.streamHeader.setClassIndex(this.streamHeader.numAttributes() - 1); diff --git a/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java b/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java index 29aa407bc..fefe7f955 100644 --- a/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java +++ b/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java @@ -23,6 +23,7 @@ import com.github.javacliparser.MultiChoiceOption; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; + import java.util.Collections; import java.util.Comparator; import java.util.HashMap; diff --git a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java index 808f3641f..b5905e34a 100644 --- a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java +++ b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import moa.core.Example; import moa.core.InstanceExample; import moa.streams.MultiTargetInstanceStream; @@ -10,11 +11,12 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Range; public class SelectAttributesFilter extends AbstractMultiLabelStreamFilter implements MultiLabelStreamFilter{ + /** * */ @@ -48,15 +50,18 @@ private void initialize(Instance instance) { inputsSelected=getSelection(inputStringOption.getValue()); outputsSelected=getSelection(outputStringOption.getValue()); int totAttributes=inputsSelected.numValues()+outputsSelected.numValues(); - Instances ds= new Instances(); + InstancesHeader ds= new InstancesHeader(); List v = new ArrayList(totAttributes); List indexValues = new ArrayList(totAttributes); int ct=0; + List inputIndexes = new ArrayList(); + List outputIndexes = new ArrayList(); for (int i=0; i> evaluator, Classifier scheme) { + protected InspectionData[] inspect(InstancesHeader data, int[] inspectionPoints, LearningPerformanceEvaluator> evaluator, Classifier scheme) { InspectionData[] result; int i; int point; @@ -178,6 +177,7 @@ protected InspectionData[] inspect(Instances data, int[] inspectionPoints, Learn result = new InspectionData[inspectionPoints.length]; scheme.prepareForUse(); + scheme.setModelContext(data); point = 0; for (i = 0; i < data.numInstances(); i++) { @@ -296,7 +296,7 @@ protected String createOutputFilename(String input, int no) { * Compares the processed data against previously saved output data. */ public void testRegression() { - Instances data; + InstancesHeader data; InspectionData[] processed; boolean ok; String regression; diff --git a/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java b/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java index 4d6879edf..02ee87bf6 100644 --- a/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java +++ b/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java @@ -1,6 +1,8 @@ package moa.streams.filters; import static org.junit.Assert.assertEquals; + +import moa.streams.ArffFileStream; import moa.streams.MultiTargetArffFileStream; import org.junit.BeforeClass; @@ -14,7 +16,7 @@ public class SelectAttributesFilterTest { @BeforeClass public static void setUpBeforeClass() throws Exception { - MultiTargetArffFileStream stream=new MultiTargetArffFileStream(ClassLoader.getSystemResource("moa/classifiers/data/small_regression.arff").getPath(), "4-6"); + ArffFileStream stream=new ArffFileStream(ClassLoader.getSystemResource("moa/classifiers/data/small_regression.arff").getPath(), "4-6"); filter= new SelectAttributesFilter(); filter.setInputStream(stream); filter.inputStringOption.setValue("2-5,8"); From 3dfb80bd13be625e8137b941b00cff9dfce8cb88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Thu, 24 Mar 2016 13:45:02 +0100 Subject: [PATCH 13/33] AttributeInformation streamlining and other fixes --- .../com/github/javacliparser/RangeOption.java | 57 - .../labs/samoa/instances/ArffLoader.java | 17 - .../yahoo/labs/samoa/instances/Attribute.java | 5 + .../instances/AttributesInformation.java | 83 +- .../labs/samoa/instances/DenseInstance.java | 5 + .../samoa/instances/DenseInstanceData.java | 5 + .../yahoo/labs/samoa/instances/Instance.java | 2 - .../labs/samoa/instances/InstanceImpl.java | 7 +- .../samoa/instances/InstanceInformation.java | 65 +- .../labs/samoa/instances/InstancesHeader.java | 1165 ++++++++--------- .../samoa/instances/MultiLabelPrediction.java | 5 + .../com/yahoo/labs/samoa/instances/Range.java | 110 -- .../LocalMultiTargetClassifier.java | 11 +- .../main/java/moa/streams/ArffFileStream.java | 2 +- .../streams/MultiTargetArffFileStream.java | 1 - .../moa/streams/clustering/FileStream.java | 14 +- .../java/moa/streams/filters/RBFFilter.java | 7 +- .../java/moa/streams/filters/ReLUFilter.java | 7 +- .../filters/SelectAttributesFilter.java | 9 +- .../AbstractClassifierTestCase.java | 4 - 20 files changed, 668 insertions(+), 913 deletions(-) delete mode 100644 moa/src/main/java/com/github/javacliparser/RangeOption.java delete mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java diff --git a/moa/src/main/java/com/github/javacliparser/RangeOption.java b/moa/src/main/java/com/github/javacliparser/RangeOption.java deleted file mode 100644 index 56f4da850..000000000 --- a/moa/src/main/java/com/github/javacliparser/RangeOption.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2007 University of Waikato. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ - -package com.github.javacliparser; - -import java.util.Arrays; -import com.yahoo.labs.samoa.instances.Range; - -/** - * Range option. - * - * @author Jesse Read (jesse@tsc.uc3m.es) - * @version $Revision: 7 $ - */ -public class RangeOption extends StringOption { - - private static final long serialVersionUID = 1L; - - public RangeOption(String name, char cliChar, String purpose, String defaultValue) { - super(name, cliChar, purpose, defaultValue); - } - - /* - * This class will be like StringOption, but expect a string of numbers like Weka's Range - * e.g., 1,2,5-9,end will return something like [0,1,4,5,6,7,8,-1] which we will use later indicate e.g. multiple class attributes - */ - - public void setRange(int indices[]) { - this.currentVal = Arrays.toString(indices); // "[1,2,3]" - this.currentVal = this.currentVal.substring(1,this.currentVal.length()-1); // "1,2,3" - } - - public Range getRange() { - return new Range(this.getValue()); - } - - /*public int[] getRange() { - Range r = new Range(this.getValue()); - return r.getSelection(); - }*/ - -} - diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java index c427141d8..fa92fc81e 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java @@ -20,7 +20,6 @@ import java.io.Reader; import java.io.StreamTokenizer; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -285,35 +284,25 @@ private void setSparseValue(Instance instance, List indexValues, List attributeLabels = new ArrayList(); @@ -363,10 +348,8 @@ private InstanceInformation getHeader(String outputDefinition, String inputDefin if (streamTokenizer.sval != null) { attributeLabels.add(streamTokenizer.sval); - // System.out.print(streamTokenizer.sval + ","); } else { attributeLabels.add(Double.toString(streamTokenizer.nval)); - //System.out.print(streamTokenizer.nval + ","); } streamTokenizer.nextToken(); diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java index 54e6c21dc..9ba21d898 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java @@ -25,6 +25,11 @@ */ public class Attribute implements Serializable { + /** + * + */ + private static final long serialVersionUID = -3739913325563469730L; + /** The keyword used to denote the start of an arff attribute declaration */ public final static String ARFF_ATTRIBUTE = "@attribute"; diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributesInformation.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributesInformation.java index 8fcbb1330..dae542dd4 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributesInformation.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributesInformation.java @@ -16,7 +16,6 @@ package com.yahoo.labs.samoa.instances; import java.io.Serializable; -import java.util.ArrayList; import java.util.List; /** @@ -27,16 +26,15 @@ * @version $Revision: 7 $ */ public class AttributesInformation implements Serializable { + /** + * + */ + private static final long serialVersionUID = 1666190771085863695L; - /** + /** * The attribute information. */ protected List attributes; - protected List indexValues; - /** - * The number of attributes. - */ - protected int numberAttributes; /** * The attribute used for default for numerical values @@ -45,29 +43,14 @@ public class AttributesInformation implements Serializable { public AttributesInformation(AttributesInformation chunk) { this.attributes = chunk.attributes; - this.indexValues = chunk.indexValues; - this.numberAttributes = chunk.numberAttributes; } - public AttributesInformation(List v, List i, int numberAttributes) { + public AttributesInformation(List v) { this.attributes = v; - this.indexValues = i; - this.numberAttributes = numberAttributes; - } - - public AttributesInformation(List v, int numberAttributes) { - this.attributes = v; - this.indexValues = new ArrayList(numberAttributes); - for (int i = 0; i < numberAttributes; i++) { - this.indexValues.add(i); - } - this.numberAttributes = numberAttributes; } public AttributesInformation() { this.attributes = null; - this.indexValues = null; - this.numberAttributes = 0; this.defaultNumericAttribute = null; } @@ -82,17 +65,11 @@ public Attribute attribute(int indexAttribute) { //All attributes are numeric return defaultNumericAttribute(); } - int location = locateIndex(indexAttribute); - if (location == -1) { - //if there is not attribute information, it is numeric - return defaultNumericAttribute(); - } - return attributes.get(location); + return attributes.get(indexAttribute); } - public void add(Attribute attribute, int value) { + public void add(Attribute attribute) { this.attributes.add(attribute); - this.indexValues.add(value); } /** @@ -102,40 +79,6 @@ public void add(Attribute attribute, int value) { */ public void setAttributes(List v) { this.attributes = v; - this.numberAttributes=v.size(); - } - - /** - * Locates the greatest index that is not greater than the given index. - * - * @return the internal index of the attribute index. Returns -1 if no index - * with this property could be found - */ - public int locateIndex(int index) { - - int min = 0; - int max = this.indexValues.size() - 1; - - if (max == -1) { - return -1; - } - - // Binary search - while ((this.indexValues.get(min) <= index) && (this.indexValues.get(max) >= index)) { - int current = (max + min) / 2; - if (this.indexValues.get(current) > index) { - max = current - 1; - } else if (this.indexValues.get(current) < index) { - min = current + 1; - } else { - return current; - } - } - if (this.indexValues.get(max) < index) { - return max; - } else { - return min - 1; - } } private Attribute defaultNumericAttribute() { @@ -145,10 +88,8 @@ private Attribute defaultNumericAttribute() { return this.defaultNumericAttribute; } - public void setAttributes(List v, List indexValues) { - this.attributes = v; - this.numberAttributes=v.size(); - this.indexValues=indexValues; - } - + public int numAttributes() { + return attributes.size(); + } + } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstance.java index bae288728..f8bc4b60d 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstance.java @@ -21,6 +21,11 @@ public class DenseInstance extends InstanceImpl { /** + * + */ + private static final long serialVersionUID = 2470663722464623836L; + + /** * Instantiates a new dense instance. * * @param weight the weight diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstanceData.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstanceData.java index c4ec564ff..200e450a3 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstanceData.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstanceData.java @@ -22,6 +22,11 @@ public class DenseInstanceData implements InstanceData{ /** + * + */ + private static final long serialVersionUID = 8799186995568094103L; + + /** * Instantiates a new dense instance data. * * @param array the array diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java index 6978bb385..15bd6bb98 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java @@ -17,8 +17,6 @@ import java.io.Serializable; -import moa.AbstractMOAObject; - /** * The Interface Instance. * diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java index 7484abec2..9305556e3 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java @@ -15,8 +15,6 @@ */ package com.yahoo.labs.samoa.instances; -import moa.AbstractMOAObject; - /** * The Class InstanceImpl. * @@ -25,6 +23,11 @@ public class InstanceImpl implements StructuredInstance { /** + * + */ + private static final long serialVersionUID = -7908832747696137766L; + + /** * The weight. */ protected double weight; diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java index d9d769f77..ebb0d8940 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java @@ -19,8 +19,6 @@ import java.util.ArrayList; import java.util.List; -import moa.AbstractMOAObject; - /** * The Class InstanceInformation. * @@ -28,7 +26,9 @@ */ public class InstanceInformation implements Serializable { - /** + private static final long serialVersionUID = 4240189973932498979L; + + /** * The dataset's name. */ protected String relationName; @@ -39,15 +39,25 @@ public class InstanceInformation implements Serializable { protected List inputIndexes; + /** + * Returns the input attribute. + * + * @param w the input attribute index (indexes only input attributes) + * @return the input attribute. + */ public Attribute inputAttribute(int w) { return this.attributesInformation.attribute(inputAttributeIndex(w)); } + /** + * Returns the output attribute. + * + * @param w the output attribute index (indexes only output attributes) + * @return the output attribute. + */ public Attribute outputAttribute(int w) { return this.attributesInformation.attribute(outputAttributeIndex(w)); } - - /** * Instantiates a new instance information. @@ -71,27 +81,16 @@ public InstanceInformation(String st, List attributes, List this.relationName = st; this.outputIndexes = outputIndexes; this.inputIndexes = inputIndexes; - this.attributesInformation = new AttributesInformation(attributes, attributes.size()); + this.attributesInformation = new AttributesInformation(attributes); } - public InstanceInformation(String st, List input, List indexes) { - this.relationName = st; - this.outputIndexes = new ArrayList(); - this.inputIndexes = new ArrayList(); - this.attributesInformation = new AttributesInformation(input, indexes, indexes.size()); - } - public InstanceInformation(String st, List input) { this.relationName = st; this.outputIndexes = new ArrayList(); this.inputIndexes = new ArrayList(); - List indexes = new ArrayList(); - for (int i = 0; i < input.size(); i++) { - indexes.add(i); - } - this.attributesInformation = new AttributesInformation(input, indexes, indexes.size()); + this.attributesInformation = new AttributesInformation(input); } - + /** * Instantiates a new instance information. */ @@ -143,7 +142,7 @@ public Attribute classAttribute() { * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#numAttributes() */ public int numAttributes() { - return this.attributesInformation.numberAttributes; + return this.attributesInformation.numAttributes(); } /* (non-Javadoc) @@ -175,7 +174,7 @@ public void insertAttributeAt(Attribute attribute, int i) { } public void setAttributes(List v) { - if(this.attributesInformation==null) + if(this.attributesInformation == null) this.attributesInformation= new AttributesInformation(); this.attributesInformation.setAttributes(v); } @@ -198,17 +197,21 @@ public int numOutputAttributes() { return outputIndexes.size(); } - - public void setAttributes(List v, List indexValues) { - if(this.attributesInformation==null) - this.attributesInformation= new AttributesInformation(); - this.attributesInformation.setAttributes(v,indexValues); - } - + + /** + * Sets the output attribute indexes, i.e., the targets. + * + * @param outputIndexes + */ public void setOutputIndexes(List outputIndexes) { this.outputIndexes = outputIndexes; } + /** + * Sets the input attribute indexes. + * + * @param inputIndexes + */ public void setInputIndexes(List inputIndexes) { this.inputIndexes = inputIndexes; } @@ -218,9 +221,9 @@ public void setInputIndexes(List inputIndexes) { */ public void setInputIndexes() { this.inputIndexes = new ArrayList(); - for (int i = 0; i < attributesInformation.indexValues.size(); i++) { - if (!outputIndexes.contains(attributesInformation.indexValues.get(i))) { - inputIndexes.add(attributesInformation.indexValues.get(i)); + for (int i = 0; i < attributesInformation.numAttributes(); i++) { + if (!outputIndexes.contains(i)) { + inputIndexes.add(i); } } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java index 421cbb74e..30401fdf5 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java @@ -22,8 +22,6 @@ import java.util.List; import java.util.Random; -import org.junit.experimental.theories.Theories; - import moa.core.Utils; /** @@ -33,624 +31,625 @@ */ public class InstancesHeader implements Serializable { - /** The keyword used to denote the start of an arff header */ - public final static String ARFF_RELATION = "@relation"; - - /** The keyword used to denote the start of the arff data section */ - public final static String ARFF_DATA = "@data"; - - private static final long serialVersionUID = 1L; - - /** - * The instance information. - */ - protected InstanceInformation instanceInformation; - /** - * The instances. - */ - protected List instances; - - /** - * The arff. - */ - protected ArffLoader arff; - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - */ - public InstancesHeader(InstancesHeader chunk) { - this(chunk, chunk.numInstances()); - chunk.copyInstances(0, this, chunk.numInstances()); - } - - /** - * Instantiates a new instances. - */ - public InstancesHeader() { - } - - /** - * Instantiates a new instances. - * - * @param reader the reader - * @param size the size - * @param classAttribute the class attribute - */ - public InstancesHeader(Reader reader, int size, int classAttribute) { - arff = new ArffLoader(reader, String.valueOf(classAttribute)); - this.instanceInformation = arff.instanceInformation; - this.instances = new ArrayList(); - } - - public InstancesHeader(Reader reader, String outputDefinition) { - this.arff = new ArffLoader(reader, outputDefinition); - this.instanceInformation = arff.instanceInformation; - this.instances = new ArrayList(); - } - - public InstancesHeader(Reader reader, String outputDefinition, String inputDefinition) { - this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); - this.instanceInformation = arff.instanceInformation; - this.instances = new ArrayList(); - } - - public InstancesHeader(Reader reader, int size, String outputDefinition, String inputDefinition) { - this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); - this.instanceInformation = arff.instanceInformation; - this.instances = new ArrayList(); - } - - /** - * Instantiates a new instances. - * - * @param reader the reader - * @param range - */ -// public Instances(Reader reader, Range range) { -// this.arff = new MultiTargetArffLoader(reader, range); -// this.instanceInformation = arff.getStructure(); -// this.instances = new ArrayList(); -// } - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - * @param capacity the capacity - */ - public InstancesHeader(InstancesHeader chunk, int capacity) { - this.instanceInformation = chunk.instanceInformation(); - if (capacity < 0) { - capacity = 0; - } - this.instances = new ArrayList(capacity); - } - - /** - * Instantiates a new instances. - * - * @param st the st - * @param v the v - * @param capacity the capacity - */ - public InstancesHeader(String st, List v, int capacity) { - this.instanceInformation = new InstanceInformation(st, v); - } - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - * @param first the first instance - * @param toCopy the j - */ - public InstancesHeader(InstancesHeader chunk, int first, int toCopy) { - - this(chunk, toCopy); - - if ((first < 0) || ((first + toCopy) > chunk.numInstances())) { - throw new IllegalArgumentException("Parameters first and/or toCopy out " - + "of range"); - } - chunk.copyInstances(first, this, toCopy); - } - - /** - * Instantiates a new instances. - * - * @param st the st - * @param capacity the capacity - */ - public InstancesHeader(StringReader st, int capacity) { - this.instances = new ArrayList(capacity); - } - - //Information Instances - /** - * Sets the relation name. - * - * @param string the new relation name - */ - public void setRelationName(String string) { - this.instanceInformation.setRelationName(string); - } - - /** - * Gets the relation name. - * - * @return the relation name - */ - public String getRelationName() { - return this.instanceInformation.getRelationName(); - } - - /** - * Class index. - * - * @return the int - */ - public int classIndex() { - return this.instanceInformation.classIndex(); - } - - /** - * Sets the class index. Also sets all other attributes as input attributes for backward compatibility. - * - * @param classIndex the new class index - */ - public void setClassIndex(int classIndex) { - this.instanceInformation.setClassIndex(classIndex); - this.instanceInformation.setInputIndexes(); - } - - public void setOutputIndexes(List outputIndexes) { - this.instanceInformation.setOutputIndexes(outputIndexes); - } - - public void setInputIndexes(List inputIndexes) { - this.instanceInformation.setInputIndexes(inputIndexes); - } + /** The keyword used to denote the start of an arff header */ + public final static String ARFF_RELATION = "@relation"; + + /** The keyword used to denote the start of the arff data section */ + public final static String ARFF_DATA = "@data"; + + private static final long serialVersionUID = 1L; + + /** + * The instance information. + */ + protected InstanceInformation instanceInformation; + /** + * The instances. + */ + protected List instances; + + /** + * The arff. + */ + protected ArffLoader arff; + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + */ + public InstancesHeader(InstancesHeader chunk) { + this(chunk, chunk.numInstances()); + chunk.copyInstances(0, this, chunk.numInstances()); + } + + /** + * Instantiates a new instances. + */ + public InstancesHeader() { + } + + /** + * Instantiates a new instances. + * + * @param reader the reader + * @param size the size + * @param classAttribute the class attribute + */ + public InstancesHeader(Reader reader, int size, int classAttribute) { + arff = new ArffLoader(reader, String.valueOf(classAttribute)); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + /** + * Instantiates a new intances header. + * + * @param reader + * @param outputDefinition defines the output attributes (others are treated as inputs) + */ + public InstancesHeader(Reader reader, String outputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + /** + * Instantiates a new intances header. + * + * @param reader + * @param outputDefinition defines the output attributes + * @param inputDefinition defines the input attributes + */ + public InstancesHeader(Reader reader, String outputDefinition, String inputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + /** + * Instantiates a new instances. + * + * @param reader the reader + * @param range + */ + // public Instances(Reader reader, Range range) { + // this.arff = new MultiTargetArffLoader(reader, range); + // this.instanceInformation = arff.getStructure(); + // this.instances = new ArrayList(); + // } + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + * @param capacity the capacity + */ + public InstancesHeader(InstancesHeader chunk, int capacity) { + this.instanceInformation = chunk.instanceInformation(); + if (capacity < 0) { + capacity = 0; + } + this.instances = new ArrayList(capacity); + } + + /** + * Instantiates a new instances. + * + * @param st the st + * @param v the v + * @param capacity the capacity + */ + public InstancesHeader(String st, List v, int capacity) { + this.instanceInformation = new InstanceInformation(st, v); + } + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + * @param first the first instance + * @param toCopy the j + */ + public InstancesHeader(InstancesHeader chunk, int first, int toCopy) { + + this(chunk, toCopy); + + if ((first < 0) || ((first + toCopy) > chunk.numInstances())) { + throw new IllegalArgumentException("Parameters first and/or toCopy out " + + "of range"); + } + chunk.copyInstances(first, this, toCopy); + } + + /** + * Instantiates a new instances. + * + * @param st the st + * @param capacity the capacity + */ + public InstancesHeader(StringReader st, int capacity) { + this.instances = new ArrayList(capacity); + } + + //Information Instances + /** + * Sets the relation name. + * + * @param string the new relation name + */ + public void setRelationName(String string) { + this.instanceInformation.setRelationName(string); + } + + /** + * Gets the relation name. + * + * @return the relation name + */ + public String getRelationName() { + return this.instanceInformation.getRelationName(); + } + + /** + * Class index. + * + * @return the int + */ + public int classIndex() { + return this.instanceInformation.classIndex(); + } + + /** + * Sets the class index. Also sets all other attributes as input attributes for backward compatibility. + * + * @param classIndex the new class index + */ + public void setClassIndex(int classIndex) { + this.instanceInformation.setClassIndex(classIndex); + this.instanceInformation.setInputIndexes(); + } + + public void setOutputIndexes(List outputIndexes) { + this.instanceInformation.setOutputIndexes(outputIndexes); + } + + public void setInputIndexes(List inputIndexes) { + this.instanceInformation.setInputIndexes(inputIndexes); + } /** * Sets all non-output attributes as input attributes. */ public void setInputIndexes() { - this.instanceInformation.setInputIndexes(); - } - - /** - * Class attribute. - * - * @return the attribute - */ - public Attribute classAttribute() { - return this.instanceInformation.classAttribute(); - } - - /** - * Num attributes. - * - * @return the int - */ - public int numAttributes() { - return this.instanceInformation.numAttributes(); - } - - /** - * Attribute. - * - * @param w the w - * @return the attribute - */ - public Attribute attribute(int w) { - return this.instanceInformation.attribute(w); - } - - /** - * Num classes. - * - * @return the int - */ - public int numClasses() { - return this.instanceInformation.numClasses(); - } - - /** - * Delete attribute at. - * - * @param integer the integer - */ - public void deleteAttributeAt(Integer integer) { - this.instanceInformation.deleteAttributeAt(integer); - } - - /** - * Insert attribute at. - * - * @param attribute the attribute - * @param i the i - */ - public void insertAttributeAt(Attribute attribute, int i) { - if (this.instanceInformation==null) - this.instanceInformation= new InstanceInformation(); - this.instanceInformation.insertAttributeAt(attribute, i); - } - - //List of Instances - /** - * Instance. - * - * @param num the num - * @return the instance - */ - public Instance instance(int num) { - return this.instances.get(num); - } - - /** - * Num instances. - * - * @return the int - */ - public int numInstances() { - return this.instances.size(); - } - - /** - * Adds the. - * - * @param inst the inst - */ - public void add(Instance inst) { - this.instances.add(inst.copy()); - } - - /** - * Randomize. - * - * @param random the random - */ - public void randomize(Random random) { - for (int j = numInstances() - 1; j > 0; j--) { - swap(j, random.nextInt(j + 1)); - } - } - - /** - * Stratify. - * - * @param numFolds the num folds - */ - public void stratify(int numFolds) { - - if (classAttribute().isNominal()) { - - // sort by class - int index = 1; - while (index < numInstances()) { - Instance instance1 = instance(index - 1); - for (int j = index; j < numInstances(); j++) { - Instance instance2 = instance(j); - if ((instance1.classValue() == instance2.classValue()) - || (instance1.classIsMissing() - && instance2.classIsMissing())) { - swap(index, j); - index++; - } - } - index++; - } - stratStep(numFolds); - } - } - - protected void stratStep(int numFolds) { - ArrayList newVec = new ArrayList(this.instances.size()); - int start = 0, j; - - // create stratified batch - while (newVec.size() < numInstances()) { - j = start; - while (j < numInstances()) { - newVec.add(instance(j)); - j = j + numFolds; - } - start++; - } - this.instances = newVec; - } - - /** - * Train cv. - * - * @param numFolds the num folds - * @param numFold - * @param n the n - * @param random the random - * @return the instances - */ - public InstancesHeader trainCV(int numFolds, int numFold, Random random) { - InstancesHeader train = trainCV(numFolds, numFold); - train.randomize(random); - return train; - } - - public InstancesHeader trainCV(int numFolds, int numFold) { - int numInstForFold, first, offset; - InstancesHeader train; - - numInstForFold = numInstances() / numFolds; - if (numFold < numInstances() % numFolds) { - numInstForFold++; - offset = numFold; - } else { - offset = numInstances() % numFolds; - } - train = new InstancesHeader(this, numInstances() - numInstForFold); - first = numFold * (numInstances() / numFolds) + offset; - copyInstances(0, train, first); - copyInstances(first + numInstForFold, train, - numInstances() - first - numInstForFold); - return train; - } - - protected void copyInstances(int from, InstancesHeader dest, int num) { - for (int i = 0; i < num; i++) { - dest.add(instance(from + i)); - } - } - - /** - * Test cv. - * - * @param numFolds the num folds - * @param numFold the num fold - * @return the instances - */ - public InstancesHeader testCV(int numFolds, int numFold) { - - int numInstForFold, first, offset; - InstancesHeader test; - - numInstForFold = numInstances() / numFolds; - if (numFold < numInstances() % numFolds) { - numInstForFold++; - offset = numFold; - } else { - offset = numInstances() % numFolds; - } - test = new InstancesHeader(this, numInstForFold); - first = numFold * (numInstances() / numFolds) + offset; - copyInstances(first, test, numInstForFold); - return test; - } - - /* public Instances dataset() { + this.instanceInformation.setInputIndexes(); + } + + /** + * Class attribute. + * + * @return the attribute + */ + public Attribute classAttribute() { + return this.instanceInformation.classAttribute(); + } + + /** + * Num attributes. + * + * @return the int + */ + public int numAttributes() { + return this.instanceInformation.numAttributes(); + } + + /** + * Attribute. + * + * @param w the w + * @return the attribute + */ + public Attribute attribute(int w) { + return this.instanceInformation.attribute(w); + } + + /** + * Num classes. + * + * @return the int + */ + public int numClasses() { + return this.instanceInformation.numClasses(); + } + + /** + * Delete attribute at. + * + * @param integer the integer + */ + public void deleteAttributeAt(Integer integer) { + this.instanceInformation.deleteAttributeAt(integer); + } + + /** + * Insert attribute at. + * + * @param attribute the attribute + * @param i the i + */ + public void insertAttributeAt(Attribute attribute, int i) { + if (this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.insertAttributeAt(attribute, i); + } + + //List of Instances + /** + * Instance. + * + * @param num the num + * @return the instance + */ + public Instance instance(int num) { + return this.instances.get(num); + } + + /** + * Num instances. + * + * @return the int + */ + public int numInstances() { + return this.instances.size(); + } + + /** + * Adds the. + * + * @param inst the inst + */ + public void add(Instance inst) { + this.instances.add(inst.copy()); + } + + /** + * Randomize. + * + * @param random the random + */ + public void randomize(Random random) { + for (int j = numInstances() - 1; j > 0; j--) { + swap(j, random.nextInt(j + 1)); + } + } + + /** + * Stratify. + * + * @param numFolds the num folds + */ + public void stratify(int numFolds) { + + if (classAttribute().isNominal()) { + + // sort by class + int index = 1; + while (index < numInstances()) { + Instance instance1 = instance(index - 1); + for (int j = index; j < numInstances(); j++) { + Instance instance2 = instance(j); + if ((instance1.classValue() == instance2.classValue()) + || (instance1.classIsMissing() + && instance2.classIsMissing())) { + swap(index, j); + index++; + } + } + index++; + } + stratStep(numFolds); + } + } + + protected void stratStep(int numFolds) { + ArrayList newVec = new ArrayList(this.instances.size()); + int start = 0, j; + + // create stratified batch + while (newVec.size() < numInstances()) { + j = start; + while (j < numInstances()) { + newVec.add(instance(j)); + j = j + numFolds; + } + start++; + } + this.instances = newVec; + } + + /** + * Train cv. + * + * @param numFolds the num folds + * @param numFold + * @param n the n + * @param random the random + * @return the instances + */ + public InstancesHeader trainCV(int numFolds, int numFold, Random random) { + InstancesHeader train = trainCV(numFolds, numFold); + train.randomize(random); + return train; + } + + public InstancesHeader trainCV(int numFolds, int numFold) { + int numInstForFold, first, offset; + InstancesHeader train; + + numInstForFold = numInstances() / numFolds; + if (numFold < numInstances() % numFolds) { + numInstForFold++; + offset = numFold; + } else { + offset = numInstances() % numFolds; + } + train = new InstancesHeader(this, numInstances() - numInstForFold); + first = numFold * (numInstances() / numFolds) + offset; + copyInstances(0, train, first); + copyInstances(first + numInstForFold, train, + numInstances() - first - numInstForFold); + return train; + } + + protected void copyInstances(int from, InstancesHeader dest, int num) { + for (int i = 0; i < num; i++) { + dest.add(instance(from + i)); + } + } + + /** + * Test cv. + * + * @param numFolds the num folds + * @param numFold the num fold + * @return the instances + */ + public InstancesHeader testCV(int numFolds, int numFold) { + + int numInstForFold, first, offset; + InstancesHeader test; + + numInstForFold = numInstances() / numFolds; + if (numFold < numInstances() % numFolds) { + numInstForFold++; + offset = numFold; + } else { + offset = numInstances() % numFolds; + } + test = new InstancesHeader(this, numInstForFold); + first = numFold * (numInstances() / numFolds) + offset; + copyInstances(first, test, numInstForFold); + return test; + } + + /* public Instances dataset() { throw new UnsupportedOperationException("Not yet implemented"); }*/ - /** - * Mean or mode. - * - * @param j the j - * @return the double - */ - public double meanOrMode(int j) { - throw new UnsupportedOperationException("Not yet implemented"); //CobWeb - } - - /** - * Read instance. - * - * @param fileReader the file reader - * @return true, if successful - */ - public boolean readInstance(Reader fileReader) { - - //ArffReader arff = new ArffReader(reader, this, m_Lines, 1); - Instance inst = arff.readInstance(); - if (inst != null) { - inst.setDataset(this); - add(inst); - return true; - } else { - return false; - } - } - - /** - * Delete. - */ - public void delete() { - this.instances = new ArrayList(); - } - - /** - * Delete. - */ - public void delete(int index) { - this.instances.remove(index); - } - - - /** - * Swap. - * - * @param i the i - * @param j the j - */ - public void swap(int i, int j) { - Instance in = instances.get(i); - instances.set(i, instances.get(j)); - instances.set(j, in); - } - - /** - * Instance information. - * - * @return the instance information - */ - private InstanceInformation instanceInformation() { - return this.instanceInformation; - } - - public Attribute attribute(String name) { - - for (int i = 0; i < numAttributes(); i++) { - if (attribute(i).name().equals(name)) { - return attribute(i); - } - } - return null; - } - - public int size() { - return this.numInstances(); - } - - public void set(int i, Instance inst) { - this.instances.set(i, inst); - } - - public Instance get(int k) { - return this.instance(k); - } - -// public void setRangeOutputIndices(Range range) { -// this.instanceInformation.setRangeOutputIndices(range); -// -// } - - public void setAttributes(List v) { - if(this.instanceInformation==null) - this.instanceInformation= new InstanceInformation(); - this.instanceInformation.setAttributes(v); - } - - public void setAttributes(List v, List indexValues) { - if(this.instanceInformation==null) - this.instanceInformation= new InstanceInformation(); - this.instanceInformation.setAttributes(v, indexValues); - } - - /** - * Returns the dataset as a string in ARFF format. Strings - * are quoted if they contain whitespace characters, or if they - * are a question mark. - * - * @return the dataset in ARFF format as a string - */ - public String toString() { - - StringBuffer text = new StringBuffer(); - - text.append(ARFF_RELATION).append(" "). - append(Utils.quote( this.instanceInformation.getRelationName())).append("\n\n"); - for (int i = 0; i < numAttributes(); i++) { - text.append(attribute(i).toString()).append("\n"); - } - text.append("\n").append(ARFF_DATA).append("\n"); - - text.append(stringWithoutHeader()); - return text.toString(); - } - - /** - * Returns the instances in the dataset as a string in ARFF format. Strings - * are quoted if they contain whitespace characters, or if they - * are a question mark. - * - * @return the dataset in ARFF format as a string - */ - protected String stringWithoutHeader() { - - StringBuffer text = new StringBuffer(); - - for (int i = 0; i < numInstances(); i++) { - text.append(instance(i)); - if (i < numInstances() - 1) { - text.append('\n'); - } - } - return text.toString(); - - } + /** + * Mean or mode. + * + * @param j the j + * @return the double + */ + public double meanOrMode(int j) { + throw new UnsupportedOperationException("Not yet implemented"); //CobWeb + } + + /** + * Read instance. + * + * @param fileReader the file reader + * @return true, if successful + */ + public boolean readInstance(Reader fileReader) { + + //ArffReader arff = new ArffReader(reader, this, m_Lines, 1); + Instance inst = arff.readInstance(); + if (inst != null) { + inst.setDataset(this); + add(inst); + return true; + } else { + return false; + } + } + + /** + * Delete. + */ + public void delete() { + this.instances = new ArrayList(); + } + + /** + * Delete. + */ + public void delete(int index) { + this.instances.remove(index); + } + + + /** + * Swap. + * + * @param i the i + * @param j the j + */ + public void swap(int i, int j) { + Instance in = instances.get(i); + instances.set(i, instances.get(j)); + instances.set(j, in); + } + + /** + * Instance information. + * + * @return the instance information + */ + private InstanceInformation instanceInformation() { + return this.instanceInformation; + } + + public Attribute attribute(String name) { + + for (int i = 0; i < numAttributes(); i++) { + if (attribute(i).name().equals(name)) { + return attribute(i); + } + } + return null; + } + + public int size() { + return this.numInstances(); + } + + public void set(int i, Instance inst) { + this.instances.set(i, inst); + } + + public Instance get(int k) { + return this.instance(k); + } + + // public void setRangeOutputIndices(Range range) { + // this.instanceInformation.setRangeOutputIndices(range); + // + // } + + public void setAttributes(List v) { + if(this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.setAttributes(v); + } + + /** + * Returns the dataset as a string in ARFF format. Strings + * are quoted if they contain whitespace characters, or if they + * are a question mark. + * + * @return the dataset in ARFF format as a string + */ + public String toString() { + + StringBuffer text = new StringBuffer(); + + text.append(ARFF_RELATION).append(" "). + append(Utils.quote( this.instanceInformation.getRelationName())).append("\n\n"); + for (int i = 0; i < numAttributes(); i++) { + text.append(attribute(i).toString()).append("\n"); + } + text.append("\n").append(ARFF_DATA).append("\n"); + + text.append(stringWithoutHeader()); + return text.toString(); + } + + /** + * Returns the instances in the dataset as a string in ARFF format. Strings + * are quoted if they contain whitespace characters, or if they + * are a question mark. + * + * @return the dataset in ARFF format as a string + */ + protected String stringWithoutHeader() { + + StringBuffer text = new StringBuffer(); + + for (int i = 0; i < numInstances(); i++) { + text.append(instance(i)); + if (i < numInstances() - 1) { + text.append('\n'); + } + } + return text.toString(); + + } public Attribute inputAttribute(int w) { - return this.instanceInformation.inputAttribute(w); + return this.instanceInformation.inputAttribute(w); } public Attribute outputAttribute(int w) { - return this.instanceInformation.outputAttribute(w); + return this.instanceInformation.outputAttribute(w); } public int numInputAttributes() { - return this.instanceInformation.numInputAttributes(); + return this.instanceInformation.numInputAttributes(); } public int numOutputAttributes() { - return this.instanceInformation.numOutputAttributes(); + return this.instanceInformation.numOutputAttributes(); } public InstanceInformation getInstanceInformation() { - return this.instanceInformation; + return this.instanceInformation; } public static String getClassNameString(InstancesHeader context) { - if (context == null) { - return "[class]"; - } - return "[class:" + context.classAttribute().name() + "]"; + if (context == null) { + return "[class]"; + } + return "[class:" + context.classAttribute().name() + "]"; } public static String getClassLabelString(InstancesHeader context, int classLabelIndex) { - if ((context == null) || (classLabelIndex >= context.numClasses())) { - return ""; - } - return ""; + if ((context == null) || (classLabelIndex >= context.numClasses())) { + return ""; + } + return ""; } public static String getAttributeNameString(InstancesHeader context, int attIndex) { - if ((context == null) || (attIndex >= context.numAttributes())) { - return "[att " + (attIndex + 1) + "]"; - } - return "[att " + (attIndex + 1) + ":" - + context.attribute(attIndex).name() + "]"; + if ((context == null) || (attIndex >= context.numAttributes())) { + return "[att " + (attIndex + 1) + "]"; + } + return "[att " + (attIndex + 1) + ":" + + context.attribute(attIndex).name() + "]"; } public static String getInputAttributeNameString(InstancesHeader context, int attIndex) { - if ((context == null) || (attIndex >= context.numInputAttributes())) { - return "[att " + (attIndex + 1) + "]"; - } - return "[att " + (attIndex + 1) + ":" - + context.inputAttribute(attIndex).name() + "]"; + if ((context == null) || (attIndex >= context.numInputAttributes())) { + return "[att " + (attIndex + 1) + "]"; + } + return "[att " + (attIndex + 1) + ":" + + context.inputAttribute(attIndex).name() + "]"; } public static String getNominalValueString(InstancesHeader context, int attIndex, int valIndex) { - if (context != null) { - if ((attIndex < context.numInputAttributes()) - && (valIndex < context.inputAttribute(attIndex).numValues())) { - return "{val " + (valIndex + 1) + ":" - + context.inputAttribute(attIndex).value(valIndex) + "}"; - } - } - return "{val " + (valIndex + 1) + "}"; + if (context != null) { + if ((attIndex < context.numInputAttributes()) + && (valIndex < context.inputAttribute(attIndex).numValues())) { + return "{val " + (valIndex + 1) + ":" + + context.inputAttribute(attIndex).value(valIndex) + "}"; + } + } + return "{val " + (valIndex + 1) + "}"; } public static String getNumericValueString(InstancesHeader context, int attIndex, double value) { - if (context != null) { - int instAttIndex = attIndex < context.classIndex() ? attIndex - : attIndex + 1; - if (instAttIndex < context.numAttributes()) { - if (context.attribute(instAttIndex).isDate()) { - return context.attribute(instAttIndex).formatDate(value); - } - } - } - return Double.toString(value); - } - - + if (context != null) { + int instAttIndex = attIndex < context.classIndex() ? attIndex + : attIndex + 1; + if (instAttIndex < context.numAttributes()) { + if (context.attribute(instAttIndex).isDate()) { + return context.attribute(instAttIndex).formatDate(value); + } + } + } + return Double.toString(value); + } + + } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index 12b35c5a3..7e8fb2bdc 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -18,6 +18,11 @@ import java.io.Serializable; public class MultiLabelPrediction implements Prediction, Serializable { + /** + * + */ + private static final long serialVersionUID = 1413498152667626736L; + protected DoubleVector [] prediction; public MultiLabelPrediction() { diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java deleted file mode 100644 index d02e5fbbc..000000000 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java +++ /dev/null @@ -1,110 +0,0 @@ - -/* - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ -package com.yahoo.labs.samoa.instances; - -import java.io.Serializable; - -public class Range implements Serializable { - - //Only works for ranges "start-end" - private int start = 0; - private int end = 0; - private int upperLimit = 0; - private final String rangeText; - - public Range(String range) { - this.rangeText = range; - //this.setRange(range); //needs upperLimit - } - - /** - * Sets the range from a string representation. - * - * @param range the start and end string - * - */ - public void setRange(String range) { - String single = range.trim(); - int hyphenIndex = range.indexOf('-'); - - if (hyphenIndex > 0) { - this.start = rangeSingle(range.substring(0, hyphenIndex)); - this.end = rangeSingle(range.substring(hyphenIndex + 1)); - } else { - int number = rangeSingle(range); - if (number >= 0) { // first n attributes - this.start = 0; - this.end = number; - } else { // last n attributes - this.start = this.upperLimit + number > 0 ? this.upperLimit + number : 0; - this.end = this.upperLimit - 1; - } - } - } - - /** - * Translates a single string selection into it's internal 0-based - * equivalent. - * - * @param single the string representing the selection (eg: 1 first last) - * @return the number corresponding to the selected value - */ - protected /*@pure@*/ int rangeSingle(/*@non_null@*/String singleSelection) { - - String single = singleSelection.trim(); - if (single.toLowerCase().equals("first")) { - return 0; - } - if (single.toLowerCase().equals("last") || single.toLowerCase().equals("-1")) { - return -1; - } - int index = Integer.parseInt(single); - if (index >= 1) { //Non for negatives - index--; - } - return index; - } - - boolean isInRange(int value) { - boolean ret = false; - if (value >= start && value <= end) { - ret = true; - } - return ret; - } - - int getSelectionLength() { - return end - start + 1; - } - - public void setUpper(int attributeNumber) { - this.upperLimit = attributeNumber; - this.setRange(this.rangeText); - } - - //JD - public int getStart() { - return start; - } - - //JD - - public int getEnd() { - return end; - } - -} diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 070665e55..7ac2b2825 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -7,7 +7,6 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -23,6 +22,11 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner implements MultiLabelClassifier, MultiTargetRegressor { + /** + * + */ + private static final long serialVersionUID = 5437749202546674734L; + public ClassOption classifierOption = new ClassOption( "classifier", 'c', @@ -50,15 +54,12 @@ private void makeHeaders() { headers = new ArrayList(); for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { List attributes = new ArrayList(); - List indexValues = new ArrayList(); for (int i = 0; i < getModelContext().numInputAttributes(); i++) { attributes.add(getModelContext().inputAttribute(i)); - indexValues.add(i); } attributes.add(getModelContext().outputAttribute(target)); - indexValues.add(getModelContext().numInputAttributes()); InstancesHeader STHeader = new InstancesHeader(); - STHeader.setAttributes(attributes, indexValues); + STHeader.setAttributes(attributes); STHeader.setClassIndex(getModelContext().numInputAttributes()); headers.add(STHeader); } diff --git a/moa/src/main/java/moa/streams/ArffFileStream.java b/moa/src/main/java/moa/streams/ArffFileStream.java index 5d0d10ef9..81d639198 100644 --- a/moa/src/main/java/moa/streams/ArffFileStream.java +++ b/moa/src/main/java/moa/streams/ArffFileStream.java @@ -155,7 +155,7 @@ public void restart() { this.fileProgressMonitor = new InputStreamProgressMonitor( fileStream); this.fileReader = new BufferedReader(new InputStreamReader(this.fileProgressMonitor)); - this.instances = new InstancesHeader(this.fileReader, 1, this.outputIndexesOption.getValue(), this.inputIndexesOption.getValue()); + this.instances = new InstancesHeader(this.fileReader, this.outputIndexesOption.getValue(), this.inputIndexesOption.getValue()); this.numInstancesRead = 0; this.lastInstanceRead = null; this.hitEndOfFile = !readNextInstanceFromFile(); diff --git a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java index 80e2ae84f..9ade14c76 100644 --- a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java +++ b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java @@ -28,7 +28,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; -import com.github.javacliparser.RangeOption; // jesse import moa.core.InputStreamProgressMonitor; import moa.core.InstanceExample; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/streams/clustering/FileStream.java b/moa/src/main/java/moa/streams/clustering/FileStream.java index 7ef557add..bd8458fff 100644 --- a/moa/src/main/java/moa/streams/clustering/FileStream.java +++ b/moa/src/main/java/moa/streams/clustering/FileStream.java @@ -38,6 +38,8 @@ import moa.core.InstanceExample; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; +import moa.core.utils.AttributeDefinitionUtil; + import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; @@ -48,7 +50,6 @@ import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class FileStream extends ClusteringStream{ @@ -65,11 +66,6 @@ public String getPurposeString() { public FileOption arffFileOption = new FileOption("arffFile", 'f', "ARFF file to load.", defaultfile, "arff", false); -// public IntOption classIndexOption = new IntOption( -// "classIndex", -// 'c', -// "Class index of data. 0 for none or -1 for last attribute in file.", -// -1, -1, Integer.MAX_VALUE); public StringOption outputIndicesOption = new StringOption( "outputIndices", @@ -81,7 +77,7 @@ public String getPurposeString() { "outputIndices", 'i', "Indices of input (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges. Leave blank for all non-output attributes.", - ""); + AttributeDefinitionUtil.nonIgnoredDefinition); public FlagOption normalizeOption = new FlagOption("normalize", 'n', @@ -169,7 +165,7 @@ public void restart() { InputStream fileStream = new FileInputStream(arffFileOption.getFile()); fileProgressMonitor = new InputStreamProgressMonitor(fileStream); fileReader = new BufferedReader(new InputStreamReader(fileProgressMonitor)); - instances = new InstancesHeader(fileReader, 1, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); + instances = new InstancesHeader(fileReader, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); //use hashset to delete duplicates and attributes numbers that aren't valid @@ -287,7 +283,7 @@ protected ArrayList readMinMaxDiffValues(HashSet ignoredAttri InputStream fileStream = new FileInputStream(arffFileOption.getFile()); InputStreamProgressMonitor fileProgressMonitor = new InputStreamProgressMonitor(fileStream); Reader fileReader = new BufferedReader(new InputStreamReader(fileProgressMonitor)); - InstancesHeader instances = new InstancesHeader(fileReader, 1, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); + InstancesHeader instances = new InstancesHeader(fileReader, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); valuesMinMaxDiff = new ArrayList(); for (int i = 0; i < instances.numAttributes()-ignoredAttributes.size(); i++) { diff --git a/moa/src/main/java/moa/streams/filters/RBFFilter.java b/moa/src/main/java/moa/streams/filters/RBFFilter.java index bf90b324c..df300eb65 100644 --- a/moa/src/main/java/moa/streams/filters/RBFFilter.java +++ b/moa/src/main/java/moa/streams/filters/RBFFilter.java @@ -5,15 +5,12 @@ import java.util.Random; import moa.core.InstanceExample; -import moa.streams.MultiTargetInstanceStream; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Range; public class RBFFilter extends AbstractStreamFilter { @@ -53,14 +50,12 @@ public InstanceExample nextInstance() { int d = x.numAttributes(); int h = numLatentOption.getValue(); - int j_c = x.classIndex(); for(int k = 0; k < h; k++) { double sum_k = 0.; for(int j = 0; j < d; j++) { sum_k += (x.value(j) - c[k]); } - double v = sum_k / Math.pow(r[k],2); z.setValue(k,Math.exp(-sum_k)); } z.setValue(h,x.classValue()); @@ -100,7 +95,7 @@ private void initialize(Instance instance) { indexValues.add(h); - ds.setAttributes(v,indexValues); + ds.setAttributes(v); dataset=(new InstancesHeader(ds)); dataset.setClassIndex(h); System.out.println(""+dataset); diff --git a/moa/src/main/java/moa/streams/filters/ReLUFilter.java b/moa/src/main/java/moa/streams/filters/ReLUFilter.java index 3f6eb7f55..4023e2194 100644 --- a/moa/src/main/java/moa/streams/filters/ReLUFilter.java +++ b/moa/src/main/java/moa/streams/filters/ReLUFilter.java @@ -4,16 +4,11 @@ import java.util.List; import java.util.Random; -import moa.core.InstanceExample; -import moa.streams.MultiTargetInstanceStream; - import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Range; public class ReLUFilter extends AbstractStreamFilter { @@ -111,7 +106,7 @@ private void initialize(Instance instance) { indexValues.add(H); - ds.setAttributes(v,indexValues); + ds.setAttributes(v); dataset=(new InstancesHeader(ds)); dataset.setClassIndex(H); diff --git a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java index b5905e34a..5270011e2 100644 --- a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java +++ b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java @@ -3,17 +3,13 @@ import java.util.ArrayList; import java.util.List; -import moa.core.Example; import moa.core.InstanceExample; -import moa.streams.MultiTargetInstanceStream; import com.github.javacliparser.StringOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Range; public class SelectAttributesFilter extends AbstractMultiLabelStreamFilter implements MultiLabelStreamFilter{ @@ -52,7 +48,6 @@ private void initialize(Instance instance) { int totAttributes=inputsSelected.numValues()+outputsSelected.numValues(); InstancesHeader ds= new InstancesHeader(); List v = new ArrayList(totAttributes); - List indexValues = new ArrayList(totAttributes); int ct=0; List inputIndexes = new ArrayList(); List outputIndexes = new ArrayList(); @@ -60,7 +55,6 @@ private void initialize(Instance instance) { { for (int j=inputsSelected.getStart(i); j<=inputsSelected.getEnd(i);j++){ v.add(instance.attribute(j-1)); - indexValues.add(ct); inputIndexes.add(ct); ct++; } @@ -70,12 +64,11 @@ private void initialize(Instance instance) { { for (int j=outputsSelected.getStart(i); j<=outputsSelected.getEnd(i);j++){ v.add(instance.attribute(j-1)); - indexValues.add(ct); outputIndexes.add(ct); ct++; } } - ds.setAttributes(v,indexValues); + ds.setAttributes(v); ds.setOutputIndexes(outputIndexes); ds.setInputIndexes(inputIndexes); dataset=(new InstancesHeader(ds)); diff --git a/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java b/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java index 5c99a5e92..4987e2718 100644 --- a/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java +++ b/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java @@ -21,7 +21,6 @@ import java.io.BufferedReader; import java.io.FileInputStream; -import java.io.FileReader; import java.io.InputStreamReader; import java.io.Reader; @@ -35,11 +34,8 @@ import moa.test.TmpFile; import weka.core.MOAUtils; -import com.yahoo.labs.samoa.instances.ArffLoader; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Range; /** * Ancestor for all classifier test cases. From 66c988f31fbeef509dbb8ea08e05acd425deabce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Tue, 10 Jan 2017 14:30:50 +0100 Subject: [PATCH 14/33] Instances rework, new iSOUPTree models and import cleanup --- moa/.settings/org.eclipse.jdt.core.prefs | 13 +- .../github/javacliparser/JavaCLIParser.java | 1 - .../gui/ClassOptionEditComponent.java | 3 +- .../ClassOptionWithNamesEditComponent.java | 3 +- .../gui/FileOptionEditComponent.java | 1 + .../gui/ListOptionEditComponent.java | 4 +- .../gui/OptionsConfigurationPanel.java | 8 +- .../labs/samoa/instances/ArffLoader.java | 1 + .../yahoo/labs/samoa/instances/Attribute.java | 7 +- .../yahoo/labs/samoa/instances/Instance.java | 16 + .../labs/samoa/instances/InstanceImpl.java | 22 + .../samoa/instances/InstanceInformation.java | 1 - .../labs/samoa/instances/InstancesHeader.java | 13 + .../samoa/instances/MultiLabelPrediction.java | 3 +- .../SamoaToWekaInstanceConverter.java | 2 +- moa/src/main/java/moa/AbstractMOAObject.java | 6 +- moa/src/main/java/moa/DoTask.java | 10 +- moa/src/main/java/moa/MOAObject.java | 2 +- .../moa/classifiers/AbstractClassifier.java | 34 +- .../AbstractMultiLabelLearner.java | 5 +- .../main/java/moa/classifiers/Classifier.java | 7 +- .../moa/classifiers/MultiLabelLearner.java | 2 +- .../classifiers/active/ActiveClassifier.java | 10 +- .../moa/classifiers/bayes/NaiveBayes.java | 3 +- .../bayes/NaiveBayesMultinomial.java | 6 +- .../core/AttributeSplitSuggestion.java | 2 +- ...naryTreeNumericAttributeClassObserver.java | 1 + ...mericAttributeClassObserverRegression.java | 1 + .../FIMTDDNumericAttributeClassObserver.java | 61 +- ...GaussianNumericAttributeClassObserver.java | 12 +- ...ldKhannaNumericAttributeClassObserver.java | 6 +- .../NominalAttributeClassObserver.java | 7 +- .../VFMLNumericAttributeClassObserver.java | 8 +- .../InstanceConditionalTest.java | 4 +- .../NominalAttributeBinaryTest.java | 1 - .../NominalAttributeMultiwayTest.java | 1 - .../NumericAttributeBinaryTest.java | 1 - .../driftdetection/ADWINChangeDetector.java | 1 + .../core/driftdetection/CusumDM.java | 1 + .../classifiers/core/driftdetection/DDM.java | 1 + .../core/driftdetection/EWMAChartDM.java | 1 + .../EnsembleDriftDetectionMethods.java | 1 + .../GeometricMovingAverageDM.java | 1 + .../core/driftdetection/HDDM_A_Test.java | 1 + .../core/driftdetection/HDDM_W_Test.java | 1 + .../core/driftdetection/PageHinkleyDM.java | 1 + .../driftdetection/SEEDChangeDetector.java | 1 + .../SeqDrift1ChangeDetector.java | 8 +- .../SeqDrift2ChangeDetector.java | 8 +- .../splitcriteria/InfoGainSplitCriterion.java | 1 + .../drift/DriftDetectionMethodClassifier.java | 6 +- .../classifiers/functions/MajorityClass.java | 3 +- .../moa/classifiers/functions/NoChange.java | 3 +- .../moa/classifiers/functions/Perceptron.java | 5 +- .../java/moa/classifiers/functions/SGD.java | 9 +- .../classifiers/functions/SGDMultiClass.java | 7 +- .../moa/classifiers/functions/SPegasos.java | 7 +- .../main/java/moa/classifiers/lazy/kNN.java | 10 +- .../java/moa/classifiers/lazy/kNNwithPAW.java | 1 - .../classifiers/lazy/kNNwithPAWandADWIN.java | 4 +- .../lazy/neighboursearch/KDTree.java | 6 +- .../NearestNeighbourSearch.java | 1 + .../neighboursearch/NormalizableDistance.java | 1 - .../kdtrees/KDTreeNodeSplitter.java | 3 +- .../main/java/moa/classifiers/meta/ADACC.java | 7 +- .../meta/AccuracyUpdatedEnsemble.java | 7 +- .../meta/AccuracyWeightedEnsemble.java | 16 +- .../main/java/moa/classifiers/meta/DACC.java | 11 +- .../moa/classifiers/meta/LeveragingBag.java | 13 +- .../classifiers/meta/LimAttClassifier.java | 18 +- .../java/moa/classifiers/meta/OCBoost.java | 10 +- .../meta/OnlineAccuracyUpdatedEnsemble.java | 1 + .../classifiers/meta/OnlineSmoothBoost.java | 1 + .../java/moa/classifiers/meta/OzaBag.java | 14 +- .../java/moa/classifiers/meta/OzaBagASHT.java | 7 +- .../moa/classifiers/meta/OzaBagAdwin.java | 10 +- .../java/moa/classifiers/meta/OzaBoost.java | 8 +- .../moa/classifiers/meta/OzaBoostAdwin.java | 11 +- .../moa/classifiers/meta/PairedLearners.java | 9 +- .../moa/classifiers/meta/RandomRules.java | 3 +- .../meta/TemporallyAugmentedClassifier.java | 14 +- .../moa/classifiers/meta/WEKAClassifier.java | 8 +- .../meta/WeightedMajorityAlgorithm.java | 17 +- .../HoeffdingTreeClassifLeaves.java | 4 +- .../LocalMultiTargetClassifier.java | 46 +- .../multilabel/MEKAClassifier.java | 22 +- .../multilabel/MajorityLabelset.java | 9 +- .../multilabel/MultilabelHoeffdingTree.java | 30 +- .../MultiLabelBSTree.java | 72 +- .../MultiLabelBSTreePCT.java | 270 ++++++ .../MultiLabelNominalAttributeObserver.java | 4 +- .../splitcriteria/ICVarianceReduction.java | 8 +- .../PCTWeightedICVarianceReduction.java | 76 ++ .../classifiers/multilabel/meta/MTOzaBag.java | 16 +- .../multilabel/meta/OzaBagAdwinML.java | 109 ++- .../classifiers/multilabel/meta/OzaBagML.java | 13 +- .../multilabel/trees/ISOUPOptionTree.java | 68 +- .../multilabel/trees/ISOUPTree.java | 901 ++++++++++-------- .../multilabel/trees/ISOUPTreeRF.java | 46 + .../BasicMultiTargetRegressor.java | 15 +- .../functions/MultiTargetNoChange.java | 6 +- .../rules/AMRulesRegressorOld.java | 3 +- .../classifiers/rules/AbstractAMRules.java | 8 +- .../moa/classifiers/rules/Predicates.java | 3 +- .../classifiers/rules/RuleClassification.java | 6 +- .../moa/classifiers/rules/RuleClassifier.java | 13 +- .../rules/RuleClassifierNBayes.java | 4 +- .../rules/core/NominalRulePredicate.java | 1 - .../rules/core/NumericRulePredicate.java | 1 - .../java/moa/classifiers/rules/core/Rule.java | 8 +- .../rules/core/RuleActiveLearningNode.java | 2 +- .../rules/core/RuleActiveRegressionNode.java | 12 +- .../moa/classifiers/rules/core/Utils.java | 5 + .../AbstractAnomalyDetector.java | 3 +- .../AnomalinessRatioScore.java | 10 +- .../anomalydetection/NoAnomalyDetection.java | 3 +- .../core/anomalydetection/OddsRatioScore.java | 10 +- .../CantellisInequality.java | 3 - .../ChebyshevInequality.java | 3 - .../probabilityfunctions/GaussInequality.java | 3 - ...TDDNumericAttributeClassLimitObserver.java | 4 +- .../NominalAttributeBinaryRulePredicate.java | 1 - .../NumericAttributeBinaryRulePredicate.java | 1 - .../SDRSplitCriterionAMRules.java | 1 - .../SDRSplitCriterionAMRulesNode.java | 2 - .../voting/AbstractErrorWeightedVote.java | 1 + .../errormeasurers/MeanAbsoluteDeviation.java | 1 - .../errormeasurers/RootMeanSquaredError.java | 2 - .../rules/functions/AMRulesLearner.java | 4 +- .../rules/functions/Perceptron.java | 2 - .../rules/functions/TargetMean.java | 2 +- .../rules/meta/RandomAMRulesOld.java | 7 +- .../multilabel/AMRulesMultiLabelLearner.java | 13 +- .../AMRulesMultiTargetRegressor.java | 2 - .../multilabel/core/LearningLiteral.java | 9 +- .../core/LearningLiteralRegression.java | 15 +- .../rules/multilabel/core/MultiLabelRule.java | 8 +- .../AbstractErrorWeightedVoteMultiLabel.java | 1 - .../voting/ErrorWeightedVoteMultiLabel.java | 2 - .../AbstractMultiLabelErrorMeasurer.java | 8 +- .../AbstractMultiTargetErrorMeasurer.java | 2 +- .../MultiLabelErrorMeasurer.java | 2 +- .../RootMeanSquaredErrorMT.java | 3 - .../AdaptiveMultiTargetRegressor.java | 7 +- .../MultiLabelTargetMeanRegressor.java | 1 - .../meta/MultiLabelRandomAMRules.java | 18 +- .../trees/AdaHoeffdingOptionTree.java | 3 +- .../moa/classifiers/trees/DecisionStump.java | 3 +- .../java/moa/classifiers/trees/FIMTDD.java | 46 +- .../trees/HoeffdingAdaptiveTree.java | 4 +- .../trees/HoeffdingOptionTree.java | 12 +- .../moa/classifiers/trees/HoeffdingTree.java | 14 +- .../trees/LimAttHoeffdingTree.java | 3 +- .../main/java/moa/classifiers/trees/ORTO.java | 7 +- .../trees/RandomHoeffdingTree.java | 3 +- moa/src/main/java/moa/cluster/CFCluster.java | 1 + moa/src/main/java/moa/cluster/Cluster.java | 4 +- moa/src/main/java/moa/cluster/Clustering.java | 6 +- .../main/java/moa/cluster/SphereCluster.java | 1 + .../moa/clusterers/AbstractClusterer.java | 10 +- .../java/moa/clusterers/ClusterGenerator.java | 4 +- .../main/java/moa/clusterers/Clusterer.java | 5 +- moa/src/main/java/moa/clusterers/CobWeb.java | 10 +- moa/src/main/java/moa/clusterers/KMeans.java | 1 + .../clusterers/WekaClusteringAlgorithm.java | 13 +- .../moa/clusterers/clustream/Clustream.java | 8 +- .../clusterers/clustream/ClustreamKernel.java | 5 +- .../moa/clusterers/clustream/WithKmeans.java | 7 +- .../moa/clusterers/clustree/ClusKernel.java | 5 +- .../moa/clusterers/clustree/ClusTree.java | 10 +- .../clusterers/denstream/MicroCluster.java | 3 +- .../moa/clusterers/denstream/WithDBSCAN.java | 9 +- .../clusterers/macro/NonConvexCluster.java | 3 +- .../outliers/AbstractC/AbstractC.java | 6 +- .../outliers/AbstractC/AbstractCBase.java | 3 +- .../outliers/AbstractC/ISBIndex.java | 1 + .../outliers/AbstractC/MyMTree.java | 1 + .../clusterers/outliers/AbstractC/Test.java | 3 +- .../outliers/Angiulli/ApproxSTORM.java | 6 +- .../outliers/Angiulli/ExactSTORM.java | 6 +- .../outliers/Angiulli/ISBIndex.java | 1 + .../clusterers/outliers/Angiulli/MyMTree.java | 1 + .../outliers/Angiulli/STORMBase.java | 6 +- .../clusterers/outliers/Angiulli/Test.java | 3 +- .../clusterers/outliers/AnyOut/AnyOut.java | 4 +- .../outliers/AnyOut/AnyOutCore.java | 6 +- .../clusterers/outliers/MCOD/ISBIndex.java | 1 + .../moa/clusterers/outliers/MCOD/MCOD.java | 8 +- .../clusterers/outliers/MCOD/MCODBase.java | 3 +- .../outliers/MCOD/MTreeMicroClusters.java | 1 + .../outliers/MCOD/MTreeStreamObjects.java | 1 + .../outliers/MCOD/MicroCluster.java | 1 + .../moa/clusterers/outliers/MCOD/Test.java | 3 +- .../outliers/MyBaseOutlierDetector.java | 6 +- .../outliers/SimpleCOD/ISBIndex.java | 1 + .../outliers/SimpleCOD/MyMTree.java | 1 + .../outliers/SimpleCOD/SimpleCOD.java | 6 +- .../outliers/SimpleCOD/SimpleCODBase.java | 1 + .../clusterers/outliers/SimpleCOD/Test.java | 3 +- .../moa/clusterers/outliers/TestSpeed.java | 3 +- .../outliers/utils/mtree/MTree.java | 1 + .../utils/mtree/PromotionFunctions.java | 1 + .../java/moa/clusterers/streamkm/Point.java | 4 +- .../moa/clusterers/streamkm/StreamKM.java | 3 +- .../java/moa/core/AutoClassDiscovery.java | 2 +- .../main/java/moa/core/AutoExpandVector.java | 2 +- .../moa/core/MultilabelInstancesHeader.java | 1 - moa/src/main/java/moa/core/Utils.java | 8 - .../main/java/moa/core/utils/Converter.java | 4 +- .../main/java/moa/evaluation/Accuracy.java | 1 + ...winClassificationPerformanceEvaluator.java | 1 - ...sicClassificationPerformanceEvaluator.java | 12 +- ...BasicConceptDriftPerformanceEvaluator.java | 1 - .../BasicMultiLabelPerformanceEvaluator.java | 8 +- .../BasicMultiTargetPerformanceEvaluator.java | 11 +- .../BasicRegressionPerformanceEvaluator.java | 7 +- .../java/moa/evaluation/CMM_GTAnalysis.java | 4 +- .../evaluation/ChangeDetectionMeasures.java | 1 + .../ClassificationPerformanceEvaluator.java | 3 +- ...WMAClassificationPerformanceEvaluator.java | 13 - .../moa/evaluation/EntropyCollection.java | 1 + moa/src/main/java/moa/evaluation/F1.java | 1 + ...torClassificationPerformanceEvaluator.java | 12 - moa/src/main/java/moa/evaluation/General.java | 4 +- .../moa/evaluation/LearningEvaluation.java | 4 +- .../LearningPerformanceEvaluator.java | 1 - .../moa/evaluation/MeasureCollection.java | 1 + .../java/moa/evaluation/MembershipMatrix.java | 1 + .../MultiTargetPerformanceEvaluator.java | 3 +- ...tWindowRegressionPerformanceEvaluator.java | 13 +- .../moa/evaluation/OutlierPerformance.java | 2 +- .../RegressionPerformanceEvaluator.java | 3 +- moa/src/main/java/moa/evaluation/SSQ.java | 1 + .../main/java/moa/evaluation/Separation.java | 7 +- .../moa/evaluation/SilhouetteCoefficient.java | 2 +- .../moa/evaluation/StatisticalCollection.java | 1 + ...dowClassificationPerformanceEvaluator.java | 12 - .../WindowRegressionPerformanceEvaluator.java | 11 +- moa/src/main/java/moa/gui/BatchCmd.java | 5 +- .../moa/gui/ClassOptionSelectionPanel.java | 3 +- .../ClassOptionWithNamesSelectionPanel.java | 3 +- .../java/moa/gui/ConceptDriftTabPanel.java | 1 + moa/src/main/java/moa/gui/GUI.java | 6 +- moa/src/main/java/moa/gui/GUIDefaults.java | 6 +- .../java/moa/gui/MultiTargetTabPanel.java | 1 + .../moa/gui/MultiTargetTaskManagerPanel.java | 2 + .../main/java/moa/gui/RegressionTabPanel.java | 1 + .../moa/gui/RegressionTaskManagerPanel.java | 6 +- .../main/java/moa/gui/TaskManagerPanel.java | 6 +- .../java/moa/gui/TaskTextViewerPanel.java | 3 +- .../moa/gui/WEKAClassOptionEditComponent.java | 12 +- .../gui/clustertab/ClusteringAlgoPanel.java | 10 +- .../gui/clustertab/ClusteringEvalPanel.java | 3 +- .../gui/clustertab/ClusteringSetupTab.java | 2 + .../clustertab/ClusteringVisualEvalPanel.java | 4 +- .../gui/clustertab/ClusteringVisualTab.java | 2 + .../gui/conceptdrift/CDTaskManagerPanel.java | 11 +- .../moa/gui/outliertab/OutlierAlgoPanel.java | 15 +- .../moa/gui/outliertab/OutlierEvalPanel.java | 4 +- .../moa/gui/outliertab/OutlierSetupTab.java | 2 + .../outliertab/OutlierVisualEvalPanel.java | 4 +- .../moa/gui/outliertab/OutlierVisualTab.java | 2 + .../moa/gui/visualization/ClusterPanel.java | 2 + .../moa/gui/visualization/GraphCanvas.java | 2 + .../moa/gui/visualization/GraphCurve.java | 1 + .../moa/gui/visualization/OutlierPanel.java | 21 +- .../visualization/RunOutlierVisualizer.java | 10 +- .../moa/gui/visualization/RunVisualizer.java | 12 +- .../gui/visualization/StreamOutlierPanel.java | 16 +- .../moa/gui/visualization/WekaExplorer.java | 7 +- .../moa/learners/ChangeDetectorLearner.java | 3 +- moa/src/main/java/moa/learners/Learner.java | 6 +- .../java/moa/options/AbstractClassOption.java | 2 + .../moa/options/AbstractOptionHandler.java | 1 + .../main/java/moa/options/ClassOption.java | 3 +- .../moa/options/ClassOptionWithNames.java | 6 +- .../main/java/moa/options/OptionHandler.java | 1 + .../main/java/moa/options/OptionsHandler.java | 2 + .../java/moa/options/WEKAClassOption.java | 6 +- .../dataset/impl/FlixsterDataset.java | 5 +- .../dataset/impl/JesterDataset.java | 9 +- .../dataset/impl/MovielensDataset.java | 6 +- .../predictor/BRISMFPredictor.java | 6 +- .../predictor/BaselinePredictor.java | 1 + .../predictor/RatingPredictor.java | 1 + .../rc/data/AbstractRecommenderData.java | 1 + .../recommender/rc/data/RecommenderData.java | 1 + .../rc/data/impl/MemRecommenderData.java | 1 + .../rc/predictor/RatingPredictor.java | 1 + .../rc/predictor/impl/BRISMFPredictor.java | 1 + .../rc/predictor/impl/BaselinePredictor.java | 1 + .../main/java/moa/streams/ArffFileStream.java | 12 +- .../moa/streams/CachedInstancesStream.java | 5 +- .../moa/streams/ConceptDriftRealStream.java | 14 +- .../java/moa/streams/ConceptDriftStream.java | 10 +- .../main/java/moa/streams/ExampleStream.java | 5 +- .../main/java/moa/streams/InstanceStream.java | 3 +- .../java/moa/streams/MultiFilteredStream.java | 9 +- .../moa/streams/MultiLabelFilteredStream.java | 1 - .../streams/MultiTargetArffFileStream.java | 15 - .../streams/MultiTargetInstanceStream.java | 3 - .../streams/RecurrentConceptDriftStream.java | 7 +- .../streams/clustering/ClusteringStream.java | 3 +- .../moa/streams/clustering/FileStream.java | 14 +- .../clustering/RandomRBFGeneratorEvents.java | 17 +- .../streams/clustering/SimpleCSVStream.java | 1 - .../AbstractMultiLabelStreamFilter.java | 1 - .../streams/filters/AbstractStreamFilter.java | 2 +- .../moa/streams/filters/AddNoiseFilter.java | 9 +- .../java/moa/streams/filters/RBFFilter.java | 4 +- .../RemoveDiscreteAttributeFilter.java | 7 +- .../filters/ReplacingMissingValuesFilter.java | 11 +- .../filters/SelectAttributesFilter.java | 4 +- .../moa/streams/filters/StreamFilter.java | 1 + .../streams/generators/AgrawalGenerator.java | 15 +- .../generators/HyperplaneGenerator.java | 11 +- .../moa/streams/generators/LEDGenerator.java | 11 +- .../streams/generators/LEDGeneratorDrift.java | 4 +- .../generators/RandomRBFGenerator.java | 11 +- .../generators/RandomRBFGeneratorDrift.java | 6 +- .../generators/RandomTreeGenerator.java | 15 +- .../moa/streams/generators/SEAGenerator.java | 11 +- .../streams/generators/STAGGERGenerator.java | 11 +- .../streams/generators/WaveformGenerator.java | 11 +- .../generators/WaveformGeneratorDrift.java | 4 +- .../cd/AbstractConceptDriftGenerator.java | 7 +- .../generators/cd/ConceptDriftGenerator.java | 1 + .../multilabel/MetaMultilabelGenerator.java | 26 +- .../multilabel/MultilabelArffFileStream.java | 8 +- .../java/moa/tasks/CacheShuffledStream.java | 3 +- .../java/moa/tasks/ConceptDriftMainTask.java | 1 + .../java/moa/tasks/EvaluateClustering.java | 5 +- .../java/moa/tasks/EvaluateConceptDrift.java | 9 +- .../moa/tasks/EvaluateInterleavedChunks.java | 12 +- .../EvaluateInterleavedTestThenTrain.java | 7 +- .../main/java/moa/tasks/EvaluateModel.java | 4 +- .../moa/tasks/EvaluateModelMultiTarget.java | 8 +- .../moa/tasks/EvaluateModelRegression.java | 5 +- .../moa/tasks/EvaluateOnlineRecommender.java | 3 +- .../tasks/EvaluatePeriodicHeldOutTest.java | 6 +- .../java/moa/tasks/EvaluatePrequential.java | 16 +- .../java/moa/tasks/EvaluatePrequentialCV.java | 28 +- .../tasks/EvaluatePrequentialMultiTarget.java | 11 +- .../tasks/EvaluatePrequentialRegression.java | 22 +- moa/src/main/java/moa/tasks/LearnModel.java | 3 +- .../java/moa/tasks/LearnModelMultiTarget.java | 1 + .../java/moa/tasks/LearnModelRegression.java | 5 +- moa/src/main/java/moa/tasks/MainTask.java | 3 +- .../java/moa/tasks/MeasureStreamSpeed.java | 4 +- .../java/moa/tasks/MultiTargetMainTask.java | 2 +- moa/src/main/java/moa/tasks/Plot.java | 3 +- .../java/moa/tasks/RegressionMainTask.java | 2 +- .../main/java/moa/tasks/RunStreamTasks.java | 1 + moa/src/main/java/moa/tasks/RunTasks.java | 5 +- .../java/moa/tasks/WriteStreamToARFFFile.java | 7 +- .../main/java/weka/classifiers/meta/MOA.java | 18 +- .../classifiers/classification/MOA.java | 19 +- .../java/weka/gui/MOAClassOptionEditor.java | 3 +- .../instances/MultiTargetArffLoaderTest.java | 12 +- .../AbstractClassifierTestCase.java | 12 +- .../AbstractMultipleClassifierTestCase.java | 1 - .../AbstractMultipleRegressorTestCase.java | 1 - .../active/ActiveClassifierTest.java | 1 - .../drift/SingleClassifierDriftTest.java | 1 - .../functions/MajorityClassTest.java | 1 - .../classifiers/functions/NoChangeTest.java | 1 - .../classifiers/functions/PerceptronTest.java | 1 - .../moa/classifiers/functions/SGDTest.java | 1 - .../classifiers/functions/SPegasosTest.java | 1 - .../meta/AccuracyUpdatedEnsembleTest.java | 1 - .../meta/AccuracyWeightedEnsembleTest.java | 1 - .../classifiers/meta/LeveragingBagTest.java | 1 - .../meta/LimAttClassifierTest.java | 1 - .../moa/classifiers/meta/OCBoostTest.java | 1 - .../OnlineAccuracyUpdatedEnsembleTest.java | 1 - .../moa/classifiers/meta/OzaBagASHTTest.java | 1 - .../moa/classifiers/meta/OzaBagAdwinTest.java | 1 - .../java/moa/classifiers/meta/OzaBagTest.java | 1 - .../classifiers/meta/OzaBoostAdwinTest.java | 1 - .../moa/classifiers/meta/OzaBoostTest.java | 1 - .../TemporallyAugmentedClassifierTest.java | 1 - .../classifiers/meta/WEKAClassifierTest.java | 1 - .../meta/WeightedMajorityAlgorithmTest.java | 1 - .../rules/AMRulesRegressorTest.java | 1 - .../rules/RuleClassifierNBayesTest.java | 1 - .../classifiers/rules/RuleClassifierTest.java | 1 - ...nverseErrorWeightedVoteMultiLabeLTest.java | 3 +- .../UniformWeightedVoteMultiLabelTest.java | 4 +- .../trees/ASHoeffdingTreeTest.java | 1 - .../trees/AdaHoeffdingOptionTreeTest.java | 1 - .../classifiers/trees/DecisionStumpTest.java | 1 - .../moa/classifiers/trees/FIMTDDTest.java | 4 +- .../trees/HoeffdingAdaptiveTreeTest.java | 1 - .../trees/HoeffdingOptionTreeTest.java | 1 - .../trees/LimAttHoeffdingTreeTest.java | 1 - .../java/moa/classifiers/trees/ORTOTest.java | 1 - .../trees/RandomHoeffdingTreeTest.java | 1 - .../moa/integration/SimpleClusterTest.java | 12 +- .../filters/SelectAttributesFilterTest.java | 5 +- .../.settings/org.eclipse.jdt.core.prefs | 9 +- 400 files changed, 2267 insertions(+), 1558 deletions(-) create mode 100644 moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTreePCT.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/PCTWeightedICVarianceReduction.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTreeRF.java diff --git a/moa/.settings/org.eclipse.jdt.core.prefs b/moa/.settings/org.eclipse.jdt.core.prefs index 60105c1b9..672496e10 100644 --- a/moa/.settings/org.eclipse.jdt.core.prefs +++ b/moa/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,12 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java b/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java index 23522e085..68191078c 100644 --- a/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java +++ b/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java @@ -73,7 +73,6 @@ public Option[] discoverOptionsViaReflection() { Field[] fields = c.getFields(); List

diff --git a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java index 6b78777a3..ae232b9b0 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java @@ -17,7 +17,6 @@ */ package moa.classifiers.lazy; -import moa.classifiers.core.driftdetection.ADWIN; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; diff --git a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java index 65e9266ed..74670860e 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java @@ -18,10 +18,12 @@ package moa.classifiers.lazy; import java.util.ArrayList; -import moa.classifiers.core.driftdetection.ADWIN; + import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.classifiers.core.driftdetection.ADWIN; + /** * k Nearest Neighbor ADAPTIVE with ADWIN+PAW.

* diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java index b3b6d7a0d..684f063d8 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java @@ -23,11 +23,13 @@ import java.util.Enumeration; import java.util.Vector; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.lazy.neighboursearch.kdtrees.KDTreeNode; import moa.classifiers.lazy.neighboursearch.kdtrees.KDTreeNodeSplitter; import moa.classifiers.lazy.neighboursearch.kdtrees.SlidingMidPointOfWidestSide; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java index ddefd58ae..541d0f527 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java @@ -21,6 +21,7 @@ package moa.classifiers.lazy.neighboursearch; import java.io.Serializable; + import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java index 7800a8576..46da24f3e 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java @@ -21,7 +21,6 @@ package moa.classifiers.lazy.neighboursearch; -import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java index f69760c9f..61126b4a0 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java @@ -23,10 +23,11 @@ import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; -import moa.classifiers.lazy.neighboursearch.EuclideanDistance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.classifiers.lazy.neighboursearch.EuclideanDistance; + /** * Class that splits up a KDTreeNode. * diff --git a/moa/src/main/java/moa/classifiers/meta/ADACC.java b/moa/src/main/java/moa/classifiers/meta/ADACC.java index 8aa324af8..f5dbe47c1 100644 --- a/moa/src/main/java/moa/classifiers/meta/ADACC.java +++ b/moa/src/main/java/moa/classifiers/meta/ADACC.java @@ -20,15 +20,16 @@ package moa.classifiers.meta; +import java.util.Arrays; +import java.util.Collections; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.Classifier; import moa.core.Measurement; - -import java.util.Arrays; -import java.util.Collections; import moa.core.Utils; /** diff --git a/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java index f9764fa19..7a935202d 100644 --- a/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java @@ -19,6 +19,10 @@ */ package moa.classifiers.meta; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.classifiers.trees.HoeffdingTree; @@ -26,10 +30,7 @@ import moa.core.Measurement; import moa.core.ObjectRepository; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * The revised version of the Accuracy Updated Ensemble as proposed by diff --git a/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java index df7e6fea1..3fd651d59 100644 --- a/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java @@ -20,18 +20,20 @@ package moa.classifiers.meta; import java.util.Random; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.ObjectRepository; +import moa.core.Utils; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import moa.core.Utils; /** * The Accuracy Weighted Ensemble classifier as proposed by Wang et al. in @@ -433,9 +435,9 @@ protected Classifier addToStored(Classifier newClassifier, double newClassifiers * * @return the size of the removed classifier. */ - protected int removePoorestModelBytes() { + protected long removePoorestModelBytes() { int poorestIndex = Utils.minIndex(this.ensembleWeights); - int byteSize = this.ensemble[poorestIndex].measureByteSize(); + long byteSize = this.ensemble[poorestIndex].measureByteSize(); discardModel(poorestIndex); return byteSize; } diff --git a/moa/src/main/java/moa/classifiers/meta/DACC.java b/moa/src/main/java/moa/classifiers/meta/DACC.java index 8cb76472b..dfb470e1e 100644 --- a/moa/src/main/java/moa/classifiers/meta/DACC.java +++ b/moa/src/main/java/moa/classifiers/meta/DACC.java @@ -20,18 +20,19 @@ package moa.classifiers.meta; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.MultiChoiceOption; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import moa.options.ClassOption; /** diff --git a/moa/src/main/java/moa/classifiers/meta/LeveragingBag.java b/moa/src/main/java/moa/classifiers/meta/LeveragingBag.java index 6d6e78830..3edcf5ae1 100644 --- a/moa/src/main/java/moa/classifiers/meta/LeveragingBag.java +++ b/moa/src/main/java/moa/classifiers/meta/LeveragingBag.java @@ -19,20 +19,19 @@ */ package moa.classifiers.meta; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.FloatOption; import com.github.javacliparser.FlagOption; -import moa.options.ClassOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; -import moa.classifiers.core.driftdetection.ADWIN; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; -import moa.options.*; +import moa.options.ClassOption; /** * Leveraging Bagging for evolving data streams using ADWIN. Leveraging Bagging diff --git a/moa/src/main/java/moa/classifiers/meta/LimAttClassifier.java b/moa/src/main/java/moa/classifiers/meta/LimAttClassifier.java index 8cb281802..d223111dc 100644 --- a/moa/src/main/java/moa/classifiers/meta/LimAttClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/LimAttClassifier.java @@ -20,21 +20,21 @@ */ package moa.classifiers.meta; -import moa.classifiers.trees.LimAttHoeffdingTree; -import com.yahoo.labs.samoa.instances.Instance; -import moa.core.Utils; - import java.math.BigInteger; import java.util.Arrays; -import moa.classifiers.core.driftdetection.ADWIN; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; -import moa.core.Measurement; -import moa.options.ClassOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.core.driftdetection.ADWIN; +import moa.classifiers.trees.LimAttHoeffdingTree; +import moa.core.Measurement; +import moa.core.Utils; +import moa.options.ClassOption; /** * Ensemble Combining Restricted Hoeffding Trees using Stacking. diff --git a/moa/src/main/java/moa/classifiers/meta/OCBoost.java b/moa/src/main/java/moa/classifiers/meta/OCBoost.java index 9e796ff7b..e9c33ff73 100644 --- a/moa/src/main/java/moa/classifiers/meta/OCBoost.java +++ b/moa/src/main/java/moa/classifiers/meta/OCBoost.java @@ -19,15 +19,15 @@ */ package moa.classifiers.meta; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import moa.core.Utils; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; import moa.core.Measurement; +import moa.core.Utils; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; /** * Online Coordinate boosting for two classes evolving data streams. diff --git a/moa/src/main/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsemble.java index 790599ff4..44e381d78 100644 --- a/moa/src/main/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsemble.java @@ -23,6 +23,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.classifiers.trees.HoeffdingTree; diff --git a/moa/src/main/java/moa/classifiers/meta/OnlineSmoothBoost.java b/moa/src/main/java/moa/classifiers/meta/OnlineSmoothBoost.java index 0810d2153..445ca1027 100644 --- a/moa/src/main/java/moa/classifiers/meta/OnlineSmoothBoost.java +++ b/moa/src/main/java/moa/classifiers/meta/OnlineSmoothBoost.java @@ -22,6 +22,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.DoubleVector; diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBag.java b/moa/src/main/java/moa/classifiers/meta/OzaBag.java index 9ca3dd639..d43f2da0b 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBag.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBag.java @@ -19,15 +19,15 @@ */ package moa.classifiers.meta; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; /** * Incremental on-line bagging of Oza and Russell. @@ -66,6 +66,14 @@ public String getPurposeString() { protected Classifier[] ensemble; + @Override + public long measureByteSize() { + long size = 0; + for (Classifier c : ensemble) + size += c.measureByteSize(); + return size; + } + @Override public void resetLearningImpl() { this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java b/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java index 4496d81de..308ef2454 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java @@ -19,13 +19,14 @@ */ package moa.classifiers.meta; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.Classifier; import moa.classifiers.trees.ASHoeffdingTree; import moa.core.DoubleVector; import moa.core.MiscUtils; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.FlagOption; -import com.yahoo.labs.samoa.instances.Instance; import moa.core.Utils; /** diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java index fa688e426..8f790f339 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java @@ -19,16 +19,16 @@ */ package moa.classifiers.meta; -import moa.classifiers.core.driftdetection.ADWIN; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; /** * Bagging for evolving data streams using ADWIN. @@ -141,7 +141,7 @@ public void trainOnInstanceImpl(Instance inst) { } if (imax != -1) { this.ensemble[imax].resetLearning(); - //this.ensemble[imax].trainOnInstance(inst); + this.ensemble[imax].trainOnInstance(inst); this.ADError[imax] = new ADWIN(); } } diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBoost.java b/moa/src/main/java/moa/classifiers/meta/OzaBoost.java index 54fc8e15b..cf149c8c9 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBoost.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBoost.java @@ -19,16 +19,16 @@ */ package moa.classifiers.meta; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; /** * Incremental on-line boosting of Oza and Russell. diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBoostAdwin.java b/moa/src/main/java/moa/classifiers/meta/OzaBoostAdwin.java index 17d370547..1e60ba154 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBoostAdwin.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBoostAdwin.java @@ -19,17 +19,18 @@ */ package moa.classifiers.meta; -import moa.classifiers.core.driftdetection.ADWIN; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; +import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Boosting for evolving data streams using ADWIN. diff --git a/moa/src/main/java/moa/classifiers/meta/PairedLearners.java b/moa/src/main/java/moa/classifiers/meta/PairedLearners.java index dc071be46..9ec64027e 100644 --- a/moa/src/main/java/moa/classifiers/meta/PairedLearners.java +++ b/moa/src/main/java/moa/classifiers/meta/PairedLearners.java @@ -18,18 +18,19 @@ */ package moa.classifiers.meta; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.Measurement; -import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; import moa.core.MiscUtils; +import moa.options.ClassOption; /** * Creates two classifiers: a stable and a reactive. The first represents the diff --git a/moa/src/main/java/moa/classifiers/meta/RandomRules.java b/moa/src/main/java/moa/classifiers/meta/RandomRules.java index e170e1ef7..143849bdb 100644 --- a/moa/src/main/java/moa/classifiers/meta/RandomRules.java +++ b/moa/src/main/java/moa/classifiers/meta/RandomRules.java @@ -19,14 +19,12 @@ */ package moa.classifiers.meta; -import moa.options.ClassOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; @@ -35,6 +33,7 @@ import moa.core.FastVector; import moa.core.Measurement; import moa.core.MiscUtils; +import moa.options.ClassOption; import moa.streams.InstanceStream; diff --git a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java index eac49168d..431348c5d 100644 --- a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java @@ -19,21 +19,23 @@ */ package moa.classifiers.meta; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.Measurement; import moa.core.Utils; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Include labels of previous instances into the training data diff --git a/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java b/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java index d9ac321c8..b2595ff28 100644 --- a/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java @@ -20,15 +20,15 @@ */ package moa.classifiers.meta; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; + import moa.classifiers.AbstractClassifier; import moa.core.Measurement; -import com.github.javacliparser.IntOption; import moa.options.WEKAClassOption; import weka.classifiers.Classifier; import weka.classifiers.UpdateableClassifier; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; /** * Class for using a classifier from WEKA. diff --git a/moa/src/main/java/moa/classifiers/meta/WeightedMajorityAlgorithm.java b/moa/src/main/java/moa/classifiers/meta/WeightedMajorityAlgorithm.java index c08bdfe6a..8ee34158b 100644 --- a/moa/src/main/java/moa/classifiers/meta/WeightedMajorityAlgorithm.java +++ b/moa/src/main/java/moa/classifiers/meta/WeightedMajorityAlgorithm.java @@ -19,19 +19,20 @@ */ package moa.classifiers.meta; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.ListOption; +import com.github.javacliparser.Option; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.ObjectRepository; +import moa.core.Utils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.ListOption; -import com.github.javacliparser.Option; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import moa.core.Utils; /** * Weighted majority algorithm for data streams. @@ -196,9 +197,9 @@ public void discardModel(int index) { this.ensembleWeights = newEnsembleWeights; } - protected int removePoorestModelBytes() { + protected long removePoorestModelBytes() { int poorestIndex = Utils.minIndex(this.ensembleWeights); - int byteSize = this.ensemble[poorestIndex].measureByteSize(); + long byteSize = this.ensemble[poorestIndex].measureByteSize(); discardModel(poorestIndex); return byteSize; } diff --git a/moa/src/main/java/moa/classifiers/multilabel/HoeffdingTreeClassifLeaves.java b/moa/src/main/java/moa/classifiers/multilabel/HoeffdingTreeClassifLeaves.java index a70def66a..600e2f2ae 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/HoeffdingTreeClassifLeaves.java +++ b/moa/src/main/java/moa/classifiers/multilabel/HoeffdingTreeClassifLeaves.java @@ -22,12 +22,14 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.Classifier; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.classifiers.trees.HoeffdingTree; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding Tree that have a classifier at the leaves. diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 7ac2b2825..6924b00e9 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -7,9 +7,9 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.classifiers.AbstractClassifier; import moa.classifiers.AbstractMultiLabelLearner; @@ -17,6 +17,7 @@ import moa.classifiers.MultiLabelClassifier; import moa.classifiers.MultiTargetRegressor; import moa.core.Measurement; +import moa.core.SizeOf; import moa.options.ClassOption; public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner @@ -36,6 +37,17 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner ArrayList classifiers = null; ArrayList headers = null; + + @Override + public long measureByteSize() { + long size = 0; + for (Classifier c : classifiers) + size += c.measureByteSize(); + for (InstancesHeader h : headers) { + size += SizeOf.sizeOf(h); + } + return size; + } @Override public boolean isRandomizable() { @@ -60,6 +72,7 @@ private void makeHeaders() { attributes.add(getModelContext().outputAttribute(target)); InstancesHeader STHeader = new InstancesHeader(); STHeader.setAttributes(attributes); + STHeader.setInstances(new ArrayList()); STHeader.setClassIndex(getModelContext().numInputAttributes()); headers.add(STHeader); } @@ -77,9 +90,7 @@ private Instance getSTInstance(StructuredInstance inst, int target) { } @Override - public void trainOnInstanceImpl(StructuredInstance instance) { - initializeClassifiers(); - + public void trainOnInstanceImpl(StructuredInstance instance) { for (int j = 0; j < instance.numberOutputTargets(); j++) { Instance STInst = getSTInstance(instance, j); @@ -89,8 +100,6 @@ public void trainOnInstanceImpl(StructuredInstance instance) { @Override public Prediction getPredictionForInstance(StructuredInstance inst) { - initializeClassifiers(); - MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); for (int j = 0; j < inst.numberOutputTargets(); j++) { Instance STInst = getSTInstance(inst, j); @@ -102,21 +111,22 @@ public Prediction getPredictionForInstance(StructuredInstance inst) { @Override public void resetLearningImpl() { classifiers = null; - + } + + public void modelContextSet() { + initializeClassifiers(); + makeHeaders(); + for (int i = 0; i < classifiers.size(); i++) + classifiers.get(i).setModelContext(getHeader(i)); } public void initializeClassifiers() { - this.classifierRandom.setSeed(1234); - if (classifiers == null) { - makeHeaders(); - classifiers = new ArrayList(); - for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { - Classifier learner = ((Classifier) getPreparedClassOption(this.classifierOption)).copy(); - classifiers.add(learner); - learner.resetLearning(); - ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; - learner.setModelContext(getHeader(i)); - } + classifiers = new ArrayList(); + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + Classifier learner = ((Classifier) getPreparedClassOption(this.classifierOption)).copy(); + classifiers.add(learner); + learner.resetLearning(); + ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; } } diff --git a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java index 96e8f09ac..388634637 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java @@ -19,28 +19,20 @@ */ package moa.classifiers.multilabel; -import java.util.Arrays; import java.io.Serializable; -import moa.core.Measurement; -import weka.classifiers.UpdateableClassifier; -import moa.classifiers.AbstractClassifier; -import moa.core.Measurement; -import com.github.javacliparser.IntOption; -import moa.options.WEKAClassOption; -import weka.classifiers.Classifier; -import weka.classifiers.UpdateableClassifier; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; -import com.yahoo.labs.samoa.instances.StructuredInstance; +import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; -import moa.classifiers.MultiLabelLearner; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; -import moa.core.Example; +import moa.core.Measurement; +import moa.options.WEKAClassOption; +import weka.classifiers.Classifier; +import weka.classifiers.UpdateableClassifier; /** * Wrapper for MEKA classifiers. diff --git a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java index 135f8f88e..9ac0dd346 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java @@ -19,16 +19,15 @@ */ package moa.classifiers.multilabel; -import java.util.Arrays; import java.util.HashMap; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; + import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; +import moa.core.Measurement; import moa.core.StringUtils; /** diff --git a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java index 1801eba28..85de46c30 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java @@ -19,23 +19,21 @@ */ package moa.classifiers.multilabel; -import java.io.StringReader; +import java.util.LinkedList; import java.util.List; -import moa.classifiers.Classifier; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.trees.HoeffdingTree; -import moa.core.StringUtils; -import moa.core.utils.Converter; + import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; -import java.util.LinkedList; +import com.yahoo.labs.samoa.instances.StructuredInstance; + +import moa.classifiers.Classifier; import moa.classifiers.MultiLabelLearner; import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; +import moa.classifiers.trees.HoeffdingTree; import moa.core.Example; -import java.util.Arrays; +import moa.core.StringUtils; /** * Hoeffding Tree for classifying multi-label data. @@ -46,7 +44,7 @@ * * */ -public class MultilabelHoeffdingTree extends HoeffdingTreeClassifLeaves implements MultiLabelLearner, MultiTargetRegressor { +public class MultilabelHoeffdingTree extends HoeffdingTreeClassifLeaves implements MultiLabelLearner, MultiTargetRegressor, Classifier { // Needs to use InfoGainSplitCriterionMultiLabel, since multilabel entropy is calculated in a different way // Trains a mlinstance adding statistics of several class values and training node classifiers // Get votes from the classifier in the learning node of the tree @@ -82,7 +80,7 @@ public MultilabelInactiveLearningNode(double[] initialClassObservations) { public void learnFromInstance(Instance inst, HoeffdingTree ht) { List labels = ((MultilabelHoeffdingTree) ht).getRelevantLabels(inst); for (int l : labels){ - this.observedClassDistribution.addToValue( l, inst.weight()); + this.observedClassDistribution.addToValue(l, inst.weight()); } } } @@ -117,7 +115,7 @@ public Prediction getPredictionForInstance(Instance inst, HoeffdingTree ht) { return this.classifier.getPredictionForInstance(inst); } - + @Override public void disableAttribute(int attIndex) { // should not disable poor atts - they are used in NB calc @@ -183,8 +181,12 @@ public Prediction getPredictionForInstance(Example example) { return getPredictionForInstance((StructuredInstance)example.getData()); } + public Prediction getPredictionForInstance(StructuredInstance inst) { + return getPredictionForInstance((Instance) inst); + } + @Override - public Prediction getPredictionForInstance(StructuredInstance inst){ + public Prediction getPredictionForInstance(Instance inst){ if (this.treeRoot != null) { FoundNode foundNode = this.treeRoot.filterInstanceToLeaf(inst, null, -1); diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java index 58fd92faa..6a23d619d 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java @@ -18,7 +18,7 @@ public class MultiLabelBSTree extends AbstractOptionHandler implements NumericSt /** * */ - public IntOption maxNodesOption = new IntOption("maxNodesOption", 'z', "Maximum number of nodes", 50, 0, Integer.MAX_VALUE); + public IntOption maxNodesOption = new IntOption("maxNodesOption", 'z', "Maximum number of nodes", 2000, 0, Integer.MAX_VALUE); protected int maxNodes; protected int numNodes; @@ -26,14 +26,25 @@ public class MultiLabelBSTree extends AbstractOptionHandler implements NumericSt protected Node root = null; - protected DoubleVector [] leftStatistics; - protected DoubleVector [] rightStatistics; + protected DoubleVector[] leftStatistics; + protected DoubleVector[] rightStatistics; + public static double roundToSignificantFigures(double num, int n) { + final double d = Math.ceil(Math.log10(num < 0 ? -num: num)); + final int power = n - (int) d; + + final double magnitude = Math.pow(10, power); + final long shifted = (long) (num*magnitude); + return shifted/magnitude; + } + @Override public void observeAttribute(double inputAttributeValue, DoubleVector[] statistics) { if (!Double.isNaN(inputAttributeValue)) { +// if ((long) inputAttributeValue != inputAttributeValue) +// inputAttributeValue = roundToSignificantFigures(inputAttributeValue, 4); if (this.root == null) { this.root = new Node(inputAttributeValue, statistics); maxNodes=maxNodesOption.getValue(); @@ -49,13 +60,13 @@ public void observeAttribute(double inputAttributeValue, public AttributeExpansionSuggestion getBestEvaluatedSplitSuggestion( MultiLabelSplitCriterion criterion, DoubleVector[] preSplitStatistics, int inputAttributeIndex) { // Initialize global variables - int numOutputs=preSplitStatistics.length; - leftStatistics=new DoubleVector[numOutputs]; - rightStatistics=new DoubleVector[numOutputs]; + int numOutputs = preSplitStatistics.length; + leftStatistics = new DoubleVector[numOutputs]; + rightStatistics = new DoubleVector[numOutputs]; for (int i=0; i< numOutputs; i++) { - leftStatistics[i]=new DoubleVector(new double [preSplitStatistics[i].numValues()]); //sets statistics to zeros - rightStatistics[i]=new DoubleVector(preSplitStatistics[i]); + leftStatistics[i] = new DoubleVector(new double [preSplitStatistics[i].numValues()]); //sets statistics to zeros + rightStatistics[i] = new DoubleVector(preSplitStatistics[i]); } return searchForBestSplitOption(this.root, null, criterion, preSplitStatistics, inputAttributeIndex); @@ -70,34 +81,36 @@ protected AttributeExpansionSuggestion searchForBestSplitOption(Node currentNode if (currentNode.left != null) { currentBestOption = searchForBestSplitOption(currentNode.left, currentBestOption, criterion, preSplitStatistics, inputAttributeIndex); } + for (int i=0; i currentBestOption.merit)) { - currentBestOption= new AttributeExpansionSuggestion(new NumericRulePredicate(inputAttributeIndex, currentNode.cutPoint, true), Utils.copy(postSplitDists), merit); + currentBestOption = new AttributeExpansionSuggestion(new NumericRulePredicate(inputAttributeIndex, currentNode.cutPoint, true), Utils.copy(postSplitDists), merit); } if (currentNode.right != null) { currentBestOption = searchForBestSplitOption(currentNode.right, currentBestOption, criterion, preSplitStatistics, inputAttributeIndex); } - for (int i=0; i currentBestOption.merit)) { + currentBestOption = new AttributeExpansionSuggestion(new NumericRulePredicate(inputAttributeIndex, currentNode.cutPoint, true), Utils.copy(postSplitTargetDists), merit); + } + + if (currentNode.right != null) { + currentBestOption = searchForBestSplitOption(currentNode.right, currentBestOption, criterion, preSplitTargetStatistics, preSplitInputStatistics, inputAttributeIndex); + } + for (int i = 0; i < leftTargetStatistics.length; i++) { + leftTargetStatistics[i].subtractValues(currentNode.targetStatistics[i]); + rightTargetStatistics[i].addValues(currentNode.targetStatistics[i]); + } + for (int i = 0; i < leftInputStatistics.length; i++) { + leftInputStatistics[i].subtractValues(currentNode.inputStatistics[i]); + rightInputStatistics[i].addValues(currentNode.inputStatistics[i]); + } + + return currentBestOption; + } + + + + + @Override + public String getPurposeString() { + return "Stores statistics for all output and input attributes for a giver input attribute."; + } + + @Override + public void getDescription(StringBuilder sb, int indent) { + } + + @Override + protected void prepareForUseImpl(TaskMonitor monitor, + ObjectRepository repository) { + + } + + + //Inner classes inspired in FIMTDDNumericalAttributeClassObserver + + protected class Node implements Serializable { + + private static final long serialVersionUID = 1L; + + // The split point to use + private double cutPoint; + + // E-BST statistics + private DoubleVector[] targetStatistics; + private DoubleVector[] inputStatistics; + + + // Child nodes + private Node left; + private Node right; + + public Node(double inputAttributeValue, DoubleVector[] targetStatistics, DoubleVector[] inputStatistics) { + cutPoint = inputAttributeValue; + int numOutputAttributes = targetStatistics.length; + int numInputAttributes = inputStatistics.length; + this.targetStatistics = new DoubleVector[numOutputAttributes]; + this.inputStatistics = new DoubleVector[numInputAttributes]; + for (int i=0; i 1) { return (squares - sum * sum / n) / (n - 1); } return 0; } - private double computeVariance(DoubleVector v) { + public double computeVariance(DoubleVector v) { return computeVariance(v.getValue(0), v.getValue(1), v.getValue(2)); } @@ -62,10 +62,10 @@ private double computeVariance(DoubleVector v) { } protected double getMeritOfSplitForOutput(DoubleVector[] preSplitDist, DoubleVector[][] postSplitDists, int outputAttributeIndex){ - return getMeritOfSplitForOutput(preSplitDist[outputAttributeIndex],postSplitDists[outputAttributeIndex]); + return getMeritOfSplitForAttribute(preSplitDist[outputAttributeIndex],postSplitDists[outputAttributeIndex]); } - protected double getMeritOfSplitForOutput(DoubleVector preSplitDist, DoubleVector[] postSplitDists) { + protected double getMeritOfSplitForAttribute(DoubleVector preSplitDist, DoubleVector[] postSplitDists) { double merit=0; //count number of branches with weightSeen higher than threshold int count = 0; diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/PCTWeightedICVarianceReduction.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/PCTWeightedICVarianceReduction.java new file mode 100644 index 000000000..adb022397 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/PCTWeightedICVarianceReduction.java @@ -0,0 +1,76 @@ +package moa.classifiers.multilabel.core.splitcriteria; + +import moa.core.DoubleVector; + +public class PCTWeightedICVarianceReduction extends WeightedICVarianceReduction { + + public DoubleVector inputWeights; + + public double targetInputTradeoff; // \in [0, 1] + + public PCTWeightedICVarianceReduction(DoubleVector targetWeights, DoubleVector inputWeights, double targetInputTradeoff) { + super(targetWeights); + this.inputWeights = inputWeights; + this.targetInputTradeoff = targetInputTradeoff; + } + + public double getMeritOfSplit(DoubleVector[] preSplitTargetDist, DoubleVector[][] postSplitTargetDists, DoubleVector[] preSplitInputDist, DoubleVector[][] postSplitInputDists) { + double targetError = 0; + double inputError = 0; + int numTargets=preSplitTargetDist.length; + int numInputs=preSplitInputDist.length; + for (int i=0; i= 0.05*preSplitDist.getValue(0)) + count = count +1; + //Consider split if all branches have required weight seen + if(count == postSplitDists.length){ + double varPreSplit=computeVariance(preSplitDist); + double sumVarPostSplit=0; + double weightTotal=0; + for (int i=0; i0) + sumVarPostSplit+=(postSplitDists[i].getValue(0)/weightTotal*variances[i]); //weight variance + merit= 1 - sumVarPostSplit / varPreSplit; + } + /*if(merit<0 || merit>1) + System.out.println("out of range");*/ + return merit; + } + + +// private double computeVariance(double n, double sum, double squares) { +// if (n > 1) { +// return (squares - sum * sum / n) / (n - 1); +// } +// return 0; +// } + +// private double computeVariance(DoubleVector v) { +// return computeVariance(v.getValue(0), v.getValue(1), v.getValue(2)); +// } + + public double getMeritOfSplit(DoubleVector[] preSplitTargetDist, DoubleVector[] preSplitInputDist, DoubleVector[][] postSplitTargetDists, DoubleVector[][] postSplitInputDists) { + double error=0; + int numOutputs=preSplitTargetDist.length; + for (int i=0; i 0) { + Instance weightedInst = (Instance) inst.copy(); + weightedInst.setWeight(inst.weight() * k); + this.ensemble[i].trainOnInstance(weightedInst); + } // get prediction - double prediction[] = this.ensemble[i].getVotesForInstance(inst); - if (prediction == null) { - prediction = new double[]{}; + Prediction P = this.ensemble[i].getPredictionForInstance(inst); + if (P == null) { + continue; // TODO what to do here? } - // get true value - double actual[] = new double[prediction.length]; - for (int j = 0; j < prediction.length; j++) { - actual[j] = (double)inst.classValue(j); + // get true value and prediction arrays + double actual[] = new double[inst.numOutputAttributes()]; + double prediction[] = new double[inst.numOutputAttributes()]; + for (int j = 0; j < inst.numOutputAttributes(); j++) { + actual[j] = (double)inst.valueOutputAttribute(j); + prediction[j] = P.getVote(j, 1); } // compute loss - double loss = Metrics.L_ZeroOne(A.toIntArray(actual,0.5), A.toIntArray(prediction,0.5)); + //double loss = Metrics.L_ZeroOne(A.toIntArray(actual,0.5), A.toIntArray(prediction,0.5)); //System.err.println("loss["+i+"] = "+loss); + int p_sum = 0, r_sum = 0; + int set_union = 0; + int set_inter = 0; + double t = 0.01; + for(int j = 0; j < prediction.length; j++) { + int p = (prediction[j] >= t) ? 1 : 0; + int R = (int) actual[j]; + if (p==1) { + p_sum++; + // predt 1, real 1 + if(R==1) { + set_inter++; + set_union++; + } + // predt 1, real 0 + else { + set_union++; + } + } + else { + // predt 0, real 1 + if(R==1) { + set_union++; + } + // predt 0, real 0 + else { + } + } + } + double accuracy = 0.0; + if(set_union > 0) //avoid NaN + accuracy = ((double)set_inter / (double)set_union); + // adwin stuff double ErrEstim = this.ADError[i].getEstimation(); - if (this.ADError[i].setInput(loss)) { + + if (this.ADError[i].setInput(1-accuracy)) { if (this.ADError[i].getEstimation() > ErrEstim) { - System.err.println("Change model "+i+"!"); - this.ensemble[i].resetLearning(); - this.ensemble[i].trainOnInstance(inst); - this.ADError[i] = new ADWIN(); + Change = true; } } } + + if (Change) { + double max=0.0; int imax=-1; + for (int i = 0; i < this.ensemble.length; i++) { + if (max(); @@ -293,24 +291,21 @@ public void processInstanceOptionNode(StructuredInstance inst, OptionNode node, // } // } + double[][] childPredictions = new double[node.numChildren()][]; for (Node child : node.children) { int i = node.getChildIndex(child); - double[] childPrediction = child.getPrediction(inst); + childPredictions[i] = child.getPrediction(inst); for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { node.optionFFSeen.get(i).setValue(j, node.optionFFSeen.get(i).getValue(j) * optionFadingFactorOption.getValue() + 1); - node.optionFFSSL.get(i).setValue(j, node.optionFFSSL.get(i).getValue(j) * optionFadingFactorOption.getValue() + Math.pow(childPrediction[j] - inst.valueOutputAttribute(j), 2)); + node.optionFFSSL.get(i).setValue(j, node.optionFFSSL.get(i).getValue(j) * optionFadingFactorOption.getValue() + (childPredictions[i][j] - inst.valueOutputAttribute(j)) * (childPredictions[i][j] - inst.valueOutputAttribute(j))); } - } - - for (Node child : node.children) { - processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); + processInstance(inst, child, childPredictions[node.getChildIndex(child)], normalError, growthAllowed && node.alternateTree == null, inAlternate); } } //endregion ================ METHODS ================ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) { - //System.out.println("Evaluating splits"); //System.out.println(examplesSeen); // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. MultiLabelSplitCriterion splitCriterion = new WeightedICVarianceReduction(targetWeights); @@ -364,28 +359,30 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) numSplits = 1; acceptedSplits.add(bestSuggestion); } - else { - // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - // TODO pruning is currently disabled - for (int i = 0; i < node.attributeObservers.size(); i++) { - AttributeStatisticsObserver obs = node.attributeObservers.get(i); - if (obs != null) { - if (getModelContext().attribute(i).isNumeric()); - //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); - if (getModelContext().attribute(i).isNominal()); - // TODO nominal class observers - } - } - } +// else { +// // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer +// // TODO pruning is currently disabled +//// for (int i = 0; i < node.attributeObservers.size(); i++) { +//// AttributeStatisticsObserver obs = node.attributeObservers.get(i); +//// if (obs != null) { +//// if (getModelContext().attribute(i).isNumeric()); +//// //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); +//// if (getModelContext().attribute(i).isNominal()); +//// // TODO nominal class observers +//// } +//// } +// } } + //System.out.println("Found " + numSplits + " candidates."); + // If the splitting criterion were met, split the current node using the chosen attribute test, and // make two new branches leading to (empty) leaves if (numSplits > 0) { double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); - if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { + if (numSplits == 1) { AttributeExpansionSuggestion splitDecision = acceptedSplits.get(0); SplitNode newSplit = newSplitNode(splitDecision.getPredicate()); newSplit.ID = node.ID; @@ -406,7 +403,7 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) parent.setChild(parentIndex, newSplit); newSplit.setParent(parent); } - } else { + } else if (optionFactor >= 2.0 || maxTreesOption.getValue() - numTrees > 1) { OptionNode optionNode = newOptionNode(); optionNode.ID = node.ID; @@ -415,7 +412,7 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) int j = 0; for (AttributeExpansionSuggestion splitDecision : acceptedSplits) { - if (j > optionFactor || maxTreesOption.getValue() - numTrees <= 0) { + if (j > optionFactor || maxTreesOption.getValue() - numTrees <= 0 || j > 4) { break; } SplitNode newSplit = newSplitNode(splitDecision.getPredicate()); @@ -447,6 +444,7 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) optionNode.resetFF(); } } + //System.out.println("Splits finished..."); } // region --- Option tree methods @@ -522,4 +520,4 @@ protected void removeExcessTrees() { } } -} +} \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index b7d54bb4a..b271de183 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -41,20 +41,21 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelBSTree; +import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelBSTreePCT; import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelNominalAttributeObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.multilabel.core.splitcriteria.PCTWeightedICVarianceReduction; import moa.classifiers.multilabel.core.splitcriteria.WeightedICVarianceReduction; import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.Predicate; @@ -71,7 +72,7 @@ * @version $Revision: 1 $ */ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetRegressor { - + private static final long serialVersionUID = 1L; public Node treeRoot; @@ -83,10 +84,13 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR private DoubleVector sumOfAttrValues = new DoubleVector(); private DoubleVector sumOfAttrSquares = new DoubleVector(); + private int numInputAttributes; + private int numOutputAttributes; + public int maxID = 0; - + private BufferedWriter writer; - + public DoubleVector targetWeights; //region ================ OPTIONS ================ @@ -161,16 +165,17 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR 'o', "Keep learning rate constant instead of decaying (if kept constant learning ratio is suggested to be 0.001)."); + public FlagOption runAsPCTOption = new FlagOption( + "runAsPCT", + 'p', + "Run as a predictive clustering tree, i.e., use input attributes in heuristic calculation."); + + public FlagOption doNotNormalizeOption = new FlagOption( "doNotNormalize", 'n', "Don't normalize."); - public FlagOption randomForestBaseModelOption = new FlagOption( - "randomForestBaseModel", - 'z', - "Use the learner as a base model in a random forest."); - public FileOption weightFile = new FileOption("targetWeightFile", 'w', "File with the weights of the targets.", null, null, false); //endregion ================ OPTIONS ================ @@ -193,7 +198,6 @@ public abstract static class Node extends AbstractMOAObject { protected Node alternateTree; protected Node originalNode; - protected AutoExpandVector attributeObservers = new AutoExpandVector(); // The error values for the Page Hinckley test // PHmT = the cumulative sum of the errors @@ -208,6 +212,12 @@ public abstract static class Node extends AbstractMOAObject { // Sum of squared y values protected DoubleVector sumOfSquares = new DoubleVector(); + // Sum of y values + protected DoubleVector sumOfInputValues; + // Sum of squared y values + protected DoubleVector sumOfInputSquares; + + public Node(ISOUPTree tree) { this.tree = tree; this.ID = tree.maxID; @@ -217,10 +227,18 @@ public void copyStatistics(Node node) { examplesSeen = node.examplesSeen; sumOfValues = (DoubleVector) node.sumOfValues.copy(); sumOfSquares = (DoubleVector) node.sumOfSquares.copy(); + if (tree.runAsPCTOption.isSet()) { + sumOfInputValues = (DoubleVector) node.sumOfInputValues.copy(); + sumOfInputSquares = (DoubleVector) node.sumOfInputSquares.copy(); + } } - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); + public long calcByteSize() { + long size = SizeOf.sizeOf(this) + SizeOf.sizeOf(sumOfSquares) + SizeOf.sizeOf(sumOfValues); + if (tree.runAsPCTOption.isSet()) { + size += SizeOf.sizeOf(sumOfInputSquares) + SizeOf.sizeOf(sumOfInputValues); + } + return size; } /** @@ -250,7 +268,7 @@ public void getDescription(StringBuilder sb, int i) {} public double[] getPrediction(StructuredInstance inst) { return null; } - + public void describeSubtree(StringBuilder out, int indent) { StringUtils.appendIndented(out, indent, "Leaf"); } @@ -298,11 +316,13 @@ public static class LeafNode extends Node { public DoubleVector errorP = new DoubleVector(); public DoubleVector errorM = new DoubleVector(); - + public List inputIndexes = null; protected double examplesSeenAtLastSplitEvaluation = 0; + protected AutoExpandVector attributeObservers = new AutoExpandVector(); + /** * Create a new LeafNode */ @@ -315,28 +335,28 @@ public LeafNode(ISOUPTree tree) { examplesSeen = 0; sumOfValues = new DoubleVector(); sumOfSquares = new DoubleVector(); + if (tree.runAsPCTOption.isSet()) { + sumOfInputValues = new DoubleVector(); + sumOfInputSquares = new DoubleVector(); + } } - public void initializeInputIndexes() { - List indexes = new Vector(); - int numAttrs = tree.getModelContext().numInputAttributes(); - for (int i = 0; i < numAttrs; i++) { - indexes.add(i, i); - } - if (tree.buildingRandomForestTree()) { - // Select the first sqrt(n) attribute indexes - for (int i = 0; i < Math.ceil(Math.sqrt(numAttrs)); i++) { - int swap = i + tree.classifierRandom.nextInt(numAttrs - i); - int temp = indexes.get(i); - indexes.set(i, indexes.get(swap)); - indexes.set(swap, temp); - } - inputIndexes = indexes.subList(0, (int) Math.ceil(Math.sqrt(numAttrs))); - } else { - inputIndexes = indexes; + public long calcByteSize() { + long size = super.calcByteSize(); + if (tree.buildingModelTree()) { + size += learningModel.calcByteSize(); + size += SizeOf.sizeOf(errorP); + size += SizeOf.sizeOf(errorM); } + size += SizeOf.sizeOf(inputIndexes); + size += SizeOf.fullSizeOf(attributeObservers); + return size; + } + + public void initializeInputIndexes() { + this.inputIndexes = tree.newInputIndexes(); } - + /** * Method to learn from an instance that passes the new instance to the perceptron learner, * and also prevents the class value from being truncated to an int when it is passed to the @@ -344,28 +364,75 @@ public void initializeInputIndexes() { */ public void learnFromInstance(StructuredInstance inst, double[] prediction, boolean growthAllowed) { // Update the statistics for this node + double weight = inst.weight(); double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; double[] predictionM = getPredictionTargetMean(inst); // number of instances passing through the node - examplesSeen += inst.weight(); + examplesSeen += weight; + + for (int i = 0; i < tree.numOutputAttributes; i++) { + if (!inst.isOutputMissing(i)) { + double outVal = inst.valueOutputAttribute(i); + // sum of y values + sumOfValues.addToValue(i, weight * outVal); + + // sum of squared y values + sumOfSquares.addToValue(i, weight * outVal * outVal); + + if (tree.buildingModelTree()) { + errorP.setValue(i, errorP.getValue(i) * 0.95 + Math.abs(predictionP[i] - outVal)); + errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - outVal)); + } + } + } - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { - // sum of y values - sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); + if (tree.runAsPCTOption.isSet()) { + for (int i = 0; i < tree.numInputAttributes; i++) { + if (!inst.isInputMissing(i)) { + double inVal = inst.valueInputAttribute(i); - // sum of squared y values - sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); + // sum of attr values + sumOfInputValues.addToValue(i, weight * inVal); - if (tree.buildingModelTree()) { - errorP.setValue(i, errorP.getValue(i) * 0.95 + Math.abs(predictionP[i] - inst.valueOutputAttribute(i))); - errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - inst.valueOutputAttribute(i))); + // sum of squared attr values + sumOfInputSquares.addToValue(i, weight * inVal * inVal); + } } } + + if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); + DoubleVector[] observations = new DoubleVector[tree.numOutputAttributes]; + DoubleVector[] inputObservations = null; + + for (int j = 0; j < tree.numOutputAttributes; j++) { + observations[j] = new DoubleVector(); + if (!inst.isOutputMissing(j)) { + double outVal = inst.valueOutputAttribute(j); + observations[j].setValue(0, weight); + observations[j].setValue(1, weight * outVal); + observations[j].setValue(2, weight * outVal * outVal); + } + } + + if (tree.runAsPCTOption.isSet()) { + inputObservations = new DoubleVector[tree.numInputAttributes]; + for (int j = 0; j < tree.numInputAttributes; j++) { + + inputObservations[j] = new DoubleVector(); + if (!inst.isInputMissing(j)) { + double inVal = inst.valueInputAttribute(j); + inputObservations[j].setValue(0, weight); + inputObservations[j].setValue(1, weight * inVal); + inputObservations[j].setValue(2, weight * inVal * inVal); + } + } + } + for (int i : inputIndexes) { AttributeStatisticsObserver obs = attributeObservers.get(i); if (obs == null) { @@ -379,15 +446,12 @@ public void learnFromInstance(StructuredInstance inst, double[] prediction, bool } } - if (obs != null) { - DoubleVector[] observations = new DoubleVector[inst.numOutputAttributes()]; - for (int j = 0; j < inst.numOutputAttributes(); j++) { - observations[j] = new DoubleVector(); - observations[j].setValue(0, inst.weight()); - observations[j].setValue(1, inst.weight() * inst.valueOutputAttribute(j)); - observations[j].setValue(2, inst.weight() * inst.valueOutputAttribute(j) * inst.valueOutputAttribute(j)); + if (obs != null ) { + if (!tree.runAsPCTOption.isSet() || !inst.inputAttribute(i).isNumeric()) { + obs.observeAttribute(inst.valueInputAttribute(i), observations); + } else { + ((MultiLabelBSTreePCT) obs).observeAttribute(inst.valueInputAttribute(i), observations, inputObservations); } - obs.observeAttribute(inst.valueInputAttribute(i), observations); //obs.observeAttributeClassVector(inst.valueInputAttribute(i), getTargetVector(inst), inst.weight()); } @@ -408,16 +472,32 @@ public AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCri for (int i : inputIndexes) { AttributeStatisticsObserver obs = attributeObservers.get(i); if (obs != null) { - DoubleVector[] preSplitStatistics = new DoubleVector[tree.getModelContext().numOutputAttributes()]; - for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + DoubleVector[] preSplitStatistics = new DoubleVector[tree.numOutputAttributes]; + DoubleVector[] preSplitInputStatistics = null; + for (int j = 0; j < tree.numOutputAttributes; j++) { preSplitStatistics[j] = new DoubleVector(); preSplitStatistics[j].setValue(0, examplesSeen); preSplitStatistics[j].setValue(1, sumOfValues.getValue(j)); preSplitStatistics[j].setValue(2, sumOfSquares.getValue(j)); } + + if (tree.runAsPCTOption.isSet() && tree.modelContext.inputAttribute(i).isNumeric()) { + preSplitInputStatistics = new DoubleVector[tree.numInputAttributes]; + for (int j = 0; j < tree.numInputAttributes; j++) { + preSplitInputStatistics[j] = new DoubleVector(); + preSplitInputStatistics[j].setValue(0, examplesSeen); + preSplitInputStatistics[j].setValue(1, sumOfInputValues.getValue(j)); + preSplitInputStatistics[j].setValue(2, sumOfInputSquares.getValue(j)); + } + + } AttributeExpansionSuggestion bestSuggestion = null; - bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, preSplitStatistics, i); + if (tree.runAsPCTOption.isSet() && tree.modelContext.inputAttribute(i).isNumeric()) { + bestSuggestion = ((MultiLabelBSTreePCT) obs).getBestEvaluatedSplitSuggestion(criterion, preSplitStatistics, preSplitInputStatistics, i); + } else { + bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, preSplitStatistics, i); + } if (bestSuggestion != null) { bestSuggestions.add(bestSuggestion); @@ -435,8 +515,8 @@ public double[] getPredictionModel(StructuredInstance inst) { } public double[] getPredictionTargetMean(StructuredInstance inst) { - double[] pred = new double[inst.numOutputAttributes()]; - for (int i = 0; i < inst.numOutputAttributes(); i++) { + double[] pred = new double[tree.numOutputAttributes]; + for (int i = 0; i < tree.numOutputAttributes; i++) { if (examplesSeen > 0) { pred[i] = sumOfValues.getValue(i) / examplesSeen; } else { @@ -483,7 +563,7 @@ public void checkForSplit() { public void describeSubtree(StringBuilder out, int indent) { StringUtils.appendIndented(out, indent, "Leaf"); StringUtils.appendNewline(out); - + if (tree.buildingModelTree()) { learningModel.getModelDescription(out, indent + 2); } else { @@ -519,6 +599,14 @@ public InnerNode(ISOUPTree tree) { super(tree); } + public long calcByteSize() { + long size = super.calcByteSize(); + size += SizeOf.sizeOf(PHsums) + SizeOf.sizeOf(PHmins) + SizeOf.sizeOf(sumOfAbsErrors); + for (Node child : children) + size += child.calcByteSize(); + return size; + } + public int numChildren() { return children.size(); } @@ -547,7 +635,7 @@ public void restartChangeDetection() { changeDetection = true; PHsums = new DoubleVector(); PHmins = new DoubleVector(); - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + for (int i = 0; i < tree.numOutputAttributes; i++) { PHmins.setValue(i, Double.MAX_VALUE); } for (Node child : children) @@ -613,6 +701,10 @@ public SplitNode(Predicate predicate, ISOUPTree tree) { ID = tree.maxID; } + public long calcByteSize() { + return super.calcByteSize() + SizeOf.sizeOf(predicate); + } + public int instanceChildIndex(StructuredInstance inst) { return (predicate.evaluate(inst)) ? 0 : 1; } @@ -649,10 +741,6 @@ public class MultitargetPerceptron { // The number of instances contributing to this model protected int instancesSeen = 0; - public String getPurposeString() { - return "A multi-target perceptron"; - } - public MultitargetPerceptron(ISOUPTree tree, MultitargetPerceptron original) { this.tree = tree; weights = original.weights.clone(); @@ -663,10 +751,19 @@ public MultitargetPerceptron(ISOUPTree tree) { initializeWeights(); } + public long calcByteSize() { + return SizeOf.sizeOf(this); + } + + public String getPurposeString() { + return "A multi-target perceptron"; + } + + public void initializeWeights() { instancesSeen = 0; - int numTargets = tree.getModelContext().numOutputAttributes(); - int numInputs = tree.getModelContext().numInputAttributes(); + int numTargets = tree.numOutputAttributes; + int numInputs = tree.numInputAttributes; weights = new double[numTargets][numInputs+1]; tree.classifierRandom.setSeed(1234); for (int i = 0; i < numTargets; i++) { @@ -706,10 +803,12 @@ public void updateWeights(StructuredInstance inst, double learningRatio) { double[] normalizedPrediction = prediction(normalizedInput); double[] normalizedTarget = tree.normalizedTargetVector(inst); - for (int i = 0; i < inst.numOutputAttributes(); i++){ - double delta = normalizedTarget[i] - normalizedPrediction[i]; - for (int j = 0; j < normalizedInput.length; j++) { - weights[i][j] += delta * learningRatio * normalizedInput[j]; + for (int i = 0; i < tree.numOutputAttributes; i++){ + if (normalizedTarget[i] != Double.NaN) { /* to account for missing target values */ + double delta = normalizedTarget[i] - normalizedPrediction[i]; + for (int j = 0; j < normalizedInput.length; j++) { + weights[i][j] += delta * learningRatio * normalizedInput[j]; + } } } normalizeWeights(); @@ -730,8 +829,8 @@ public void normalizeWeights() { * Output the prediction made by this perceptron on the given instance */ public double[] prediction(double[] instanceValues) { - double[] out = new double[tree.getModelContext().numOutputAttributes()]; - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + double[] out = new double[tree.numOutputAttributes]; + for (int i = 0; i < tree.numOutputAttributes; i++) { out[i] = 0; for (int j = 0; j < instanceValues.length; j++) { out[i] += weights[i][j] * instanceValues[j]; @@ -749,7 +848,7 @@ private double[] prediction(StructuredInstance inst) { private double[] denormalizePrediction(double[] normalizedPrediction) { double[] out = new double[normalizedPrediction.length]; if (tree.normalize()) { - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + for (int i = 0; i < tree.numOutputAttributes; i++) { double mean = tree.sumOfValues.getValue(i) / tree.examplesSeen; double sd = computeSD(tree.sumOfSquares.getValue(i), tree.sumOfValues.getValue(i), tree.examplesSeen); if (examplesSeen > 1) @@ -763,9 +862,9 @@ private double[] denormalizePrediction(double[] normalizedPrediction) { public void getModelDescription(StringBuilder out, int indent) { if (getModelContext() != null) { - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + for (int i = 0; i < tree.numOutputAttributes; i++) { StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "] ="); - for (int j = 0; j < getModelContext().numInputAttributes(); j++) { + for (int j = 0; j < tree.numInputAttributes; j++) { if (getModelContext().inputAttribute(j).isNumeric()) { out.append((j == 0 && weights[i][j] >= 0) ? " " : (weights[i][j] < 0) ? " - " : " + "); out.append(String.format("%.4f", Math.abs(weights[i][j]))); @@ -773,7 +872,7 @@ public void getModelDescription(StringBuilder out, int indent) { out.append(getModelContext().inputAttribute(j).name()); } } - out.append((weights[i][getModelContext().numInputAttributes()] < 0 ? " - " : " + ") + String.format("%.4f", Math.abs(weights[i][getModelContext().numInputAttributes()]))); + out.append((weights[i][tree.numInputAttributes] < 0 ? " - " : " + ") + String.format("%.4f", Math.abs(weights[i][tree.numInputAttributes]))); } StringUtils.appendNewline(out); } @@ -789,6 +888,14 @@ public ISOUPTree() { super(); } + public List newInputIndexes() { + List indexes = new Vector(); + for (int i = 0; i < this.numInputAttributes; i++) { + indexes.add(i, i); + } + return indexes; + } + public String getPurposeString() { return "Implementation of the iSOUP-Tree algorithm as described by Osojnik et al."; } @@ -801,12 +908,16 @@ public void resetLearningImpl() { sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); - + } - + @Override public void modelContextSet() { + assert getModelContext() != null; + this.numInputAttributes = getModelContext().numInputAttributes(); + this.numOutputAttributes = getModelContext().numOutputAttributes(); loadWeights(); + checkRoot(); } public void loadWeights() { @@ -815,10 +926,11 @@ public void loadWeights() { List lines = Files.readAllLines(Paths.get(weightFile.getValue()), Charset.defaultCharset()); for (int i = 0 ; i < lines.size(); i++) targetWeights.setValue(i, Double.valueOf(lines.get(i))); } catch (Exception e) { - for (int i = 0; i < getModelContext().numOutputAttributes(); i++) targetWeights.setValue(i, 1.0); + for (int i = 0; i < this.numOutputAttributes; i++) + targetWeights.setValue(i, 1.0); } } - + public boolean isRandomizable() { return true; } @@ -826,7 +938,7 @@ public boolean isRandomizable() { public void getModelDescription(StringBuilder out, int indent) { if (treeRoot != null) treeRoot.describeSubtree(out, indent); } - + protected Measurement[] getModelMeasurementsImpl() { return new Measurement[]{ //new Measurement("tree size (nodes)", this.leafNodeCount + this.splitNodeCount), @@ -834,19 +946,25 @@ protected Measurement[] getModelMeasurementsImpl() { }; } - public int calcByteSize() { - int size = (int) SizeOf.sizeOf(this); + public long measureByteSize() { + return calcByteSize(); + } + + public long calcByteSize() { + long size = SizeOf.sizeOf(this); if (this.treeRoot != null) { size += this.treeRoot.calcByteSize(); } + size += SizeOf.sizeOf(sumOfValues) + SizeOf.sizeOf(sumOfSquares); + size += SizeOf.sizeOf(sumOfAttrValues) + SizeOf.sizeOf(sumOfAttrSquares); + size += SizeOf.sizeOf(targetWeights); return size; } public Prediction getPredictionForInstance(StructuredInstance inst) { - checkRoot(); double[] predictionVector = treeRoot.getPrediction(inst); - MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); - for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + MultiLabelPrediction prediction = new MultiLabelPrediction(this.numOutputAttributes); + for (int i = 0; i < this.numOutputAttributes; i++) { prediction.setVote(i, 1, predictionVector[i]); } return prediction; @@ -854,9 +972,9 @@ public Prediction getPredictionForInstance(StructuredInstance inst) { public double[] normalizedInputVector(StructuredInstance inst) { // Normalize Instance - double[] normalizedInput = new double[inst.numInputAttributes()+1]; + double[] normalizedInput = new double[this.numInputAttributes+1]; if (normalize()) { - for (int j = 0; j < inst.numInputAttributes(); j++) { + for (int j = 0; j < this.numInputAttributes; j++) { Attribute attr = inst.inputAttribute(j); double value = inst.valueInputAttribute(j); double mean = sumOfAttrValues.getValue(j) / examplesSeen; @@ -870,33 +988,35 @@ public double[] normalizedInputVector(StructuredInstance inst) { normalizedInput[j] = 0; } if (examplesSeen > 1) - normalizedInput[inst.numInputAttributes()] = 1.0; // Value to be multiplied with the constant factor + normalizedInput[this.numInputAttributes] = 1.0; // Value to be multiplied with the constant factor else - normalizedInput[inst.numInputAttributes()] = 0.0; + normalizedInput[this.numInputAttributes] = 0.0; } else { - for (int j = 0; j < inst.numInputAttributes(); j++) { + for (int j = 0; j < this.numInputAttributes; j++) { normalizedInput[j] = inst.valueInputAttribute(j); } - normalizedInput[inst.numInputAttributes()] = 1.0; + normalizedInput[this.numInputAttributes] = 1.0; } return normalizedInput; } public double[] normalizedTargetVector(StructuredInstance inst) { - double[] out = new double[getModelContext().numOutputAttributes()]; + double[] out = new double[this.numOutputAttributes]; if (normalize()) { - for (int i = 0; i < inst.numOutputAttributes(); i++) { - double value = inst.valueOutputAttribute(i); - double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); - double average = sumOfValues.getValue(i) / examplesSeen; - if (sd > 0 && examplesSeen > 1) - out[i] = (value - average) / (sd); - else - out[i] = 0; + for (int i = 0; i < this.numOutputAttributes; i++) { + double value = (inst.isOutputMissing(i)) ? Double.NaN : inst.valueOutputAttribute(i);; + if (value != Double.NaN) { + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); + double average = sumOfValues.getValue(i) / examplesSeen; + if (sd > 0 && examplesSeen > 1) + out[i] = (value - average) / (sd); + else + out[i] = 0; + } else out[i] = value; } } else { - for (int i = 0; i < inst.numOutputAttributes(); i++) { - out[i] = inst.valueOutputAttribute(i); + for (int i = 0; i < this.numOutputAttributes; i++) { + out[i] = (inst.isOutputMissing(i)) ? Double.NaN : inst.valueOutputAttribute(i); } } return out; @@ -951,8 +1071,8 @@ public double normalizeTargetValue(double value, int i) { public double[] getNormalizedError(StructuredInstance inst, double[] prediction) { double[] normalPrediction = normalizeTargetVector(prediction); double[] normalValue = normalizedTargetVector(inst); - double[] out = new double[getModelContext().numOutputAttributes()]; - for (int i = 0; i < inst.numOutputAttributes(); i++) { + double[] out = new double[this.numOutputAttributes]; + for (int i = 0; i < this.numOutputAttributes; i++) { out[i] = Math.abs(normalValue[i] - normalPrediction[i]); } return out; @@ -962,281 +1082,304 @@ public double[] getNormalizedError(StructuredInstance inst, double[] prediction) /** * Method for updating (training) the model using a new instance */ - public void trainOnInstanceImpl(StructuredInstance inst) { - if (inst.weight() > 0) { - checkRoot(); - - double[] prediction = treeRoot.getPrediction(inst); - double[] normalError = getNormalizedError(inst, prediction); - - processInstance(inst, treeRoot, prediction, normalError, true, false); - - examplesSeen += inst.weight(); - for (int i = 0; i < inst.numberOutputTargets(); i++) { - sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); - sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); - } - - for (int i = 0; i < inst.numInputAttributes(); i++) { - sumOfAttrValues.addToValue(i, inst.weight() * inst.valueInputAttribute(i)); - sumOfAttrSquares.addToValue(i, inst.weight() * inst.valueInputAttribute(i) * inst.valueInputAttribute(i)); - } - } - } - - public void processInstance(StructuredInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { - Node currentNode = node; - while (true) { - if (currentNode instanceof LeafNode) { - ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); - break; - } else { - currentNode.examplesSeen += inst.weight(); - //currentNode.sumOfAbsErrors.addValues(normalError); - // SplitNode iNode = (SplitNode) currentNode; - // if (!inAlternate && iNode.alternateTree != null) { - // boolean altTree = true; - // double lossO = Math.pow(inst.valueOutputAttribute() - prediction, 2); - // double lossA = Math.pow(inst.valueOutputAttribute() - iNode.alternateTree.getPrediction(inst), 2); - // - // iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; - // iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; - // iNode.lossExamplesSeen++; - // - // double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - // double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - // iNode.lossSumQi += Qi; - // iNode.lossNumQiTests += 1; - // double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - // - // if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { - // iNode.previousWeight = iNode.lossExamplesSeen; - // if (Qi > 0) { - // SplitNode parent = currentNode.getParent(); - // - // if (parent != null) { - // Node replacementTree = iNode.alternateTree; - // parent.setChild(parent.getChildIndex(currentNode), replacementTree); - // if (growthAllowed) replacementTree.restartChangeDetection(); - // } else { - // treeRoot = iNode.alternateTree; - // treeRoot.restartChangeDetection(); - // } - // - // currentNode = iNode.alternateTree; - // altTree = false; - // } else if ( - // (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) - // || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() - // ) { - // iNode.alternateTree = null; - // if (growthAllowed) iNode.restartChangeDetection(); - // altTree = false; - // } - // } - // - // if (altTree) { - // growthAllowed = false; - // processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); - // } - // } - - // if (iNode.changeDetection && !inAlternate) { - // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { - // iNode.initializeAlternateTree(this); - // } - // } - if (currentNode instanceof SplitNode) { - currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); - } else { // if the replaced alternate tree is just a leaf node - ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); - break; - } - } - } - } - - //region --- Object instatiation methods - - protected NumericStatisticsObserver newNumericClassObserver() { - return new MultiLabelBSTree(); - } - - public NominalStatisticsObserver newNominalClassObserver() { - return new MultiLabelNominalAttributeObserver(); - } - - // protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { - // maxID++; - // return new SplitNode(splitTest, this); - // } - - protected SplitNode newSplitNode(Predicate predicate) { - maxID++; - return new SplitNode(predicate, this); - } - - protected LeafNode newLeafNode() { - maxID++; - return new LeafNode(this); - } - - public MultitargetPerceptron newLeafModel() { - return new MultitargetPerceptron(this); - } - - //endregion --- Object instatiation methods - - //region --- Processing methods - protected void checkRoot() { - if (treeRoot == null) { - treeRoot = newLeafNode(); - } - } - - public static double computeHoeffdingBound(double range, double confidence, double n) { - return Math.sqrt(((range * range) * Math.log(1 / confidence)) / (2.0 * n)); - } - - public boolean buildingModelTree() { - return !regressionTreeOption.isSet(); - } - - public boolean buildingRandomForestTree() { - return randomForestBaseModelOption.isSet(); - } - - public boolean normalize() { - return !doNotNormalizeOption.isSet(); - } - - protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) { - // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - MultiLabelSplitCriterion splitCriterion = new WeightedICVarianceReduction(targetWeights); - - // Using this criterion, find the best split per attribute and rank the results - AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option - Arrays.sort(bestSplitSuggestions); - - // Declare a variable to determine if any of the splits should be performed - boolean shouldSplit = false; - // If only one split was returned, use it - if (bestSplitSuggestions.length < 2) { - shouldSplit = bestSplitSuggestions.length > 0; - } else { // Otherwise, consider which of the splits proposed may be worth trying - - // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); - // Determine the top two ranked splitting suggestions - AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - - // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), - // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this - // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and - // splitting should occur. - // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit - // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two - // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { - shouldSplit = true; - } - // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - else { - // TODO pruning is currently disabled - for (int i = 0; i < node.attributeObservers.size(); i++) { - AttributeStatisticsObserver obs = node.attributeObservers.get(i); - if (obs != null) { - if (getModelContext().attribute(i).isNumeric()); - //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); - if (getModelContext().attribute(i).isNominal()); - // TODO nominal class observers - } - } - } - } - - // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (shouldSplit) { - AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - - SplitNode newSplit = newSplitNode(splitDecision.predicate); - newSplit.ID = node.ID; - newSplit.copyStatistics(node); - newSplit.changeDetection = node.changeDetection; - newSplit.ID = node.ID; - log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); - for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) - LeafNode newChild = newLeafNode(); - if (buildingModelTree()) { - // Copy the splitting node's perceptron to it's children - newChild.learningModel = new MultitargetPerceptron(this, (MultitargetPerceptron) node.learningModel); - - } - newChild.changeDetection = node.changeDetection; - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - } - if (parent == null && node.originalNode == null) { - treeRoot = newSplit; - } else if (parent == null && node.originalNode != null) { - node.originalNode.alternateTree = newSplit; - } else { - parent.setChild(parentIndex, newSplit); - newSplit.setParent(parent); - } - } - } - - public double computeSD(double squaredVal, double val, double size) { - if (size > 1) - return Math.sqrt((squaredVal - ((val * val) / size)) / size); - else - return 0.0; - } - - public static double scalarProduct(DoubleVector u, DoubleVector v) { - double ret = 0.0; - for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { - ret += u.getValue(i) * v.getValue(i); - } - return ret; - } - //endregion --- Processing methods - - public void initWriter(String filename) { - try { - writer = new BufferedWriter(new FileWriter(filename)); - writer.write(""); - writer.close(); - writer = new BufferedWriter(new FileWriter(filename, true)); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void closeWriter() { - try { - writer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - writer = null; - - } - - public void log(String s) { - if (writer != null) { - try { - writer.write(s + "\n"); - writer.flush(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - //endregion ================ METHODS ================ + public void trainOnInstanceImpl(StructuredInstance inst) { + if (inst.weight() > 0) { + + double[] prediction = treeRoot.getPrediction(inst); + double[] normalError = getNormalizedError(inst, prediction); + + processInstance(inst, treeRoot, prediction, normalError, true, false); + + double weight = inst.weight(); + + examplesSeen += weight; + for (int i = 0; i < this.numOutputAttributes; i++) { + double iVal = inst.valueOutputAttribute(i); + sumOfValues.addToValue(i, weight * iVal); + sumOfSquares.addToValue(i, weight * iVal * iVal); + } + + for (int i = 0; i < this.numInputAttributes; i++) { + double iVal = inst.valueInputAttribute(i); + sumOfAttrValues.addToValue(i, weight * iVal); + sumOfAttrSquares.addToValue(i, weight * iVal * iVal); + } + } + } + + public void processInstance(StructuredInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } else { + currentNode.examplesSeen += inst.weight(); + //currentNode.sumOfAbsErrors.addValues(normalError); + // SplitNode iNode = (SplitNode) currentNode; + // if (!inAlternate && iNode.alternateTree != null) { + // boolean altTree = true; + // double lossO = Math.pow(inst.valueOutputAttribute() - prediction, 2); + // double lossA = Math.pow(inst.valueOutputAttribute() - iNode.alternateTree.getPrediction(inst), 2); + // + // iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + // iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + // iNode.lossExamplesSeen++; + // + // double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + // double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // iNode.lossSumQi += Qi; + // iNode.lossNumQiTests += 1; + // double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // + // if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + // iNode.previousWeight = iNode.lossExamplesSeen; + // if (Qi > 0) { + // SplitNode parent = currentNode.getParent(); + // + // if (parent != null) { + // Node replacementTree = iNode.alternateTree; + // parent.setChild(parent.getChildIndex(currentNode), replacementTree); + // if (growthAllowed) replacementTree.restartChangeDetection(); + // } else { + // treeRoot = iNode.alternateTree; + // treeRoot.restartChangeDetection(); + // } + // + // currentNode = iNode.alternateTree; + // altTree = false; + // } else if ( + // (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) + // || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() + // ) { + // iNode.alternateTree = null; + // if (growthAllowed) iNode.restartChangeDetection(); + // altTree = false; + // } + // } + // + // if (altTree) { + // growthAllowed = false; + // processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + // } + // } + + // if (iNode.changeDetection && !inAlternate) { + // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + // iNode.initializeAlternateTree(this); + // } + // } + //if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); + //} else { // if the replaced alternate tree is just a leaf node + // ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + //break; + } + } + } + + //region --- Object instatiation methods + + protected NumericStatisticsObserver newNumericClassObserver() { + try { + //NumericStatisticsObserver o = (NumericStatisticsObserver) ClassOption.cliStringToObject("MultiLabelBSTree -z 2000", MultiLabelBSTree.class, null); + //NumericStatisticsObserver o = (NumericStatisticsObserver) ClassOption.cliStringToObject("MultiLabelBSTree2 -z 2000", MultiLabelBSTree2.class, null); + if (runAsPCTOption.isSet()) { + return new MultiLabelBSTreePCT(); + } else { + return new MultiLabelBSTree(); + } + + } catch (Exception e) { + return null; + } + } + + public NominalStatisticsObserver newNominalClassObserver() { + return new MultiLabelNominalAttributeObserver(); + } + + // protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + // maxID++; + // return new SplitNode(splitTest, this); + // } + + protected SplitNode newSplitNode(Predicate predicate) { + maxID++; + return new SplitNode(predicate, this); + } + + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } + + public MultitargetPerceptron newLeafModel() { + return new MultitargetPerceptron(this); + } + + //endregion --- Object instatiation methods + + //region --- Processing methods + protected void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + } + } + + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(((range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } + + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } + + public boolean normalize() { + return !doNotNormalizeOption.isSet(); + } + + protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) { + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + MultiLabelSplitCriterion splitCriterion = null; + if (!runAsPCTOption.isSet()) { + splitCriterion = new WeightedICVarianceReduction(targetWeights); + } else { + DoubleVector inputWeights = new DoubleVector(); + for (int i = 0; i < numInputAttributes; i++) inputWeights.setValue(i, 1); + splitCriterion = new PCTWeightedICVarianceReduction(targetWeights, new DoubleVector(), 0.5); + } + + // Using this criterion, find the best split per attribute and rank the results + AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine if any of the splits should be performed + boolean shouldSplit = false; + // If only one split was returned, use it + if (bestSplitSuggestions.length < 2) { + shouldSplit = bestSplitSuggestions.length > 0; + } else { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { + shouldSplit = true; + } + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + else { + // TODO pruning is currently disabled + for (int i = 0; i < node.attributeObservers.size(); i++) { + AttributeStatisticsObserver obs = node.attributeObservers.get(i); + if (obs != null) { + if (getModelContext().attribute(i).isNumeric()); + //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); + if (getModelContext().attribute(i).isNominal()); + // TODO nominal class observers + } + } + } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + // try { + // Thread.sleep(20000); + // } catch (InterruptedException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + + if (shouldSplit) { + AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + + SplitNode newSplit = newSplitNode(splitDecision.predicate); + newSplit.ID = node.ID; + newSplit.copyStatistics(node); + newSplit.changeDetection = node.changeDetection; + newSplit.ID = node.ID; + log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); + for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) + LeafNode newChild = newLeafNode(); + if (buildingModelTree()) { + // Copy the splitting node's perceptron to it's children + newChild.learningModel = new MultitargetPerceptron(this, node.learningModel); + + } + newChild.changeDetection = node.changeDetection; + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + parent.setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + } + } + + public double computeSD(double squaredVal, double val, double size) { + if (size > 1) + return Math.sqrt((squaredVal - ((val * val) / size)) / size); + else + return 0.0; + } + + public static double scalarProduct(DoubleVector u, DoubleVector v) { + double ret = 0.0; + for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { + ret += u.getValue(i) * v.getValue(i); + } + return ret; + } + //endregion --- Processing methods + + public void initWriter(String filename) { + try { + writer = new BufferedWriter(new FileWriter(filename)); + writer.write(""); + writer.close(); + writer = new BufferedWriter(new FileWriter(filename, true)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void closeWriter() { + try { + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + writer = null; + + } + + public void log(String s) { + if (writer != null) { + try { + writer.write(s + "\n"); + writer.flush(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + //endregion ================ METHODS ================ } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTreeRF.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTreeRF.java new file mode 100644 index 000000000..ea8193d91 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTreeRF.java @@ -0,0 +1,46 @@ +package moa.classifiers.multilabel.trees; + +import java.util.List; +import java.util.Vector; + +import com.github.javacliparser.MultiChoiceOption; + +public class ISOUPTreeRF extends ISOUPTree { + + /** + * + */ + private static final long serialVersionUID = 3145263568676115808L; + public MultiChoiceOption radndomForestFunAttrsOption = new MultiChoiceOption( + "randomForestFunAttr", + 'z', + "The function of the number of input attribtues to use in the random forest construction.", + new String[]{"sqrt", "log", "percent"}, new String[]{"Square root", "Logarithm", "10% percent"}, 0); + + + public int numRFAttrs() { + switch (radndomForestFunAttrsOption.getChosenLabel()) { + case "sqrt": return (int) Math.ceil(Math.sqrt(this.getModelContext().numInputAttributes())); + case "log": return (int) Math.ceil(Math.log(this.getModelContext().numInputAttributes())) + 1; + case "percent": return (int) Math.ceil(0.1 * this.getModelContext().numInputAttributes()); + } + return 0; + } + + @Override + public List newInputIndexes() { + List indexes = new Vector(); + int numAttrs = this.getModelContext().numInputAttributes(); + for (int i = 0; i < numAttrs; i++) { + indexes.add(i, i); + } + for (int i = 0; i < Math.ceil(numRFAttrs()); i++) { + int swap = i + this.classifierRandom.nextInt(numAttrs - i); + int temp = indexes.get(i); + indexes.set(i, indexes.get(swap)); + indexes.set(swap, temp); + } + return indexes.subList(0, numRFAttrs()); + } + +} diff --git a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java index edad24332..a7a1a1ac1 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java @@ -1,6 +1,13 @@ package moa.classifiers.multitarget; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.Classifier; @@ -12,14 +19,6 @@ import moa.options.ClassOption; import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.MultiLabelPrediction; -import com.yahoo.labs.samoa.instances.Prediction; - public class BasicMultiTargetRegressor extends AbstractMultiLabelLearner implements MultiTargetRegressor{ diff --git a/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java b/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java index 9f08ed855..cae16376a 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java +++ b/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java @@ -1,14 +1,10 @@ package moa.classifiers.multitarget.functions; -import com.yahoo.labs.samoa.instances.DenseInstanceData; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; -import moa.classifiers.AbstractClassifier; import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; import moa.core.Measurement; diff --git a/moa/src/main/java/moa/classifiers/rules/AMRulesRegressorOld.java b/moa/src/main/java/moa/classifiers/rules/AMRulesRegressorOld.java index 63b1d3f9f..8a8020529 100644 --- a/moa/src/main/java/moa/classifiers/rules/AMRulesRegressorOld.java +++ b/moa/src/main/java/moa/classifiers/rules/AMRulesRegressorOld.java @@ -64,11 +64,10 @@ import com.github.javacliparser.MultiChoiceOption; import moa.classifiers.Regressor; -import moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion; import moa.classifiers.rules.core.Rule; +import moa.classifiers.rules.core.Rule.Builder; import moa.classifiers.rules.core.RuleActiveLearningNode; import moa.classifiers.rules.core.RuleActiveRegressionNode; -import moa.classifiers.rules.core.Rule.Builder; import moa.classifiers.rules.core.splitcriteria.AMRulesSplitCriterion; import moa.classifiers.rules.core.voting.ErrorWeightedVote; import moa.classifiers.rules.functions.Perceptron; diff --git a/moa/src/main/java/moa/classifiers/rules/AbstractAMRules.java b/moa/src/main/java/moa/classifiers/rules/AbstractAMRules.java index ab2555b7a..8f6911d14 100644 --- a/moa/src/main/java/moa/classifiers/rules/AbstractAMRules.java +++ b/moa/src/main/java/moa/classifiers/rules/AbstractAMRules.java @@ -31,19 +31,19 @@ * **/ +import java.util.Arrays; +import java.util.Iterator; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import java.util.Arrays; -import java.util.Iterator; - import moa.classifiers.AbstractClassifier; import moa.classifiers.rules.core.Rule; +import moa.classifiers.rules.core.Rule.Builder; import moa.classifiers.rules.core.RuleActiveLearningNode; import moa.classifiers.rules.core.RuleSet; -import moa.classifiers.rules.core.Rule.Builder; import moa.classifiers.rules.core.attributeclassobservers.FIMTDDNumericAttributeClassLimitObserver; import moa.classifiers.rules.core.voting.ErrorWeightedVote; import moa.classifiers.rules.core.voting.Vote; diff --git a/moa/src/main/java/moa/classifiers/rules/Predicates.java b/moa/src/main/java/moa/classifiers/rules/Predicates.java index 76b96f084..db1583359 100644 --- a/moa/src/main/java/moa/classifiers/rules/Predicates.java +++ b/moa/src/main/java/moa/classifiers/rules/Predicates.java @@ -21,6 +21,8 @@ package moa.classifiers.rules; +import com.yahoo.labs.samoa.instances.Instance; + /** * Class that creates and evaluates the predicates * @@ -32,7 +34,6 @@ */ import moa.AbstractMOAObject; -import com.yahoo.labs.samoa.instances.Instance; public class Predicates extends AbstractMOAObject{ diff --git a/moa/src/main/java/moa/classifiers/rules/RuleClassification.java b/moa/src/main/java/moa/classifiers/rules/RuleClassification.java index c7b9866e4..3d6fdcda9 100644 --- a/moa/src/main/java/moa/classifiers/rules/RuleClassification.java +++ b/moa/src/main/java/moa/classifiers/rules/RuleClassification.java @@ -33,11 +33,13 @@ */ import java.util.ArrayList; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.AbstractMOAObject; -import moa.classifiers.core.attributeclassobservers.*; +import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.core.AutoExpandVector; import moa.core.DoubleVector; -import com.yahoo.labs.samoa.instances.Instance; public class RuleClassification extends AbstractMOAObject{ diff --git a/moa/src/main/java/moa/classifiers/rules/RuleClassifier.java b/moa/src/main/java/moa/classifiers/rules/RuleClassifier.java index 0e8dbd6e3..6d4f860d6 100644 --- a/moa/src/main/java/moa/classifiers/rules/RuleClassifier.java +++ b/moa/src/main/java/moa/classifiers/rules/RuleClassifier.java @@ -25,21 +25,26 @@ import java.io.IOException; import java.io.PrintWriter; import java.math.BigDecimal; -import java.util.*; -import com.github.javacliparser.FlagOption; +import java.util.ArrayList; +import java.util.Collections; +import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; -import moa.classifiers.core.attributeclassobservers.*; +import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; +import moa.classifiers.core.attributeclassobservers.BinaryTreeNumericAttributeClassObserver; import moa.classifiers.core.attributeclassobservers.BinaryTreeNumericAttributeClassObserver.Node; +import moa.classifiers.core.attributeclassobservers.GaussianNumericAttributeClassObserver; +import moa.classifiers.core.attributeclassobservers.NominalAttributeClassObserver; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.StringUtils; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/classifiers/rules/RuleClassifierNBayes.java b/moa/src/main/java/moa/classifiers/rules/RuleClassifierNBayes.java index 6a23e9f06..d495592f3 100644 --- a/moa/src/main/java/moa/classifiers/rules/RuleClassifierNBayes.java +++ b/moa/src/main/java/moa/classifiers/rules/RuleClassifierNBayes.java @@ -22,10 +22,12 @@ import java.util.ArrayList; import java.util.Collections; + import com.github.javacliparser.IntOption; -import moa.classifiers.bayes.NaiveBayes; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.bayes.NaiveBayes; + /** * This classifier learn ordered and unordered rule set from data stream with naive Bayes learners. *

This algorithm also does the detection of anomalies. diff --git a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java index 7e5febe56..fb5505ef7 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java @@ -2,7 +2,6 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java index a6b313c12..8387610c0 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java @@ -2,7 +2,6 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/core/Rule.java b/moa/src/main/java/moa/classifiers/rules/core/Rule.java index c12befcb2..4cea1b6dc 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/Rule.java +++ b/moa/src/main/java/moa/classifiers/rules/core/Rule.java @@ -19,6 +19,10 @@ */ package moa.classifiers.rules.core; +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; + /** * Class that stores an arrayList of predicates of a rule and the observers * (statistics). This class implements a function that evaluates a rule. @@ -36,10 +40,6 @@ import com.github.javacliparser.FloatOption; import com.yahoo.labs.samoa.instances.Instance; -import java.io.Serializable; -import java.util.LinkedList; -import java.util.List; - import moa.AbstractMOAObject; import moa.classifiers.core.conditionaltests.InstanceConditionalTest; import moa.classifiers.core.conditionaltests.NumericAttributeBinaryTest; diff --git a/moa/src/main/java/moa/classifiers/rules/core/RuleActiveLearningNode.java b/moa/src/main/java/moa/classifiers/rules/core/RuleActiveLearningNode.java index 1613a7049..1eaff66bd 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/RuleActiveLearningNode.java +++ b/moa/src/main/java/moa/classifiers/rules/core/RuleActiveLearningNode.java @@ -24,8 +24,8 @@ import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.rules.AbstractAMRules; -import moa.classifiers.rules.driftdetection.PageHinkleyTest; import moa.classifiers.rules.driftdetection.PageHinkleyFading; +import moa.classifiers.rules.driftdetection.PageHinkleyTest; import moa.classifiers.trees.HoeffdingTree; import moa.classifiers.trees.HoeffdingTree.ActiveLearningNode; import moa.core.AutoExpandVector; diff --git a/moa/src/main/java/moa/classifiers/rules/core/RuleActiveRegressionNode.java b/moa/src/main/java/moa/classifiers/rules/core/RuleActiveRegressionNode.java index 1eebdfad7..0f39b9f91 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/RuleActiveRegressionNode.java +++ b/moa/src/main/java/moa/classifiers/rules/core/RuleActiveRegressionNode.java @@ -20,28 +20,20 @@ package moa.classifiers.rules.core; -import com.yahoo.labs.samoa.instances.Instance; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.sql.PreparedStatement; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.classifiers.rules.AMRulesRegressorOld; -import moa.classifiers.rules.AbstractAMRules; import moa.classifiers.rules.core.splitcriteria.AMRulesSplitCriterion; -import moa.classifiers.rules.core.splitcriteria.SDRSplitCriterionAMRules; import moa.classifiers.rules.functions.Perceptron; import moa.classifiers.rules.functions.TargetMean; import moa.core.DoubleVector; diff --git a/moa/src/main/java/moa/classifiers/rules/core/Utils.java b/moa/src/main/java/moa/classifiers/rules/core/Utils.java index 1c60f8dfb..5340ea695 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/Utils.java +++ b/moa/src/main/java/moa/classifiers/rules/core/Utils.java @@ -14,6 +14,11 @@ public static double computeVariance(DoubleVector statistics) return computeVariance(statistics.getValue(0),statistics.getValue(1),statistics.getValue(2)); } + public static double computeVariance(double[] statistics) + { + return computeVariance(statistics[0],statistics[1],statistics[2]); + } + public static double computeSD(double squaredSum, double sum, double weightSeen) { if (weightSeen > 1) { return Math.sqrt((squaredSum - ((sum * sum) / weightSeen)) / (weightSeen - 1.0)); diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java index 13a4f85ba..5d91180e4 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java @@ -1,8 +1,9 @@ package moa.classifiers.rules.core.anomalydetection; -import moa.options.AbstractOptionHandler; import com.yahoo.labs.samoa.instances.StructuredInstance; +import moa.options.AbstractOptionHandler; + public abstract class AbstractAnomalyDetector extends AbstractOptionHandler implements AnomalyDetector { diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java index 9297ebe1e..a6a3bdae6 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java @@ -1,18 +1,16 @@ package moa.classifiers.rules.core.anomalydetection; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.rules.core.Utils; import moa.classifiers.rules.core.anomalydetection.probabilityfunctions.ProbabilityFunction; -import moa.classifiers.rules.core.attributeclassobservers.FIMTDDNumericAttributeClassLimitObserver; import moa.core.AutoExpandVector; import moa.core.ObjectRepository; import moa.options.ClassOption; import moa.tasks.TaskMonitor; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; - public class AnomalinessRatioScore extends AbstractAnomalyDetector { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java index 722f15dfa..6ad69595a 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java @@ -1,8 +1,9 @@ package moa.classifiers.rules.core.anomalydetection; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.core.ObjectRepository; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.StructuredInstance; public class NoAnomalyDetection extends AbstractAnomalyDetector{ diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java index 53cc8556c..ee841f6f2 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java @@ -1,5 +1,10 @@ package moa.classifiers.rules.core.anomalydetection; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.rules.core.Utils; import moa.classifiers.rules.core.anomalydetection.probabilityfunctions.CantellisInequality; import moa.classifiers.rules.core.anomalydetection.probabilityfunctions.ProbabilityFunction; @@ -8,11 +13,6 @@ import moa.options.ClassOption; import moa.tasks.TaskMonitor; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; - public class OddsRatioScore extends AbstractAnomalyDetector { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/CantellisInequality.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/CantellisInequality.java index c021dad34..63aad5315 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/CantellisInequality.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/CantellisInequality.java @@ -2,11 +2,8 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import moa.options.OptionHandler; import moa.tasks.TaskMonitor; -import com.github.javacliparser.Options; - public class CantellisInequality extends AbstractOptionHandler implements ProbabilityFunction { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/ChebyshevInequality.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/ChebyshevInequality.java index 52d897aa1..f32fb6243 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/ChebyshevInequality.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/ChebyshevInequality.java @@ -2,11 +2,8 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import moa.options.OptionHandler; import moa.tasks.TaskMonitor; -import com.github.javacliparser.Options; - public class ChebyshevInequality extends AbstractOptionHandler implements ProbabilityFunction { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/GaussInequality.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/GaussInequality.java index aa73a67a5..ea587e6dd 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/GaussInequality.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/GaussInequality.java @@ -2,11 +2,8 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import moa.options.OptionHandler; import moa.tasks.TaskMonitor; -import com.github.javacliparser.Options; - public class GaussInequality extends AbstractOptionHandler implements ProbabilityFunction { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java b/moa/src/main/java/moa/classifiers/rules/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java index de93184cf..83740c403 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java +++ b/moa/src/main/java/moa/classifiers/rules/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java @@ -20,6 +20,7 @@ package moa.classifiers.rules.core.attributeclassobservers; import com.github.javacliparser.IntOption; + import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; @@ -99,9 +100,6 @@ else if (val < this.cut_point) { // right (>) distribution and send the value down to the right child node. // If no right child exists, create one else { // val > cut_point - this.rightStatistics.addToValue(0,1); - this.rightStatistics.addToValue(1,label); - this.rightStatistics.addToValue(2,label*label); if (this.right == null) { if(numNodes>{ public double getCurrentError(); diff --git a/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java b/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java index a5e48b1a8..d8d6bdd81 100644 --- a/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java +++ b/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java @@ -25,10 +25,8 @@ import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.classifiers.AbstractClassifier; -import moa.classifiers.Regressor; import moa.core.DoubleVector; import moa.core.Measurement; diff --git a/moa/src/main/java/moa/classifiers/rules/functions/TargetMean.java b/moa/src/main/java/moa/classifiers/rules/functions/TargetMean.java index 53f8c63c1..fcb7e6f8d 100644 --- a/moa/src/main/java/moa/classifiers/rules/functions/TargetMean.java +++ b/moa/src/main/java/moa/classifiers/rules/functions/TargetMean.java @@ -26,8 +26,8 @@ * */ import com.github.javacliparser.FloatOption; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; -import moa.classifiers.Regressor; import moa.core.Measurement; import moa.core.StringUtils; diff --git a/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java b/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java index 8828c1d84..5037efd76 100644 --- a/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java +++ b/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java @@ -21,13 +21,10 @@ import java.util.Arrays; -import moa.options.ClassOption; - import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; @@ -38,11 +35,9 @@ import moa.classifiers.rules.AbstractAMRules; import moa.classifiers.rules.core.voting.ErrorWeightedVote; import moa.classifiers.rules.core.voting.Vote; -import moa.core.DoubleVector; -import moa.core.FastVector; import moa.core.Measurement; import moa.core.MiscUtils; -import moa.streams.InstanceStream; +import moa.options.ClassOption; public class RandomAMRulesOld extends AbstractClassifier implements Regressor { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java index 44a24ae5f..0ad8c1ec2 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java @@ -33,6 +33,12 @@ import java.util.Iterator; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiLabelLearner; import moa.classifiers.core.driftdetection.ChangeDetector; @@ -44,7 +50,6 @@ import moa.classifiers.rules.multilabel.core.MultiLabelRule; import moa.classifiers.rules.multilabel.core.MultiLabelRuleSet; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; -import moa.classifiers.rules.multilabel.core.voting.MultiLabelVote; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; import moa.classifiers.rules.multilabel.outputselectors.SelectAllOutputs; @@ -52,12 +57,6 @@ import moa.core.StringUtils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - public abstract class AMRulesMultiLabelLearner extends AbstractMultiLabelLearner implements MultiLabelLearner{ diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java index 146a6be85..461c63925 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java @@ -2,12 +2,10 @@ import moa.classifiers.MultiLabelLearner; import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.Regressor; import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.core.MultiLabelRule; import moa.classifiers.rules.multilabel.core.MultiLabelRuleRegression; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; -import moa.classifiers.rules.multilabel.core.voting.InverseErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java index 9c179d2f6..a8bafb4a1 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java @@ -7,15 +7,10 @@ import java.util.Random; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.classifiers.MultiLabelLearner; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.NumericAttributeClassObserver; import moa.classifiers.core.driftdetection.ChangeDetector; import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; @@ -23,13 +18,11 @@ import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; -import moa.classifiers.rules.multilabel.errormeasurers.AbstractMultiTargetErrorMeasurer; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.options.AbstractOptionHandler; -import moa.options.ClassOption; public abstract class LearningLiteral extends AbstractOptionHandler { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java index f9e2c5c82..282ca1dba 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java @@ -1,20 +1,14 @@ package moa.classifiers.rules.multilabel.core; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.MultiLabelLearner; -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.driftdetection.ChangeDetector; -import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; @@ -25,7 +19,6 @@ import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.ObjectRepository; -import moa.learners.Learner; import moa.tasks.TaskMonitor; public class LearningLiteralRegression extends LearningLiteral { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java index 0fb2aba8b..23e58b418 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java @@ -5,22 +5,16 @@ import java.util.List; import java.util.Random; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; import moa.classifiers.MultiLabelLearner; -import moa.classifiers.core.attributeclassobservers.NumericAttributeClassObserver; -import moa.classifiers.core.conditionaltests.InstanceConditionalTest; -import moa.classifiers.core.conditionaltests.NumericAttributeBinaryTest; import moa.classifiers.core.driftdetection.ChangeDetector; import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; -import moa.classifiers.rules.core.RuleActiveLearningNode; -import moa.classifiers.rules.core.RuleSplitNode; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; -import moa.classifiers.rules.core.conditionaltests.NumericAttributeBinaryRulePredicate; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; import moa.core.StringUtils; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/AbstractErrorWeightedVoteMultiLabel.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/AbstractErrorWeightedVoteMultiLabel.java index 8572a8b5a..59cada880 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/AbstractErrorWeightedVoteMultiLabel.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/AbstractErrorWeightedVoteMultiLabel.java @@ -26,7 +26,6 @@ import com.yahoo.labs.samoa.instances.Prediction; import moa.AbstractMOAObject; -import moa.core.DoubleVector; /** * AbstractErrorWeightedVote class for weighted votes based on estimates of errors. diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/ErrorWeightedVoteMultiLabel.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/ErrorWeightedVoteMultiLabel.java index 5bdb2530e..22d49cc75 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/ErrorWeightedVoteMultiLabel.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/ErrorWeightedVoteMultiLabel.java @@ -20,8 +20,6 @@ package moa.classifiers.rules.multilabel.core.voting; -import java.util.List; - import com.yahoo.labs.samoa.instances.Prediction; import moa.MOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java index b96ddd2a7..1d393bf4b 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java @@ -1,13 +1,13 @@ package moa.classifiers.rules.multilabel.errormeasurers; +import com.github.javacliparser.FloatOption; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.tasks.TaskMonitor; -import com.github.javacliparser.FloatOption; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - public abstract class AbstractMultiLabelErrorMeasurer extends AbstractOptionHandler implements MultiTargetErrorMeasurer{ /** diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java index 5b2bc3be8..bb22ff469 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java @@ -1,8 +1,8 @@ package moa.classifiers.rules.multilabel.errormeasurers; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; public abstract class AbstractMultiTargetErrorMeasurer extends AbstractMultiLabelErrorMeasurer implements MultiLabelErrorMeasurer{ diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/MultiLabelErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/MultiLabelErrorMeasurer.java index 66259cfe6..9f280d765 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/MultiLabelErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/MultiLabelErrorMeasurer.java @@ -1,7 +1,7 @@ package moa.classifiers.rules.multilabel.errormeasurers; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.options.OptionHandler; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RootMeanSquaredErrorMT.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RootMeanSquaredErrorMT.java index cab1cab93..08d5d319d 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RootMeanSquaredErrorMT.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RootMeanSquaredErrorMT.java @@ -1,8 +1,5 @@ package moa.classifiers.rules.multilabel.errormeasurers; -import moa.core.ObjectRepository; -import moa.tasks.TaskMonitor; - import com.yahoo.labs.samoa.instances.Prediction; public class RootMeanSquaredErrorMT extends AbstractMultiTargetErrorMeasurer { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/functions/AdaptiveMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/rules/multilabel/functions/AdaptiveMultiTargetRegressor.java index 1f0adf4b4..7541446ac 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/functions/AdaptiveMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/functions/AdaptiveMultiTargetRegressor.java @@ -1,16 +1,15 @@ package moa.classifiers.rules.multilabel.functions; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; import moa.classifiers.rules.multilabel.errormeasurers.AbstractMultiTargetErrorMeasurer; import moa.classifiers.rules.multilabel.errormeasurers.MultiTargetErrorMeasurer; import moa.core.Measurement; -import moa.learners.Learner; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - public class AdaptiveMultiTargetRegressor extends AbstractMultiLabelLearner implements MultiTargetRegressor, AMRulesFunction { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/functions/MultiLabelTargetMeanRegressor.java b/moa/src/main/java/moa/classifiers/rules/multilabel/functions/MultiLabelTargetMeanRegressor.java index ce744a59f..4a80a690d 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/functions/MultiLabelTargetMeanRegressor.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/functions/MultiLabelTargetMeanRegressor.java @@ -4,7 +4,6 @@ import moa.classifiers.MultiTargetRegressor; import moa.classifiers.multitarget.BasicMultiTargetRegressor; -import moa.classifiers.rules.functions.Perceptron; import moa.classifiers.rules.functions.TargetMean; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/meta/MultiLabelRandomAMRules.java b/moa/src/main/java/moa/classifiers/rules/multilabel/meta/MultiLabelRandomAMRules.java index 7c08a3eed..8085c13bb 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/meta/MultiLabelRandomAMRules.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/meta/MultiLabelRandomAMRules.java @@ -1,9 +1,15 @@ package moa.classifiers.rules.multilabel.meta; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.rules.AbstractAMRules; -import moa.classifiers.rules.core.voting.ErrorWeightedVote; import moa.classifiers.rules.multilabel.AMRulesMultiLabelLearner; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.core.voting.UniformWeightedVoteMultiLabel; @@ -13,14 +19,6 @@ import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - public class MultiLabelRandomAMRules extends AbstractMultiLabelLearner implements MultiTargetRegressor { diff --git a/moa/src/main/java/moa/classifiers/trees/AdaHoeffdingOptionTree.java b/moa/src/main/java/moa/classifiers/trees/AdaHoeffdingOptionTree.java index 6e6db6109..2cefc4f0e 100644 --- a/moa/src/main/java/moa/classifiers/trees/AdaHoeffdingOptionTree.java +++ b/moa/src/main/java/moa/classifiers/trees/AdaHoeffdingOptionTree.java @@ -19,9 +19,10 @@ */ package moa.classifiers.trees; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.bayes.NaiveBayes; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; /** * Adaptive decision option tree for streaming data with adaptive Naive diff --git a/moa/src/main/java/moa/classifiers/trees/DecisionStump.java b/moa/src/main/java/moa/classifiers/trees/DecisionStump.java index 10f4e0fa0..705c73348 100644 --- a/moa/src/main/java/moa/classifiers/trees/DecisionStump.java +++ b/moa/src/main/java/moa/classifiers/trees/DecisionStump.java @@ -21,6 +21,8 @@ import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; @@ -31,7 +33,6 @@ import moa.core.DoubleVector; import moa.core.Measurement; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Decision trees of one level.
diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java index f986c3d60..8962cd12c 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java @@ -25,24 +25,24 @@ import java.util.LinkedList; import java.util.List; -import com.yahoo.labs.samoa.instances.Instance; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; -import moa.options.ClassOption; import moa.AbstractMOAObject; +import moa.classifiers.AbstractClassifier; import moa.classifiers.Regressor; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.conditionaltests.InstanceConditionalTest; import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.classifiers.AbstractClassifier; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.SizeOf; import moa.core.StringUtils; +import moa.options.ClassOption; /* * Implementation of FIMTDD, regression and model trees for data streams. @@ -159,8 +159,8 @@ public void copyStatistics(Node node) { sumOfAbsErrors = node.sumOfAbsErrors; } - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); + public long calcByteSize() { + return SizeOf.sizeOf(this) + (originalNode == null && alternateTree != null ? alternateTree.calcByteSize() : 0); } /** @@ -259,6 +259,14 @@ public LeafNode(FIMTDD tree) { sumOfAbsErrors = 0; } + public long calcByteSize() { + long size = super.calcByteSize(); + if (tree.buildingModelTree()) + size += learningModel.calcByteSize(); + size += SizeOf.fullSizeOf(attributeObservers); + return size; + } + public void setChild(int parentBranch, Node node) { } @@ -416,6 +424,13 @@ public abstract static class InnerNode extends Node { public InnerNode(FIMTDD tree) { super(tree); } + + public long calcByteSize() { + long size = super.calcByteSize(); + for (Node child : children) + size += child.calcByteSize(); + return size; + } public int numChildren() { return children.size(); @@ -505,6 +520,12 @@ public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { super(tree); this.splitTest = splitTest; } + + public long calcByteSize() { + long size = super.calcByteSize(); + size += SizeOf.sizeOf(splitTest); + return size; + } public int instanceChildIndex(Instance inst) { return splitTest.branchForInstance(inst); @@ -561,6 +582,10 @@ public FIMTDDPerceptron(FIMTDD tree) { } + public long calcByteSize() { + return SizeOf.sizeOf(this); + } + public void initializeWeights() { weightAttribute = new double[tree.getModelContext().numInputAttributes()+1]; instancesSeen = 0; @@ -710,8 +735,15 @@ protected Measurement[] getModelMeasurementsImpl() { }; } - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); + @Override + public long measureByteSize() { + return calcByteSize(); + } + + public long calcByteSize() { + long size = (long) (SizeOf.sizeOf(this)) + this.treeRoot.calcByteSize(); + size += (long) (SizeOf.sizeOf(this.sumOfAttrValues)) + (int) (SizeOf.sizeOf(this.sumOfAttrSquares)); + return size; } public double[] getVotesForInstance(Instance inst) { diff --git a/moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTree.java b/moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTree.java index dd1691fd2..c68657bc0 100644 --- a/moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTree.java +++ b/moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTree.java @@ -22,13 +22,15 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.bayes.NaiveBayes; import moa.classifiers.core.conditionaltests.InstanceConditionalTest; import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.MiscUtils; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding Adaptive Tree for evolving data streams. diff --git a/moa/src/main/java/moa/classifiers/trees/HoeffdingOptionTree.java b/moa/src/main/java/moa/classifiers/trees/HoeffdingOptionTree.java index e4dd74b0a..3ba18b87d 100644 --- a/moa/src/main/java/moa/classifiers/trees/HoeffdingOptionTree.java +++ b/moa/src/main/java/moa/classifiers/trees/HoeffdingOptionTree.java @@ -28,11 +28,14 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; + import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.AbstractMOAObject; import moa.classifiers.AbstractClassifier; import moa.classifiers.bayes.NaiveBayes; @@ -51,7 +54,6 @@ import moa.core.StringUtils; import moa.core.Utils; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding Option Tree. @@ -612,8 +614,8 @@ public void disableAttribute(int attIndex) { protected int maxPredictionPaths; - public int calcByteSize() { - int size = (int) SizeOf.sizeOf(this); + public long calcByteSize() { + long size = SizeOf.sizeOf(this); if (this.treeRoot != null) { size += this.treeRoot.calcByteSizeIncludingSubtree(); } @@ -621,7 +623,7 @@ public int calcByteSize() { } @Override - public int measureByteSize() { + public long measureByteSize() { return calcByteSize(); } @@ -1035,7 +1037,7 @@ public void estimateModelByteSizes() { this.inactiveLeafByteSizeEstimate = (double) totalInactiveSize / this.inactiveLeafNodeCount; } - int actualModelSize = this.measureByteSize(); + long actualModelSize = this.measureByteSize(); double estimatedModelSize = (this.activeLeafNodeCount * this.activeLeafByteSizeEstimate + this.inactiveLeafNodeCount * this.inactiveLeafByteSizeEstimate); diff --git a/moa/src/main/java/moa/classifiers/trees/HoeffdingTree.java b/moa/src/main/java/moa/classifiers/trees/HoeffdingTree.java index c6729b9d8..d8d64f17c 100644 --- a/moa/src/main/java/moa/classifiers/trees/HoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/trees/HoeffdingTree.java @@ -25,10 +25,13 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.AbstractMOAObject; import moa.classifiers.AbstractClassifier; import moa.classifiers.bayes.NaiveBayes; @@ -46,7 +49,6 @@ import moa.core.StringUtils; import moa.core.Utils; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding Tree or VFDT. @@ -149,7 +151,7 @@ public String getPurposeString() { 't', "Threshold below which a split will be forced to break ties.", 0.05, 0.0, 1.0); -public FlagOption binarySplitsOption = new FlagOption("binarySplits", 'b', + public FlagOption binarySplitsOption = new FlagOption("binarySplits", 'b', "Only allow binary splits."); public FlagOption stopMemManagementOption = new FlagOption( @@ -479,8 +481,8 @@ public void disableAttribute(int attIndex) { protected boolean growthAllowed; - public int calcByteSize() { - int size = (int) SizeOf.sizeOf(this); + public long calcByteSize() { + long size = SizeOf.sizeOf(this); if (this.treeRoot != null) { size += this.treeRoot.calcByteSizeIncludingSubtree(); } @@ -488,7 +490,7 @@ public int calcByteSize() { } @Override - public int measureByteSize() { + public long measureByteSize() { return calcByteSize(); } @@ -764,7 +766,7 @@ public void estimateModelByteSizes() { this.inactiveLeafByteSizeEstimate = (double) totalInactiveSize / this.inactiveLeafNodeCount; } - int actualModelSize = this.measureByteSize(); + long actualModelSize = this.measureByteSize(); double estimatedModelSize = (this.activeLeafNodeCount * this.activeLeafByteSizeEstimate + this.inactiveLeafNodeCount * this.inactiveLeafByteSizeEstimate); diff --git a/moa/src/main/java/moa/classifiers/trees/LimAttHoeffdingTree.java b/moa/src/main/java/moa/classifiers/trees/LimAttHoeffdingTree.java index 05b02df91..6c0b669a6 100644 --- a/moa/src/main/java/moa/classifiers/trees/LimAttHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/trees/LimAttHoeffdingTree.java @@ -19,10 +19,11 @@ */ package moa.classifiers.trees; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.bayes.NaiveBayes; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding decision trees with a restricted number of attributes for data diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index 5c48c0e21..519486b45 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -20,22 +20,21 @@ package moa.classifiers.trees; -import java.util.Stack; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.Stack; -import com.yahoo.labs.samoa.instances.Instance; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; import moa.classifiers.Regressor; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.splitcriteria.SplitCriterion; - import moa.core.AutoExpandVector; import moa.core.Measurement; import moa.core.StringUtils; @@ -101,7 +100,7 @@ public static class OptionNode extends InnerNode { public OptionNode(FIMTDD tree) { super(tree); } - + public void resetFF() { optionFFSSL = new double[children.size()]; optionFFSeen = new double[children.size()]; diff --git a/moa/src/main/java/moa/classifiers/trees/RandomHoeffdingTree.java b/moa/src/main/java/moa/classifiers/trees/RandomHoeffdingTree.java index f4b86a209..884c285b3 100644 --- a/moa/src/main/java/moa/classifiers/trees/RandomHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/trees/RandomHoeffdingTree.java @@ -19,10 +19,11 @@ */ package moa.classifiers.trees; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.bayes.NaiveBayes; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; /** * Random decision trees for data streams. diff --git a/moa/src/main/java/moa/cluster/CFCluster.java b/moa/src/main/java/moa/cluster/CFCluster.java index 727b0c567..bd6e83b33 100644 --- a/moa/src/main/java/moa/cluster/CFCluster.java +++ b/moa/src/main/java/moa/cluster/CFCluster.java @@ -20,6 +20,7 @@ package moa.cluster; import java.util.Arrays; + import com.yahoo.labs.samoa.instances.Instance; /* micro cluster, as defined by Aggarwal et al, On Clustering Massive Data Streams: A Summarization Praradigm diff --git a/moa/src/main/java/moa/cluster/Cluster.java b/moa/src/main/java/moa/cluster/Cluster.java index 42c175c24..caab641ed 100644 --- a/moa/src/main/java/moa/cluster/Cluster.java +++ b/moa/src/main/java/moa/cluster/Cluster.java @@ -25,9 +25,11 @@ import java.util.Iterator; import java.util.Map; import java.util.Random; -import moa.AbstractMOAObject; + import com.yahoo.labs.samoa.instances.Instance; +import moa.AbstractMOAObject; + public abstract class Cluster extends AbstractMOAObject { private static final long serialVersionUID = 1L; diff --git a/moa/src/main/java/moa/cluster/Clustering.java b/moa/src/main/java/moa/cluster/Clustering.java index 079e1b3ef..afc47799d 100644 --- a/moa/src/main/java/moa/cluster/Clustering.java +++ b/moa/src/main/java/moa/cluster/Clustering.java @@ -28,11 +28,13 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; + +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.Instance; + import moa.AbstractMOAObject; import moa.core.AutoExpandVector; import moa.gui.visualization.DataPoint; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.Instance; public class Clustering extends AbstractMOAObject{ diff --git a/moa/src/main/java/moa/cluster/SphereCluster.java b/moa/src/main/java/moa/cluster/SphereCluster.java index 0991500dc..533ba108e 100644 --- a/moa/src/main/java/moa/cluster/SphereCluster.java +++ b/moa/src/main/java/moa/cluster/SphereCluster.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; + import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/clusterers/AbstractClusterer.java b/moa/src/main/java/moa/clusterers/AbstractClusterer.java index a8f23f48e..3e32c4d50 100644 --- a/moa/src/main/java/moa/clusterers/AbstractClusterer.java +++ b/moa/src/main/java/moa/clusterers/AbstractClusterer.java @@ -22,19 +22,19 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; -import moa.cluster.Clustering; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; + +import moa.cluster.Clustering; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.StringUtils; import moa.gui.AWTRenderer; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public abstract class AbstractClusterer extends AbstractOptionHandler implements Clusterer { diff --git a/moa/src/main/java/moa/clusterers/ClusterGenerator.java b/moa/src/main/java/moa/clusterers/ClusterGenerator.java index 2c1a5cd63..4ad2e09f8 100644 --- a/moa/src/main/java/moa/clusterers/ClusterGenerator.java +++ b/moa/src/main/java/moa/clusterers/ClusterGenerator.java @@ -23,13 +23,15 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Random; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.core.Measurement; import moa.gui.visualization.DataPoint; -import com.yahoo.labs.samoa.instances.Instance; public class ClusterGenerator extends AbstractClusterer{ diff --git a/moa/src/main/java/moa/clusterers/Clusterer.java b/moa/src/main/java/moa/clusterers/Clusterer.java index b018b421f..b7badff51 100644 --- a/moa/src/main/java/moa/clusterers/Clusterer.java +++ b/moa/src/main/java/moa/clusterers/Clusterer.java @@ -19,13 +19,14 @@ */ package moa.clusterers; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.MOAObject; import moa.cluster.Clustering; import moa.core.Measurement; import moa.gui.AWTRenderable; import moa.options.OptionHandler; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public interface Clusterer extends MOAObject, OptionHandler, AWTRenderable { diff --git a/moa/src/main/java/moa/clusterers/CobWeb.java b/moa/src/main/java/moa/clusterers/CobWeb.java index 03e34a5f9..6f315ba9e 100644 --- a/moa/src/main/java/moa/clusterers/CobWeb.java +++ b/moa/src/main/java/moa/clusterers/CobWeb.java @@ -21,16 +21,16 @@ import java.io.Serializable; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.cluster.Clustering; import moa.cluster.SphereCluster; +import moa.core.FastVector; import moa.core.Measurement; import moa.core.StringUtils; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import moa.core.FastVector; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; import weka.core.AttributeStats; import weka.experiment.Stats; import weka.filters.unsupervised.attribute.Add; diff --git a/moa/src/main/java/moa/clusterers/KMeans.java b/moa/src/main/java/moa/clusterers/KMeans.java index b7014b5f7..d509f26a7 100644 --- a/moa/src/main/java/moa/clusterers/KMeans.java +++ b/moa/src/main/java/moa/clusterers/KMeans.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; + import moa.cluster.CFCluster; import moa.cluster.Cluster; import moa.cluster.Clustering; diff --git a/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java b/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java index 978290119..ef5ddaeda 100644 --- a/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java +++ b/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java @@ -21,21 +21,22 @@ import java.util.ArrayList; import java.util.List; -import moa.cluster.Clustering; -import moa.core.AutoClassDiscovery; -import moa.core.AutoExpandVector; -import moa.core.Measurement; -import moa.options.ClassOption; + import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; import com.github.javacliparser.StringOption; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; +import moa.cluster.Clustering; +import moa.core.AutoClassDiscovery; +import moa.core.AutoExpandVector; +import moa.core.FastVector; +import moa.core.Measurement; +import moa.options.ClassOption; import weka.core.Utils; public class WekaClusteringAlgorithm extends AbstractClusterer { diff --git a/moa/src/main/java/moa/clusterers/clustream/Clustream.java b/moa/src/main/java/moa/clusterers/clustream/Clustream.java index 85edb1c81..b10a2e029 100644 --- a/moa/src/main/java/moa/clusterers/clustream/Clustream.java +++ b/moa/src/main/java/moa/clusterers/clustream/Clustream.java @@ -24,14 +24,16 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; + +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.clusterers.AbstractClusterer; import moa.core.Measurement; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; /** Citation: CluStream: Charu C. Aggarwal, Jiawei Han, Jianyong Wang, Philip S. Yu: * A Framework for Clustering Evolving Data Streams. VLDB 2003: 81-92 diff --git a/moa/src/main/java/moa/clusterers/clustream/ClustreamKernel.java b/moa/src/main/java/moa/clusterers/clustream/ClustreamKernel.java index 83ae0324d..73ef8a6a7 100644 --- a/moa/src/main/java/moa/clusterers/clustream/ClustreamKernel.java +++ b/moa/src/main/java/moa/clusterers/clustream/ClustreamKernel.java @@ -20,10 +20,11 @@ package moa.clusterers.clustream; import java.util.ArrayList; -import java.util.Random; -import moa.cluster.CFCluster; + import com.yahoo.labs.samoa.instances.Instance; +import moa.cluster.CFCluster; + public class ClustreamKernel extends CFCluster { private static final long serialVersionUID = 1L; diff --git a/moa/src/main/java/moa/clusterers/clustream/WithKmeans.java b/moa/src/main/java/moa/clusterers/clustream/WithKmeans.java index 281c02813..175e1137e 100644 --- a/moa/src/main/java/moa/clusterers/clustream/WithKmeans.java +++ b/moa/src/main/java/moa/clusterers/clustream/WithKmeans.java @@ -32,15 +32,16 @@ import java.util.List; import java.util.Random; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.CFCluster; import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.clusterers.AbstractClusterer; import moa.core.Measurement; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; public class WithKmeans extends AbstractClusterer { diff --git a/moa/src/main/java/moa/clusterers/clustree/ClusKernel.java b/moa/src/main/java/moa/clusterers/clustree/ClusKernel.java index 025f86f92..fdddc6f31 100644 --- a/moa/src/main/java/moa/clusterers/clustree/ClusKernel.java +++ b/moa/src/main/java/moa/clusterers/clustree/ClusKernel.java @@ -20,11 +20,12 @@ package moa.clusterers.clustree; -import moa.clusterers.clustree.util.*; import java.util.Arrays; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.CFCluster; import moa.cluster.Cluster; -import com.yahoo.labs.samoa.instances.Instance; /** * Representation of an Entry in the tree diff --git a/moa/src/main/java/moa/clusterers/clustree/ClusTree.java b/moa/src/main/java/moa/clusterers/clustree/ClusTree.java index d6200debc..4c5f3fe14 100644 --- a/moa/src/main/java/moa/clusterers/clustree/ClusTree.java +++ b/moa/src/main/java/moa/clusterers/clustree/ClusTree.java @@ -21,14 +21,16 @@ package moa.clusterers.clustree; import java.util.ArrayList; - import java.util.LinkedList; -import moa.clusterers.clustree.util.*; + +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; +import moa.clusterers.clustree.util.Budget; +import moa.clusterers.clustree.util.SimpleBudget; import moa.core.Measurement; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Citation: ClusTree: Philipp Kranen, Ira Assent, Corinna Baldauf, Thomas Seidl: diff --git a/moa/src/main/java/moa/clusterers/denstream/MicroCluster.java b/moa/src/main/java/moa/clusterers/denstream/MicroCluster.java index 4b98a5606..cf6c25dba 100644 --- a/moa/src/main/java/moa/clusterers/denstream/MicroCluster.java +++ b/moa/src/main/java/moa/clusterers/denstream/MicroCluster.java @@ -19,9 +19,10 @@ */ package moa.clusterers.denstream; -import moa.cluster.CFCluster; import com.yahoo.labs.samoa.instances.Instance; +import moa.cluster.CFCluster; + public class MicroCluster extends CFCluster { private long lastEditT = -1; diff --git a/moa/src/main/java/moa/clusterers/denstream/WithDBSCAN.java b/moa/src/main/java/moa/clusterers/denstream/WithDBSCAN.java index fbc55d462..f243d664a 100644 --- a/moa/src/main/java/moa/clusterers/denstream/WithDBSCAN.java +++ b/moa/src/main/java/moa/clusterers/denstream/WithDBSCAN.java @@ -26,15 +26,16 @@ import java.util.ArrayList; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; import moa.clusterers.macro.dbscan.DBScan; import moa.core.Measurement; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; public class WithDBSCAN extends AbstractClusterer { diff --git a/moa/src/main/java/moa/clusterers/macro/NonConvexCluster.java b/moa/src/main/java/moa/clusterers/macro/NonConvexCluster.java index d264f8564..e132b69d2 100644 --- a/moa/src/main/java/moa/clusterers/macro/NonConvexCluster.java +++ b/moa/src/main/java/moa/clusterers/macro/NonConvexCluster.java @@ -26,9 +26,10 @@ import java.util.List; import java.util.Vector; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.CFCluster; import moa.cluster.Clustering; -import com.yahoo.labs.samoa.instances.Instance; public class NonConvexCluster extends CFCluster implements IDenseMacroCluster { diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractC.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractC.java index 4b67c3e78..9ac25bf0a 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractC.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractC.java @@ -21,13 +21,15 @@ package moa.clusterers.outliers.AbstractC; import java.util.Vector; -import moa.clusterers.outliers.AbstractC.ISBIndex.ISBNode; -import moa.clusterers.outliers.AbstractC.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.AbstractC.ISBIndex.ISBNode; +import moa.clusterers.outliers.AbstractC.ISBIndex.ISBSearchResult; + //The algorithm is presented in: //D. Yang, E. Rundensteiner, and M. Ward. //Neighbor-based pattern detection for windows over streaming data. diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractCBase.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractCBase.java index 6e39b8360..67150fa8b 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractCBase.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractCBase.java @@ -23,8 +23,9 @@ import java.util.ArrayList; import java.util.Vector; -import moa.clusterers.outliers.AbstractC.ISBIndex.ISBNode; + import moa.clusterers.outliers.MyBaseOutlierDetector; +import moa.clusterers.outliers.AbstractC.ISBIndex.ISBNode; public abstract class AbstractCBase extends MyBaseOutlierDetector { protected static final Long FIRST_OBJ_ID = 1L; diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/ISBIndex.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/ISBIndex.java index 9a0be6f04..26c4292ad 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/ISBIndex.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/ISBIndex.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Set; import java.util.Vector; + import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/MyMTree.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/MyMTree.java index af419a92f..5a2f5d531 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/MyMTree.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/MyMTree.java @@ -22,6 +22,7 @@ package moa.clusterers.outliers.AbstractC; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/Test.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/Test.java index 430a2c82f..46cc09f59 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/Test.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/Test.java @@ -21,9 +21,10 @@ package moa.clusterers.outliers.AbstractC; -import moa.streams.clustering.RandomRBFGeneratorEvents; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.clustering.RandomRBFGeneratorEvents; + public class Test { public static void main(String[] args) throws Exception { diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ApproxSTORM.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ApproxSTORM.java index 4eb279806..7b965ee9c 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ApproxSTORM.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ApproxSTORM.java @@ -26,12 +26,14 @@ import java.util.Random; import java.util.Set; import java.util.Vector; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBSearchResult; + public class ApproxSTORM extends STORMBase { public class ISBNodeAppr extends ISBNode { diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ExactSTORM.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ExactSTORM.java index 7bcd76f2f..652632ae1 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ExactSTORM.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ExactSTORM.java @@ -24,12 +24,14 @@ import java.util.Collections; import java.util.Iterator; import java.util.Vector; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBSearchResult; + // The algorithm is presented in "Distance-based outlier queries in data streams: the novel task and algorithms. //Data Mining and Knowledge Discovery, 20(2):290–324,2010. diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ISBIndex.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ISBIndex.java index c92781052..47bb87b5c 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ISBIndex.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ISBIndex.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Set; import java.util.Vector; + import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/MyMTree.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/MyMTree.java index e71e17623..96ba2625c 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/MyMTree.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/MyMTree.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.Angiulli; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/STORMBase.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/STORMBase.java index 7cc8b4f80..d1e2cbf28 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/STORMBase.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/STORMBase.java @@ -21,10 +21,12 @@ package moa.clusterers.outliers.Angiulli; import java.util.Vector; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; -import moa.clusterers.outliers.MyBaseOutlierDetector; + import com.github.javacliparser.FlagOption; +import moa.clusterers.outliers.MyBaseOutlierDetector; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; + public abstract class STORMBase extends MyBaseOutlierDetector { public FlagOption waitWinFullOption = new FlagOption("waitWinFull", 'a', "Output outliers when windows is full."); diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/Test.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/Test.java index 4921d99f7..dc6de05d5 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/Test.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/Test.java @@ -20,9 +20,10 @@ package moa.clusterers.outliers.Angiulli; -import moa.streams.clustering.RandomRBFGeneratorEvents; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.clustering.RandomRBFGeneratorEvents; + public class Test { public static void main(String[] args) throws Exception diff --git a/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOut.java b/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOut.java index 6086e6964..16e4a0f45 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOut.java +++ b/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOut.java @@ -21,9 +21,11 @@ package moa.clusterers.outliers.AnyOut; +import java.util.ArrayList; + import com.github.javacliparser.Options; import com.yahoo.labs.samoa.instances.Instance; -import java.util.ArrayList; + import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.AnyOut.util.DataObject; import moa.clusterers.outliers.AnyOut.util.DataSet; diff --git a/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOutCore.java b/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOutCore.java index a714f2d10..a56728cc8 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOutCore.java +++ b/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOutCore.java @@ -21,12 +21,14 @@ package moa.clusterers.outliers.AnyOut; +import java.util.ArrayList; +import java.util.HashMap; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; -import java.util.ArrayList; -import java.util.HashMap; + import moa.clusterers.clustree.ClusKernel; import moa.clusterers.clustree.ClusTree; import moa.clusterers.clustree.Entry; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/ISBIndex.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/ISBIndex.java index d151e92dd..047c964ff 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/ISBIndex.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/ISBIndex.java @@ -30,6 +30,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.Vector; + import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MCOD.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MCOD.java index 60ed3df4d..0d58e7b02 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MCOD.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MCOD.java @@ -23,13 +23,15 @@ import java.util.ArrayList; import java.util.TreeSet; import java.util.Vector; -import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode; -import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode.NodeType; -import moa.clusterers.outliers.MCOD.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode; +import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode.NodeType; +import moa.clusterers.outliers.MCOD.ISBIndex.ISBSearchResult; + //The algorithm is described in // M. Kontaki, A. Gounaris, A. N. Papadopoulos, K. Tsichlas, and Y. Manolopoulos. diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MCODBase.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MCODBase.java index 66548a726..94f7ba167 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MCODBase.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MCODBase.java @@ -25,9 +25,10 @@ import java.util.Set; import java.util.TreeSet; import java.util.Vector; + +import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode; import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode.NodeType; -import moa.clusterers.outliers.MyBaseOutlierDetector; public abstract class MCODBase extends MyBaseOutlierDetector { protected static class EventItem implements Comparable { diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeMicroClusters.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeMicroClusters.java index 575b42b63..42be983f2 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeMicroClusters.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeMicroClusters.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.MCOD; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeStreamObjects.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeStreamObjects.java index 77679064b..20f44c653 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeStreamObjects.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeStreamObjects.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.MCOD; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MicroCluster.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MicroCluster.java index 8b8fd6a1d..40741a868 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MicroCluster.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MicroCluster.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.MCOD; import java.util.ArrayList; + import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode; import moa.clusterers.outliers.utils.mtree.DistanceFunctions.EuclideanCoordinate; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/Test.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/Test.java index d22e61aaf..5b8474cab 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/Test.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/Test.java @@ -20,9 +20,10 @@ package moa.clusterers.outliers.MCOD; -import moa.streams.clustering.RandomRBFGeneratorEvents; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.clustering.RandomRBFGeneratorEvents; + public class Test { public static void main(String[] args) throws Exception diff --git a/moa/src/main/java/moa/clusterers/outliers/MyBaseOutlierDetector.java b/moa/src/main/java/moa/clusterers/outliers/MyBaseOutlierDetector.java index a9be5efb7..1ffe3e98a 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MyBaseOutlierDetector.java +++ b/moa/src/main/java/moa/clusterers/outliers/MyBaseOutlierDetector.java @@ -27,13 +27,15 @@ import java.util.Set; import java.util.TreeSet; import java.util.Vector; + +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.clusterers.AbstractClusterer; import moa.core.Measurement; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; public abstract class MyBaseOutlierDetector extends AbstractClusterer { public static class Outlier implements Comparable { diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/ISBIndex.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/ISBIndex.java index e088c2edb..4a12a6459 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/ISBIndex.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/ISBIndex.java @@ -30,6 +30,7 @@ import java.util.Map; import java.util.Set; import java.util.Vector; + import com.yahoo.labs.samoa.instances.Instance; public class ISBIndex { diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/MyMTree.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/MyMTree.java index 9cfa7e925..722ee5687 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/MyMTree.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/MyMTree.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.SimpleCOD; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCOD.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCOD.java index c7ed23161..2e8a1fb80 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCOD.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCOD.java @@ -21,12 +21,14 @@ package moa.clusterers.outliers.SimpleCOD; import java.util.Vector; -import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBNode; -import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBNode; +import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBSearchResult; + ////The algorithm is described in // M. Kontaki, A. Gounaris, A. N. Papadopoulos, K. Tsichlas, and Y. Manolopoulos. diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCODBase.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCODBase.java index b94e0992f..cd8ac90d3 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCODBase.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCODBase.java @@ -24,6 +24,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.Vector; + import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBNode; diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/Test.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/Test.java index 8039566ff..a8ed48e79 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/Test.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/Test.java @@ -20,9 +20,10 @@ package moa.clusterers.outliers.SimpleCOD; -import moa.streams.ArffFileStream; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.ArffFileStream; + public class Test { public static void main(String[] args) throws Exception diff --git a/moa/src/main/java/moa/clusterers/outliers/TestSpeed.java b/moa/src/main/java/moa/clusterers/outliers/TestSpeed.java index 019b74f91..31e903388 100644 --- a/moa/src/main/java/moa/clusterers/outliers/TestSpeed.java +++ b/moa/src/main/java/moa/clusterers/outliers/TestSpeed.java @@ -20,12 +20,13 @@ package moa.clusterers.outliers; +import com.yahoo.labs.samoa.instances.Instance; + import moa.clusterers.outliers.AbstractC.AbstractC; import moa.clusterers.outliers.Angiulli.ExactSTORM; import moa.clusterers.outliers.MCOD.MCOD; import moa.clusterers.outliers.SimpleCOD.SimpleCOD; import moa.streams.clustering.RandomRBFGeneratorEvents; -import com.yahoo.labs.samoa.instances.Instance; public class TestSpeed { public static void main(String[] args) throws Exception diff --git a/moa/src/main/java/moa/clusterers/outliers/utils/mtree/MTree.java b/moa/src/main/java/moa/clusterers/outliers/utils/mtree/MTree.java index 9c135a799..e2c8db618 100644 --- a/moa/src/main/java/moa/clusterers/outliers/utils/mtree/MTree.java +++ b/moa/src/main/java/moa/clusterers/outliers/utils/mtree/MTree.java @@ -24,6 +24,7 @@ import java.util.NoSuchElementException; import java.util.PriorityQueue; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.SplitFunction.SplitResult; diff --git a/moa/src/main/java/moa/clusterers/outliers/utils/mtree/PromotionFunctions.java b/moa/src/main/java/moa/clusterers/outliers/utils/mtree/PromotionFunctions.java index d7aa38ba4..b603935b4 100644 --- a/moa/src/main/java/moa/clusterers/outliers/utils/mtree/PromotionFunctions.java +++ b/moa/src/main/java/moa/clusterers/outliers/utils/mtree/PromotionFunctions.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.utils.Pair; import moa.clusterers.outliers.utils.mtree.utils.Utils; diff --git a/moa/src/main/java/moa/clusterers/streamkm/Point.java b/moa/src/main/java/moa/clusterers/streamkm/Point.java index 28fa9d232..b272a41d6 100644 --- a/moa/src/main/java/moa/clusterers/streamkm/Point.java +++ b/moa/src/main/java/moa/clusterers/streamkm/Point.java @@ -1,10 +1,10 @@ package moa.clusterers.streamkm; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.SphereCluster; -import com.yahoo.labs.samoa.instances.Instance; - /** * * @author Marcel R. Ackermann, Christiane Lammersen, Marcus Maertens, Christoph Raupach, diff --git a/moa/src/main/java/moa/clusterers/streamkm/StreamKM.java b/moa/src/main/java/moa/clusterers/streamkm/StreamKM.java index ac66163eb..599db86f8 100644 --- a/moa/src/main/java/moa/clusterers/streamkm/StreamKM.java +++ b/moa/src/main/java/moa/clusterers/streamkm/StreamKM.java @@ -1,10 +1,11 @@ package moa.clusterers.streamkm; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.Instance; /** * diff --git a/moa/src/main/java/moa/core/AutoClassDiscovery.java b/moa/src/main/java/moa/core/AutoClassDiscovery.java index 9b085e5ca..d8e456893 100644 --- a/moa/src/main/java/moa/core/AutoClassDiscovery.java +++ b/moa/src/main/java/moa/core/AutoClassDiscovery.java @@ -21,9 +21,9 @@ import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; diff --git a/moa/src/main/java/moa/core/AutoExpandVector.java b/moa/src/main/java/moa/core/AutoExpandVector.java index 33c3ed53e..938f70a78 100644 --- a/moa/src/main/java/moa/core/AutoExpandVector.java +++ b/moa/src/main/java/moa/core/AutoExpandVector.java @@ -121,7 +121,7 @@ public MOAObject copy() { } @Override - public int measureByteSize() { + public long measureByteSize() { return AbstractMOAObject.measureByteSize(this); } diff --git a/moa/src/main/java/moa/core/MultilabelInstancesHeader.java b/moa/src/main/java/moa/core/MultilabelInstancesHeader.java index b8dc3b3c2..7ae45510a 100644 --- a/moa/src/main/java/moa/core/MultilabelInstancesHeader.java +++ b/moa/src/main/java/moa/core/MultilabelInstancesHeader.java @@ -19,7 +19,6 @@ */ package moa.core; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; /** diff --git a/moa/src/main/java/moa/core/Utils.java b/moa/src/main/java/moa/core/Utils.java index ecb4cf19d..d3ec5a4e2 100644 --- a/moa/src/main/java/moa/core/Utils.java +++ b/moa/src/main/java/moa/core/Utils.java @@ -21,17 +21,9 @@ package moa.core; -import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.FileWriter; import java.lang.reflect.Array; -import java.net.URL; import java.text.BreakIterator; -import java.util.Enumeration; -import java.util.Properties; import java.util.Random; import java.util.Vector; diff --git a/moa/src/main/java/moa/core/utils/Converter.java b/moa/src/main/java/moa/core/utils/Converter.java index a3f976c38..5a06a8490 100755 --- a/moa/src/main/java/moa/core/utils/Converter.java +++ b/moa/src/main/java/moa/core/utils/Converter.java @@ -21,10 +21,12 @@ import java.util.LinkedList; import java.util.List; -import moa.AbstractMOAObject; + import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.AbstractMOAObject; + /** * Converter. This class can be used to convert a multi-label instance into a * single-label instance. diff --git a/moa/src/main/java/moa/evaluation/Accuracy.java b/moa/src/main/java/moa/evaluation/Accuracy.java index d8925799d..049ef9913 100644 --- a/moa/src/main/java/moa/evaluation/Accuracy.java +++ b/moa/src/main/java/moa/evaluation/Accuracy.java @@ -20,6 +20,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/AdwinClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/AdwinClassificationPerformanceEvaluator.java index a0c79202c..aea7cf19e 100644 --- a/moa/src/main/java/moa/evaluation/AdwinClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/AdwinClassificationPerformanceEvaluator.java @@ -19,7 +19,6 @@ */ package moa.evaluation; -import com.github.javacliparser.IntOption; import moa.classifiers.core.driftdetection.ADWIN; /** diff --git a/moa/src/main/java/moa/evaluation/BasicClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicClassificationPerformanceEvaluator.java index f2bba1612..eeb29f978 100644 --- a/moa/src/main/java/moa/evaluation/BasicClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicClassificationPerformanceEvaluator.java @@ -20,20 +20,18 @@ */ package moa.evaluation; -import moa.AbstractMOAObject; +import java.io.Serializable; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.Utils; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; import moa.options.AbstractOptionHandler; import moa.tasks.TaskMonitor; -import java.io.Serializable; - /** * Classification evaluator that performs basic incremental evaluation. * diff --git a/moa/src/main/java/moa/evaluation/BasicConceptDriftPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicConceptDriftPerformanceEvaluator.java index d5df7cf06..40057d4cc 100644 --- a/moa/src/main/java/moa/evaluation/BasicConceptDriftPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicConceptDriftPerformanceEvaluator.java @@ -20,7 +20,6 @@ package moa.evaluation; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; import com.yahoo.labs.samoa.instances.Prediction; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java index 33e6b18d1..d18061094 100644 --- a/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java @@ -19,14 +19,14 @@ */ package moa.evaluation; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.AbstractMOAObject; import moa.core.Example; import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Multilabel Window Classification Performance Evaluator. * diff --git a/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java index 5b87a670b..0f522b1e6 100644 --- a/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java @@ -19,17 +19,14 @@ */ package moa.evaluation; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.AbstractMOAObject; import moa.core.Example; import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.DenseInstanceData; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Regression evaluator that performs basic incremental evaluation. * diff --git a/moa/src/main/java/moa/evaluation/BasicRegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicRegressionPerformanceEvaluator.java index 3948cfeba..f4ca38547 100644 --- a/moa/src/main/java/moa/evaluation/BasicRegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicRegressionPerformanceEvaluator.java @@ -19,14 +19,13 @@ */ package moa.evaluation; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + import moa.AbstractMOAObject; import moa.core.Example; import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Regression evaluator that performs basic incremental evaluation. * diff --git a/moa/src/main/java/moa/evaluation/CMM_GTAnalysis.java b/moa/src/main/java/moa/evaluation/CMM_GTAnalysis.java index 204909e2e..db4f8273b 100644 --- a/moa/src/main/java/moa/evaluation/CMM_GTAnalysis.java +++ b/moa/src/main/java/moa/evaluation/CMM_GTAnalysis.java @@ -36,10 +36,12 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.core.AutoExpandVector; import moa.gui.visualization.DataPoint; -import com.yahoo.labs.samoa.instances.Instance; public class CMM_GTAnalysis{ diff --git a/moa/src/main/java/moa/evaluation/ChangeDetectionMeasures.java b/moa/src/main/java/moa/evaluation/ChangeDetectionMeasures.java index c40dda432..faccffcc6 100644 --- a/moa/src/main/java/moa/evaluation/ChangeDetectionMeasures.java +++ b/moa/src/main/java/moa/evaluation/ChangeDetectionMeasures.java @@ -21,6 +21,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/ClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/ClassificationPerformanceEvaluator.java index 0eb9176c9..d1a6ba878 100644 --- a/moa/src/main/java/moa/evaluation/ClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/ClassificationPerformanceEvaluator.java @@ -20,9 +20,8 @@ package moa.evaluation; import com.yahoo.labs.samoa.instances.Instance; -import moa.MOAObject; + import moa.core.Example; -import moa.core.Measurement; public interface ClassificationPerformanceEvaluator extends LearningPerformanceEvaluator> { diff --git a/moa/src/main/java/moa/evaluation/EWMAClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/EWMAClassificationPerformanceEvaluator.java index 31f8ace8f..04a33adf2 100644 --- a/moa/src/main/java/moa/evaluation/EWMAClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/EWMAClassificationPerformanceEvaluator.java @@ -19,21 +19,8 @@ */ package moa.evaluation; -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; - import com.github.javacliparser.FloatOption; -import moa.options.AbstractOptionHandler; -import moa.tasks.TaskMonitor; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - -import moa.core.Utils; - /** * Classification evaluator that updates evaluation results using an Exponential Weighted Moving Average. * diff --git a/moa/src/main/java/moa/evaluation/EntropyCollection.java b/moa/src/main/java/moa/evaluation/EntropyCollection.java index 53a67226b..dcf04e018 100644 --- a/moa/src/main/java/moa/evaluation/EntropyCollection.java +++ b/moa/src/main/java/moa/evaluation/EntropyCollection.java @@ -21,6 +21,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/F1.java b/moa/src/main/java/moa/evaluation/F1.java index 36e3529ab..de214877c 100644 --- a/moa/src/main/java/moa/evaluation/F1.java +++ b/moa/src/main/java/moa/evaluation/F1.java @@ -20,6 +20,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/FadingFactorClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/FadingFactorClassificationPerformanceEvaluator.java index ed1cd700e..54bbe72e4 100644 --- a/moa/src/main/java/moa/evaluation/FadingFactorClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/FadingFactorClassificationPerformanceEvaluator.java @@ -19,20 +19,8 @@ */ package moa.evaluation; -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; - import com.github.javacliparser.FloatOption; -import moa.options.AbstractOptionHandler; -import moa.tasks.TaskMonitor; -import moa.core.Utils; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Classification evaluator that updates evaluation results using a fading factor. * diff --git a/moa/src/main/java/moa/evaluation/General.java b/moa/src/main/java/moa/evaluation/General.java index c50d1ca9f..90682d18b 100644 --- a/moa/src/main/java/moa/evaluation/General.java +++ b/moa/src/main/java/moa/evaluation/General.java @@ -22,10 +22,12 @@ import java.util.ArrayList; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.gui.visualization.DataPoint; -import com.yahoo.labs.samoa.instances.Instance; public class General extends MeasureCollection{ private int numPoints; diff --git a/moa/src/main/java/moa/evaluation/LearningEvaluation.java b/moa/src/main/java/moa/evaluation/LearningEvaluation.java index e03d8aaed..70bb17315 100644 --- a/moa/src/main/java/moa/evaluation/LearningEvaluation.java +++ b/moa/src/main/java/moa/evaluation/LearningEvaluation.java @@ -24,10 +24,8 @@ import java.util.List; import moa.AbstractMOAObject; -import moa.classifiers.Classifier; -import moa.clusterers.Clusterer; -import moa.learners.Learner; import moa.core.Measurement; +import moa.learners.Learner; /** * Class that stores an array of evaluation measurements. diff --git a/moa/src/main/java/moa/evaluation/LearningPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/LearningPerformanceEvaluator.java index 49b44c3c2..820886e1d 100644 --- a/moa/src/main/java/moa/evaluation/LearningPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/LearningPerformanceEvaluator.java @@ -19,7 +19,6 @@ */ package moa.evaluation; -import com.yahoo.labs.samoa.instances.InstanceData; import com.yahoo.labs.samoa.instances.Prediction; import moa.MOAObject; diff --git a/moa/src/main/java/moa/evaluation/MeasureCollection.java b/moa/src/main/java/moa/evaluation/MeasureCollection.java index 521470ccc..236d87328 100644 --- a/moa/src/main/java/moa/evaluation/MeasureCollection.java +++ b/moa/src/main/java/moa/evaluation/MeasureCollection.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.HashMap; + import moa.AbstractMOAObject; import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/MembershipMatrix.java b/moa/src/main/java/moa/evaluation/MembershipMatrix.java index b139683df..d29777667 100644 --- a/moa/src/main/java/moa/evaluation/MembershipMatrix.java +++ b/moa/src/main/java/moa/evaluation/MembershipMatrix.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.HashMap; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/MultiTargetPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/MultiTargetPerformanceEvaluator.java index 38d2c10d1..166f3fe24 100644 --- a/moa/src/main/java/moa/evaluation/MultiTargetPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/MultiTargetPerformanceEvaluator.java @@ -19,9 +19,10 @@ */ package moa.evaluation; -import moa.core.Example; import com.yahoo.labs.samoa.instances.Instance; +import moa.core.Example; + /** * Interface implemented by learner evaluators to monitor diff --git a/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java index 24d45642d..0e8323c07 100644 --- a/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java @@ -19,20 +19,17 @@ */ package moa.evaluation; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; - -import com.github.javacliparser.IntOption; - import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Multi-target regression evaluator that updates evaluation results using a sliding window. * diff --git a/moa/src/main/java/moa/evaluation/OutlierPerformance.java b/moa/src/main/java/moa/evaluation/OutlierPerformance.java index f940a631c..298472f54 100644 --- a/moa/src/main/java/moa/evaluation/OutlierPerformance.java +++ b/moa/src/main/java/moa/evaluation/OutlierPerformance.java @@ -21,7 +21,7 @@ package moa.evaluation; import java.util.ArrayList; -import java.util.Arrays; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/RegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/RegressionPerformanceEvaluator.java index 4934ab79f..78513adb7 100644 --- a/moa/src/main/java/moa/evaluation/RegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/RegressionPerformanceEvaluator.java @@ -19,9 +19,10 @@ */ package moa.evaluation; -import moa.core.Example; import com.yahoo.labs.samoa.instances.Instance; +import moa.core.Example; + /** * Interface implemented by learner evaluators to monitor diff --git a/moa/src/main/java/moa/evaluation/SSQ.java b/moa/src/main/java/moa/evaluation/SSQ.java index 34e6dc4ba..37fab259e 100644 --- a/moa/src/main/java/moa/evaluation/SSQ.java +++ b/moa/src/main/java/moa/evaluation/SSQ.java @@ -21,6 +21,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/Separation.java b/moa/src/main/java/moa/evaluation/Separation.java index 46a151262..fd5c9fbf8 100644 --- a/moa/src/main/java/moa/evaluation/Separation.java +++ b/moa/src/main/java/moa/evaluation/Separation.java @@ -1,5 +1,8 @@ package moa.evaluation; +import java.util.ArrayList; +import java.util.List; + /* * #%L * SAMOA @@ -22,14 +25,12 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.gui.visualization.DataPoint; -import java.util.ArrayList; -import java.util.List; - public class Separation extends MeasureCollection { public Separation() { diff --git a/moa/src/main/java/moa/evaluation/SilhouetteCoefficient.java b/moa/src/main/java/moa/evaluation/SilhouetteCoefficient.java index 5f2697155..c58a7a8da 100644 --- a/moa/src/main/java/moa/evaluation/SilhouetteCoefficient.java +++ b/moa/src/main/java/moa/evaluation/SilhouetteCoefficient.java @@ -21,7 +21,7 @@ package moa.evaluation; import java.util.ArrayList; -import java.util.HashMap; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/StatisticalCollection.java b/moa/src/main/java/moa/evaluation/StatisticalCollection.java index be51d4605..74f9576d1 100644 --- a/moa/src/main/java/moa/evaluation/StatisticalCollection.java +++ b/moa/src/main/java/moa/evaluation/StatisticalCollection.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Arrays; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/WindowClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/WindowClassificationPerformanceEvaluator.java index 31b9f3ef4..c6df7de30 100644 --- a/moa/src/main/java/moa/evaluation/WindowClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/WindowClassificationPerformanceEvaluator.java @@ -19,20 +19,8 @@ */ package moa.evaluation; -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; -import moa.options.AbstractOptionHandler; - import com.github.javacliparser.IntOption; -import moa.tasks.TaskMonitor; -import moa.core.Utils; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Classification evaluator that updates evaluation results using a sliding * window. diff --git a/moa/src/main/java/moa/evaluation/WindowRegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/WindowRegressionPerformanceEvaluator.java index 45d2f4e5a..280893b11 100644 --- a/moa/src/main/java/moa/evaluation/WindowRegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/WindowRegressionPerformanceEvaluator.java @@ -19,19 +19,16 @@ */ package moa.evaluation; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; - -import com.github.javacliparser.IntOption; - import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Regression evaluator that updates evaluation results using a sliding window. * diff --git a/moa/src/main/java/moa/gui/BatchCmd.java b/moa/src/main/java/moa/gui/BatchCmd.java index c793093c1..eacbc966f 100644 --- a/moa/src/main/java/moa/gui/BatchCmd.java +++ b/moa/src/main/java/moa/gui/BatchCmd.java @@ -32,6 +32,9 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; import moa.clusterers.ClusterGenerator; @@ -46,11 +49,9 @@ import moa.gui.visualization.DataPoint; import moa.gui.visualization.RunVisualizer; import moa.streams.clustering.ClusterEvent; -import com.yahoo.labs.samoa.instances.Instance; import moa.streams.clustering.ClusterEventListener; import moa.streams.clustering.ClusteringStream; import moa.streams.clustering.RandomRBFGeneratorEvents; -import com.yahoo.labs.samoa.instances.DenseInstance; public class BatchCmd implements ClusterEventListener{ diff --git a/moa/src/main/java/moa/gui/ClassOptionSelectionPanel.java b/moa/src/main/java/moa/gui/ClassOptionSelectionPanel.java index 16c2fbe74..239c42406 100644 --- a/moa/src/main/java/moa/gui/ClassOptionSelectionPanel.java +++ b/moa/src/main/java/moa/gui/ClassOptionSelectionPanel.java @@ -19,7 +19,6 @@ */ package moa.gui; -import com.github.javacliparser.gui.OptionsConfigurationPanel; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Window; @@ -32,6 +31,8 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; +import com.github.javacliparser.gui.OptionsConfigurationPanel; + import moa.core.AutoClassDiscovery; import moa.core.AutoExpandVector; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/gui/ClassOptionWithNamesSelectionPanel.java b/moa/src/main/java/moa/gui/ClassOptionWithNamesSelectionPanel.java index a0ba8a8c6..524199618 100644 --- a/moa/src/main/java/moa/gui/ClassOptionWithNamesSelectionPanel.java +++ b/moa/src/main/java/moa/gui/ClassOptionWithNamesSelectionPanel.java @@ -10,7 +10,6 @@ package moa.gui; -import com.github.javacliparser.gui.OptionsConfigurationPanel; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Window; @@ -23,6 +22,8 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; +import com.github.javacliparser.gui.OptionsConfigurationPanel; + import moa.core.AutoClassDiscovery; import moa.core.AutoExpandVector; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/gui/ConceptDriftTabPanel.java b/moa/src/main/java/moa/gui/ConceptDriftTabPanel.java index 5cd80e515..de248e6de 100644 --- a/moa/src/main/java/moa/gui/ConceptDriftTabPanel.java +++ b/moa/src/main/java/moa/gui/ConceptDriftTabPanel.java @@ -20,6 +20,7 @@ package moa.gui; import java.awt.BorderLayout; + import moa.gui.PreviewPanel.TypePanel; import moa.gui.conceptdrift.CDTaskManagerPanel; diff --git a/moa/src/main/java/moa/gui/GUI.java b/moa/src/main/java/moa/gui/GUI.java index 442566626..ae5be1a43 100644 --- a/moa/src/main/java/moa/gui/GUI.java +++ b/moa/src/main/java/moa/gui/GUI.java @@ -21,13 +21,11 @@ package moa.gui; import java.awt.BorderLayout; -import java.util.logging.Level; -import java.util.logging.Logger; + import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; -import javax.swing.UIManager.LookAndFeelInfo; -import javax.swing.UnsupportedLookAndFeelException; + import moa.DoTask; import moa.core.WekaUtils; diff --git a/moa/src/main/java/moa/gui/GUIDefaults.java b/moa/src/main/java/moa/gui/GUIDefaults.java index 5ff90ed57..466ff3b0c 100644 --- a/moa/src/main/java/moa/gui/GUIDefaults.java +++ b/moa/src/main/java/moa/gui/GUIDefaults.java @@ -20,15 +20,15 @@ */ package moa.gui; -import moa.core.PropertiesReader; -import moa.core.Utils; - import java.io.Serializable; import java.util.Collections; import java.util.Enumeration; import java.util.Properties; import java.util.Vector; +import moa.core.PropertiesReader; +import moa.core.Utils; + /** * This class offers get methods for the default GUI settings in * the props file moa/gui/GUI.props. diff --git a/moa/src/main/java/moa/gui/MultiTargetTabPanel.java b/moa/src/main/java/moa/gui/MultiTargetTabPanel.java index 955cad212..63ef5f263 100644 --- a/moa/src/main/java/moa/gui/MultiTargetTabPanel.java +++ b/moa/src/main/java/moa/gui/MultiTargetTabPanel.java @@ -20,6 +20,7 @@ package moa.gui; import java.awt.BorderLayout; + import moa.gui.PreviewPanel.TypePanel; /** diff --git a/moa/src/main/java/moa/gui/MultiTargetTaskManagerPanel.java b/moa/src/main/java/moa/gui/MultiTargetTaskManagerPanel.java index 01a9ea4cf..0d5745bd0 100644 --- a/moa/src/main/java/moa/gui/MultiTargetTaskManagerPanel.java +++ b/moa/src/main/java/moa/gui/MultiTargetTaskManagerPanel.java @@ -38,6 +38,7 @@ import java.util.ArrayList; import java.util.List; import java.util.prefs.Preferences; + import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; @@ -56,6 +57,7 @@ import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; + import moa.core.StringUtils; import moa.options.ClassOption; import moa.options.OptionHandler; diff --git a/moa/src/main/java/moa/gui/RegressionTabPanel.java b/moa/src/main/java/moa/gui/RegressionTabPanel.java index 372157ad8..ae99d364c 100644 --- a/moa/src/main/java/moa/gui/RegressionTabPanel.java +++ b/moa/src/main/java/moa/gui/RegressionTabPanel.java @@ -20,6 +20,7 @@ package moa.gui; import java.awt.BorderLayout; + import moa.gui.PreviewPanel.TypePanel; /** diff --git a/moa/src/main/java/moa/gui/RegressionTaskManagerPanel.java b/moa/src/main/java/moa/gui/RegressionTaskManagerPanel.java index 226421523..4d7fb91ab 100644 --- a/moa/src/main/java/moa/gui/RegressionTaskManagerPanel.java +++ b/moa/src/main/java/moa/gui/RegressionTaskManagerPanel.java @@ -23,13 +23,13 @@ import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; diff --git a/moa/src/main/java/moa/gui/TaskManagerPanel.java b/moa/src/main/java/moa/gui/TaskManagerPanel.java index 7ab117cf1..1eb3b29df 100644 --- a/moa/src/main/java/moa/gui/TaskManagerPanel.java +++ b/moa/src/main/java/moa/gui/TaskManagerPanel.java @@ -23,13 +23,13 @@ import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; diff --git a/moa/src/main/java/moa/gui/TaskTextViewerPanel.java b/moa/src/main/java/moa/gui/TaskTextViewerPanel.java index 20a28e1f4..27deaba22 100644 --- a/moa/src/main/java/moa/gui/TaskTextViewerPanel.java +++ b/moa/src/main/java/moa/gui/TaskTextViewerPanel.java @@ -40,9 +40,8 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; -import moa.evaluation.Accuracy; + import moa.evaluation.MeasureCollection; -import moa.evaluation.RegressionAccuracy; import moa.gui.PreviewPanel.TypePanel; import moa.gui.conceptdrift.CDTaskManagerPanel; import moa.streams.clustering.ClusterEvent; diff --git a/moa/src/main/java/moa/gui/WEKAClassOptionEditComponent.java b/moa/src/main/java/moa/gui/WEKAClassOptionEditComponent.java index 5288a0ce5..755326f70 100644 --- a/moa/src/main/java/moa/gui/WEKAClassOptionEditComponent.java +++ b/moa/src/main/java/moa/gui/WEKAClassOptionEditComponent.java @@ -20,12 +20,6 @@ */ package moa.gui; -import com.github.javacliparser.gui.OptionEditComponent; -import moa.core.Utils; -import weka.gui.GenericObjectEditor; -import weka.gui.PropertyDialog; -import weka.gui.GenericObjectEditor.GOEPanel; - import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -35,7 +29,13 @@ import javax.swing.JTextField; import com.github.javacliparser.Option; +import com.github.javacliparser.gui.OptionEditComponent; + +import moa.core.Utils; import moa.options.WEKAClassOption; +import weka.gui.GenericObjectEditor; +import weka.gui.GenericObjectEditor.GOEPanel; +import weka.gui.PropertyDialog; /** * An OptionEditComponent that lets the user edit a WEKA class option. diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringAlgoPanel.java b/moa/src/main/java/moa/gui/clustertab/ClusteringAlgoPanel.java index 0a04c98f9..61385baf7 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringAlgoPanel.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringAlgoPanel.java @@ -21,7 +21,6 @@ package moa.gui.clustertab; import java.awt.BorderLayout; - import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -32,20 +31,21 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; + import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; +import com.github.javacliparser.Option; +import com.github.javacliparser.gui.OptionEditComponent; +import com.github.javacliparser.gui.OptionsConfigurationPanel; + import moa.clusterers.AbstractClusterer; import moa.clusterers.Clusterer; import moa.gui.GUIUtils; -import com.github.javacliparser.gui.OptionEditComponent; -import com.github.javacliparser.gui.OptionsConfigurationPanel; import moa.options.ClassOption; -import com.github.javacliparser.Option; import moa.streams.clustering.ClusteringStream; -import moa.streams.generators.RandomRBFGenerator; public class ClusteringAlgoPanel extends javax.swing.JPanel implements ActionListener{ diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringEvalPanel.java b/moa/src/main/java/moa/gui/clustertab/ClusteringEvalPanel.java index eb9a57d81..9d94481db 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringEvalPanel.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringEvalPanel.java @@ -22,11 +22,12 @@ import java.awt.GridBagConstraints; import java.util.ArrayList; import java.util.logging.Logger; + import javax.swing.JCheckBox; import javax.swing.JLabel; + import moa.core.AutoClassDiscovery; import moa.core.AutoExpandVector; -import moa.evaluation.ClassificationMeasureCollection; import moa.evaluation.MeasureCollection; public class ClusteringEvalPanel extends javax.swing.JPanel { diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringSetupTab.java b/moa/src/main/java/moa/gui/clustertab/ClusteringSetupTab.java index beffc7e52..f27f5eece 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringSetupTab.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringSetupTab.java @@ -24,7 +24,9 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; + import javax.swing.JFileChooser; + import moa.clusterers.AbstractClusterer; import moa.evaluation.MeasureCollection; import moa.gui.FileExtensionFilter; diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringVisualEvalPanel.java b/moa/src/main/java/moa/gui/clustertab/ClusteringVisualEvalPanel.java index 626bed80a..574a78b96 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringVisualEvalPanel.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringVisualEvalPanel.java @@ -25,13 +25,13 @@ import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.event.ActionListener; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; import java.text.DecimalFormat; import java.util.ArrayList; + import javax.swing.ButtonGroup; import javax.swing.JLabel; import javax.swing.JRadioButton; + import moa.evaluation.MeasureCollection; public class ClusteringVisualEvalPanel extends javax.swing.JPanel{ diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringVisualTab.java b/moa/src/main/java/moa/gui/clustertab/ClusteringVisualTab.java index ba2f22c94..02fe10e7b 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringVisualTab.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringVisualTab.java @@ -24,10 +24,12 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; + import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.ToolTipManager; + import moa.gui.FileExtensionFilter; import moa.gui.visualization.GraphCanvas; import moa.gui.visualization.RunVisualizer; diff --git a/moa/src/main/java/moa/gui/conceptdrift/CDTaskManagerPanel.java b/moa/src/main/java/moa/gui/conceptdrift/CDTaskManagerPanel.java index 2b8ad6651..3794d6667 100644 --- a/moa/src/main/java/moa/gui/conceptdrift/CDTaskManagerPanel.java +++ b/moa/src/main/java/moa/gui/conceptdrift/CDTaskManagerPanel.java @@ -20,17 +20,16 @@ */ package moa.gui.conceptdrift; -import moa.gui.*; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; @@ -60,6 +59,10 @@ import javax.swing.table.TableCellRenderer; import moa.core.StringUtils; +import moa.gui.ClassOptionSelectionPanel; +import moa.gui.FileExtensionFilter; +import moa.gui.GUIUtils; +import moa.gui.PreviewPanel; import moa.options.ClassOption; import moa.options.OptionHandler; import moa.tasks.ConceptDriftMainTask; diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierAlgoPanel.java b/moa/src/main/java/moa/gui/outliertab/OutlierAlgoPanel.java index d7fd2acd8..9951c4aa7 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierAlgoPanel.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierAlgoPanel.java @@ -20,7 +20,11 @@ package moa.gui.outliertab; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; @@ -28,16 +32,19 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; + import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; -import moa.clusterers.outliers.MyBaseOutlierDetector; -import moa.gui.GUIUtils; -import moa.options.ClassOption; + import com.github.javacliparser.Option; import com.github.javacliparser.gui.OptionEditComponent; import com.github.javacliparser.gui.OptionsConfigurationPanel; + +import moa.clusterers.outliers.MyBaseOutlierDetector; +import moa.gui.GUIUtils; +import moa.options.ClassOption; import moa.streams.clustering.ClusteringStream; public class OutlierAlgoPanel extends javax.swing.JPanel implements ActionListener{ diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierEvalPanel.java b/moa/src/main/java/moa/gui/outliertab/OutlierEvalPanel.java index 84500eb92..0883b9034 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierEvalPanel.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierEvalPanel.java @@ -22,12 +22,12 @@ import java.awt.GridBagConstraints; import java.util.ArrayList; -import java.util.logging.Logger; + import javax.swing.JCheckBox; import javax.swing.JLabel; + import moa.core.AutoClassDiscovery; import moa.core.AutoExpandVector; -import moa.evaluation.ClassificationMeasureCollection; import moa.evaluation.MeasureCollection; import moa.evaluation.OutlierPerformance; diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierSetupTab.java b/moa/src/main/java/moa/gui/outliertab/OutlierSetupTab.java index 70b2dd742..56c6889d4 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierSetupTab.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierSetupTab.java @@ -24,7 +24,9 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; + import javax.swing.JFileChooser; + import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.evaluation.MeasureCollection; import moa.gui.FileExtensionFilter; diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierVisualEvalPanel.java b/moa/src/main/java/moa/gui/outliertab/OutlierVisualEvalPanel.java index 7c5307f1d..24c410add 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierVisualEvalPanel.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierVisualEvalPanel.java @@ -25,13 +25,13 @@ import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.event.ActionListener; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; import java.text.DecimalFormat; import java.util.ArrayList; + import javax.swing.ButtonGroup; import javax.swing.JLabel; import javax.swing.JRadioButton; + import moa.evaluation.MeasureCollection; public class OutlierVisualEvalPanel extends javax.swing.JPanel{ diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierVisualTab.java b/moa/src/main/java/moa/gui/outliertab/OutlierVisualTab.java index 2322a01f6..9923bfeed 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierVisualTab.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierVisualTab.java @@ -28,10 +28,12 @@ import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.io.File; + import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.ToolTipManager; + import moa.gui.FileExtensionFilter; import moa.gui.visualization.GraphCanvas; import moa.gui.visualization.RunOutlierVisualizer; diff --git a/moa/src/main/java/moa/gui/visualization/ClusterPanel.java b/moa/src/main/java/moa/gui/visualization/ClusterPanel.java index 3db527710..352100b4d 100644 --- a/moa/src/main/java/moa/gui/visualization/ClusterPanel.java +++ b/moa/src/main/java/moa/gui/visualization/ClusterPanel.java @@ -24,7 +24,9 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; + import javax.swing.JPanel; + import moa.cluster.SphereCluster; public class ClusterPanel extends JPanel { diff --git a/moa/src/main/java/moa/gui/visualization/GraphCanvas.java b/moa/src/main/java/moa/gui/visualization/GraphCanvas.java index 6aecc5a32..fe857f285 100644 --- a/moa/src/main/java/moa/gui/visualization/GraphCanvas.java +++ b/moa/src/main/java/moa/gui/visualization/GraphCanvas.java @@ -22,9 +22,11 @@ import java.awt.Dimension; import java.awt.Graphics; import java.util.ArrayList; + import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JViewport; + import moa.evaluation.MeasureCollection; import moa.streams.clustering.ClusterEvent; diff --git a/moa/src/main/java/moa/gui/visualization/GraphCurve.java b/moa/src/main/java/moa/gui/visualization/GraphCurve.java index a791cafb3..46518e7a1 100644 --- a/moa/src/main/java/moa/gui/visualization/GraphCurve.java +++ b/moa/src/main/java/moa/gui/visualization/GraphCurve.java @@ -23,6 +23,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.util.ArrayList; + import moa.evaluation.MeasureCollection; import moa.streams.clustering.ClusterEvent; diff --git a/moa/src/main/java/moa/gui/visualization/OutlierPanel.java b/moa/src/main/java/moa/gui/visualization/OutlierPanel.java index 68c5c1a48..f917a0ad9 100644 --- a/moa/src/main/java/moa/gui/visualization/OutlierPanel.java +++ b/moa/src/main/java/moa/gui/visualization/OutlierPanel.java @@ -21,13 +21,20 @@ package moa.gui.visualization; -import java.awt.*; -import java.awt.event.WindowEvent; -import java.awt.event.WindowFocusListener; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; -import javax.swing.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.PointerInfo; +import java.awt.RenderingHints; + +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + import moa.cluster.SphereCluster; import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.MyBaseOutlierDetector.Outlier; diff --git a/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java b/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java index ce611e1ba..5dd794716 100644 --- a/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java +++ b/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java @@ -39,6 +39,12 @@ import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; + +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.clusterers.outliers.MyBaseOutlierDetector; @@ -56,10 +62,6 @@ import moa.streams.clustering.ClusterEventListener; import moa.streams.clustering.ClusteringStream; import moa.streams.clustering.RandomRBFGeneratorEvents; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class RunOutlierVisualizer implements Runnable, ActionListener, ClusterEventListener{ /** the pause interval, being read from the gui at startup */ diff --git a/moa/src/main/java/moa/gui/visualization/RunVisualizer.java b/moa/src/main/java/moa/gui/visualization/RunVisualizer.java index 1e08cab18..0e33cbebb 100644 --- a/moa/src/main/java/moa/gui/visualization/RunVisualizer.java +++ b/moa/src/main/java/moa/gui/visualization/RunVisualizer.java @@ -34,25 +34,25 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; import moa.clusterers.ClusterGenerator; +import moa.core.FastVector; import moa.evaluation.MeasureCollection; import moa.gui.TextViewerPanel; import moa.gui.clustertab.ClusteringSetupTab; import moa.gui.clustertab.ClusteringVisualEvalPanel; import moa.gui.clustertab.ClusteringVisualTab; import moa.streams.clustering.ClusterEvent; -import com.yahoo.labs.samoa.instances.Instance; -import moa.gui.clustertab.ClusteringSetupTab; import moa.streams.clustering.ClusterEventListener; import moa.streams.clustering.ClusteringStream; import moa.streams.clustering.RandomRBFGeneratorEvents; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class RunVisualizer implements Runnable, ActionListener, ClusterEventListener{ diff --git a/moa/src/main/java/moa/gui/visualization/StreamOutlierPanel.java b/moa/src/main/java/moa/gui/visualization/StreamOutlierPanel.java index 039619ad8..58f95e1a7 100644 --- a/moa/src/main/java/moa/gui/visualization/StreamOutlierPanel.java +++ b/moa/src/main/java/moa/gui/visualization/StreamOutlierPanel.java @@ -20,19 +20,31 @@ package moa.gui.visualization; -import java.awt.*; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.RenderingHints; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.RescaleOp; -import java.io.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; + import javax.imageio.ImageIO; import javax.swing.JPanel; import javax.swing.JScrollPane; + import moa.cluster.SphereCluster; import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.MyBaseOutlierDetector.Outlier; diff --git a/moa/src/main/java/moa/gui/visualization/WekaExplorer.java b/moa/src/main/java/moa/gui/visualization/WekaExplorer.java index cfc1d5254..6ed93c826 100644 --- a/moa/src/main/java/moa/gui/visualization/WekaExplorer.java +++ b/moa/src/main/java/moa/gui/visualization/WekaExplorer.java @@ -27,18 +27,21 @@ package moa.gui.visualization; -import weka.gui.explorer.Explorer; -import weka.core.Memory; //import weka.gui.LookAndFeel; import java.awt.BorderLayout; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; + import javax.swing.JFrame; + import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; +import weka.core.Memory; +import weka.gui.explorer.Explorer; + public class WekaExplorer { diff --git a/moa/src/main/java/moa/learners/ChangeDetectorLearner.java b/moa/src/main/java/moa/learners/ChangeDetectorLearner.java index db3abce46..d13d93025 100644 --- a/moa/src/main/java/moa/learners/ChangeDetectorLearner.java +++ b/moa/src/main/java/moa/learners/ChangeDetectorLearner.java @@ -19,9 +19,10 @@ package moa.learners; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; -import moa.core.Measurement; import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.core.Measurement; import moa.options.ClassOption; /** diff --git a/moa/src/main/java/moa/learners/Learner.java b/moa/src/main/java/moa/learners/Learner.java index 5d700571e..823e8797f 100644 --- a/moa/src/main/java/moa/learners/Learner.java +++ b/moa/src/main/java/moa/learners/Learner.java @@ -19,13 +19,11 @@ */ package moa.learners; -import moa.MOAObject; -import moa.core.Example; - -import com.yahoo.labs.samoa.instances.InstanceData; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Prediction; +import moa.MOAObject; +import moa.core.Example; import moa.core.Measurement; import moa.gui.AWTRenderable; import moa.options.OptionHandler; diff --git a/moa/src/main/java/moa/options/AbstractClassOption.java b/moa/src/main/java/moa/options/AbstractClassOption.java index 00b0a10c0..70e1af183 100644 --- a/moa/src/main/java/moa/options/AbstractClassOption.java +++ b/moa/src/main/java/moa/options/AbstractClassOption.java @@ -20,8 +20,10 @@ package moa.options; import java.io.File; + import com.github.javacliparser.AbstractOption; import com.github.javacliparser.SerializeUtils; + import moa.core.ObjectRepository; import moa.tasks.Task; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/options/AbstractOptionHandler.java b/moa/src/main/java/moa/options/AbstractOptionHandler.java index 622f969a4..a26009fc4 100644 --- a/moa/src/main/java/moa/options/AbstractOptionHandler.java +++ b/moa/src/main/java/moa/options/AbstractOptionHandler.java @@ -20,6 +20,7 @@ package moa.options; import com.github.javacliparser.Options; + import moa.AbstractMOAObject; import moa.core.ObjectRepository; import moa.tasks.NullMonitor; diff --git a/moa/src/main/java/moa/options/ClassOption.java b/moa/src/main/java/moa/options/ClassOption.java index 56eaf8d19..8a94d3c78 100644 --- a/moa/src/main/java/moa/options/ClassOption.java +++ b/moa/src/main/java/moa/options/ClassOption.java @@ -20,9 +20,10 @@ package moa.options; import java.io.File; + import com.github.javacliparser.Option; import com.github.javacliparser.Options; -import moa.options.OptionHandler; + import moa.tasks.Task; /** diff --git a/moa/src/main/java/moa/options/ClassOptionWithNames.java b/moa/src/main/java/moa/options/ClassOptionWithNames.java index 256dfdfc2..59959d90c 100644 --- a/moa/src/main/java/moa/options/ClassOptionWithNames.java +++ b/moa/src/main/java/moa/options/ClassOptionWithNames.java @@ -11,13 +11,11 @@ package moa.options; -import com.github.javacliparser.Options; -import com.github.javacliparser.Option; import java.io.File; -import javax.swing.JComponent; +import com.github.javacliparser.Option; +import com.github.javacliparser.Options; -import com.github.javacliparser.gui.ClassOptionWithNamesEditComponent; import moa.tasks.Task; public class ClassOptionWithNames extends AbstractClassOption { diff --git a/moa/src/main/java/moa/options/OptionHandler.java b/moa/src/main/java/moa/options/OptionHandler.java index 6faba81ad..1fac302da 100644 --- a/moa/src/main/java/moa/options/OptionHandler.java +++ b/moa/src/main/java/moa/options/OptionHandler.java @@ -21,6 +21,7 @@ import com.github.javacliparser.Configurable; import com.github.javacliparser.Options; + import moa.MOAObject; import moa.core.ObjectRepository; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/options/OptionsHandler.java b/moa/src/main/java/moa/options/OptionsHandler.java index fac313a80..42e0b54f2 100644 --- a/moa/src/main/java/moa/options/OptionsHandler.java +++ b/moa/src/main/java/moa/options/OptionsHandler.java @@ -2,8 +2,10 @@ import java.util.HashMap; + import com.github.javacliparser.JavaCLIParser; import com.github.javacliparser.Option; + import moa.core.ObjectRepository; import moa.tasks.NullMonitor; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/options/WEKAClassOption.java b/moa/src/main/java/moa/options/WEKAClassOption.java index f117dbbf9..c46d75476 100644 --- a/moa/src/main/java/moa/options/WEKAClassOption.java +++ b/moa/src/main/java/moa/options/WEKAClassOption.java @@ -20,17 +20,17 @@ */ package moa.options; -import com.github.javacliparser.Option; -import weka.core.Utils; - import java.io.File; import java.util.Enumeration; import java.util.Vector; +import com.github.javacliparser.Option; + //import javax.swing.JComponent; //import moa.gui.WEKAClassOptionEditComponent; import moa.tasks.Task; +import weka.core.Utils; /** * WEKA class option. This option is used to access options in WEKA. diff --git a/moa/src/main/java/moa/recommender/dataset/impl/FlixsterDataset.java b/moa/src/main/java/moa/recommender/dataset/impl/FlixsterDataset.java index 0f1844d5e..19841cc24 100644 --- a/moa/src/main/java/moa/recommender/dataset/impl/FlixsterDataset.java +++ b/moa/src/main/java/moa/recommender/dataset/impl/FlixsterDataset.java @@ -28,10 +28,11 @@ import java.io.InputStreamReader; import java.util.logging.Level; import java.util.logging.Logger; -import moa.core.ObjectRepository; -import moa.options.AbstractOptionHandler; + import com.github.javacliparser.FileOption; +import moa.core.ObjectRepository; +import moa.options.AbstractOptionHandler; import moa.recommender.dataset.Dataset; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/recommender/dataset/impl/JesterDataset.java b/moa/src/main/java/moa/recommender/dataset/impl/JesterDataset.java index 7ff32b3c0..13716c156 100644 --- a/moa/src/main/java/moa/recommender/dataset/impl/JesterDataset.java +++ b/moa/src/main/java/moa/recommender/dataset/impl/JesterDataset.java @@ -23,16 +23,17 @@ import java.io.BufferedReader; import java.io.DataInputStream; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; - -import moa.recommender.dataset.Dataset; -import java.io.FileNotFoundException; import java.util.logging.Level; import java.util.logging.Logger; + +import com.github.javacliparser.FileOption; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FileOption; +import moa.recommender.dataset.Dataset; import moa.tasks.TaskMonitor; public class JesterDataset extends AbstractOptionHandler implements Dataset { diff --git a/moa/src/main/java/moa/recommender/dataset/impl/MovielensDataset.java b/moa/src/main/java/moa/recommender/dataset/impl/MovielensDataset.java index 8d42e2221..66c86baa6 100644 --- a/moa/src/main/java/moa/recommender/dataset/impl/MovielensDataset.java +++ b/moa/src/main/java/moa/recommender/dataset/impl/MovielensDataset.java @@ -20,7 +20,6 @@ package moa.recommender.dataset.impl; -import moa.recommender.dataset.Dataset; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.FileInputStream; @@ -29,9 +28,12 @@ import java.io.InputStreamReader; import java.util.logging.Level; import java.util.logging.Logger; + +import com.github.javacliparser.FileOption; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FileOption; +import moa.recommender.dataset.Dataset; import moa.tasks.TaskMonitor; public class MovielensDataset extends AbstractOptionHandler implements Dataset { diff --git a/moa/src/main/java/moa/recommender/predictor/BRISMFPredictor.java b/moa/src/main/java/moa/recommender/predictor/BRISMFPredictor.java index 69932b399..8d69c8450 100644 --- a/moa/src/main/java/moa/recommender/predictor/BRISMFPredictor.java +++ b/moa/src/main/java/moa/recommender/predictor/BRISMFPredictor.java @@ -21,11 +21,13 @@ package moa.recommender.predictor; import java.util.List; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.recommender.data.RecommenderData; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/recommender/predictor/BaselinePredictor.java b/moa/src/main/java/moa/recommender/predictor/BaselinePredictor.java index 3433ff24b..1ca885c1e 100644 --- a/moa/src/main/java/moa/recommender/predictor/BaselinePredictor.java +++ b/moa/src/main/java/moa/recommender/predictor/BaselinePredictor.java @@ -21,6 +21,7 @@ package moa.recommender.predictor; import java.util.List; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/recommender/predictor/RatingPredictor.java b/moa/src/main/java/moa/recommender/predictor/RatingPredictor.java index 911864980..839821251 100644 --- a/moa/src/main/java/moa/recommender/predictor/RatingPredictor.java +++ b/moa/src/main/java/moa/recommender/predictor/RatingPredictor.java @@ -22,6 +22,7 @@ import java.io.Serializable; import java.util.List; + import moa.recommender.rc.data.RecommenderData; /** diff --git a/moa/src/main/java/moa/recommender/rc/data/AbstractRecommenderData.java b/moa/src/main/java/moa/recommender/rc/data/AbstractRecommenderData.java index b3d6cab0b..8c755448f 100644 --- a/moa/src/main/java/moa/recommender/rc/data/AbstractRecommenderData.java +++ b/moa/src/main/java/moa/recommender/rc/data/AbstractRecommenderData.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; + import moa.recommender.rc.utils.Updatable; diff --git a/moa/src/main/java/moa/recommender/rc/data/RecommenderData.java b/moa/src/main/java/moa/recommender/rc/data/RecommenderData.java index 455f29f5c..d986dcee2 100644 --- a/moa/src/main/java/moa/recommender/rc/data/RecommenderData.java +++ b/moa/src/main/java/moa/recommender/rc/data/RecommenderData.java @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; + import moa.recommender.rc.utils.Rating; import moa.recommender.rc.utils.SparseVector; import moa.recommender.rc.utils.Updatable; diff --git a/moa/src/main/java/moa/recommender/rc/data/impl/MemRecommenderData.java b/moa/src/main/java/moa/recommender/rc/data/impl/MemRecommenderData.java index 9e61cbe83..af9b55f9c 100644 --- a/moa/src/main/java/moa/recommender/rc/data/impl/MemRecommenderData.java +++ b/moa/src/main/java/moa/recommender/rc/data/impl/MemRecommenderData.java @@ -27,6 +27,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; + import moa.recommender.rc.data.AbstractRecommenderData; import moa.recommender.rc.utils.Rating; import moa.recommender.rc.utils.SparseVector; diff --git a/moa/src/main/java/moa/recommender/rc/predictor/RatingPredictor.java b/moa/src/main/java/moa/recommender/rc/predictor/RatingPredictor.java index d160de6f2..9033917f9 100644 --- a/moa/src/main/java/moa/recommender/rc/predictor/RatingPredictor.java +++ b/moa/src/main/java/moa/recommender/rc/predictor/RatingPredictor.java @@ -22,6 +22,7 @@ import java.io.Serializable; import java.util.List; + import moa.recommender.rc.data.RecommenderData; public interface RatingPredictor extends Serializable { diff --git a/moa/src/main/java/moa/recommender/rc/predictor/impl/BRISMFPredictor.java b/moa/src/main/java/moa/recommender/rc/predictor/impl/BRISMFPredictor.java index ccc6e1e25..936496e73 100644 --- a/moa/src/main/java/moa/recommender/rc/predictor/impl/BRISMFPredictor.java +++ b/moa/src/main/java/moa/recommender/rc/predictor/impl/BRISMFPredictor.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.List; import java.util.Random; + import moa.recommender.rc.data.RecommenderData; import moa.recommender.rc.utils.Pair; import moa.recommender.rc.utils.Rating; diff --git a/moa/src/main/java/moa/recommender/rc/predictor/impl/BaselinePredictor.java b/moa/src/main/java/moa/recommender/rc/predictor/impl/BaselinePredictor.java index cfc22b2e2..6411ce6e9 100644 --- a/moa/src/main/java/moa/recommender/rc/predictor/impl/BaselinePredictor.java +++ b/moa/src/main/java/moa/recommender/rc/predictor/impl/BaselinePredictor.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; + import moa.recommender.rc.data.RecommenderData; import moa.recommender.rc.predictor.RatingPredictor; diff --git a/moa/src/main/java/moa/streams/ArffFileStream.java b/moa/src/main/java/moa/streams/ArffFileStream.java index 81d639198..3161ac6ba 100644 --- a/moa/src/main/java/moa/streams/ArffFileStream.java +++ b/moa/src/main/java/moa/streams/ArffFileStream.java @@ -19,17 +19,17 @@ */ package moa.streams; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.StringOption; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.Reader; +import java.io.Reader; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.StringOption; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.InputStreamProgressMonitor; import moa.core.InstanceExample; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/streams/CachedInstancesStream.java b/moa/src/main/java/moa/streams/CachedInstancesStream.java index bb618fac8..bd260db04 100644 --- a/moa/src/main/java/moa/streams/CachedInstancesStream.java +++ b/moa/src/main/java/moa/streams/CachedInstancesStream.java @@ -19,11 +19,10 @@ */ package moa.streams; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.AbstractMOAObject; import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator for representing a stream that is cached in memory. diff --git a/moa/src/main/java/moa/streams/ConceptDriftRealStream.java b/moa/src/main/java/moa/streams/ConceptDriftRealStream.java index 46c30398a..b0bd8b18e 100644 --- a/moa/src/main/java/moa/streams/ConceptDriftRealStream.java +++ b/moa/src/main/java/moa/streams/ConceptDriftRealStream.java @@ -19,24 +19,20 @@ */ package moa.streams; +import java.util.Random; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; -import moa.core.utils.AttributeDefinitionUtil; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/ConceptDriftStream.java b/moa/src/main/java/moa/streams/ConceptDriftStream.java index 19ff13c49..50de9fa90 100644 --- a/moa/src/main/java/moa/streams/ConceptDriftStream.java +++ b/moa/src/main/java/moa/streams/ConceptDriftStream.java @@ -20,16 +20,16 @@ package moa.streams; import java.util.Random; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; -import moa.core.InstanceExample; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator that adds concept drift to examples in a stream. diff --git a/moa/src/main/java/moa/streams/ExampleStream.java b/moa/src/main/java/moa/streams/ExampleStream.java index 20877597a..d06f4d915 100644 --- a/moa/src/main/java/moa/streams/ExampleStream.java +++ b/moa/src/main/java/moa/streams/ExampleStream.java @@ -19,12 +19,11 @@ */ package moa.streams; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.MOAObject; import moa.core.Example; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; - /** * Interface representing a data stream of examples. * diff --git a/moa/src/main/java/moa/streams/InstanceStream.java b/moa/src/main/java/moa/streams/InstanceStream.java index 83e246300..530201337 100644 --- a/moa/src/main/java/moa/streams/InstanceStream.java +++ b/moa/src/main/java/moa/streams/InstanceStream.java @@ -19,9 +19,10 @@ */ package moa.streams; -import moa.core.Example; import com.yahoo.labs.samoa.instances.Instance; +import moa.core.Example; + /** * Interface representing a data stream of instances. * diff --git a/moa/src/main/java/moa/streams/MultiFilteredStream.java b/moa/src/main/java/moa/streams/MultiFilteredStream.java index befa684b6..b4247be27 100644 --- a/moa/src/main/java/moa/streams/MultiFilteredStream.java +++ b/moa/src/main/java/moa/streams/MultiFilteredStream.java @@ -19,18 +19,17 @@ */ package moa.streams; +import com.github.javacliparser.ListOption; +import com.github.javacliparser.Option; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; -import moa.core.InstanceExample; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; -import com.github.javacliparser.ListOption; -import com.github.javacliparser.Option; import moa.options.OptionHandler; import moa.streams.filters.StreamFilter; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Class for representing a stream that is filtered. diff --git a/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java b/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java index f7c8bdf79..dd722fc2b 100644 --- a/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java +++ b/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java @@ -28,7 +28,6 @@ import moa.options.OptionHandler; import moa.streams.filters.MultiLabelStreamFilter; import moa.streams.filters.SelectAttributesFilter; -import moa.streams.filters.StreamFilter; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java index 9ade14c76..54fe69cee 100644 --- a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java +++ b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java @@ -19,21 +19,6 @@ */ package moa.streams; -import com.github.javacliparser.FileOption; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import moa.core.InputStreamProgressMonitor; -import moa.core.InstanceExample; -import moa.core.ObjectRepository; -import moa.options.AbstractOptionHandler; -import moa.tasks.TaskMonitor; - /** * Stream reader of ARFF files. * diff --git a/moa/src/main/java/moa/streams/MultiTargetInstanceStream.java b/moa/src/main/java/moa/streams/MultiTargetInstanceStream.java index 6e706a8e1..6b5432c90 100644 --- a/moa/src/main/java/moa/streams/MultiTargetInstanceStream.java +++ b/moa/src/main/java/moa/streams/MultiTargetInstanceStream.java @@ -19,9 +19,6 @@ */ package moa.streams; -import moa.core.Example; -import com.yahoo.labs.samoa.instances.Instance; - /** * Interface representing a data stream of instances. * diff --git a/moa/src/main/java/moa/streams/RecurrentConceptDriftStream.java b/moa/src/main/java/moa/streams/RecurrentConceptDriftStream.java index 54476e78a..1082192f9 100644 --- a/moa/src/main/java/moa/streams/RecurrentConceptDriftStream.java +++ b/moa/src/main/java/moa/streams/RecurrentConceptDriftStream.java @@ -20,12 +20,13 @@ */ package moa.streams; -import moa.core.Example; import java.util.Random; + +import com.github.javacliparser.IntOption; + +import moa.core.Example; import moa.core.ObjectRepository; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.github.javacliparser.IntOption; diff --git a/moa/src/main/java/moa/streams/clustering/ClusteringStream.java b/moa/src/main/java/moa/streams/clustering/ClusteringStream.java index e7c2b4bf8..c40660b02 100644 --- a/moa/src/main/java/moa/streams/clustering/ClusteringStream.java +++ b/moa/src/main/java/moa/streams/clustering/ClusteringStream.java @@ -20,9 +20,10 @@ package moa.streams.clustering; -import moa.options.AbstractOptionHandler; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; + +import moa.options.AbstractOptionHandler; import moa.streams.InstanceStream; public abstract class ClusteringStream extends AbstractOptionHandler implements InstanceStream{ diff --git a/moa/src/main/java/moa/streams/clustering/FileStream.java b/moa/src/main/java/moa/streams/clustering/FileStream.java index bd8458fff..422fc23a1 100644 --- a/moa/src/main/java/moa/streams/clustering/FileStream.java +++ b/moa/src/main/java/moa/streams/clustering/FileStream.java @@ -34,23 +34,21 @@ import java.util.Arrays; import java.util.HashSet; -import moa.core.InputStreamProgressMonitor; -import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import moa.core.ObjectRepository; -import moa.core.utils.AttributeDefinitionUtil; - import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.ListOption; import com.github.javacliparser.Option; import com.github.javacliparser.StringOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InputStreamProgressMonitor; +import moa.core.InstanceExample; +import moa.core.ObjectRepository; +import moa.core.utils.AttributeDefinitionUtil; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; - public class FileStream extends ClusteringStream{ @Override diff --git a/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java b/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java index 84b15eebc..f26ca664e 100644 --- a/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java +++ b/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java @@ -31,23 +31,22 @@ import java.util.Random; import java.util.Vector; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.core.AutoExpandVector; import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.gui.visualization.DataPoint; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class RandomRBFGeneratorEvents extends ClusteringStream { diff --git a/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java b/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java index fe46621be..946b5d728 100644 --- a/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java +++ b/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java @@ -34,7 +34,6 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.InputStreamProgressMonitor; import moa.core.InstanceExample; diff --git a/moa/src/main/java/moa/streams/filters/AbstractMultiLabelStreamFilter.java b/moa/src/main/java/moa/streams/filters/AbstractMultiLabelStreamFilter.java index e099e7ba3..4206ba4ca 100644 --- a/moa/src/main/java/moa/streams/filters/AbstractMultiLabelStreamFilter.java +++ b/moa/src/main/java/moa/streams/filters/AbstractMultiLabelStreamFilter.java @@ -25,7 +25,6 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/filters/AbstractStreamFilter.java b/moa/src/main/java/moa/streams/filters/AbstractStreamFilter.java index dd6d3ffbb..29b691cc1 100644 --- a/moa/src/main/java/moa/streams/filters/AbstractStreamFilter.java +++ b/moa/src/main/java/moa/streams/filters/AbstractStreamFilter.java @@ -20,11 +20,11 @@ package moa.streams.filters; import com.yahoo.labs.samoa.instances.Instance; + import moa.core.InstanceExample; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java b/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java index c7968e479..7787ae0b1 100644 --- a/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java +++ b/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java @@ -21,16 +21,15 @@ import java.util.Random; -import moa.core.AutoExpandVector; -import moa.core.DoubleVector; -import moa.core.GaussianEstimator; -import moa.core.InstanceExample; - import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.GaussianEstimator; + /** * Filter for adding random noise to examples in a stream. * Noise can be added to attribute values or to class labels. diff --git a/moa/src/main/java/moa/streams/filters/RBFFilter.java b/moa/src/main/java/moa/streams/filters/RBFFilter.java index df300eb65..3a7e787a8 100644 --- a/moa/src/main/java/moa/streams/filters/RBFFilter.java +++ b/moa/src/main/java/moa/streams/filters/RBFFilter.java @@ -4,14 +4,14 @@ import java.util.List; import java.util.Random; -import moa.core.InstanceExample; - import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InstanceExample; + public class RBFFilter extends AbstractStreamFilter { /** diff --git a/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java b/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java index f2143f080..d5e49c595 100644 --- a/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java +++ b/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java @@ -21,14 +21,15 @@ import java.util.ArrayList; import java.util.List; -import moa.core.InstanceExample; -import moa.streams.InstanceStream; + import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SparseInstance; + import moa.core.FastVector; +import moa.core.InstanceExample; +import moa.streams.InstanceStream; /** * Filter for removing discrete attributes in instances of a stream. diff --git a/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java b/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java index fefe7f955..718de5a27 100644 --- a/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java +++ b/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java @@ -19,11 +19,6 @@ */ package moa.streams.filters; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; - import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -31,6 +26,12 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.InstanceExample; diff --git a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java index 5270011e2..3847bb637 100644 --- a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java +++ b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java @@ -3,14 +3,14 @@ import java.util.ArrayList; import java.util.List; -import moa.core.InstanceExample; - import com.github.javacliparser.StringOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InstanceExample; + public class SelectAttributesFilter extends AbstractMultiLabelStreamFilter implements MultiLabelStreamFilter{ /** diff --git a/moa/src/main/java/moa/streams/filters/StreamFilter.java b/moa/src/main/java/moa/streams/filters/StreamFilter.java index 2f866dc64..9b864d63a 100644 --- a/moa/src/main/java/moa/streams/filters/StreamFilter.java +++ b/moa/src/main/java/moa/streams/filters/StreamFilter.java @@ -20,6 +20,7 @@ package moa.streams.filters; import com.yahoo.labs.samoa.instances.Instance; + import moa.streams.ExampleStream; /** diff --git a/moa/src/main/java/moa/streams/generators/AgrawalGenerator.java b/moa/src/main/java/moa/streams/generators/AgrawalGenerator.java index b6fd685eb..9af709ce6 100644 --- a/moa/src/main/java/moa/streams/generators/AgrawalGenerator.java +++ b/moa/src/main/java/moa/streams/generators/AgrawalGenerator.java @@ -19,23 +19,20 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; -import moa.core.Example; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import moa.streams.ExampleStream; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/HyperplaneGenerator.java b/moa/src/main/java/moa/streams/generators/HyperplaneGenerator.java index be6e6aa71..cfaac82ee 100644 --- a/moa/src/main/java/moa/streams/generators/HyperplaneGenerator.java +++ b/moa/src/main/java/moa/streams/generators/HyperplaneGenerator.java @@ -20,19 +20,20 @@ package moa.streams.generators; import java.util.Random; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.FastVector; import moa.core.InstanceExample; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator for Hyperplane data stream. diff --git a/moa/src/main/java/moa/streams/generators/LEDGenerator.java b/moa/src/main/java/moa/streams/generators/LEDGenerator.java index a57fb1dc1..8479c9479 100644 --- a/moa/src/main/java/moa/streams/generators/LEDGenerator.java +++ b/moa/src/main/java/moa/streams/generators/LEDGenerator.java @@ -19,20 +19,19 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/LEDGeneratorDrift.java b/moa/src/main/java/moa/streams/generators/LEDGeneratorDrift.java index 26ee76a89..01ab912ce 100644 --- a/moa/src/main/java/moa/streams/generators/LEDGeneratorDrift.java +++ b/moa/src/main/java/moa/streams/generators/LEDGeneratorDrift.java @@ -19,13 +19,13 @@ */ package moa.streams.generators; -import moa.core.InstanceExample; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InstanceExample; import moa.core.ObjectRepository; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/generators/RandomRBFGenerator.java b/moa/src/main/java/moa/streams/generators/RandomRBFGenerator.java index cbbe0202c..fc67d6ab9 100644 --- a/moa/src/main/java/moa/streams/generators/RandomRBFGenerator.java +++ b/moa/src/main/java/moa/streams/generators/RandomRBFGenerator.java @@ -19,21 +19,20 @@ */ package moa.streams.generators; +import java.io.Serializable; +import java.util.Random; + +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.io.Serializable; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.MiscUtils; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/RandomRBFGeneratorDrift.java b/moa/src/main/java/moa/streams/generators/RandomRBFGeneratorDrift.java index c437a4a95..abcb14e32 100644 --- a/moa/src/main/java/moa/streams/generators/RandomRBFGeneratorDrift.java +++ b/moa/src/main/java/moa/streams/generators/RandomRBFGeneratorDrift.java @@ -20,11 +20,11 @@ package moa.streams.generators; import java.util.Random; -import moa.core.InstanceExample; -import com.github.javacliparser.IntOption; import com.github.javacliparser.FloatOption; -import com.yahoo.labs.samoa.instances.Instance; +import com.github.javacliparser.IntOption; + +import moa.core.InstanceExample; /** * Stream generator for a random radial basis function stream with drift. diff --git a/moa/src/main/java/moa/streams/generators/RandomTreeGenerator.java b/moa/src/main/java/moa/streams/generators/RandomTreeGenerator.java index 282618a02..157ce8adb 100644 --- a/moa/src/main/java/moa/streams/generators/RandomTreeGenerator.java +++ b/moa/src/main/java/moa/streams/generators/RandomTreeGenerator.java @@ -19,22 +19,21 @@ */ package moa.streams.generators; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Random; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/SEAGenerator.java b/moa/src/main/java/moa/streams/generators/SEAGenerator.java index 06da33f07..e4ede9220 100644 --- a/moa/src/main/java/moa/streams/generators/SEAGenerator.java +++ b/moa/src/main/java/moa/streams/generators/SEAGenerator.java @@ -19,20 +19,19 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/STAGGERGenerator.java b/moa/src/main/java/moa/streams/generators/STAGGERGenerator.java index a92118e17..def9e5ee4 100644 --- a/moa/src/main/java/moa/streams/generators/STAGGERGenerator.java +++ b/moa/src/main/java/moa/streams/generators/STAGGERGenerator.java @@ -19,20 +19,19 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/WaveformGenerator.java b/moa/src/main/java/moa/streams/generators/WaveformGenerator.java index f66e5b0ff..06cc45350 100644 --- a/moa/src/main/java/moa/streams/generators/WaveformGenerator.java +++ b/moa/src/main/java/moa/streams/generators/WaveformGenerator.java @@ -19,20 +19,19 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/WaveformGeneratorDrift.java b/moa/src/main/java/moa/streams/generators/WaveformGeneratorDrift.java index c918ad8b3..e5b17cfdb 100644 --- a/moa/src/main/java/moa/streams/generators/WaveformGeneratorDrift.java +++ b/moa/src/main/java/moa/streams/generators/WaveformGeneratorDrift.java @@ -20,13 +20,13 @@ */ package moa.streams.generators; -import moa.core.InstanceExample; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InstanceExample; import moa.core.ObjectRepository; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/generators/cd/AbstractConceptDriftGenerator.java b/moa/src/main/java/moa/streams/generators/cd/AbstractConceptDriftGenerator.java index 7dd440d98..6a1ae7979 100644 --- a/moa/src/main/java/moa/streams/generators/cd/AbstractConceptDriftGenerator.java +++ b/moa/src/main/java/moa/streams/generators/cd/AbstractConceptDriftGenerator.java @@ -19,15 +19,16 @@ */ package moa.streams.generators.cd; +import java.util.ArrayList; +import java.util.Random; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.ArrayList; -import java.util.Random; + import moa.core.FastVector; import moa.core.InstanceExample; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/streams/generators/cd/ConceptDriftGenerator.java b/moa/src/main/java/moa/streams/generators/cd/ConceptDriftGenerator.java index 02ed7c229..732885aa7 100644 --- a/moa/src/main/java/moa/streams/generators/cd/ConceptDriftGenerator.java +++ b/moa/src/main/java/moa/streams/generators/cd/ConceptDriftGenerator.java @@ -20,6 +20,7 @@ package moa.streams.generators.cd; import java.util.ArrayList; + import moa.streams.InstanceStream; import moa.streams.clustering.ClusterEvent; diff --git a/moa/src/main/java/moa/streams/generators/multilabel/MetaMultilabelGenerator.java b/moa/src/main/java/moa/streams/generators/multilabel/MetaMultilabelGenerator.java index 62536ddc5..f2ac3625e 100644 --- a/moa/src/main/java/moa/streams/generators/multilabel/MetaMultilabelGenerator.java +++ b/moa/src/main/java/moa/streams/generators/multilabel/MetaMultilabelGenerator.java @@ -19,22 +19,32 @@ */ package moa.streams.generators.multilabel; -import java.util.*; -import moa.core.InstanceExample; -import moa.core.MultilabelInstancesHeader; -import moa.core.ObjectRepository; -import moa.options.AbstractOptionHandler; -import moa.options.ClassOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; -import moa.streams.InstanceStream; -import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SparseInstance; + import moa.core.FastVector; +import moa.core.InstanceExample; +import moa.core.MultilabelInstancesHeader; +import moa.core.ObjectRepository; import moa.core.Utils; +import moa.options.AbstractOptionHandler; +import moa.options.ClassOption; +import moa.streams.InstanceStream; +import moa.tasks.TaskMonitor; /** * Stream generator for multilabel data. diff --git a/moa/src/main/java/moa/streams/generators/multilabel/MultilabelArffFileStream.java b/moa/src/main/java/moa/streams/generators/multilabel/MultilabelArffFileStream.java index cec7e0aa4..064d4fae0 100644 --- a/moa/src/main/java/moa/streams/generators/multilabel/MultilabelArffFileStream.java +++ b/moa/src/main/java/moa/streams/generators/multilabel/MultilabelArffFileStream.java @@ -19,13 +19,13 @@ */ package moa.streams.generators.multilabel; -import moa.streams.ArffFileStream; -import moa.streams.MultiTargetInstanceStream; -import moa.core.MultilabelInstancesHeader; - import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.MultilabelInstancesHeader; +import moa.streams.ArffFileStream; +import moa.streams.MultiTargetInstanceStream; + /** * Stream reader for ARFF files of multilabel data. * diff --git a/moa/src/main/java/moa/tasks/CacheShuffledStream.java b/moa/src/main/java/moa/tasks/CacheShuffledStream.java index ae50c8c53..91cf2194f 100644 --- a/moa/src/main/java/moa/tasks/CacheShuffledStream.java +++ b/moa/src/main/java/moa/tasks/CacheShuffledStream.java @@ -21,10 +21,11 @@ import java.util.Random; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.ObjectRepository; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.streams.CachedInstancesStream; import moa.streams.InstanceStream; diff --git a/moa/src/main/java/moa/tasks/ConceptDriftMainTask.java b/moa/src/main/java/moa/tasks/ConceptDriftMainTask.java index a5841fc12..1cdfcf560 100644 --- a/moa/src/main/java/moa/tasks/ConceptDriftMainTask.java +++ b/moa/src/main/java/moa/tasks/ConceptDriftMainTask.java @@ -20,6 +20,7 @@ package moa.tasks; import java.util.ArrayList; + import moa.streams.clustering.ClusterEvent; public abstract class ConceptDriftMainTask extends MainTask { diff --git a/moa/src/main/java/moa/tasks/EvaluateClustering.java b/moa/src/main/java/moa/tasks/EvaluateClustering.java index 0fc7f4f62..df03b8498 100644 --- a/moa/src/main/java/moa/tasks/EvaluateClustering.java +++ b/moa/src/main/java/moa/tasks/EvaluateClustering.java @@ -8,13 +8,14 @@ */ package moa.tasks; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; + import moa.clusterers.AbstractClusterer; import moa.core.ObjectRepository; import moa.evaluation.LearningCurve; import moa.gui.BatchCmd; import moa.options.ClassOption; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; import moa.streams.clustering.ClusteringStream; /** diff --git a/moa/src/main/java/moa/tasks/EvaluateConceptDrift.java b/moa/src/main/java/moa/tasks/EvaluateConceptDrift.java index 5f268ebb4..c59a965f9 100644 --- a/moa/src/main/java/moa/tasks/EvaluateConceptDrift.java +++ b/moa/src/main/java/moa/tasks/EvaluateConceptDrift.java @@ -20,12 +20,14 @@ */ package moa.tasks; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; @@ -35,7 +37,6 @@ import moa.evaluation.LearningPerformanceEvaluator; import moa.learners.ChangeDetectorLearner; import moa.options.ClassOption; - import moa.streams.clustering.ClusterEvent; import moa.streams.generators.cd.ConceptDriftGenerator; diff --git a/moa/src/main/java/moa/tasks/EvaluateInterleavedChunks.java b/moa/src/main/java/moa/tasks/EvaluateInterleavedChunks.java index f8c78b6bb..5ce5a1ec2 100644 --- a/moa/src/main/java/moa/tasks/EvaluateInterleavedChunks.java +++ b/moa/src/main/java/moa/tasks/EvaluateInterleavedChunks.java @@ -22,7 +22,12 @@ import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; -import moa.classifiers.Classifier; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; import moa.core.InstanceExample; import moa.core.Measurement; @@ -33,12 +38,7 @@ import moa.evaluation.LearningPerformanceEvaluator; import moa.learners.Learner; import moa.options.ClassOption; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class EvaluateInterleavedChunks extends MainTask { diff --git a/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java b/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java index 36791f102..46f6ca2c2 100644 --- a/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java +++ b/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java @@ -23,7 +23,9 @@ import java.io.FileOutputStream; import java.io.PrintStream; -import moa.classifiers.Classifier; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; @@ -33,11 +35,8 @@ import moa.evaluation.LearningPerformanceEvaluator; import moa.learners.Learner; import moa.options.ClassOption; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; /** * Task for evaluating a classifier on a stream by testing then training with each example in sequence. diff --git a/moa/src/main/java/moa/tasks/EvaluateModel.java b/moa/src/main/java/moa/tasks/EvaluateModel.java index 8a0a04cc1..9ee1feeec 100644 --- a/moa/src/main/java/moa/tasks/EvaluateModel.java +++ b/moa/src/main/java/moa/tasks/EvaluateModel.java @@ -22,8 +22,11 @@ import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; + import com.github.javacliparser.FileOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.Classifier; import moa.core.Example; import moa.core.ObjectRepository; @@ -34,7 +37,6 @@ import moa.options.ClassOption; import moa.streams.ExampleStream; import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; /** * Task for evaluating a static model on a stream. diff --git a/moa/src/main/java/moa/tasks/EvaluateModelMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluateModelMultiTarget.java index df5d18631..0ef68f18f 100644 --- a/moa/src/main/java/moa/tasks/EvaluateModelMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluateModelMultiTarget.java @@ -19,12 +19,14 @@ */ package moa.tasks; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.Classifier; import moa.classifiers.MultiTargetRegressor; import moa.core.Example; diff --git a/moa/src/main/java/moa/tasks/EvaluateModelRegression.java b/moa/src/main/java/moa/tasks/EvaluateModelRegression.java index 34b57232c..3e7318e1a 100644 --- a/moa/src/main/java/moa/tasks/EvaluateModelRegression.java +++ b/moa/src/main/java/moa/tasks/EvaluateModelRegression.java @@ -22,13 +22,15 @@ import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; + import com.github.javacliparser.FileOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.Classifier; import moa.classifiers.Regressor; import moa.core.Example; import moa.core.ObjectRepository; -import moa.core.Utils; import moa.evaluation.LearningEvaluation; import moa.evaluation.LearningPerformanceEvaluator; import moa.evaluation.RegressionPerformanceEvaluator; @@ -36,7 +38,6 @@ import moa.options.ClassOption; import moa.streams.ExampleStream; import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; /** * Task for evaluating a static model on a stream. diff --git a/moa/src/main/java/moa/tasks/EvaluateOnlineRecommender.java b/moa/src/main/java/moa/tasks/EvaluateOnlineRecommender.java index 0fbc8cb32..470382d9c 100644 --- a/moa/src/main/java/moa/tasks/EvaluateOnlineRecommender.java +++ b/moa/src/main/java/moa/tasks/EvaluateOnlineRecommender.java @@ -19,12 +19,13 @@ */ package moa.tasks; +import com.github.javacliparser.IntOption; + import moa.core.Measurement; import moa.core.ObjectRepository; import moa.evaluation.LearningCurve; import moa.evaluation.LearningEvaluation; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.recommender.dataset.Dataset; import moa.recommender.predictor.RatingPredictor; import moa.recommender.rc.data.RecommenderData; diff --git a/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java b/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java index fac762d2f..3457c743a 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java +++ b/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java @@ -25,9 +25,13 @@ import java.io.PrintStream; import java.util.ArrayList; import java.util.List; + import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; @@ -40,8 +44,6 @@ import moa.options.ClassOption; import moa.streams.CachedInstancesStream; import moa.streams.ExampleStream; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Task for evaluating a classifier on a stream by periodically testing on a heldout set. diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequential.java b/moa/src/main/java/moa/tasks/EvaluatePrequential.java index be9e8252d..a2284a403 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequential.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequential.java @@ -24,27 +24,25 @@ import java.io.FileOutputStream; import java.io.PrintStream; -import moa.classifiers.Classifier; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.TimingUtils; -import moa.evaluation.WindowClassificationPerformanceEvaluator; +import moa.core.Utils; import moa.evaluation.EWMAClassificationPerformanceEvaluator; import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; import moa.evaluation.LearningCurve; import moa.evaluation.LearningEvaluation; import moa.evaluation.LearningPerformanceEvaluator; +import moa.evaluation.WindowClassificationPerformanceEvaluator; import moa.learners.Learner; import moa.options.ClassOption; - -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; -import moa.core.Utils; /** * Task for evaluating a classifier on a stream by testing then training with each example in sequence. diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialCV.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialCV.java index 87ea7c9c7..e3eefcee4 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialCV.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialCV.java @@ -20,18 +20,6 @@ */ package moa.tasks; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; -import moa.classifiers.Classifier; -import moa.core.*; -import moa.evaluation.*; -import moa.learners.Learner; -import moa.options.ClassOption; -import moa.streams.ExampleStream; - import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; @@ -40,6 +28,22 @@ import java.util.List; import java.util.Random; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; + +import moa.core.Example; +import moa.core.Measurement; +import moa.core.MiscUtils; +import moa.core.ObjectRepository; +import moa.core.TimingUtils; +import moa.evaluation.LearningCurve; +import moa.evaluation.LearningEvaluation; +import moa.evaluation.LearningPerformanceEvaluator; +import moa.learners.Learner; +import moa.options.ClassOption; +import moa.streams.ExampleStream; + /** * Task for prequential cross-validation evaluation of a classifier on a stream by testing then training with each * example in sequence and doing cross-validation at the same time. diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index 61f2ee877..22f209cfe 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -20,19 +20,17 @@ */ package moa.tasks; +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; + import com.github.javacliparser.FileOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; import com.yahoo.labs.samoa.instances.Prediction; -import java.io.File; -import java.io.FileOutputStream; -import java.io.PrintStream; - import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.Regressor; import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; @@ -43,7 +41,6 @@ import moa.evaluation.LearningEvaluation; import moa.evaluation.LearningPerformanceEvaluator; import moa.evaluation.MultiTargetPerformanceEvaluator; -import moa.evaluation.RegressionPerformanceEvaluator; import moa.evaluation.WindowClassificationPerformanceEvaluator; import moa.learners.Learner; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java index 7a3d8b059..56996cb47 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java @@ -24,32 +24,28 @@ import java.io.FileOutputStream; import java.io.PrintStream; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + +import moa.classifiers.Regressor; import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.TimingUtils; -import moa.evaluation.WindowClassificationPerformanceEvaluator; import moa.evaluation.EWMAClassificationPerformanceEvaluator; import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; import moa.evaluation.LearningCurve; import moa.evaluation.LearningEvaluation; import moa.evaluation.LearningPerformanceEvaluator; +import moa.evaluation.RegressionPerformanceEvaluator; +import moa.evaluation.WindowClassificationPerformanceEvaluator; import moa.learners.Learner; import moa.options.ClassOption; - -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; - -import moa.classifiers.Regressor; import moa.streams.ExampleStream; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - -import moa.evaluation.RegressionPerformanceEvaluator; - /** * Task for evaluating a classifier on a stream by testing then training with each example in sequence. * diff --git a/moa/src/main/java/moa/tasks/LearnModel.java b/moa/src/main/java/moa/tasks/LearnModel.java index a38b6f97c..b9b104300 100644 --- a/moa/src/main/java/moa/tasks/LearnModel.java +++ b/moa/src/main/java/moa/tasks/LearnModel.java @@ -19,11 +19,12 @@ */ package moa.tasks; +import com.github.javacliparser.IntOption; + import moa.classifiers.Classifier; import moa.core.ObjectRepository; import moa.learners.Learner; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; import moa.streams.InstanceStream; diff --git a/moa/src/main/java/moa/tasks/LearnModelMultiTarget.java b/moa/src/main/java/moa/tasks/LearnModelMultiTarget.java index e1ce7f43f..14f30af31 100644 --- a/moa/src/main/java/moa/tasks/LearnModelMultiTarget.java +++ b/moa/src/main/java/moa/tasks/LearnModelMultiTarget.java @@ -20,6 +20,7 @@ package moa.tasks; import com.github.javacliparser.IntOption; + import moa.classifiers.Classifier; import moa.classifiers.MultiTargetRegressor; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/tasks/LearnModelRegression.java b/moa/src/main/java/moa/tasks/LearnModelRegression.java index 84e1cca2e..4869602e3 100644 --- a/moa/src/main/java/moa/tasks/LearnModelRegression.java +++ b/moa/src/main/java/moa/tasks/LearnModelRegression.java @@ -19,12 +19,13 @@ */ package moa.tasks; +import com.github.javacliparser.IntOption; + import moa.classifiers.Classifier; +import moa.classifiers.Regressor; import moa.core.ObjectRepository; import moa.learners.Learner; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; -import moa.classifiers.Regressor; import moa.streams.ExampleStream; import moa.streams.InstanceStream; diff --git a/moa/src/main/java/moa/tasks/MainTask.java b/moa/src/main/java/moa/tasks/MainTask.java index cc5498311..4a62e816f 100644 --- a/moa/src/main/java/moa/tasks/MainTask.java +++ b/moa/src/main/java/moa/tasks/MainTask.java @@ -23,9 +23,10 @@ import java.io.IOException; import java.io.Serializable; +import com.github.javacliparser.FileOption; + import moa.core.ObjectRepository; import moa.core.SerializeUtils; -import com.github.javacliparser.FileOption; /** * Abstract Main Task. All tasks that want to write their result diff --git a/moa/src/main/java/moa/tasks/MeasureStreamSpeed.java b/moa/src/main/java/moa/tasks/MeasureStreamSpeed.java index 49d05a34e..2651db95c 100644 --- a/moa/src/main/java/moa/tasks/MeasureStreamSpeed.java +++ b/moa/src/main/java/moa/tasks/MeasureStreamSpeed.java @@ -19,14 +19,14 @@ */ package moa.tasks; +import com.github.javacliparser.IntOption; + import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.TimingUtils; import moa.evaluation.LearningEvaluation; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; /** * Task for measuring the speed of the stream. diff --git a/moa/src/main/java/moa/tasks/MultiTargetMainTask.java b/moa/src/main/java/moa/tasks/MultiTargetMainTask.java index 0d0797078..1b5ce701e 100644 --- a/moa/src/main/java/moa/tasks/MultiTargetMainTask.java +++ b/moa/src/main/java/moa/tasks/MultiTargetMainTask.java @@ -5,7 +5,7 @@ package moa.tasks; import java.util.ArrayList; -import moa.streams.InstanceStream; + import moa.streams.clustering.ClusterEvent; /** diff --git a/moa/src/main/java/moa/tasks/Plot.java b/moa/src/main/java/moa/tasks/Plot.java index 8ea104707..328625433 100644 --- a/moa/src/main/java/moa/tasks/Plot.java +++ b/moa/src/main/java/moa/tasks/Plot.java @@ -26,7 +26,6 @@ import java.io.IOException; import java.io.InputStreamReader; -import moa.core.ObjectRepository; import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; @@ -34,6 +33,8 @@ import com.github.javacliparser.MultiChoiceOption; import com.github.javacliparser.StringOption; +import moa.core.ObjectRepository; + /** * A task allowing to create and plot gnuplot scripts. * diff --git a/moa/src/main/java/moa/tasks/RegressionMainTask.java b/moa/src/main/java/moa/tasks/RegressionMainTask.java index e6eeffa1f..fc45af42d 100644 --- a/moa/src/main/java/moa/tasks/RegressionMainTask.java +++ b/moa/src/main/java/moa/tasks/RegressionMainTask.java @@ -5,7 +5,7 @@ package moa.tasks; import java.util.ArrayList; -import moa.streams.InstanceStream; + import moa.streams.clustering.ClusterEvent; /** diff --git a/moa/src/main/java/moa/tasks/RunStreamTasks.java b/moa/src/main/java/moa/tasks/RunStreamTasks.java index ded79182a..43d5621ee 100644 --- a/moa/src/main/java/moa/tasks/RunStreamTasks.java +++ b/moa/src/main/java/moa/tasks/RunStreamTasks.java @@ -22,6 +22,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.StringOption; + import moa.MOAObject; import moa.core.ObjectRepository; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/tasks/RunTasks.java b/moa/src/main/java/moa/tasks/RunTasks.java index 47314962b..4e79f573e 100644 --- a/moa/src/main/java/moa/tasks/RunTasks.java +++ b/moa/src/main/java/moa/tasks/RunTasks.java @@ -20,11 +20,12 @@ */ package moa.tasks; -import moa.core.ObjectRepository; -import moa.options.ClassOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.StringOption; +import moa.core.ObjectRepository; +import moa.options.ClassOption; + /** * Task for running several experiments modifying values of parameters. * diff --git a/moa/src/main/java/moa/tasks/WriteStreamToARFFFile.java b/moa/src/main/java/moa/tasks/WriteStreamToARFFFile.java index d0f252703..314dde2ad 100644 --- a/moa/src/main/java/moa/tasks/WriteStreamToARFFFile.java +++ b/moa/src/main/java/moa/tasks/WriteStreamToARFFFile.java @@ -24,13 +24,12 @@ import java.io.FileWriter; import java.io.Writer; -import moa.core.ObjectRepository; -import moa.options.ClassOption; import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.InstanceImpl; -import com.yahoo.labs.samoa.instances.InstancesHeader; + +import moa.core.ObjectRepository; +import moa.options.ClassOption; import moa.streams.InstanceStream; /** diff --git a/moa/src/main/java/weka/classifiers/meta/MOA.java b/moa/src/main/java/weka/classifiers/meta/MOA.java index e736f1495..753969d2a 100644 --- a/moa/src/main/java/weka/classifiers/meta/MOA.java +++ b/moa/src/main/java/weka/classifiers/meta/MOA.java @@ -21,23 +21,23 @@ package weka.classifiers.meta; +import java.util.Enumeration; +import java.util.Vector; + +import com.yahoo.labs.samoa.instances.WekaToSamoaInstanceConverter; + +import moa.classifiers.Classifier; +import moa.classifiers.trees.DecisionStump; +import moa.options.ClassOption; import weka.classifiers.UpdateableClassifier; import weka.core.Capabilities; +import weka.core.Capabilities.Capability; import weka.core.Instance; import weka.core.Instances; import weka.core.MOAUtils; import weka.core.Option; import weka.core.RevisionUtils; import weka.core.Utils; -import weka.core.Capabilities.Capability; - -import java.util.Enumeration; -import java.util.Vector; - -import moa.classifiers.Classifier; -import moa.classifiers.trees.DecisionStump; -import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.WekaToSamoaInstanceConverter; /** diff --git a/moa/src/main/java/weka/datagenerators/classifiers/classification/MOA.java b/moa/src/main/java/weka/datagenerators/classifiers/classification/MOA.java index 50537008e..76257e8e6 100644 --- a/moa/src/main/java/weka/datagenerators/classifiers/classification/MOA.java +++ b/moa/src/main/java/weka/datagenerators/classifiers/classification/MOA.java @@ -22,24 +22,23 @@ package weka.datagenerators.classifiers.classification; -import weka.core.Instance; -import weka.core.Instances; -import weka.core.MOAUtils; -import weka.core.Option; -import weka.core.RevisionUtils; -import weka.core.Utils; -import weka.datagenerators.ClassificationGenerator; - import java.util.Enumeration; import java.util.Random; import java.util.Vector; +import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; + import moa.options.AbstractOptionHandler; import moa.options.ClassOption; import moa.streams.InstanceStream; import moa.streams.generators.LEDGenerator; -import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; -import com.yahoo.labs.samoa.instances.WekaToSamoaInstanceConverter; +import weka.core.Instance; +import weka.core.Instances; +import weka.core.MOAUtils; +import weka.core.Option; +import weka.core.RevisionUtils; +import weka.core.Utils; +import weka.datagenerators.ClassificationGenerator; /** diff --git a/moa/src/main/java/weka/gui/MOAClassOptionEditor.java b/moa/src/main/java/weka/gui/MOAClassOptionEditor.java index 5604cf644..029f0f025 100644 --- a/moa/src/main/java/weka/gui/MOAClassOptionEditor.java +++ b/moa/src/main/java/weka/gui/MOAClassOptionEditor.java @@ -20,10 +20,11 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import com.github.javacliparser.Option; import com.github.javacliparser.gui.ClassOptionEditComponent; import com.github.javacliparser.gui.OptionsConfigurationPanel; + import moa.options.ClassOption; -import com.github.javacliparser.Option; /** * An editor for MOA ClassOption objects. diff --git a/moa/src/test/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoaderTest.java b/moa/src/test/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoaderTest.java index 1171e785b..adf24d539 100644 --- a/moa/src/test/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoaderTest.java +++ b/moa/src/test/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoaderTest.java @@ -1,6 +1,7 @@ package com.yahoo.labs.samoa.instances; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.io.BufferedReader; import java.io.FileInputStream; @@ -9,15 +10,6 @@ import java.io.InputStreamReader; import java.io.Reader; -import moa.core.InputStreamProgressMonitor; -import moa.streams.ArffFileStream; -import moa.streams.MultiTargetArffFileStream; -import moa.test.MoaTestCase; -import moa.test.TmpFile; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; diff --git a/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java b/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java index 4987e2718..7cccd9e5a 100644 --- a/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java +++ b/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java @@ -24,6 +24,9 @@ import java.io.InputStreamReader; import java.io.Reader; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; import moa.core.InstanceExample; import moa.core.Measurement; @@ -34,9 +37,6 @@ import moa.test.TmpFile; import weka.core.MOAUtils; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; - /** * Ancestor for all classifier test cases. * @@ -130,14 +130,8 @@ protected AbstractTestHelper newTestHelper() { */ protected InstancesHeader load(String filename, int classIndex) { InstancesHeader result = null; - //ArffLoader loader; - - //result = null; try { - /*loader = new ArffLoader(); - loader.setFile(new TmpFile(filename)); - result = loader.getDataSet();*/ // JD: weka's ARffLoader TmpFile tmp=new TmpFile(filename); FileInputStream fileStream = new FileInputStream(tmp.getAbsolutePath()); Reader reader=new BufferedReader(new InputStreamReader(fileStream)); diff --git a/moa/src/test/java/moa/classifiers/AbstractMultipleClassifierTestCase.java b/moa/src/test/java/moa/classifiers/AbstractMultipleClassifierTestCase.java index bbb6a231f..1c59250f4 100644 --- a/moa/src/test/java/moa/classifiers/AbstractMultipleClassifierTestCase.java +++ b/moa/src/test/java/moa/classifiers/AbstractMultipleClassifierTestCase.java @@ -22,7 +22,6 @@ import moa.core.Example; import moa.evaluation.BasicClassificationPerformanceEvaluator; -import moa.evaluation.BasicRegressionPerformanceEvaluator; import moa.evaluation.LearningPerformanceEvaluator; /** diff --git a/moa/src/test/java/moa/classifiers/AbstractMultipleRegressorTestCase.java b/moa/src/test/java/moa/classifiers/AbstractMultipleRegressorTestCase.java index 657782eed..1cfab00ef 100644 --- a/moa/src/test/java/moa/classifiers/AbstractMultipleRegressorTestCase.java +++ b/moa/src/test/java/moa/classifiers/AbstractMultipleRegressorTestCase.java @@ -22,7 +22,6 @@ import moa.core.Example; import moa.evaluation.BasicRegressionPerformanceEvaluator; -import moa.evaluation.ClassificationPerformanceEvaluator; import moa.evaluation.LearningPerformanceEvaluator; /** diff --git a/moa/src/test/java/moa/classifiers/active/ActiveClassifierTest.java b/moa/src/test/java/moa/classifiers/active/ActiveClassifierTest.java index 51cce2895..4ccc930ce 100644 --- a/moa/src/test/java/moa/classifiers/active/ActiveClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/active/ActiveClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the ActiveClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/drift/SingleClassifierDriftTest.java b/moa/src/test/java/moa/classifiers/drift/SingleClassifierDriftTest.java index 3fe81a73c..959679e80 100644 --- a/moa/src/test/java/moa/classifiers/drift/SingleClassifierDriftTest.java +++ b/moa/src/test/java/moa/classifiers/drift/SingleClassifierDriftTest.java @@ -24,7 +24,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the SingleClassifierDrift classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/MajorityClassTest.java b/moa/src/test/java/moa/classifiers/functions/MajorityClassTest.java index c74a92408..05cd19aaa 100644 --- a/moa/src/test/java/moa/classifiers/functions/MajorityClassTest.java +++ b/moa/src/test/java/moa/classifiers/functions/MajorityClassTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the MajorityClass classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/NoChangeTest.java b/moa/src/test/java/moa/classifiers/functions/NoChangeTest.java index 9bb60fb75..f2a16a5ae 100644 --- a/moa/src/test/java/moa/classifiers/functions/NoChangeTest.java +++ b/moa/src/test/java/moa/classifiers/functions/NoChangeTest.java @@ -24,7 +24,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the NoChange classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/PerceptronTest.java b/moa/src/test/java/moa/classifiers/functions/PerceptronTest.java index b7bf710dc..7019b4a25 100644 --- a/moa/src/test/java/moa/classifiers/functions/PerceptronTest.java +++ b/moa/src/test/java/moa/classifiers/functions/PerceptronTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the Perceptron classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/SGDTest.java b/moa/src/test/java/moa/classifiers/functions/SGDTest.java index 7319242a9..34f6c6783 100644 --- a/moa/src/test/java/moa/classifiers/functions/SGDTest.java +++ b/moa/src/test/java/moa/classifiers/functions/SGDTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the SGD classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/SPegasosTest.java b/moa/src/test/java/moa/classifiers/functions/SPegasosTest.java index 5f6d7c5d7..6586cb408 100644 --- a/moa/src/test/java/moa/classifiers/functions/SPegasosTest.java +++ b/moa/src/test/java/moa/classifiers/functions/SPegasosTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the SPegasos classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/AccuracyUpdatedEnsembleTest.java b/moa/src/test/java/moa/classifiers/meta/AccuracyUpdatedEnsembleTest.java index 404dbd614..54044879c 100644 --- a/moa/src/test/java/moa/classifiers/meta/AccuracyUpdatedEnsembleTest.java +++ b/moa/src/test/java/moa/classifiers/meta/AccuracyUpdatedEnsembleTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the AccuracyUpdatedEnsemble classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/AccuracyWeightedEnsembleTest.java b/moa/src/test/java/moa/classifiers/meta/AccuracyWeightedEnsembleTest.java index 9a1be3d65..62aa6ff98 100644 --- a/moa/src/test/java/moa/classifiers/meta/AccuracyWeightedEnsembleTest.java +++ b/moa/src/test/java/moa/classifiers/meta/AccuracyWeightedEnsembleTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the AccuracyWeightedEnsemble classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/LeveragingBagTest.java b/moa/src/test/java/moa/classifiers/meta/LeveragingBagTest.java index 901b86331..015aa68a4 100644 --- a/moa/src/test/java/moa/classifiers/meta/LeveragingBagTest.java +++ b/moa/src/test/java/moa/classifiers/meta/LeveragingBagTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the LeveragingBag classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/LimAttClassifierTest.java b/moa/src/test/java/moa/classifiers/meta/LimAttClassifierTest.java index 17eaf73e3..0daec8b4b 100644 --- a/moa/src/test/java/moa/classifiers/meta/LimAttClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/meta/LimAttClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the LimAttClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OCBoostTest.java b/moa/src/test/java/moa/classifiers/meta/OCBoostTest.java index 4954c654a..e536ff91c 100644 --- a/moa/src/test/java/moa/classifiers/meta/OCBoostTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OCBoostTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OCBoost classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsembleTest.java b/moa/src/test/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsembleTest.java index 984aa61fa..3b5070ad3 100644 --- a/moa/src/test/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsembleTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsembleTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OnlineAccuracyUpdatedEnsemble classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBagASHTTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBagASHTTest.java index 5b69c0598..531ec6b4c 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBagASHTTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBagASHTTest.java @@ -24,7 +24,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBagASHT classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBagAdwinTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBagAdwinTest.java index 653d4ba08..5b63754e8 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBagAdwinTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBagAdwinTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBagAdwin classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBagTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBagTest.java index a70e900d9..8b9975880 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBagTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBagTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBag classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBoostAdwinTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBoostAdwinTest.java index ae14a1fcb..edd191889 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBoostAdwinTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBoostAdwinTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBoostAdwin classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBoostTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBoostTest.java index 313694835..679bb2fbe 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBoostTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBoostTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBoost classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/TemporallyAugmentedClassifierTest.java b/moa/src/test/java/moa/classifiers/meta/TemporallyAugmentedClassifierTest.java index 8f4b711ac..e38df4f74 100644 --- a/moa/src/test/java/moa/classifiers/meta/TemporallyAugmentedClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/meta/TemporallyAugmentedClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the TemporallyAugmentedClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/WEKAClassifierTest.java b/moa/src/test/java/moa/classifiers/meta/WEKAClassifierTest.java index edfb78792..cbed95b51 100644 --- a/moa/src/test/java/moa/classifiers/meta/WEKAClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/meta/WEKAClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the WEKAClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/WeightedMajorityAlgorithmTest.java b/moa/src/test/java/moa/classifiers/meta/WeightedMajorityAlgorithmTest.java index bbef3c0e7..16061d035 100644 --- a/moa/src/test/java/moa/classifiers/meta/WeightedMajorityAlgorithmTest.java +++ b/moa/src/test/java/moa/classifiers/meta/WeightedMajorityAlgorithmTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the WeightedMajorityAlgorithm classifier. diff --git a/moa/src/test/java/moa/classifiers/rules/AMRulesRegressorTest.java b/moa/src/test/java/moa/classifiers/rules/AMRulesRegressorTest.java index a66b6717d..b07a43514 100644 --- a/moa/src/test/java/moa/classifiers/rules/AMRulesRegressorTest.java +++ b/moa/src/test/java/moa/classifiers/rules/AMRulesRegressorTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleRegressorTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the AMRulesRegressor classifier. diff --git a/moa/src/test/java/moa/classifiers/rules/RuleClassifierNBayesTest.java b/moa/src/test/java/moa/classifiers/rules/RuleClassifierNBayesTest.java index c78ed0149..ba1ac994d 100644 --- a/moa/src/test/java/moa/classifiers/rules/RuleClassifierNBayesTest.java +++ b/moa/src/test/java/moa/classifiers/rules/RuleClassifierNBayesTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the RuleClassifierNBayes classifier. diff --git a/moa/src/test/java/moa/classifiers/rules/RuleClassifierTest.java b/moa/src/test/java/moa/classifiers/rules/RuleClassifierTest.java index 4660bde9b..4d5562a3e 100644 --- a/moa/src/test/java/moa/classifiers/rules/RuleClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/rules/RuleClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the RuleClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabeLTest.java b/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabeLTest.java index b34e58063..bc3da45c5 100644 --- a/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabeLTest.java +++ b/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabeLTest.java @@ -1,7 +1,6 @@ package moa.classifiers.rules.multilabel.core.voting; -import static org.junit.Assert.*; -import moa.classifiers.rules.core.voting.InverseErrorWeightedVote; +import static org.junit.Assert.assertEquals; import org.junit.BeforeClass; import org.junit.Test; diff --git a/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java b/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java index e9f91997a..92ff6bdcb 100644 --- a/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java +++ b/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java @@ -1,10 +1,10 @@ package moa.classifiers.rules.multilabel.core.voting; +import static org.junit.Assert.assertEquals; + import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assert.*; - import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; diff --git a/moa/src/test/java/moa/classifiers/trees/ASHoeffdingTreeTest.java b/moa/src/test/java/moa/classifiers/trees/ASHoeffdingTreeTest.java index 1614cb051..4012c9652 100644 --- a/moa/src/test/java/moa/classifiers/trees/ASHoeffdingTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/ASHoeffdingTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the ASHoeffdingTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/AdaHoeffdingOptionTreeTest.java b/moa/src/test/java/moa/classifiers/trees/AdaHoeffdingOptionTreeTest.java index 3960e6d97..fd343eaea 100644 --- a/moa/src/test/java/moa/classifiers/trees/AdaHoeffdingOptionTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/AdaHoeffdingOptionTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the AdaHoeffdingOptionTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/DecisionStumpTest.java b/moa/src/test/java/moa/classifiers/trees/DecisionStumpTest.java index 1e4b3297a..407365442 100644 --- a/moa/src/test/java/moa/classifiers/trees/DecisionStumpTest.java +++ b/moa/src/test/java/moa/classifiers/trees/DecisionStumpTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the DecisionStump classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java b/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java index eb863020e..fa2876054 100644 --- a/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java +++ b/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleRegressorTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the FIMTDD classifier. @@ -31,8 +30,7 @@ * @author fracpete (fracpete at waikato dot ac dot nz) * @version $Revision$ */ -public class FIMTDDTest - extends AbstractMultipleRegressorTestCase { +public class FIMTDDTest extends AbstractMultipleRegressorTestCase { /** * Constructs the test case. Called by subclasses. diff --git a/moa/src/test/java/moa/classifiers/trees/HoeffdingAdaptiveTreeTest.java b/moa/src/test/java/moa/classifiers/trees/HoeffdingAdaptiveTreeTest.java index 8729f2fe2..20312bb02 100644 --- a/moa/src/test/java/moa/classifiers/trees/HoeffdingAdaptiveTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/HoeffdingAdaptiveTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the HoeffdingAdaptiveTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/HoeffdingOptionTreeTest.java b/moa/src/test/java/moa/classifiers/trees/HoeffdingOptionTreeTest.java index 1af0b309d..b0ab7fe1c 100644 --- a/moa/src/test/java/moa/classifiers/trees/HoeffdingOptionTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/HoeffdingOptionTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the HoeffdingOptionTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/LimAttHoeffdingTreeTest.java b/moa/src/test/java/moa/classifiers/trees/LimAttHoeffdingTreeTest.java index 8f59fae43..e19351825 100644 --- a/moa/src/test/java/moa/classifiers/trees/LimAttHoeffdingTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/LimAttHoeffdingTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the LimAttHoeffdingTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/ORTOTest.java b/moa/src/test/java/moa/classifiers/trees/ORTOTest.java index fd83e41f0..d9ff53950 100644 --- a/moa/src/test/java/moa/classifiers/trees/ORTOTest.java +++ b/moa/src/test/java/moa/classifiers/trees/ORTOTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleRegressorTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the ORTO classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/RandomHoeffdingTreeTest.java b/moa/src/test/java/moa/classifiers/trees/RandomHoeffdingTreeTest.java index 3e804b065..a08f2e4ec 100644 --- a/moa/src/test/java/moa/classifiers/trees/RandomHoeffdingTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/RandomHoeffdingTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the RandomHoeffdingTree classifier. diff --git a/moa/src/test/java/moa/integration/SimpleClusterTest.java b/moa/src/test/java/moa/integration/SimpleClusterTest.java index 678627b38..4ac287d82 100644 --- a/moa/src/test/java/moa/integration/SimpleClusterTest.java +++ b/moa/src/test/java/moa/integration/SimpleClusterTest.java @@ -1,5 +1,11 @@ package moa.integration; +import org.junit.Test; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.Option; + import junit.framework.TestCase; import moa.core.Globals; import moa.core.Measurement; @@ -10,12 +16,6 @@ import moa.tasks.Task; import moa.tasks.TaskThread; -import org.junit.Test; - -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.Option; - /* test that all clusterers run, i.e., do not die on simpe input **/ public class SimpleClusterTest extends TestCase { diff --git a/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java b/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java index 02ee87bf6..86cf29292 100644 --- a/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java +++ b/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java @@ -2,14 +2,13 @@ import static org.junit.Assert.assertEquals; -import moa.streams.ArffFileStream; -import moa.streams.MultiTargetArffFileStream; - import org.junit.BeforeClass; import org.junit.Test; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.ArffFileStream; + public class SelectAttributesFilterTest { private static double EPS=0.00000001; private static SelectAttributesFilter filter; diff --git a/weka-package/.settings/org.eclipse.jdt.core.prefs b/weka-package/.settings/org.eclipse.jdt.core.prefs index 60105c1b9..6e80039d3 100644 --- a/weka-package/.settings/org.eclipse.jdt.core.prefs +++ b/weka-package/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,8 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.8 From 16f12141682965aa076cd33a57a5f96246acbd9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Tue, 13 Jun 2017 11:58:39 +0200 Subject: [PATCH 15/33] Commit before cleanup --- moa/.classpath | 2 +- .../instances/FeatureRelevanceResult.java | 14 +++++++ .../java/moa/classifiers/meta/OzaBag.java | 3 +- .../moa/classifiers/meta/OzaBagAdwin.java | 3 +- .../trees/{FIMTDD.java => FIMTDD2.java} | 40 ++++++++++++++----- .../trees/{ORTO.java => ORTO2.java} | 8 ++-- .../tasks/EvaluatePrequentialRegression.java | 2 +- .../java/moa/tasks/LearnModelRegression.java | 2 +- .../moa/classifiers/trees/FIMTDDTest.java | 2 +- .../java/moa/classifiers/trees/ORTOTest.java | 2 +- weka-package/.classpath | 2 +- 11 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/FeatureRelevanceResult.java rename moa/src/main/java/moa/classifiers/trees/{FIMTDD.java => FIMTDD2.java} (96%) rename moa/src/main/java/moa/classifiers/trees/{ORTO.java => ORTO2.java} (98%) diff --git a/moa/.classpath b/moa/.classpath index 534b5e52f..fae1a2b37 100644 --- a/moa/.classpath +++ b/moa/.classpath @@ -22,7 +22,7 @@ - + diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/FeatureRelevanceResult.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/FeatureRelevanceResult.java new file mode 100644 index 000000000..cc29c97d4 --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/FeatureRelevanceResult.java @@ -0,0 +1,14 @@ +package com.yahoo.labs.samoa.instances; + +import java.util.List; + +public interface FeatureRelevanceResult { + public void addFeature(Attribute attr); + + public void setFeatureRelevance(Attribute attr, double relevance); + + public double getFeatureRelevance(Attribute attr); + + public List getFeatures(); + +} diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBag.java b/moa/src/main/java/moa/classifiers/meta/OzaBag.java index d43f2da0b..2cc5000cc 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBag.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBag.java @@ -24,6 +24,7 @@ import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; +import moa.classifiers.Regressor; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; @@ -49,7 +50,7 @@ * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * @version $Revision: 7 $ */ -public class OzaBag extends AbstractClassifier { +public class OzaBag extends AbstractClassifier implements Regressor, Classifier { @Override public String getPurposeString() { diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java index 8f790f339..f88027cfe 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java @@ -24,6 +24,7 @@ import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; +import moa.classifiers.Regressor; import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.Measurement; @@ -79,7 +80,7 @@ * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) * @version $Revision: 7 $ */ -public class OzaBagAdwin extends AbstractClassifier { +public class OzaBagAdwin extends AbstractClassifier implements Classifier, Regressor { private static final long serialVersionUID = 1L; diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD2.java similarity index 96% rename from moa/src/main/java/moa/classifiers/trees/FIMTDD.java rename to moa/src/main/java/moa/classifiers/trees/FIMTDD2.java index 8962cd12c..f98be75d8 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD2.java @@ -48,14 +48,14 @@ * Implementation of FIMTDD, regression and model trees for data streams. */ -public class FIMTDD extends AbstractClassifier implements Regressor { +public class FIMTDD2 extends AbstractClassifier implements Regressor { private static final long serialVersionUID = 1L; public Node treeRoot; - protected int leafNodeCount = 0; - protected int splitNodeCount = 0; + public int leafNodeCount = 0; + public int splitNodeCount = 0; protected double examplesSeen = 0.0; protected double sumOfValues = 0.0; @@ -117,6 +117,10 @@ public class FIMTDD extends AbstractClassifier implements Regressor { public FlagOption learningRatioConstOption = new FlagOption( "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); + + public IntOption maxDepthOption = new IntOption( + "maxDepthFactor", 'b', "The maximum depth of the tree.", + Integer.MAX_VALUE, 0, Integer.MAX_VALUE); //endregion ================ OPTIONS ================ @@ -128,7 +132,7 @@ public abstract static class Node extends AbstractMOAObject { public int ID; - protected FIMTDD tree; + protected FIMTDD2 tree; protected boolean changeDetection = true; @@ -147,7 +151,7 @@ public abstract static class Node extends AbstractMOAObject { // Sum of absolute errors protected double sumOfAbsErrors; // Needed for PH tracking of mean error - public Node(FIMTDD tree) { + public Node(FIMTDD2 tree) { this.tree = tree; ID = tree.maxID; } @@ -226,6 +230,10 @@ public int getNumSubtrees() { return 1; } + public int numLeaves() { + return 1; + } + protected boolean skipInLevelCount() { return false; } @@ -248,7 +256,7 @@ public static class LeafNode extends Node { /** * Create a new LeafNode */ - public LeafNode(FIMTDD tree) { + public LeafNode(FIMTDD2 tree) { super(tree); if (tree.buildingModelTree()) { learningModel = tree.newLeafModel(); @@ -381,7 +389,7 @@ public double getPrediction(Instance inst) { public void checkForSplit(Instance inst, double prediction) { // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node - if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { + if (this.getLevel() < tree.maxDepthOption.getValue() && examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { int index = (parent != null) ? parent.getChildIndex(this) : 0; tree.attemptToSplit(this, parent, index, inst, prediction); @@ -421,7 +429,7 @@ public abstract static class InnerNode extends Node { protected double lossSumQi; protected double previousWeight = 0; - public InnerNode(FIMTDD tree) { + public InnerNode(FIMTDD2 tree) { super(tree); } @@ -436,6 +444,12 @@ public int numChildren() { return children.size(); } + public int numLeaves() { + int leaves = 0; + for (Node child : children) leaves += child.numLeaves(); + return leaves; + } + public Node getChild(int index) { return children.get(index); } @@ -516,7 +530,7 @@ public static class SplitNode extends InnerNode { * Create a new SplitNode * @param tree */ - public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { + public SplitNode(InstanceConditionalTest splitTest, FIMTDD2 tree) { super(tree); this.splitTest = splitTest; } @@ -558,7 +572,7 @@ public class FIMTDDPerceptron implements Serializable { private static final long serialVersionUID = 1L; - protected FIMTDD tree; + protected FIMTDD2 tree; // The Perception weights protected double[] weightAttribute; @@ -576,7 +590,7 @@ public FIMTDDPerceptron(FIMTDDPerceptron original) { instancesSeen = original.instancesSeen / 2; } - public FIMTDDPerceptron(FIMTDD tree) { + public FIMTDDPerceptron(FIMTDD2 tree) { this.tree = tree; initializeWeights(); @@ -837,6 +851,7 @@ public void processInstance(Instance inst, Node node, double prediction, double // Switch the subtrees Node parent = iNode.getParent(); + System.out.println("Switching trees!"); if (parent != null) { Node replacementTree = iNode.alternateTree; parent.setChild(parent.getChildIndex(iNode), replacementTree); @@ -845,6 +860,8 @@ public void processInstance(Instance inst, Node node, double prediction, double treeRoot = iNode.alternateTree; treeRoot.restartChangeDetection(); } + leafNodeCount += iNode.alternateTree.numLeaves() - iNode.numLeaves(); + currentNode = iNode.alternateTree; currentNode.originalNode = null; @@ -865,6 +882,7 @@ public void processInstance(Instance inst, Node node, double prediction, double if (iNode.changeDetection && !inAlternate) { if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + System.out.println("CD triggered!"); iNode.initializeAlternateTree(); growthAllowed = false; } diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO2.java similarity index 98% rename from moa/src/main/java/moa/classifiers/trees/ORTO.java rename to moa/src/main/java/moa/classifiers/trees/ORTO2.java index 519486b45..a2d5a263c 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO2.java @@ -44,7 +44,7 @@ * Implementation of ORTO, option trees for data streams. */ -public class ORTO extends FIMTDD implements Regressor { +public class ORTO2 extends FIMTDD2 implements Regressor { private static final long serialVersionUID = 1L; @@ -97,7 +97,7 @@ public static class OptionNode extends InnerNode { protected double[] optionFFSSL; protected double[] optionFFSeen; - public OptionNode(FIMTDD tree) { + public OptionNode(FIMTDD2 tree) { super(tree); } @@ -141,13 +141,13 @@ public double getPrediction(Instance inst) { } private double aggregate(double[] predictions) { - if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average + if (((ORTO2) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average double sum = 0.0; for (int i = 0; i < predictions.length; i++) { sum += predictions[i]; } return sum / predictions.length; - } else if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 1) { + } else if (((ORTO2) tree).optionNodeAggregationOption.getChosenIndex() == 1) { int d = directionForBestTree(); return predictions[d]; } else { diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java index 56996cb47..8f0d2839a 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java @@ -63,7 +63,7 @@ public String getPurposeString() { private static final long serialVersionUID = 1L; public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", Regressor.class, "moa.classifiers.trees.FIMTDD"); + "Learner to train.", Regressor.class, "moa.classifiers.trees.ORTO"); public ClassOption streamOption = new ClassOption("stream", 's', "Stream to learn from.", ExampleStream.class, diff --git a/moa/src/main/java/moa/tasks/LearnModelRegression.java b/moa/src/main/java/moa/tasks/LearnModelRegression.java index 4869602e3..fd92e8453 100644 --- a/moa/src/main/java/moa/tasks/LearnModelRegression.java +++ b/moa/src/main/java/moa/tasks/LearnModelRegression.java @@ -45,7 +45,7 @@ public String getPurposeString() { private static final long serialVersionUID = 1L; public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", Regressor.class, "moa.classifiers.trees.FIMTDD"); + "Learner to train.", Regressor.class, "moa.classifiers.trees.HoeffdingTree"); public ClassOption streamOption = new ClassOption("stream", 's', "Stream to learn from.", ExampleStream.class, diff --git a/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java b/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java index fa2876054..dc931074a 100644 --- a/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java +++ b/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java @@ -50,7 +50,7 @@ public FIMTDDTest(String name) { @Override protected Classifier[] getRegressionClassifierSetups() { return new Classifier[]{ - new FIMTDD(), + new FIMTDD2(), }; } diff --git a/moa/src/test/java/moa/classifiers/trees/ORTOTest.java b/moa/src/test/java/moa/classifiers/trees/ORTOTest.java index d9ff53950..4a86c0099 100644 --- a/moa/src/test/java/moa/classifiers/trees/ORTOTest.java +++ b/moa/src/test/java/moa/classifiers/trees/ORTOTest.java @@ -51,7 +51,7 @@ public ORTOTest(String name) { @Override protected Classifier[] getRegressionClassifierSetups() { return new Classifier[]{ - new ORTO(), + new ORTO2(), }; } diff --git a/weka-package/.classpath b/weka-package/.classpath index fd7ad7fbd..af1430be1 100644 --- a/weka-package/.classpath +++ b/weka-package/.classpath @@ -12,7 +12,7 @@ - + From 4d7a7a267c02889f120dcaa6078c075b6abcd5aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 14:33:22 +0100 Subject: [PATCH 16/33] Added some classifiers for multi-label classification --- .../samoa/instances/MultiLabelPrediction.java | 8 + .../LocalMultiTargetClassifier.java | 145 +++++++++ .../classifiers/multilabel/meta/MTOzaBag.java | 107 +++++++ .../multilabel/trees/ISOUPOptionTree.java | 277 ++++++++++++++++++ .../tasks/EvaluatePrequentialMultiTarget.java | 7 +- 5 files changed, 542 insertions(+), 2 deletions(-) create mode 100644 moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index 6c53bbd1a..b5731a154 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -29,6 +29,10 @@ public MultiLabelPrediction(int numOutputAttributes) { for (int i=0; i classifiers = null; + LinkedList headers = null; + + @Override + public boolean isRandomizable() { + // TODO Auto-generated method stub + return true; + } + + private InstancesHeader getHeader(int target) { + if (headers == null) + makeHeaders(); + return headers.get(target); + + } + + private void makeHeaders() { + if (headers == null) { + headers = new LinkedList(); + for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { + List attributes = new LinkedList(); + List indexValues = new LinkedList(); + for (int i = 0; i < getModelContext().numInputAttributes(); i++) { + attributes.add(getModelContext().inputAttribute(i)); + indexValues.add(i); + } + attributes.add(getModelContext().outputAttribute(target)); + indexValues.add(getModelContext().numInputAttributes()); + InstancesHeader STHeader = new InstancesHeader(); + STHeader.setAttributes(attributes, indexValues); + STHeader.setClassIndex(getModelContext().numInputAttributes()); + headers.add(STHeader); + } + } + } + + private Instance getSTInstance(MultiLabelInstance inst, int target) { + double[] instanceData = new double[getModelContext().numInputAttributes() + 1]; + for (int i = 0; i < inst.numInputAttributes(); i++) + instanceData[i] = inst.valueInputAttribute(i); + instanceData[inst.numInputAttributes()] = inst.valueOutputAttribute(target); + DenseInstance STInst = new DenseInstance(inst.weight(), instanceData); + STInst.setDataset(getHeader(target)); + return STInst; + } + + @Override + public void trainOnInstanceImpl(MultiLabelInstance instance) { + // TODO Auto-generated method stub + initializeClassifiers(); + + for (int j = 0; j < instance.numberOutputTargets(); j++) { + Instance STInst = getSTInstance(instance, j); + + classifiers.get(j).trainOnInstance(STInst); + } + } + + @Override + public Prediction getPredictionForInstance(MultiLabelInstance inst) { + initializeClassifiers(); + + MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); + for (int j = 0; j < inst.numberOutputTargets(); j++) { + Instance STInst = getSTInstance(inst, j); + + prediction.setVote(j, 1, classifiers.get(j).getVotesForInstance(STInst)[0]); + } + return prediction; + } + + @Override + public void resetLearningImpl() { + classifiers = null; + + } + + public void initializeClassifiers() { + this.classifierRandom.setSeed(1234); + if (classifiers == null) { + makeHeaders(); + classifiers = new LinkedList(); + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + Classifier learner = (Classifier) getPreparedClassOption(this.classifierOption); + classifiers.add(learner); + learner.resetLearning(); + ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; + learner.setModelContext(getHeader(i)); + } + } + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + for (int i =0; i < getModelContext().numOutputAttributes(); i++) { + out.append(getModelContext().outputAttribute(i).name() + '\n'); + ((AbstractClassifier) classifiers.get(i)).getModelDescription(out, indent); + } + + } + +} + \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java new file mode 100644 index 000000000..e2db81e43 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java @@ -0,0 +1,107 @@ +/* + * MLOzaBag.java + * Copyright (C) 2012 University of Waikato, Hamilton, New Zealand + * @author Jesse Read (jesse@tsc.uc3m.es) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.classifiers.multilabel.meta; + +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +import com.yahoo.labs.samoa.instances.Prediction; + +import moa.classifiers.Classifier; +import moa.classifiers.MultiLabelLearner; +import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.meta.OzaBag; +import moa.core.DoubleVector; +import moa.core.Example; +import moa.options.ClassOption; + +/** + * OzaBag for Multi-label data. + * + * @author Jesse Read (jesse@tsc.uc3m.es) + * @version $Revision: 1 $ + */ +public class MTOzaBag extends OzaBag implements MultiLabelLearner, MultiTargetRegressor { + + public MTOzaBag() { + super(); + this.baseLearnerOption = new ClassOption("baseLearner", 'l', + "Classifier to train.", MultiLabelLearner.class, "multilabel.trees.ISOUPTree"); + } + + @Override + public void resetLearningImpl() { + this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; + MultiLabelLearner baseLearner = (MultiLabelLearner) getPreparedClassOption(this.baseLearnerOption); + baseLearner.resetLearning(); + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i] = baseLearner.copy(); + } + } + + @Override + public void setModelContext(InstancesHeader raw_header) { + + //set the multilabel model context + this.modelContext = raw_header; + + // reset ensemble + this.resetLearningImpl(); + + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i].setModelContext(raw_header); + this.ensemble[i].resetLearning(); + } + } + + @Override // @note don't need this here + public boolean isRandomizable() { + return true; + } + + public Prediction getPredictionForInstance(MultiLabelInstance inst) { + DoubleVector[][] predictions = new DoubleVector[this.ensemble.length][getModelContext().numOutputAttributes()]; + for (int i = 0; i < this.ensemble.length; i++) { + Prediction basePrediction = this.ensemble[i].getPredictionForInstance(inst); + predictions[i] = ((MultiLabelPrediction) basePrediction).getPrediction(); + } + DoubleVector[] prediction = new DoubleVector[getModelContext().numOutputAttributes()]; + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + prediction[j] = new DoubleVector(); + for (int i = 0; i < this.ensemble.length; i++) { + prediction[j].addValues(predictions[i][j]); + } + prediction[j].scaleValues(1.0 / this.ensemble.length); + } + return new MultiLabelPrediction(prediction); + } + + @Override + public void trainOnInstanceImpl(MultiLabelInstance instance) { + trainOnInstanceImpl((Instance) instance); + } + + @Override + public Prediction getPredictionForInstance(Example example) { + return getPredictionForInstance((MultiLabelInstance)example.getData()); + } + +} diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java new file mode 100644 index 000000000..93de284a0 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java @@ -0,0 +1,277 @@ +package moa.classifiers.multilabel.trees; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.MultiLabelInstance; + +import moa.classifiers.multilabel.trees.ISOUPTree.LeafNode; +import moa.classifiers.multilabel.trees.ISOUPTree.Node; +import moa.classifiers.multilabel.trees.ISOUPTree.SplitNode; +import moa.classifiers.trees.ORTO; +import moa.classifiers.trees.FIMTDD.InnerNode; +import moa.classifiers.trees.ORTO.OptionNode; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.Measurement; + +public class ISOUPOptionTree extends ISOUPTree { + + private static final long serialVersionUID = 1L; + + private int innerNodeCount = 0; + private int optionNodeCount = 0; + + private int numTrees = 1; + + //region ================ OPTIONS ================ + + public IntOption maxTreesOption = new IntOption( + "maxTrees", + 'm', + "The maximum number of trees contained in the option tree.", + 10, 1, Integer.MAX_VALUE); + + public IntOption maxOptionLevelOption = new IntOption( + "maxOptionLevel", + 'x', + "The maximal depth at which option nodes can be created.", + 10, 0, Integer.MAX_VALUE); + + public FloatOption optionDecayFactorOption = new FloatOption( + "optionDecayFactor", + 'z', + "The option decay factor that determines how many options can be selected at a given level.", + 0.9, 0.0, 1.0); + + public MultiChoiceOption optionNodeAggregationOption = new MultiChoiceOption( + "optionNodeAggregation", + 'o', + "The aggregation method used to combine predictions in option nodes.", + new String[]{"average", "bestTree"}, new String[]{"Average", "Best tree"}, 0); + + public FloatOption optionFadingFactorOption = new FloatOption( + "optionFadingFactor", + 'q', + "The fading factor used for comparing subtrees of an option node.", + 0.9995, 0.0, 1.0); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public static class OptionNode extends InnerNode { + protected AutoExpandVector optionFFSSL; + protected AutoExpandVector optionFFSeen; + + public OptionNode(ISOUPTree tree) { + super(tree); + } + + public void resetFF() { + optionFFSSL = new AutoExpandVector(); + optionFFSeen = new AutoExpandVector(); + for (int i = 0; i < numChildren(); i++) { + optionFFSSL.set(i, new DoubleVector()); + optionFFSeen.set(i, new DoubleVector()); + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + optionFFSSL.get(i).setValue(j, 0.0); + optionFFSeen.get(i).setValue(j, 0.0); + } + } + } + + public int getNumSubtrees() { + int num = 0; + for (Node child : children) { + num += child.getNumSubtrees(); + } + return num; + } + + public double[] getPrediction(MultiLabelInstance inst) { + double[][] predictions = new double[numChildren()][tree.getModelContext().numOutputAttributes()]; + for (int i = 0; i < numChildren(); i++) { + predictions[i] = getChild(i).getPrediction(inst); + } + return aggregate(predictions); + } + + private double[] aggregate(double[][] predictions) { + if (((ISOUPOptionTree) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average + double[] sums = new double[tree.getModelContext().numOutputAttributes()]; + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + for (int i = 0; i < numChildren(); i++) { + sums[j] += predictions[i][j]; + } + sums[j] = sums[j] / numChildren(); + } + return sums; + } else if (((ISOUPOptionTree) tree).optionNodeAggregationOption.getChosenIndex() == 1) { + int d = directionForBestTree(); + return predictions[d]; + } else { + return new double[] {}; + } + } + + public int directionForBestTree() { + int d = 0; + double min = Double.MAX_VALUE; + for (int i = 0; i < numChildren(); i++) { + double avg = 0.0; + for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + avg += getFFRatio(i, j); + } + avg /= tree.getModelContext().numOutputAttributes(); + if (avg < min) { + min = avg; + d = i; + } + } + return d; + } + + public double getFFRatio(int childIndex, int targetIndex) { + return optionFFSSL.get(childIndex).getValue(targetIndex) / optionFFSeen.get(childIndex).getValue(targetIndex); + } + + protected boolean skipInLevelCount() { + return true; + } + } + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + public String getPurposeString() { + return "Implementation of the ORTO tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + super.resetLearningImpl(); + this.innerNodeCount = 0; + this.optionNodeCount = 0; + } + + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("number of subtrees", this.numTrees), + //new Measurement("tree size (nodes)", this.leafNodeCount + this.innerNodeCount), + //new Measurement("tree size (leaves)", this.leafNodeCount), + new Measurement("number of option nodes", this.optionNodeCount),}; + } + + @Override + public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + if (node instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) node, prediction, normalError, growthAllowed, inAlternate); + } else { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } else { + currentNode.examplesSeen += inst.weight(); +// if (!inAlternate && iNode.alternateTree != null) { +// boolean altTree = true; +// double lossO = Math.pow(inst.classValue() - prediction, 2); +// double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); +// +// iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; +// iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; +// iNode.lossExamplesSeen++; +// +// double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); +// double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; +// iNode.lossSumQi += Qi; +// iNode.lossNumQiTests += 1; +// double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; +// +// if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { +// iNode.previousWeight = iNode.lossExamplesSeen; +// if (Qi > 0) { +// // Switch the subtrees +// Node parent = currentNode.parent; +// +// if (parent != null) { +// Node replacementTree = iNode.alternateTree; +// parent.setChild(parent.getChildIndex(iNode), replacementTree); +// if (growthAllowed) replacementTree.restartChangeDetection(); +// } else { +// treeRoot = iNode.alternateTree; +// treeRoot.restartChangeDetection(); +// } +// optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); +// removeExcessTrees(); +// +// currentNode = iNode.alternateTree; +// currentNode.originalNode = null; +// altTree = false; +// } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { +// // Remove the alternate tree +// iNode.alternateTree = null; +// if (growthAllowed) iNode.restartChangeDetection(); +// altTree = false; +// } +// } +// if (altTree) { +// growthAllowed = false; // this is the growth of the original tree +// processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree +// } else if (currentNode instanceof OptionNode) { +// // this happens when an option node is switched into the tree +// for (Node child : ((OptionNode) currentNode).children) { +// processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); +// } +// break; +// } +// } + +// if (iNode.changeDetection && !inAlternate) { +// if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { +// iNode.initializeAlternateTree(); +// } +// } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); + } else if (currentNode instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) currentNode, prediction, normalError, growthAllowed, inAlternate); + break; + } + } + } + } + + } + + public void processInstanceOptionNode(MultiLabelInstance inst, OptionNode node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { +// if (node.changeDetection) { +// double error = Math.abs(prediction - inst.classValue()); +// node.sumOfAbsErrors += error; +// +// if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { +// node.initializeAlternateTree(); +// } +// } + + for (Node child : node.children) { + int i = node.getChildIndex(child); + double[] childPrediction = child.getPrediction(inst); + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + node.optionFFSeen.get(i).setValue(j, node.optionFFSeen.get(i).getValue(j) * optionFadingFactorOption.getValue() + 1); + node.optionFFSSL.get(i).setValue(j, node.optionFFSSL.get(i).getValue(j) * optionFadingFactorOption.getValue() + Math.pow(childPrediction[j] - inst.valueOutputAttribute(j), 2)); + } + } + + for (Node child : node.children) { + processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); + } + } + + //endregion ================ METHODS ================ + +} diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index eba9b70b5..55ee5302d 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -202,8 +202,11 @@ protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { Prediction prediction = learner.getPredictionForInstance(testInst); // Output prediction if (outputPredictionFile != null) { - double trueClass = ((Instance) trainInst.getData()).classValue(); - outputPredictionResultStream.println(prediction + "," + trueClass); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); } //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); From 1cebdabef542a3e1f797a20b08ba801b4a846383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 14:43:19 +0100 Subject: [PATCH 17/33] Updates to multi-label methods --- .../samoa/instances/MultiLabelPrediction.java | 4 ++++ .../multilabel/LocalMultiTargetClassifier.java | 11 ++++++----- .../classifiers/multilabel/meta/MTOzaBag.java | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index b5731a154..fbffed6ae 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -34,6 +34,10 @@ public MultiLabelPrediction(DoubleVector[] prediction) { this.prediction = prediction; } + public MultiLabelPrediction(DoubleVector[] prediction) { + this.prediction = prediction; + } + @Override public int numOutputAttributes() { return prediction.length; diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index f28ba2e8f..21c34b1dc 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -1,5 +1,6 @@ package moa.classifiers.multilabel; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Vector; @@ -34,8 +35,8 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner Classifier.class, "moa.classifiers.trees.FIMTDD"); - LinkedList classifiers = null; - LinkedList headers = null; + ArrayList classifiers = null; + ArrayList headers = null; @Override public boolean isRandomizable() { @@ -52,7 +53,7 @@ private InstancesHeader getHeader(int target) { private void makeHeaders() { if (headers == null) { - headers = new LinkedList(); + headers = new ArrayList(); for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { List attributes = new LinkedList(); List indexValues = new LinkedList(); @@ -115,9 +116,9 @@ public void initializeClassifiers() { this.classifierRandom.setSeed(1234); if (classifiers == null) { makeHeaders(); - classifiers = new LinkedList(); + classifiers = new ArrayList(); for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { - Classifier learner = (Classifier) getPreparedClassOption(this.classifierOption); + Classifier learner = ((Classifier) getPreparedClassOption(this.classifierOption)).copy(); classifiers.add(learner); learner.resetLearning(); ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java index e2db81e43..2594f61be 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java @@ -93,6 +93,24 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { } return new MultiLabelPrediction(prediction); } + + public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) { + int actual = Math.max(1, Math.min(n, this.ensemble.length)); + DoubleVector[][] predictions = new DoubleVector[actual][getModelContext().numOutputAttributes()]; + for (int i = 0; i < actual; i++) { + Prediction basePrediction = this.ensemble[i].getPredictionForInstance(inst); + predictions[i] = ((MultiLabelPrediction) basePrediction).getPrediction(); + } + DoubleVector[] prediction = new DoubleVector[getModelContext().numOutputAttributes()]; + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + prediction[j] = new DoubleVector(); + for (int i = 0; i < actual; i++) { + prediction[j].addValues(predictions[i][j]); + } + prediction[j].scaleValues(1.0 / actual); + } + return new MultiLabelPrediction(prediction); + } @Override public void trainOnInstanceImpl(MultiLabelInstance instance) { From 12f6b0c1c44a35951b8bf07156699485767cfbec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 15:22:23 +0100 Subject: [PATCH 18/33] Removed merging artefacts --- .../samoa/instances/MultiLabelPrediction.java | 5 +- .../tasks/EvaluatePrequentialMultiTarget.java | 566 +++++++++--------- 2 files changed, 284 insertions(+), 287 deletions(-) diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index fbffed6ae..81c9b86f5 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -33,10 +33,7 @@ public MultiLabelPrediction(int numOutputAttributes) { public MultiLabelPrediction(DoubleVector[] prediction) { this.prediction = prediction; } - - public MultiLabelPrediction(DoubleVector[] prediction) { - this.prediction = prediction; - } + @Override public int numOutputAttributes() { diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index 55ee5302d..c7c7b5db0 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -1,283 +1,283 @@ -/* - * EvaluatePrequentialMultiTarget.java - * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package moa.tasks; - -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.PrintStream; - -import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.Regressor; -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; -import moa.core.TimingUtils; -import moa.evaluation.EWMAClassificationPerformanceEvaluator; -import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; -import moa.evaluation.LearningCurve; -import moa.evaluation.LearningEvaluation; -import moa.evaluation.LearningPerformanceEvaluator; -import moa.evaluation.MultiTargetPerformanceEvaluator; -import moa.evaluation.RegressionPerformanceEvaluator; -import moa.evaluation.WindowClassificationPerformanceEvaluator; -import moa.learners.Learner; -import moa.options.ClassOption; -import moa.streams.ExampleStream; -import moa.streams.MultiTargetInstanceStream; - -/** - * Task for evaluating a classifier on a stream by testing then training with each example in sequence. - * - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) - * @version $Revision: 7 $ - */ -public class EvaluatePrequentialMultiTarget extends MultiTargetMainTask { - - @Override - public String getPurposeString() { - return "Evaluates a classifier on a stream by testing then training with each example in sequence."; - } - - private static final long serialVersionUID = 1L; - - public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); - - public ClassOption streamOption = new ClassOption("stream", 's', - "Stream to learn from.", MultiTargetInstanceStream.class, - "MultiTargetArffFileStream"); - - public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', - "Classification performance evaluation method.", - MultiTargetPerformanceEvaluator.class, - "BasicMultiTargetPerformanceEvaluator"); - - public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', - "Maximum number of instances to test/train on (-1 = no limit).", - 100000000, -1, Integer.MAX_VALUE); - - public IntOption timeLimitOption = new IntOption("timeLimit", 't', - "Maximum number of seconds to test/train for (-1 = no limit).", -1, - -1, Integer.MAX_VALUE); - - public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", - 'f', - "How many instances between samples of the learning performance.", - 100000, 0, Integer.MAX_VALUE); - - public IntOption memCheckFrequencyOption = new IntOption( - "memCheckFrequency", 'q', - "How many instances between memory bound checks.", 100000, 0, - Integer.MAX_VALUE); - - public FileOption dumpFileOption = new FileOption("dumpFile", 'd', - "File to append intermediate csv results to.", null, "csv", true); - - public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', - "File to append output predictions to.", null, "pred", true); - - //New for prequential method DEPRECATED - public IntOption widthOption = new IntOption("width", - 'w', "Size of Window", 1000); - - public FloatOption alphaOption = new FloatOption("alpha", - 'a', "Fading factor or exponential smoothing factor", .01); - //End New for prequential methods - - @Override - public Class getTaskResultType() { - return LearningCurve.class; - } - - @Override - protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { - Learner learner = (Learner) getPreparedClassOption(this.learnerOption); - ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); - LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); - LearningCurve learningCurve = new LearningCurve( - "learning evaluation instances"); - - //New for prequential methods - if (evaluator instanceof WindowClassificationPerformanceEvaluator) { - //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); - if (widthOption.getValue() != 1000) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { - //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { - //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - //End New for prequential methods - - learner.setModelContext(stream.getHeader()); - int maxInstances = this.instanceLimitOption.getValue(); - long instancesProcessed = 0; - int maxSeconds = this.timeLimitOption.getValue(); - int secondsElapsed = 0; - monitor.setCurrentActivity("Evaluating learner...", -1.0); - - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - //File for output predictions - File outputPredictionFile = this.outputPredictionFileOption.getFile(); - PrintStream outputPredictionResultStream = null; - if (outputPredictionFile != null) { - try { - if (outputPredictionFile.exists()) { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile, true), true); - } else { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open prediction result file: " + outputPredictionFile, ex); - } - } - boolean firstDump = true; - boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); - long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - long lastEvaluateStartTime = evaluateStartTime; - double RAMHours = 0.0; - while (stream.hasMoreInstances() - && ((maxInstances < 0) || (instancesProcessed < maxInstances)) - && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { - Example trainInst = stream.nextInstance(); - Example testInst = (Example) trainInst; //.copy(); - //testInst.setClassMissing(); - //double[] prediction = learner.getVotesForInstance(testInst); - Prediction prediction = learner.getPredictionForInstance(testInst); - // Output prediction - if (outputPredictionFile != null) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { - sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); - } - outputPredictionResultStream.println(prediction + "," + sb.toString()); - } - - //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); - evaluator.addResult(testInst, prediction); - learner.trainOnInstance(trainInst); - instancesProcessed++; - if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 - || stream.hasMoreInstances() == false) { - long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); - double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); - double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs - RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours - RAMHours += RAMHoursIncrement; - lastEvaluateStartTime = evaluateTime; - learningCurve.insertEntry(new LearningEvaluation( - new Measurement[]{ - new Measurement( - "learning evaluation instances", - instancesProcessed), - new Measurement( - "evaluation time (" - + (preciseCPUTiming ? "cpu " - : "") + "seconds)", - time), - new Measurement( - "model cost (RAM-Hours)", - RAMHours) - }, - evaluator, learner)); - - if (immediateResultStream != null) { - if (firstDump) { - immediateResultStream.println(learningCurve.headerToString()); - firstDump = false; - } - immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); - immediateResultStream.flush(); - } - } - if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { - if (monitor.taskShouldAbort()) { - return null; - } - long estimatedRemainingInstances = stream.estimatedRemainingInstances(); - if (maxInstances > 0) { - long maxRemaining = maxInstances - instancesProcessed; - if ((estimatedRemainingInstances < 0) - || (maxRemaining < estimatedRemainingInstances)) { - estimatedRemainingInstances = maxRemaining; - } - } - monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 - : (double) instancesProcessed - / (double) (instancesProcessed + estimatedRemainingInstances)); - if (monitor.resultPreviewRequested()) { - monitor.setLatestResultPreview(learningCurve.copy()); - } - secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() - - evaluateStartTime); - } - } - StringBuilder sb= new StringBuilder(); - learner.getDescription(sb, 0); - System.out.println(sb.toString()); - if (immediateResultStream != null) { - immediateResultStream.close(); - } - if (outputPredictionResultStream != null) { - outputPredictionResultStream.close(); - } - return learningCurve; - } -} +/* + * EvaluatePrequentialMultiTarget.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.tasks; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstanceData; +import com.yahoo.labs.samoa.instances.Prediction; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; + +import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.Regressor; +import moa.core.Example; +import moa.core.Measurement; +import moa.core.ObjectRepository; +import moa.core.TimingUtils; +import moa.evaluation.EWMAClassificationPerformanceEvaluator; +import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; +import moa.evaluation.LearningCurve; +import moa.evaluation.LearningEvaluation; +import moa.evaluation.LearningPerformanceEvaluator; +import moa.evaluation.MultiTargetPerformanceEvaluator; +import moa.evaluation.RegressionPerformanceEvaluator; +import moa.evaluation.WindowClassificationPerformanceEvaluator; +import moa.learners.Learner; +import moa.options.ClassOption; +import moa.streams.ExampleStream; +import moa.streams.MultiTargetInstanceStream; + +/** + * Task for evaluating a classifier on a stream by testing then training with each example in sequence. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * @version $Revision: 7 $ + */ +public class EvaluatePrequentialMultiTarget extends MultiTargetMainTask { + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } + + private static final long serialVersionUID = 1L; + + public ClassOption learnerOption = new ClassOption("learner", 'l', + "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); + + public ClassOption streamOption = new ClassOption("stream", 's', + "Stream to learn from.", MultiTargetInstanceStream.class, + "MultiTargetArffFileStream"); + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + MultiTargetPerformanceEvaluator.class, + "BasicMultiTargetPerformanceEvaluator"); + + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); + + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); + + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); + + public FileOption dumpFileOption = new FileOption("dumpFile", 'd', + "File to append intermediate csv results to.", null, "csv", true); + + public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', + "File to append output predictions to.", null, "pred", true); + + //New for prequential method DEPRECATED + public IntOption widthOption = new IntOption("width", + 'w', "Size of Window", 1000); + + public FloatOption alphaOption = new FloatOption("alpha", + 'a', "Fading factor or exponential smoothing factor", .01); + //End New for prequential methods + + @Override + public Class getTaskResultType() { + return LearningCurve.class; + } + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + Learner learner = (Learner) getPreparedClassOption(this.learnerOption); + ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); + LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); + LearningCurve learningCurve = new LearningCurve( + "learning evaluation instances"); + + //New for prequential methods + if (evaluator instanceof WindowClassificationPerformanceEvaluator) { + //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); + if (widthOption.getValue() != 1000) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { + //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { + //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + //End New for prequential methods + + learner.setModelContext(stream.getHeader()); + int maxInstances = this.instanceLimitOption.getValue(); + long instancesProcessed = 0; + int maxSeconds = this.timeLimitOption.getValue(); + int secondsElapsed = 0; + monitor.setCurrentActivity("Evaluating learner...", -1.0); + + File dumpFile = this.dumpFileOption.getFile(); + PrintStream immediateResultStream = null; + if (dumpFile != null) { + try { + if (dumpFile.exists()) { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile, true), true); + } else { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open immediate result file: " + dumpFile, ex); + } + } + //File for output predictions + File outputPredictionFile = this.outputPredictionFileOption.getFile(); + PrintStream outputPredictionResultStream = null; + if (outputPredictionFile != null) { + try { + if (outputPredictionFile.exists()) { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile, true), true); + } else { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open prediction result file: " + outputPredictionFile, ex); + } + } + boolean firstDump = true; + boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); + long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + long lastEvaluateStartTime = evaluateStartTime; + double RAMHours = 0.0; + while (stream.hasMoreInstances() + && ((maxInstances < 0) || (instancesProcessed < maxInstances)) + && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { + Example trainInst = stream.nextInstance(); + Example testInst = (Example) trainInst; //.copy(); + //testInst.setClassMissing(); + //double[] prediction = learner.getVotesForInstance(testInst); + Prediction prediction = learner.getPredictionForInstance(testInst); + // Output prediction + if (outputPredictionFile != null) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); + } + + //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); + evaluator.addResult(testInst, prediction); + learner.trainOnInstance(trainInst); + instancesProcessed++; + if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 + || stream.hasMoreInstances() == false) { + long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); + double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); + double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs + RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours + RAMHours += RAMHoursIncrement; + lastEvaluateStartTime = evaluateTime; + learningCurve.insertEntry(new LearningEvaluation( + new Measurement[]{ + new Measurement( + "learning evaluation instances", + instancesProcessed), + new Measurement( + "evaluation time (" + + (preciseCPUTiming ? "cpu " + : "") + "seconds)", + time), + new Measurement( + "model cost (RAM-Hours)", + RAMHours) + }, + evaluator, learner)); + + if (immediateResultStream != null) { + if (firstDump) { + immediateResultStream.println(learningCurve.headerToString()); + firstDump = false; + } + immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); + immediateResultStream.flush(); + } + } + if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { + if (monitor.taskShouldAbort()) { + return null; + } + long estimatedRemainingInstances = stream.estimatedRemainingInstances(); + if (maxInstances > 0) { + long maxRemaining = maxInstances - instancesProcessed; + if ((estimatedRemainingInstances < 0) + || (maxRemaining < estimatedRemainingInstances)) { + estimatedRemainingInstances = maxRemaining; + } + } + monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 + : (double) instancesProcessed + / (double) (instancesProcessed + estimatedRemainingInstances)); + if (monitor.resultPreviewRequested()) { + monitor.setLatestResultPreview(learningCurve.copy()); + } + secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() + - evaluateStartTime); + } + } + StringBuilder sb= new StringBuilder(); + learner.getDescription(sb, 0); + System.out.println(sb.toString()); + if (immediateResultStream != null) { + immediateResultStream.close(); + } + if (outputPredictionResultStream != null) { + outputPredictionResultStream.close(); + } + return learningCurve; + } +} From 3bcb756268a2d3aa4b8f81acdbd1d8f74199cbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:07:34 +0100 Subject: [PATCH 19/33] Additional merging artefacts fixed --- .../MultitargetAttributeClassObserver.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java diff --git a/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java b/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java new file mode 100644 index 000000000..0cfc7acb6 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java @@ -0,0 +1,15 @@ +package moa.classifiers.core.attributeclassobservers; + +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.core.DoubleVector; + +public interface MultitargetAttributeClassObserver extends AttributeClassObserver { + + public void observeAttributeClassVector(double attVal, DoubleVector classVector, double weight); + + public AttributeSplitSuggestion getBestEvaluatedSplitSuggestion( + SplitCriterion criterion, double examlpesSeen, DoubleVector preSplitSums, DoubleVector preSplitSquares, int attIndex, + int numTargets, boolean binaryOnly); + +} From 458ac70871477e4a06481edb8cd726e096228aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:09:11 +0100 Subject: [PATCH 20/33] Test commit of everything --- .classpath | 13 ++ .project | 6 + moa/.classpath | 17 +- moa/.settings/org.eclipse.jdt.core.prefs | 3 + moa/pom.xml | 149 ------------------ .../classifiers/DecisionStumpTutorial.java | 7 +- .../classifiers/multilabel/trees/.gitignore | 1 + moa/src/main/java/moa/evaluation/.gitignore | 2 + weka-package/pom.xml | 53 ------- 9 files changed, 35 insertions(+), 216 deletions(-) create mode 100644 .classpath delete mode 100755 moa/pom.xml create mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore create mode 100644 moa/src/main/java/moa/evaluation/.gitignore delete mode 100644 weka-package/pom.xml diff --git a/.classpath b/.classpath new file mode 100644 index 000000000..dec9f005e --- /dev/null +++ b/.classpath @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/.project b/.project index 76bea900b..56c2846a7 100644 --- a/.project +++ b/.project @@ -5,6 +5,11 @@ + + org.eclipse.jdt.core.javabuilder + + + org.eclipse.m2e.core.maven2Builder @@ -13,5 +18,6 @@ org.eclipse.m2e.core.maven2Nature + org.eclipse.jdt.core.javanature diff --git a/moa/.classpath b/moa/.classpath index 534b5e52f..f5accf223 100644 --- a/moa/.classpath +++ b/moa/.classpath @@ -11,26 +11,21 @@ - - - - - - - - - - - + + + + + + diff --git a/moa/.settings/org.eclipse.jdt.core.prefs b/moa/.settings/org.eclipse.jdt.core.prefs index 60105c1b9..69c31cd49 100644 --- a/moa/.settings/org.eclipse.jdt.core.prefs +++ b/moa/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,8 @@ eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.source=1.6 diff --git a/moa/pom.xml b/moa/pom.xml deleted file mode 100755 index 11e6a9b6a..000000000 --- a/moa/pom.xml +++ /dev/null @@ -1,149 +0,0 @@ - - 4.0.0 - - - nz.ac.waikato.cms.moa - moa-pom - 2017.10-SNAPSHOT - - - moa - jar - - MOA: Massive Online Analysis - - Massive On-line Analysis is an environment for massive data mining. MOA - provides a framework for data stream mining and includes tools for evaluation - and a collection of machine learning algorithms. Related to the WEKA project, - also written in Java, while scaling to more demanding problems. - - http://moa.cms.waikato.ac.nz/ - - University of Waikato, Hamilton, NZ - http://www.waikato.ac.nz/ - - - - GNU General Public License 3.0 - http://www.gnu.org/licenses/gpl-3.0.txt - repo - - - - - - abifet - Albert Bifet - abifet@waikato.ac.nz - - - rkirkby - Richard Kirkby - - - - - - nz.ac.waikato.cms.weka - weka-dev - - - - com.googlecode.sizeofag - sizeofag - - - - net.sf.meka - meka - - - - junit - junit - test - - - - org.apache.commons - commons-math3 - 3.6.1 - - - - com.googlecode.java-diff-utils - diffutils - 1.2.1 - test - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.7 - 1.7 - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - - org.codehaus.mojo - license-maven-plugin - - - - org.codehaus.mojo - latex-maven-plugin - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - - license-maven-plugin - - [1.1,) - - add-third-party - - - - - - - - - - - - - - diff --git a/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java b/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java index f22f5a04b..0cabab7dc 100644 --- a/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java +++ b/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java @@ -1,7 +1,5 @@ package moa.classifiers; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.GaussianNumericAttributeClassObserver; @@ -9,8 +7,11 @@ import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.core.AutoExpandVector; import moa.core.DoubleVector; -import moa.core.Measurement; import moa.options.ClassOption; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; + import com.yahoo.labs.samoa.instances.Instance; public class DecisionStumpTutorial extends AbstractClassifier { diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore b/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore new file mode 100644 index 000000000..8e36d7391 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore @@ -0,0 +1 @@ +/BaselinePerceptron.java diff --git a/moa/src/main/java/moa/evaluation/.gitignore b/moa/src/main/java/moa/evaluation/.gitignore new file mode 100644 index 000000000..48df8b2bf --- /dev/null +++ b/moa/src/main/java/moa/evaluation/.gitignore @@ -0,0 +1,2 @@ +/MultilabelWindowClassificationPerformanceEvaluatorWithMEKAMetrics.java +/MultiTargetWindowRegressionPerformanceEvaluator2.java diff --git a/weka-package/pom.xml b/weka-package/pom.xml deleted file mode 100644 index 4110e3065..000000000 --- a/weka-package/pom.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - 4.0.0 - - - nz.ac.waikato.cms.moa - moa-pom - 2017.10-SNAPSHOT - - - weka-package - jar - - MOA: WEKA Package - - Massive On-line Analysis is an environment for massive data mining. MOA provides a framework for data stream mining and includes tools for evaluation and a collection of machine learning algorithms. Related to the WEKA project, also written in Java, while scaling to more demanding problems. - This artifact enables you to use MOA from within WEKA. - - http://moa.cms.waikato.ac.nz/ - - University of Waikato, Hamilton, NZ - http://www.waikato.ac.nz/ - - - - GNU General Public License 3 - http://www.gnu.org/licenses/gpl-3.0.txt - repo - - - - - - abifet - Albert Bifet - abifet@waikato.ac.nz - - - fracpete - Peter Reutemann - fracpete@waikato.ac.nz - - - - - - nz.ac.waikato.cms.moa - moa - [${project.version},) - - - From a40904dd0e9bcde5b9cc7a3a653fdc8534041381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:37:42 +0100 Subject: [PATCH 21/33] Revert "Test commit of everything" This reverts commit 02d26831ad12964b8c91204bb81c22a5fdd5550b. --- .classpath | 13 -- .project | 6 - moa/.classpath | 17 ++- moa/.settings/org.eclipse.jdt.core.prefs | 3 - moa/pom.xml | 138 ++++++++++++++++++ .../classifiers/DecisionStumpTutorial.java | 13 +- .../classifiers/multilabel/trees/.gitignore | 1 - moa/src/main/java/moa/evaluation/.gitignore | 2 - weka-package/pom.xml | 53 +++++++ 9 files changed, 205 insertions(+), 41 deletions(-) delete mode 100644 .classpath create mode 100755 moa/pom.xml delete mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore delete mode 100644 moa/src/main/java/moa/evaluation/.gitignore create mode 100644 weka-package/pom.xml diff --git a/.classpath b/.classpath deleted file mode 100644 index dec9f005e..000000000 --- a/.classpath +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/.project b/.project index 56c2846a7..76bea900b 100644 --- a/.project +++ b/.project @@ -5,11 +5,6 @@ - - org.eclipse.jdt.core.javabuilder - - - org.eclipse.m2e.core.maven2Builder @@ -18,6 +13,5 @@ org.eclipse.m2e.core.maven2Nature - org.eclipse.jdt.core.javanature diff --git a/moa/.classpath b/moa/.classpath index f5accf223..534b5e52f 100644 --- a/moa/.classpath +++ b/moa/.classpath @@ -11,21 +11,26 @@ + + + + + + + + + + + - - - - - - diff --git a/moa/.settings/org.eclipse.jdt.core.prefs b/moa/.settings/org.eclipse.jdt.core.prefs index 69c31cd49..60105c1b9 100644 --- a/moa/.settings/org.eclipse.jdt.core.prefs +++ b/moa/.settings/org.eclipse.jdt.core.prefs @@ -1,8 +1,5 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.source=1.6 diff --git a/moa/pom.xml b/moa/pom.xml new file mode 100755 index 000000000..dd44c7979 --- /dev/null +++ b/moa/pom.xml @@ -0,0 +1,138 @@ + + 4.0.0 + + + nz.ac.waikato.cms.moa + moa-pom + 2015.05-SNAPSHOT + + + moa + jar + + MOA: Massive Online Analysis + + Massive On-line Analysis is an environment for massive data mining. MOA + provides a framework for data stream mining and includes tools for evaluation + and a collection of machine learning algorithms. Related to the WEKA project, + also written in Java, while scaling to more demanding problems. + + http://moa.cms.waikato.ac.nz/ + + University of Waikato, Hamilton, NZ + http://www.waikato.ac.nz/ + + + + GNU General Public License 3.0 + http://www.gnu.org/licenses/gpl-3.0.txt + repo + + + + + + abifet + Albert Bifet + abifet@waikato.ac.nz + + + rkirkby + Richard Kirkby + + + + + + nz.ac.waikato.cms.weka + weka-dev + + + + com.googlecode.sizeofag + sizeofag + + + + junit + junit + test + + + + com.googlecode.java-diff-utils + diffutils + 1.2.1 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + org.codehaus.mojo + license-maven-plugin + + + + org.codehaus.mojo + latex-maven-plugin + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + + license-maven-plugin + + [1.1,) + + add-third-party + + + + + + + + + + + + + + diff --git a/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java b/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java index 0cabab7dc..8d18b0a9d 100644 --- a/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java +++ b/moa/src/examples/java/moa/classifiers/DecisionStumpTutorial.java @@ -1,18 +1,11 @@ package moa.classifiers; -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.GaussianNumericAttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.NominalAttributeClassObserver; -import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.options.ClassOption; - -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; - -import com.yahoo.labs.samoa.instances.Instance; +import moa.options.FlagOption; +import moa.options.IntOption; +import weka.core.Instance; public class DecisionStumpTutorial extends AbstractClassifier { diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore b/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore deleted file mode 100644 index 8e36d7391..000000000 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/BaselinePerceptron.java diff --git a/moa/src/main/java/moa/evaluation/.gitignore b/moa/src/main/java/moa/evaluation/.gitignore deleted file mode 100644 index 48df8b2bf..000000000 --- a/moa/src/main/java/moa/evaluation/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/MultilabelWindowClassificationPerformanceEvaluatorWithMEKAMetrics.java -/MultiTargetWindowRegressionPerformanceEvaluator2.java diff --git a/weka-package/pom.xml b/weka-package/pom.xml new file mode 100644 index 000000000..6cd73530c --- /dev/null +++ b/weka-package/pom.xml @@ -0,0 +1,53 @@ + + + + 4.0.0 + + + nz.ac.waikato.cms.moa + moa-pom + 2012.09-SNAPSHOT + + + weka-package + jar + + MOA: WEKA Package + + Massive On-line Analysis is an environment for massive data mining. MOA provides a framework for data stream mining and includes tools for evaluation and a collection of machine learning algorithms. Related to the WEKA project, also written in Java, while scaling to more demanding problems. + This artifact enables you to use MOA from within WEKA. + + http://moa.cms.waikato.ac.nz/ + + University of Waikato, Hamilton, NZ + http://www.waikato.ac.nz/ + + + + GNU General Public License 3 + http://www.gnu.org/licenses/gpl-3.0.txt + repo + + + + + + abifet + Albert Bifet + abifet@waikato.ac.nz + + + fracpete + Peter Reutemann + fracpete@waikato.ac.nz + + + + + + nz.ac.waikato.cms.moa + moa + [${project.version},) + + + From 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:37:46 +0100 Subject: [PATCH 22/33] Revert "Additional merging artefacts fixed" This reverts commit 5dec8c12eaac8f4785df76b61e4d40a591a13321. --- .../MultitargetAttributeClassObserver.java | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java diff --git a/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java b/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java deleted file mode 100644 index 0cfc7acb6..000000000 --- a/moa/src/main/java/moa/classifiers/core/attributeclassobservers/MultitargetAttributeClassObserver.java +++ /dev/null @@ -1,15 +0,0 @@ -package moa.classifiers.core.attributeclassobservers; - -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.core.DoubleVector; - -public interface MultitargetAttributeClassObserver extends AttributeClassObserver { - - public void observeAttributeClassVector(double attVal, DoubleVector classVector, double weight); - - public AttributeSplitSuggestion getBestEvaluatedSplitSuggestion( - SplitCriterion criterion, double examlpesSeen, DoubleVector preSplitSums, DoubleVector preSplitSquares, int attIndex, - int numTargets, boolean binaryOnly); - -} From e4f2eb61e5ef780975d8948c9f132b8d2e4199f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 9 Nov 2015 16:38:13 +0100 Subject: [PATCH 23/33] Revert "Removed merging artefacts" This reverts commit 4e3116ae22afc259caa4f4e7d967ae369aae367c. --- .../samoa/instances/MultiLabelPrediction.java | 5 +- .../LocalMultiTargetClassifier.java | 3 +- .../multilabel/trees/ISOUPTree.java | 43 +- .../java/moa/classifiers/trees/FIMTDD.java | 1001 +++++++++++++++++ .../main/java/moa/classifiers/trees/ORTO.java | 203 ++++ 5 files changed, 1238 insertions(+), 17 deletions(-) diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index 81c9b86f5..fbffed6ae 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -33,7 +33,10 @@ public MultiLabelPrediction(int numOutputAttributes) { public MultiLabelPrediction(DoubleVector[] prediction) { this.prediction = prediction; } - + + public MultiLabelPrediction(DoubleVector[] prediction) { + this.prediction = prediction; + } @Override public int numOutputAttributes() { diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 21c34b1dc..428434562 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -28,6 +28,8 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner implements MultiLabelClassifier, MultiTargetRegressor { + private static final long serialVersionUID = 1L; + public ClassOption classifierOption = new ClassOption( "classifier", 'c', @@ -100,7 +102,6 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); for (int j = 0; j < inst.numberOutputTargets(); j++) { Instance STInst = getSTInstance(inst, j); - prediction.setVote(j, 1, classifiers.get(j).getVotesForInstance(STInst)[0]); } return prediction; diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index 6b6df7e18..c657f290d 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -82,6 +82,14 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR //region ================ OPTIONS ================ + // public ClassOption splitCriterionOption = new ClassOption( + // "splitCriterion", + // 's', + // "Split criterion to use.", + // SplitCriterion.class, + // "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); + // TODO not used at the moment, consider later when the implementation catches up + public IntOption gracePeriodOption = new IntOption( "gracePeriod", 'g', @@ -305,6 +313,7 @@ public LeafNode(ISOUPTree tree) { */ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, boolean growthAllowed) { // Update the statistics for this node + double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; double[] predictionM = getPredictionTargetMean(inst); @@ -323,6 +332,7 @@ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, bool errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - inst.valueOutputAttribute(i))); } } + if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); for (int i = 0; i < inst.numInputAttributes(); i++) { @@ -398,6 +408,8 @@ public double[] getPredictionTargetMean(MultiLabelInstance inst) { if (examplesSeen > 0) { for (int i = 0; i < inst.numOutputAttributes(); i++) { pred[i] = sumOfValues.getValue(i) / examplesSeen; + } else { + pred[i] = 0; } } return pred; @@ -598,7 +610,8 @@ public class MultitargetPerceptron { protected ISOUPTree tree; // The Perception weights - protected double[][] weights; + public double[][] weights; + // The number of instances contributing to this model protected int instancesSeen = 0; @@ -629,6 +642,7 @@ public void initializeWeights() { weights[i][j] = 2 * tree.classifierRandom.nextDouble() - 1; } } + normalizeWeights(); } /** @@ -730,6 +744,7 @@ public void getModelDescription(StringBuilder out, int indent) { } StringUtils.appendNewline(out); } + StringUtils.appendNewline(out); } } @@ -746,9 +761,12 @@ public String getPurposeString() { public void resetLearningImpl() { treeRoot = null; - leafNodeCount = 0; - splitNodeCount = 0; - maxID = 0; + examplesSeen = 0.0; + sumOfValues = new DoubleVector(); + sumOfSquares = new DoubleVector(); + + sumOfAttrValues = new DoubleVector(); + sumOfAttrSquares = new DoubleVector(); } public boolean isRandomizable() { @@ -842,7 +860,7 @@ public double[] normalizeTargetVector(double[] pred) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0 && examplesSeen > 1) - out[i] = (value - average) / (3 * sd); + out[i] = (value - average) / sd; else out[i] = 0; } @@ -858,7 +876,7 @@ public double normalizeTargetValue(MultiLabelInstance inst, int i) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0) - return (value - average) / (3 * sd); + return (value - average) / sd; else return 0; } @@ -872,7 +890,7 @@ public double normalizeTargetValue(double value, int i) { double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); double average = sumOfValues.getValue(i) / examplesSeen; if (sd > 0) - return (value - average) / (3 * sd); + return (value - average) / sd; else return 0; } @@ -900,9 +918,9 @@ public void trainOnInstanceImpl(MultiLabelInstance inst) { double[] prediction = treeRoot.getPrediction(inst); double[] normalError = getNormalizedError(inst, prediction); - //normalError.scaleValues(inst.weight()); + processInstance(inst, treeRoot, prediction, normalError, true, false); - + examplesSeen += inst.weight(); for (int i = 0; i < inst.numberOutputTargets(); i++) { sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); @@ -1013,7 +1031,7 @@ protected LeafNode newLeafNode() { return new LeafNode(this); } - protected MultitargetPerceptron newLeafModel() { + public MultitargetPerceptron newLeafModel() { return new MultitargetPerceptron(this); } @@ -1023,7 +1041,6 @@ protected MultitargetPerceptron newLeafModel() { protected void checkRoot() { if (treeRoot == null) { treeRoot = newLeafNode(); - leafNodeCount = 1; } } @@ -1101,7 +1118,6 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) newSplit.copyStatistics(node); newSplit.changeDetection = node.changeDetection; newSplit.ID = node.ID; - leafNodeCount--; //System.out.println("Splitting"); //System.out.println(examplesSeen); for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) @@ -1114,7 +1130,6 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) newChild.changeDetection = node.changeDetection; newChild.setParent(newSplit); newSplit.setChild(i, newChild); - leafNodeCount++; } if (parent == null && node.originalNode == null) { treeRoot = newSplit; @@ -1124,8 +1139,6 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) parent.setChild(parentIndex, newSplit); newSplit.setParent(parent); } - - splitNodeCount++; } } diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java index 219fd3a2a..a2dcd0b7c 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java @@ -1,3 +1,1000 @@ +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 +======= +<<<<<<< HEAD +/* + * FIMTDD.java + * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia + * @author Aljaž Osojnik + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package moa.classifiers.trees; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import com.yahoo.labs.samoa.instances.Instance; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; + +import moa.options.ClassOption; +import moa.AbstractMOAObject; +import moa.classifiers.Regressor; +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; +import moa.classifiers.core.conditionaltests.InstanceConditionalTest; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.classifiers.AbstractClassifier; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.Measurement; +import moa.core.SizeOf; +import moa.core.StringUtils; + +/* + * Implementation of FIMTDD, regression and model trees for data streams. + */ + +public class FIMTDD extends AbstractClassifier implements Regressor { + + private static final long serialVersionUID = 1L; + + protected Node treeRoot; + + protected int leafNodeCount = 0; + protected int splitNodeCount = 0; + + protected double examplesSeen = 0.0; + protected double sumOfValues = 0.0; + protected double sumOfSquares = 0.0; + + protected DoubleVector sumOfAttrValues = new DoubleVector(); + protected DoubleVector sumOfAttrSquares = new DoubleVector(); + + public int maxID = 0; + + //region ================ OPTIONS ================ + + public ClassOption splitCriterionOption = new ClassOption( + "splitCriterion", 's', "Split criterion to use.", + SplitCriterion.class, "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); + + public IntOption gracePeriodOption = new IntOption( + "gracePeriod", 'g', "Number of instances a leaf should observe between split attempts.", + 200, 0, Integer.MAX_VALUE); + + public FloatOption splitConfidenceOption = new FloatOption( + "splitConfidence", 'c', "Allowed error in split decision, values close to 0 will take long to decide.", + 0.0000001, 0.0, 1.0); + + public FloatOption tieThresholdOption = new FloatOption( + "tieThreshold", 't', "Threshold below which a split will be forced to break ties.", + 0.05, 0.0, 1.0); + + public FloatOption PageHinckleyAlphaOption = new FloatOption( + "PageHinckleyAlpha", 'a', "Alpha value to use in the Page Hinckley change detection tests.", + 0.005, 0.0, 1.0); + + public IntOption PageHinckleyThresholdOption = new IntOption( + "PageHinckleyThreshold", 'h', "Threshold value used in the Page Hinckley change detection tests.", + 50, 0, Integer.MAX_VALUE); + + public FloatOption alternateTreeFadingFactorOption = new FloatOption( + "alternateTreeFadingFactor", 'f', "Fading factor used to decide if an alternate tree should replace an original.", + 0.995, 0.0, 1.0); + + public IntOption alternateTreeTMinOption = new IntOption( + "alternateTreeTMin", 'y', "Tmin value used to decide if an alternate tree should replace an original.", + 150, 0, Integer.MAX_VALUE); + + public IntOption alternateTreeTimeOption = new IntOption( + "alternateTreeTime", 'u', "The number of instances used to decide if an alternate tree should be discarded.", + 1500, 0, Integer.MAX_VALUE); + + public FlagOption regressionTreeOption = new FlagOption( + "regressionTree", 'e', "Build a regression tree instead of a model tree."); + + public FloatOption learningRatioOption = new FloatOption( + "learningRatio", 'l', "Learning ratio to used for training the Perceptrons in the leaves.", + 0.003, 0, 1.00); + + public FloatOption learningRateDecayFactorOption = new FloatOption( + "learningRatioDecayFactor", 'd', "Learning rate decay factor (not used when learning rate is constant).", + 0.001, 0, 1.00); + + public FlagOption learningRatioConstOption = new FlagOption( + "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public abstract static class Node extends AbstractMOAObject { + + private static final long serialVersionUID = 1L; + + public int ID; + + protected FIMTDD tree; + + protected boolean changeDetection = true; + + protected Node parent; + + protected Node alternateTree; + protected Node originalNode; + + // The statistics for this node: + // Number of instances that have reached it + protected double examplesSeen; + // Sum of y values + protected double sumOfValues; + // Sum of squared y values + protected double sumOfSquares; + // Sum of absolute errors + protected double sumOfAbsErrors; // Needed for PH tracking of mean error + + public Node(FIMTDD tree) { + this.tree = tree; + ID = tree.maxID; + } + + public void copyStatistics(Node node) { + examplesSeen = node.examplesSeen; + sumOfValues = node.sumOfValues; + sumOfSquares = node.sumOfSquares; + sumOfAbsErrors = node.sumOfAbsErrors; + } + + public int calcByteSize() { + return (int) SizeOf.fullSizeOf(this); + } + + /** + * Set the parent node + */ + public void setParent(Node parent) { + this.parent = parent; + } + + /** + * Return the parent node + */ + public Node getParent() { + return parent; + } + + public void disableChangeDetection() { + changeDetection = false; + } + + public void restartChangeDetection() { + changeDetection = true; + } + + public void getDescription(StringBuilder sb, int indent) { + + } + + public double getPrediction(Instance inst) { + return 0; + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf"); + } + + public int getLevel() { + Node target = this; + int level = 0; + while (target.getParent() != null) { + if (target.skipInLevelCount()) { + target = target.getParent(); + continue; + } + level = level + 1; + target = target.getParent(); + } + if (target.originalNode == null) { + return level; + } else { + return level + originalNode.getLevel(); + } + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + } + + public static class LeafNode extends Node { + + private static final long serialVersionUID = 1L; + + public double errorModel = 0.0; + public double errorTargetMean = 0.0; + + // Perceptron model that carries out the actual learning in each node + public FIMTDDPerceptron learningModel; + + protected AutoExpandVector attributeObservers = new AutoExpandVector(); + + protected double examplesSeenAtLastSplitEvaluation = 0; + + /** + * Create a new LeafNode + */ + public LeafNode(FIMTDD tree) { + super(tree); + if (tree.buildingModelTree()) { + learningModel = tree.newLeafModel(); + } + examplesSeen = 0; + sumOfValues = 0; + sumOfSquares = 0; + sumOfAbsErrors = 0; + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + + /** + * Method to learn from an instance that passes the new instance to the perceptron learner, + * and also prevents the class value from being truncated to an int when it is passed to the + * attribute observer + */ + public void learnFromInstance(Instance inst, boolean growthAllowed, double prediction) { + //The prediction must be calculated here -- it may be different from the tree's prediction due to alternate trees + + // Update the statistics for this node + // number of instances passing through the node + examplesSeen += inst.weight(); + + // sum of y values + sumOfValues += inst.weight() * inst.classValue(); + + // sum of squared y values + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + // sum of absolute errors + sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - prediction))); + + if (tree.buildingModelTree()) { + double predictionModel = getPredictionModel(inst); + double predictionTargetMean = getPredictionTargetMean(inst); + + errorModel = errorModel * 0.95 + Math.abs(predictionModel - inst.classValue()); + errorTargetMean = errorTargetMean * 0.95 + Math.abs(predictionTargetMean - inst.classValue()); + + learningModel.updatePerceptron(inst); + } + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); + FIMTDDNumericAttributeClassObserver obs = attributeObservers.get(i); + if (obs == null) { + // At this stage all nominal attributes are ignored + if (inst.attribute(instAttIndex).isNumeric()) { + obs = tree.newNumericClassObserver(); + this.attributeObservers.set(i, obs); + } + } + if (obs != null) { + obs.observeAttributeClass(inst.value(instAttIndex), inst.classValue(), inst.weight()); + } + } + + if (growthAllowed) { + checkForSplit(); + } + } + + /** + * Return the best split suggestions for this node using the given split criteria + */ + public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion) { + + List bestSuggestions = new LinkedList(); + + // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution + double[] nodeSplitDist = new double[] {examplesSeen, sumOfValues, sumOfSquares}; + + for (int i = 0; i < this.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = this.attributeObservers.get(i); + if (obs != null) { + + // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED + AttributeSplitSuggestion bestSuggestion = null; + if (obs instanceof FIMTDDNumericAttributeClassObserver) { + bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, nodeSplitDist, i, true); + } + + if (bestSuggestion != null) { + bestSuggestions.add(bestSuggestion); + } + } + } + return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); + } + + /** + * Retrieve the class votes using the perceptron learner + */ + public double getPredictionModel(Instance inst) { + return learningModel.prediction(inst); + } + + public double getPredictionTargetMean(Instance inst) { + return (examplesSeen > 0.0) ? sumOfValues / examplesSeen : 0.0; + } + + public double getPrediction(Instance inst) { + if (tree.buildingModelTree()) { + //return getPredictionModel(inst); + return (errorModel < errorTargetMean) ? getPredictionModel(inst) : getPredictionTargetMean(inst); + } else + return getPredictionTargetMean(inst); + } + + public void checkForSplit() { + // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node + if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { + int index = (parent != null) ? parent.getChildIndex(this) : 0; + tree.attemptToSplit(this, parent, index); + + // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation + examplesSeenAtLastSplitEvaluation = examplesSeen; + } + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf "); + if (tree.buildingModelTree()) { + learningModel.getModelDescription(out, 0); + } else { + out.append(tree.getClassNameString() + " = " + String.format("%.4f", sumOfValues / examplesSeen)); + StringUtils.appendNewline(out); + } + } + } + + public abstract static class InnerNode extends Node { + // The InnerNode and SplitNode design is used for easy extension in ORTO + private static final long serialVersionUID = 1L; + + protected AutoExpandVector children = new AutoExpandVector(); + + // The error values for the Page Hinckley test + // PHmT = the cumulative sum of the errors + // PHMT = the minimum error value seen so far + protected double PHsum = 0; + protected double PHmin = Double.MAX_VALUE; + + // Keep track of the statistics for loss error calculations + protected double lossExamplesSeen; + protected double lossFadedSumOriginal; + protected double lossFadedSumAlternate; + protected double lossNumQiTests; + protected double lossSumQi; + protected double previousWeight = 0; + + public InnerNode(FIMTDD tree) { + super(tree); + } + + public int numChildren() { + return children.size(); + } + + public Node getChild(int index) { + return children.get(index); + } + + public int getChildIndex(Node child) { + return children.indexOf(child); + } + + public void setChild(int index, Node child) { + children.set(index, child); + } + + public void disableChangeDetection() { + changeDetection = false; + for (Node child : children) { + child.disableChangeDetection(); + } + } + + public void restartChangeDetection() { + if (alternateTree == null) { + changeDetection = true; + PHsum = 0; + PHmin = Integer.MAX_VALUE; + for (Node child : children) + child.restartChangeDetection(); + } + } + + /** + * Check to see if the tree needs updating + */ + public boolean PageHinckleyTest(double error, double threshold) { + // Update the cumulative mT sum + PHsum += error; + + // Update the minimum mT value if the new mT is + // smaller than the current minimum + if(PHsum < PHmin) { + PHmin = PHsum; + } + // Return true if the cumulative value - the current minimum is + // greater than the current threshold (in which case we should adapt) + return PHsum - PHmin > threshold; + } + + public void initializeAlternateTree() { + // Start a new alternate tree, beginning with a learning node + alternateTree = tree.newLeafNode(); + alternateTree.originalNode = this; + + // Set up the blank statistics + // Number of instances reaching this node since the alternate tree was started + lossExamplesSeen = 0; + // Faded squared error (original tree) + lossFadedSumOriginal = 0; + // Faded squared error (alternate tree) + lossFadedSumAlternate = 0; + // Number of evaluations of alternate tree + lossNumQiTests = 0; + // Sum of Qi values + lossSumQi = 0; + // Number of examples at last test + previousWeight = 0; + + // Disable the change detection mechanism bellow this node + disableChangeDetection(); + } + } + + public static class SplitNode extends InnerNode { + + private static final long serialVersionUID = 1L; + + protected InstanceConditionalTest splitTest; + + /** + * Create a new SplitNode + * @param tree + */ + public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { + super(tree); + this.splitTest = splitTest; + } + + public int instanceChildIndex(Instance inst) { + return splitTest.branchForInstance(inst); + } + + public Node descendOneStep(Instance inst) { + return children.get(splitTest.branchForInstance(inst)); + } + + public void describeSubtree(StringBuilder out, int indent) { + for (int branch = 0; branch < children.size(); branch++) { + Node child = getChild(branch); + if (child != null) { + StringUtils.appendIndented(out, indent, "if "); + out.append(this.splitTest.describeConditionForBranch(branch, + tree.getModelContext())); + out.append(": "); + StringUtils.appendNewline(out); + child.describeSubtree(out, indent + 2); + } + } + } + + public double getPrediction(Instance inst) { + return children.get(splitTest.branchForInstance(inst)).getPrediction(inst); + } + } + + public class FIMTDDPerceptron implements Serializable { + + private static final long serialVersionUID = 1L; + + protected FIMTDD tree; + + // The Perception weights + protected double[] weightAttribute; + + // The number of instances contributing to this model + protected double instancesSeen = 0; + + public String getPurposeString() { + return "A perceptron regressor as specified by Ikonomovska et al. used for FIMTDD"; + } + + public FIMTDDPerceptron(FIMTDDPerceptron original) { + this.tree = original.tree; + weightAttribute = original.weightAttribute.clone(); + } + + public FIMTDDPerceptron(FIMTDD tree) { + this.tree = tree; + initializeWeights(); + + } + + public void initializeWeights() { + weightAttribute = new double[tree.getModelContext().numInputAttributes()+1]; + instancesSeen = 0; + for (int j = 0; j < tree.getModelContext().numInputAttributes()+1; j++) { + // The last index corresponds to the constant b + weightAttribute[j] = 2 * tree.classifierRandom.nextDouble() - 1; + } + normalizeWeights(); + } + + /** + * Update the model using the provided instance + */ + public void updatePerceptron(Instance inst) { + + // Update attribute statistics + instancesSeen += inst.weight(); + + // Update weights + double learningRatio = 0.0; + if (tree.learningRatioConstOption.isSet()) { + learningRatio = learningRatioOption.getValue(); + } else { + learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); + } + + // Loop for compatibility with bagging methods + for (int i = 0; i < (int) inst.weight(); i++) { + updateWeights(inst, learningRatio); + } + + } + + public void updateWeights(Instance inst, double learningRatio) { + // Compute the normalized instance and the delta + double[] normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + double normalizedValue = tree.normalizeTargetValue(inst.classValue()); + double delta = normalizedValue - normalizedPrediction; + for (int i = 0; i < weightAttribute.length; i++) { + weightAttribute[i] += delta * learningRatio * normalizedInstance[i]; + } + + normalizeWeights(); + } + + public void normalizeWeights() { + double sum = 0; + for (int i = 0; i < this.weightAttribute.length; i++) + sum += Math.abs(weightAttribute[i]); + for (int i = 0; i < this.weightAttribute.length; i++) + weightAttribute[i] /= sum; + } + + public double[] normalizedInstance(Instance inst) { + // Normalize Instance + double[] normalizedInstance = new double[inst.numInputAttributes()+1]; + for (int j = 0; j < inst.numInputAttributes(); j++) { + double mean = tree.sumOfAttrValues.getValue(j) / tree.examplesSeen; + double sd = computeSD(tree.sumOfAttrSquares.getValue(j), tree.sumOfAttrValues.getValue(j), tree.examplesSeen); + if (inst.inputAttribute(j).isNumeric() && tree.examplesSeen > 1 && sd > 0.0000001) + normalizedInstance[j] = (inst.valueInputAttribute(j) - mean) / (sd); + else + normalizedInstance[j] = 0; + } + normalizedInstance[inst.numInputAttributes()] = tree.examplesSeen > 1 ? 1 : 0; // Value to be multiplied with the constant factor + return normalizedInstance; + } + + /** + * Output the prediction made by this perceptron on the given instance + */ + public double prediction(double[] instanceValues) { + double ret = 0; + for (int i = 0; i < instanceValues.length; i++) + ret += instanceValues[i] * weightAttribute[i]; + return ret; + } + + protected double prediction(Instance inst) { + double[] normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + return denormalizePrediction(normalizedPrediction); + } + + private double denormalizePrediction(double normalizedPrediction) { + double mean = tree.sumOfValues / tree.examplesSeen; + double sd = computeSD(tree.sumOfSquares, tree.sumOfValues, tree.examplesSeen); + if (examplesSeen > 1) + return normalizedPrediction * sd + mean; + else + return 0.0; + } + + public void getModelDescription(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, getClassNameString() + " ="); + if (getModelContext() != null) { + for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { + if (getModelContext().attribute(j).isNumeric()) { + out.append((j == 0 || weightAttribute[j] < 0) ? " " : " + "); + out.append(String.format("%.4f", weightAttribute[j])); + out.append(" * "); + out.append(getAttributeNameString(j)); + } + } + out.append(" + " + weightAttribute[getModelContext().numInputAttributes()]); + } + StringUtils.appendNewline(out); + } + } + + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + // region --- Regressor methods + + public String getPurposeString() { + return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + this.treeRoot = null; + this.leafNodeCount = 0; + this.splitNodeCount = 0; + this.maxID = 0; + this.examplesSeen = 0; + this.sumOfValues = 0.0; + this.sumOfSquares = 0.0; + + this.sumOfAttrValues = new DoubleVector(); + this.sumOfAttrSquares = new DoubleVector(); + } + + public boolean isRandomizable() { + return true; + } + + public void getModelDescription(StringBuilder out, int indent) { + if (treeRoot != null) treeRoot.describeSubtree(out, indent); + } + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("tree size (leaves)", this.leafNodeCount) + }; + } + + public int calcByteSize() { + return (int) SizeOf.fullSizeOf(this); + } + + public double[] getVotesForInstance(Instance inst) { + if (treeRoot == null) { + return new double[] {0}; + } + + double prediction = treeRoot.getPrediction(inst); + + return new double[] {prediction}; + } + + public double normalizeTargetValue(double value) { + if (examplesSeen > 1) { + double sd = Math.sqrt((sumOfSquares - ((sumOfValues * sumOfValues)/examplesSeen))/examplesSeen); + double average = sumOfValues / examplesSeen; + if (sd > 0 && examplesSeen > 1) + return (value - average) / sd; + else + return 0.0; + } + return 0.0; + } + + public double getNormalizedError(Instance inst, double prediction) { + double normalPrediction = normalizeTargetValue(prediction); + double normalValue = normalizeTargetValue(inst.classValue()); + return Math.abs(normalValue - normalPrediction); + } + + + /** + * Method for updating (training) the model using a new instance + */ + public void trainOnInstanceImpl(Instance inst) { + checkRoot(); + + double prediction = treeRoot.getPrediction(inst); + double normalError = getNormalizedError(inst, prediction); + + processInstance(inst, treeRoot, prediction, normalError, true, false); + + examplesSeen += inst.weight(); + sumOfValues += inst.weight() * inst.classValue(); + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int aIndex = modelAttIndexToInstanceAttIndex(i, inst); + sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); + } + + + } + + public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); + break; + } else { + currentNode.examplesSeen += inst.weight(); + currentNode.sumOfAbsErrors += inst.weight() * normalError; + InnerNode iNode = (InnerNode) currentNode; + if (!inAlternate && iNode.alternateTree != null) { + boolean altTree = true; + double lossO = Math.pow(inst.classValue() - prediction, 2); + double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); + + // Loop for compatibility with bagging methods + for (int i = 0; i < inst.weight(); i++) { + iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + iNode.lossExamplesSeen++; + + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + iNode.lossSumQi += Qi; + iNode.lossNumQiTests += 1; + } + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + + if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + iNode.previousWeight = iNode.lossExamplesSeen; + if (Qi > 0) { + // Switch the subtrees + Node parent = iNode.getParent(); + + if (parent != null) { + Node replacementTree = iNode.alternateTree; + parent.setChild(parent.getChildIndex(iNode), replacementTree); + if (growthAllowed) replacementTree.restartChangeDetection(); + } else { + treeRoot = iNode.alternateTree; + treeRoot.restartChangeDetection(); + } + + currentNode = iNode.alternateTree; + currentNode.originalNode = null; + altTree = false; + } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { + // Remove the alternate tree + iNode.alternateTree = null; + if (growthAllowed) iNode.restartChangeDetection(); + altTree = false; + } + } + + if (altTree) { + growthAllowed = false; + processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + } + } + + if (false && iNode.changeDetection && !inAlternate) { + if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + iNode.initializeAlternateTree(); + growthAllowed = false; + } + } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).descendOneStep(inst); + } + } + } + } + + // endregion --- Regressor methods + + // region --- Object instatiation methods + + protected FIMTDDNumericAttributeClassObserver newNumericClassObserver() { + return new FIMTDDNumericAttributeClassObserver(); + } + + protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + maxID++; + return new SplitNode(splitTest, this); + } + + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } + + protected FIMTDDPerceptron newLeafModel() { + return new FIMTDDPerceptron(this); + } + + //endregion --- Object instatiation methods + + // region --- Processing methods + + protected void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + leafNodeCount = 1; + } + } + + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } + + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } + + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); + + // Using this criterion, find the best split per attribute and rank the results + AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine if any of the splits should be performed + boolean shouldSplit = false; + + // If only one split was returned, use it + if (bestSplitSuggestions.length < 2) { + shouldSplit = bestSplitSuggestions.length > 0; + } else { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, this.splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { + shouldSplit = true; + } + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + else { + for (int i = 0; i < node.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = node.attributeObservers.get(i); + if (obs != null) { + obs.removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); + } + } + } +// if (hoeffdingBound < this.tieThresholdOption.getValue() && !(secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound)) { +// System.out.println("Forced to split due to tie at " + this.examplesSeen); +// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); +// } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (shouldSplit) { +// System.out.println("splitting node"); +// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); +// if (node.parent == null) { +// System.out.println("splitting root node at " + this.examplesSeen); +// } + AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + + SplitNode newSplit = newSplitNode(splitDecision.splitTest); + newSplit.copyStatistics(node); + newSplit.changeDetection = node.changeDetection; + newSplit.ID = node.ID; + leafNodeCount--; + for (int i = 0; i < splitDecision.numSplits(); i++) { + LeafNode newChild = newLeafNode(); + if (buildingModelTree()) { + // Copy the splitting node's perceptron to it's children + newChild.learningModel = new FIMTDDPerceptron((FIMTDDPerceptron) node.learningModel); + + } + newChild.changeDetection = node.changeDetection; + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + leafNodeCount++; + } + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + ((SplitNode) parent).setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + + splitNodeCount++; + } + } + + public double computeSD(double squaredVal, double val, double size) { + if (size > 1) + return Math.sqrt((squaredVal - ((val * val) / size)) / size); + else + return 0.0; + } + + public double scalarProduct(DoubleVector u, DoubleVector v) { + double ret = 0.0; + for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { + ret += u.getValue(i) * v.getValue(i); + } + return ret; + } + //endregion --- Processing methods + + //endregion ================ METHODS ================ +} + +======= +>>>>>>> Revert "Removed merging artefacts" /* * FIMTDD.java * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia @@ -967,3 +1964,7 @@ public double scalarProduct(DoubleVector u, DoubleVector v) { //endregion ================ METHODS ================ } +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index eda46103c..d2e697d6e 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -35,8 +35,21 @@ import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.splitcriteria.SplitCriterion; +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 import moa.core.AutoExpandVector; import moa.core.Measurement; +======= +<<<<<<< HEAD +import moa.classifiers.trees.FIMTDD.InnerNode; +import moa.classifiers.trees.FIMTDD.Node; +import moa.core.AutoExpandVector; +import moa.core.Measurement; +import moa.core.StringUtils; +======= +import moa.core.AutoExpandVector; +import moa.core.Measurement; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" /* * Implementation of ORTO, option trees for data streams. @@ -119,9 +132,15 @@ public int getNumSubtrees() { public int directionForBestTree() { int d = 0; +<<<<<<< HEAD + double min = Double.MAX_VALUE; + for (int i = 0; i < numChildren(); i++) { + double tmp = getFFRatio(i); +======= double tmp = 0.0, min = Double.MAX_VALUE; for (int i = 0; i < children.size(); i++) { tmp = getFFRatio(i); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (tmp < min) { min = tmp; d = i; @@ -130,22 +149,54 @@ public int directionForBestTree() { return d; } +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 + public double getPrediction(Instance inst, ORTO tree) { +======= +<<<<<<< HEAD + public double getPrediction(Instance inst) { +======= public double getPrediction(Instance inst, ORTO tree) { +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" double[] predictions = new double[numChildren()]; for (int i = 0; i < numChildren(); i++) { predictions[i] = getChild(i).getPrediction(inst); } +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 return aggregate(predictions, tree); } private double aggregate(double[] predictions, ORTO tree) { if (tree.optionNodeAggregationOption.getChosenIndex() == 0) { // Average +======= +<<<<<<< HEAD + return aggregate(predictions); + } + + private double aggregate(double[] predictions) { + if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average +======= + return aggregate(predictions, tree); + } + + private double aggregate(double[] predictions, ORTO tree) { + if (tree.optionNodeAggregationOption.getChosenIndex() == 0) { // Average +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" double sum = 0.0; for (int i = 0; i < predictions.length; i++) { sum += predictions[i]; } return sum / predictions.length; +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 + } else if (tree.optionNodeAggregationOption.getChosenIndex() == 1) { +======= +<<<<<<< HEAD + } else if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 1) { +======= } else if (tree.optionNodeAggregationOption.getChosenIndex() == 1) { +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" int d = directionForBestTree(); return predictions[d]; } else { @@ -160,6 +211,24 @@ public double getFFRatio(int childIndex) { protected boolean skipInLevelCount() { return true; } +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 +======= +<<<<<<< HEAD + + @Override + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "[option node]"); + StringUtils.appendNewline(out); + for (int childIndex = 0; childIndex < children.size(); childIndex++) { + Node split = getChild(childIndex); + StringUtils.appendIndented(out, indent, "[" + childIndex + "]"); + StringUtils.appendNewline(out); + split.describeSubtree(out, indent + 2); + } + } +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" } //endregion ================ CLASSES ================ @@ -194,7 +263,15 @@ public void processInstance(Instance inst, Node node, double prediction, double Node currentNode = node; while (true) { if (currentNode instanceof LeafNode) { +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); +======= +<<<<<<< HEAD + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); +======= ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" break; } else { currentNode.examplesSeen += inst.weight(); @@ -203,7 +280,15 @@ public void processInstance(Instance inst, Node node, double prediction, double if (!inAlternate && iNode.alternateTree != null) { boolean altTree = true; double lossO = Math.pow(inst.classValue() - prediction, 2); +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 + double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); +======= +<<<<<<< HEAD + double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); +======= double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { @@ -223,7 +308,15 @@ public void processInstance(Instance inst, Node node, double prediction, double iNode.previousWeight = iNode.lossExamplesSeen; if (Qi > 0) { // Switch the subtrees +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 Node parent = currentNode.parent; +======= +<<<<<<< HEAD + Node parent = iNode.getParent(); +======= + Node parent = currentNode.parent; +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" if (parent != null) { Node replacementTree = iNode.alternateTree; @@ -233,7 +326,15 @@ public void processInstance(Instance inst, Node node, double prediction, double treeRoot = iNode.alternateTree; treeRoot.restartChangeDetection(); } +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 + optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); +======= +<<<<<<< HEAD + optionNodeCount += iNode.alternateTree.getNumSubtrees() - iNode.getNumSubtrees(); +======= optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" removeExcessTrees(); currentNode = iNode.alternateTree; @@ -248,7 +349,15 @@ public void processInstance(Instance inst, Node node, double prediction, double } if (altTree) { growthAllowed = false; // this is the growth of the original tree +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree +======= +<<<<<<< HEAD + processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree +======= + processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" } else if (currentNode instanceof OptionNode) { // this happens when an option node is switched into the tree for (Node child : ((OptionNode) currentNode).children) { @@ -276,18 +385,44 @@ public void processInstance(Instance inst, Node node, double prediction, double } public void processInstanceOptionNode(Instance inst, OptionNode node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 +======= +<<<<<<< HEAD + node.examplesSeen += inst.weight(); + node.sumOfAbsErrors += inst.weight() * normalError; +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" if (node.changeDetection) { double error = Math.abs(prediction - inst.classValue()); node.sumOfAbsErrors += error; if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { node.initializeAlternateTree(); +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 +======= +<<<<<<< HEAD + growthAllowed = false; +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" } } for (Node child : node.children) { int index = node.getChildIndex(child); double childPrediction = child.getPrediction(inst); +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 +======= +<<<<<<< HEAD + node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; + node.optionFFSSL[index] = node.optionFFSSL[index] * optionFadingFactorOption.getValue() + Math.pow(childPrediction - inst.classValue(), 2); + } + + for (Node child : node.children) { + processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); +======= +>>>>>>> Revert "Removed merging artefacts" // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; @@ -297,6 +432,7 @@ public void processInstanceOptionNode(Instance inst, OptionNode node, double pre for (Node child : node.children) { processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } @@ -314,6 +450,10 @@ protected OptionNode newOptionNode() { // region --- Processing methods protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { +<<<<<<< HEAD + +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Initialize the split criterion SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); @@ -321,7 +461,11 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); List acceptedSplits = new LinkedList(); Arrays.sort(bestSplitSuggestions); +<<<<<<< HEAD + +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Declare a variable to determine the number of splits to be performed int numSplits = 0; @@ -339,6 +483,13 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 +======= +<<<<<<< HEAD + +======= +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and @@ -350,12 +501,30 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { numSplits = 1; acceptedSplits.add(bestSuggestion); } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 + for (AttributeSplitSuggestion suggestion : bestSplitSuggestions) { +======= +<<<<<<< HEAD + for (int i = 0; i < bestSplitSuggestions.length; i++) { + AttributeSplitSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; +>>>>>>> Revert "Removed merging artefacts" + if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { + numSplits++; + acceptedSplits.add(suggestion); + } + } +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 +======= + +======= for (AttributeSplitSuggestion suggestion : bestSplitSuggestions) { if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { numSplits++; acceptedSplits.add(suggestion); } } +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" } else if (hoeffdingBound < tieThresholdOption.getValue()) { numSplits = 1; acceptedSplits.add(bestSplitSuggestions[0]); @@ -374,7 +543,11 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (numSplits > 0) { double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); +<<<<<<< HEAD + if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 0) { +======= if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa AttributeSplitSuggestion splitDecision = acceptedSplits.get(0); SplitNode newSplit = newSplitNode(splitDecision.splitTest); for (int i = 0; i < splitDecision.numSplits(); i++) { @@ -385,10 +558,25 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { leafNodeCount--; innerNodeCount++; leafNodeCount += splitDecision.numSplits(); +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 + if (parent == null) { +======= +<<<<<<< HEAD + if (parent == null && node.originalNode == null) { +>>>>>>> Revert "Removed merging artefacts" + treeRoot = newSplit; + } else { +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 + parent.setChild(parent.getChildIndex(node), newSplit); +======= + parent.setChild(parentIndex, newSplit); +======= if (parent == null) { treeRoot = newSplit; } else { parent.setChild(parent.getChildIndex(node), newSplit); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" newSplit.setParent(parent); } } else { @@ -422,7 +610,15 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (parent == null) { treeRoot = optionNode; } else { +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 parent.setChild(parent.getChildIndex(node), optionNode); +======= +<<<<<<< HEAD + parent.setChild(parentIndex, optionNode); +======= + parent.setChild(parent.getChildIndex(node), optionNode); +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" optionNode.setParent(parent); } @@ -505,4 +701,11 @@ protected void removeExcessTrees() { // endregion --- Option tree methods //endregion ================ METHODS ================ +<<<<<<< HEAD +} +<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 +======= +======= } +>>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa +>>>>>>> Revert "Removed merging artefacts" From b6037c6d877eb624fb9752730977fb5eec5aecd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Fri, 13 Nov 2015 13:57:24 +0100 Subject: [PATCH 24/33] Updates with the new versions of the algorithms (some code is imported from the 2015.10 prerelease version, so the pom files were updated back to the 2014.04 version) --- Release.key | 19 + moa/pom.xml | 2 +- .../samoa/instances/MultiLabelPrediction.java | 4 - .../LocalMultiTargetClassifier.java | 6 - .../AttributeStatisticsObserver.java | 6 +- .../MultiLabelBSTree.java | 6 +- .../MultiLabelNominalAttributeObserver.java | 6 +- .../NominalStatisticsObserver.java | 3 +- .../NumericStatisticsObserver.java | 3 +- .../splitcriteria/ICVarianceReduction.java | 1 - .../MultiLabelSplitCriterion.java | 2 +- .../multilabel/trees/ISOUPOptionTree.java | 15 +- .../multilabel/trees/ISOUPTree.java | 230 +- .../core/AttributeExpansionSuggestion.java | 3 +- .../multilabel/AMRulesMultiLabelLearner.java | 6 +- .../AMRulesMultiTargetRegressor.java | 2 +- .../multilabel/core/LearningLiteral.java | 10 +- .../core/LearningLiteralRegression.java | 9 +- .../rules/multilabel/core/MultiLabelRule.java | 6 +- .../MultiTargetVarianceRatio.java | 1 + .../java/moa/classifiers/trees/FIMTDD.java | 1982 ++++++++--------- .../main/java/moa/classifiers/trees/ORTO.java | 191 +- .../tasks/EvaluatePrequentialMultiTarget.java | 404 ++-- weka-package/pom.xml | 2 +- 24 files changed, 1358 insertions(+), 1561 deletions(-) create mode 100644 Release.key rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/AttributeStatisticsObserver.java (90%) rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/MultiLabelBSTree.java (96%) rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/MultiLabelNominalAttributeObserver.java (93%) rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/NominalStatisticsObserver.java (56%) rename moa/src/main/java/moa/classifiers/{rules/multilabel => multilabel/core}/attributeclassobservers/NumericStatisticsObserver.java (56%) rename moa/src/main/java/moa/classifiers/{rules => }/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java (85%) rename moa/src/main/java/moa/classifiers/rules/{multilabel => }/core/AttributeExpansionSuggestion.java (95%) diff --git a/Release.key b/Release.key new file mode 100644 index 000000000..549e44194 --- /dev/null +++ b/Release.key @@ -0,0 +1,19 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.5 (GNU/Linux) + +mQGiBE8ySNwRBACKcsg4AceGW7vuOSywcGiiNZg4I8vIzn7zphgj+s6/i2/hs8TQ +TOHy1s3b0f32ani3sBRmTWtgNv8+HSaKSVUcNqqNL+Jy6Pulyao7amGTtvqVKmuz +6ADrbVz0SxWmzTlSctdxK3g3yRSb+vfYrBPrbXNCNB5g9C/uK1uh0fpj1wCgn3MX +GFlZsO3bF7SNqqYlzpV6DM0D/AjnBlxTwRJOA1sLAVSXipLOdkjo00OQ8jgOFDio +oJsqLtsscNGocPCqNRo6QSVQKNs5sfYP2GXWTnPVM5oJI1p6bjuADRE8mneJrJvF +Uc+Mt1MdS6ttF4tVqd5Ncc8LKYQJRn+AtiuxAAayAA35JOslnMM0bqSYMlw4BJTP +8TlPA/4r+k+ucz3cJtM2aaL/ngUdrhmGKfGK7npXA3Ic6FzQo2NlJyKfWjSsR8x+ +oN7tKEpuYxE5fcdbWd3v+4Ypx0LYMgBT1pUgI09AXxrx1cLRZI4yovrvQJgiA4Mh +CZ0eFkJJ1nwQR3NPMj5soar+7d3Ubc2EqkESGm0CgGtjgg+7HrQ6aXN2Om93bkNs +b3VkIE9CUyBQcm9qZWN0IDxpc3Y6b3duQ2xvdWRAYnVpbGQub3BlbnN1c2Uub3Jn +PohmBBMRAgAmBQJU2MJUAhsDBQkJxSl4BgsJCAcDAgQVAggDBBYCAwECHgECF4AA +CgkQl3xDqLpoQiMpOQCggCpaq5yz8C3ckqEr0RkTjICcQYMAnRvjarxoY6iSThDN +7vgxE1Fe8X5EiEYEExECAAYFAk8ySNwACgkQOzARt2udZSPlpwCfQZKNN8Rxx0LE +BF32EYXBdEvkMYYAoIt3lfXL8uwmjvyljzb0JgBQN1cF +=FJ6Q +-----END PGP PUBLIC KEY BLOCK----- diff --git a/moa/pom.xml b/moa/pom.xml index dd44c7979..ec5e36169 100755 --- a/moa/pom.xml +++ b/moa/pom.xml @@ -4,7 +4,7 @@ nz.ac.waikato.cms.moa moa-pom - 2015.05-SNAPSHOT + 2014.04 moa diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index fbffed6ae..12b35c5a3 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -29,10 +29,6 @@ public MultiLabelPrediction(int numOutputAttributes) { for (int i=0; i. * */ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; -import moa.classifiers.rules.multilabel.core.AttributeExpansionSuggestion; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.core.DoubleVector; import moa.options.OptionHandler; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelBSTree.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java similarity index 96% rename from moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelBSTree.java rename to moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java index 9058f9479..58fd92faa 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelBSTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java @@ -1,13 +1,13 @@ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; import java.io.Serializable; import com.github.javacliparser.IntOption; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.NumericRulePredicate; import moa.classifiers.rules.core.Utils; -import moa.classifiers.rules.multilabel.core.AttributeExpansionSuggestion; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.core.DoubleVector; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelNominalAttributeObserver.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelNominalAttributeObserver.java similarity index 93% rename from moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelNominalAttributeObserver.java rename to moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelNominalAttributeObserver.java index 969f28576..2495b158f 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelNominalAttributeObserver.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelNominalAttributeObserver.java @@ -1,13 +1,13 @@ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.NominalRulePredicate; import moa.classifiers.rules.core.Utils; -import moa.classifiers.rules.multilabel.core.AttributeExpansionSuggestion; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.core.DoubleVector; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NominalStatisticsObserver.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NominalStatisticsObserver.java similarity index 56% rename from moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NominalStatisticsObserver.java rename to moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NominalStatisticsObserver.java index 64ce01864..e52a0cb42 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NominalStatisticsObserver.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NominalStatisticsObserver.java @@ -1,4 +1,5 @@ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; + public interface NominalStatisticsObserver extends AttributeStatisticsObserver { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NumericStatisticsObserver.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NumericStatisticsObserver.java similarity index 56% rename from moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NumericStatisticsObserver.java rename to moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NumericStatisticsObserver.java index 5914dbb15..b899ce1dc 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/NumericStatisticsObserver.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/NumericStatisticsObserver.java @@ -1,4 +1,5 @@ -package moa.classifiers.rules.multilabel.attributeclassobservers; +package moa.classifiers.multilabel.core.attributeclassobservers; + public interface NumericStatisticsObserver extends AttributeStatisticsObserver { diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java index c3f2299d2..176f3dfd0 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java @@ -5,7 +5,6 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.tasks.TaskMonitor; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion;; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java similarity index 85% rename from moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java rename to moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java index 099748611..cc9247039 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/MultiLabelSplitCriterion.java @@ -1,4 +1,4 @@ -package moa.classifiers.rules.multilabel.core.splitcriteria; +package moa.classifiers.multilabel.core.splitcriteria; import moa.core.DoubleVector; diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java index 93de284a0..a0ce07563 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java @@ -3,15 +3,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.MultiLabelInstance; - -import moa.classifiers.multilabel.trees.ISOUPTree.LeafNode; -import moa.classifiers.multilabel.trees.ISOUPTree.Node; -import moa.classifiers.multilabel.trees.ISOUPTree.SplitNode; -import moa.classifiers.trees.ORTO; -import moa.classifiers.trees.FIMTDD.InnerNode; -import moa.classifiers.trees.ORTO.OptionNode; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; @@ -20,7 +12,6 @@ public class ISOUPOptionTree extends ISOUPTree { private static final long serialVersionUID = 1L; - private int innerNodeCount = 0; private int optionNodeCount = 0; private int numTrees = 1; @@ -62,6 +53,11 @@ public class ISOUPOptionTree extends ISOUPTree { //region ================ CLASSES ================ public static class OptionNode extends InnerNode { + /** + * + */ + private static final long serialVersionUID = 1L; + protected AutoExpandVector optionFFSSL; protected AutoExpandVector optionFFSeen; @@ -152,7 +148,6 @@ public String getPurposeString() { public void resetLearningImpl() { super.resetLearningImpl(); - this.innerNodeCount = 0; this.optionNodeCount = 0; } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index c657f290d..4ce0c89b6 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -66,10 +66,7 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR private static final long serialVersionUID = 1L; - protected Node treeRoot; - - private int leafNodeCount = 0; - private int splitNodeCount = 0; + public Node treeRoot; private double examplesSeen = 0.0; private DoubleVector sumOfValues = new DoubleVector(); @@ -82,14 +79,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR //region ================ OPTIONS ================ - // public ClassOption splitCriterionOption = new ClassOption( - // "splitCriterion", - // 's', - // "Split criterion to use.", - // SplitCriterion.class, - // "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); - // TODO not used at the moment, consider later when the implementation catches up - public IntOption gracePeriodOption = new IntOption( "gracePeriod", 'g', @@ -108,17 +97,17 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR "Threshold below which a split will be forced to break ties.", 0.05, 0.0, 1.0); -// public FloatOption PageHinckleyAlphaOption = new FloatOption( -// "PageHinckleyAlpha", -// 'a', -// "The alpha value to use in the Page Hinckley change detection tests.", -// 0.005, 0.0, 1.0); -// -// public IntOption PageHinckleyThresholdOption = new IntOption( -// "PageHinckleyThreshold", -// 'h', -// "The threshold value to be used in the Page Hinckley change detection tests.", -// 50, 0, Integer.MAX_VALUE); + public FloatOption PageHinckleyAlphaOption = new FloatOption( + "PageHinckleyAlpha", + 'a', + "The alpha value to use in the Page Hinckley change detection tests.", + 0.005, 0.0, 1.0); + + public IntOption PageHinckleyThresholdOption = new IntOption( + "PageHinckleyThreshold", + 'h', + "The threshold value to be used in the Page Hinckley change detection tests.", + 50, 0, Integer.MAX_VALUE); public FloatOption alternateTreeFadingFactorOption = new FloatOption( "alternateTreeFadingFactor", @@ -165,7 +154,6 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR 'n', "Don't normalize."); - //endregion ================ OPTIONS ================ //region ================ CLASSES ================ @@ -313,7 +301,6 @@ public LeafNode(ISOUPTree tree) { */ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, boolean growthAllowed) { // Update the statistics for this node - double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; double[] predictionM = getPredictionTargetMean(inst); @@ -332,7 +319,6 @@ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, bool errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - inst.valueOutputAttribute(i))); } } - if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); for (int i = 0; i < inst.numInputAttributes(); i++) { @@ -405,8 +391,8 @@ public double[] getPredictionModel(MultiLabelInstance inst) { public double[] getPredictionTargetMean(MultiLabelInstance inst) { double[] pred = new double[inst.numOutputAttributes()]; - if (examplesSeen > 0) { - for (int i = 0; i < inst.numOutputAttributes(); i++) { + for (int i = 0; i < inst.numOutputAttributes(); i++) { + if (examplesSeen > 0) { pred[i] = sumOfValues.getValue(i) / examplesSeen; } else { pred[i] = 0; @@ -612,7 +598,6 @@ public class MultitargetPerceptron { // The Perception weights public double[][] weights; - // The number of instances contributing to this model protected int instancesSeen = 0; @@ -670,7 +655,7 @@ public void updateWeights(MultiLabelInstance inst, double learningRatio) { if (instancesSeen > 1.0) { // Compute the normalized instance and the delta double[] normalizedInput = tree.normalizedInputVector(inst); - double[] normalizedPrediction = prediction(normalizedInput); + double[] normalizedPrediction = prediction(normalizedInput); double[] normalizedTarget = tree.normalizedTargetVector(inst); for (int i = 0; i < inst.numOutputAttributes(); i++){ @@ -732,19 +717,18 @@ public void getModelDescription(StringBuilder out, int indent) { for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "]"); if (getModelContext() != null) { - for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { - if (getModelContext().attribute(j).isNumeric()) { - out.append((j == 0 || weights[i][j] < 0) ? " " : " + "); - out.append(String.format("%.4f", weights[i][j])); - out.append(" * "); - out.append(getAttributeNameString(j)); - } - } - out.append(" + " + weights[i][getModelContext().numOutputAttributes()]); + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + if (getModelContext().attribute(j).isNumeric()) { + out.append((j == 0 || weights[i][j] < 0) ? " " : " + "); + out.append(String.format("%.4f", weights[i][j])); + out.append(" * "); + out.append(getAttributeNameString(j)); + } + } + out.append(" + " + weights[i][getModelContext().numOutputAttributes()]); } StringUtils.appendNewline(out); } - StringUtils.appendNewline(out); } } @@ -916,23 +900,23 @@ public void trainOnInstanceImpl(MultiLabelInstance inst) { if (inst.weight() > 0) { checkRoot(); - double[] prediction = treeRoot.getPrediction(inst); - double[] normalError = getNormalizedError(inst, prediction); - - processInstance(inst, treeRoot, prediction, normalError, true, false); - - examplesSeen += inst.weight(); - for (int i = 0; i < inst.numberOutputTargets(); i++) { - sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); - sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); - } + double[] prediction = treeRoot.getPrediction(inst); + double[] normalError = getNormalizedError(inst, prediction); - for (int i = 0; i < inst.numInputAttributes(); i++) { - sumOfAttrValues.addToValue(i, inst.weight() * inst.valueInputAttribute(i)); - sumOfAttrSquares.addToValue(i, inst.weight() * inst.valueInputAttribute(i) * inst.valueInputAttribute(i)); - } - } - } + processInstance(inst, treeRoot, prediction, normalError, true, false); + + examplesSeen += inst.weight(); + for (int i = 0; i < inst.numberOutputTargets(); i++) { + sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); + sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); + } + + for (int i = 0; i < inst.numInputAttributes(); i++) { + sumOfAttrValues.addToValue(i, inst.weight() * inst.valueInputAttribute(i)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.valueInputAttribute(i) * inst.valueInputAttribute(i)); + } + } + } public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { Node currentNode = node; @@ -1031,18 +1015,18 @@ protected LeafNode newLeafNode() { return new LeafNode(this); } - public MultitargetPerceptron newLeafModel() { - return new MultitargetPerceptron(this); - } + public MultitargetPerceptron newLeafModel() { + return new MultitargetPerceptron(this); + } //endregion --- Object instatiation methods - //region --- Processing methods - protected void checkRoot() { - if (treeRoot == null) { - treeRoot = newLeafNode(); - } - } + //region --- Processing methods + protected void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + } + } public static double computeHoeffdingBound(double range, double confidence, double n) { return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); @@ -1081,66 +1065,66 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), - // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this - // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and - // splitting should occur. - // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit - // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two - // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - //System.out.print(hoeffdingBound); - //System.out.print(" "); - ///System.out.println(secondBestSuggestion.merit / bestSuggestion.merit); - if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { - shouldSplit = true; - } - // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - else { - // TODO pruning is currently disabled - for (int i = 0; i < node.attributeObservers.size(); i++) { - AttributeStatisticsObserver obs = node.attributeObservers.get(i); - if (obs != null) { - if (getModelContext().attribute(i).isNumeric()); - //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); - if (getModelContext().attribute(i).isNominal()); - // TODO nominal class observers - } - } - } - } + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + //System.out.print(hoeffdingBound); + //System.out.print(" "); + ///System.out.println(secondBestSuggestion.merit / bestSuggestion.merit); + if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { + shouldSplit = true; + } + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + else { + // TODO pruning is currently disabled + for (int i = 0; i < node.attributeObservers.size(); i++) { + AttributeStatisticsObserver obs = node.attributeObservers.get(i); + if (obs != null) { + if (getModelContext().attribute(i).isNumeric()); + //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); + if (getModelContext().attribute(i).isNominal()); + // TODO nominal class observers + } + } + } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (shouldSplit) { + AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + + SplitNode newSplit = newSplitNode(splitDecision.predicate); + newSplit.copyStatistics(node); + newSplit.changeDetection = node.changeDetection; + newSplit.ID = node.ID; + for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) + LeafNode newChild = newLeafNode(); + if (buildingModelTree()) { + // Copy the splitting node's perceptron to it's children + newChild.learningModel = new MultitargetPerceptron(this, (MultitargetPerceptron) node.learningModel); + + } + newChild.changeDetection = node.changeDetection; + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + parent.setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + } + } - // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (shouldSplit) { - AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - - SplitNode newSplit = newSplitNode(splitDecision.predicate); - newSplit.copyStatistics(node); - newSplit.changeDetection = node.changeDetection; - newSplit.ID = node.ID; - //System.out.println("Splitting"); - //System.out.println(examplesSeen); - for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) - LeafNode newChild = newLeafNode(); - if (buildingModelTree()) { - // Copy the splitting node's perceptron to it's children - newChild.learningModel = new MultitargetPerceptron(this, (MultitargetPerceptron) node.learningModel); - } - newChild.changeDetection = node.changeDetection; - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - } - if (parent == null && node.originalNode == null) { - treeRoot = newSplit; - } else if (parent == null && node.originalNode != null) { - node.originalNode.alternateTree = newSplit; - } else { - parent.setChild(parentIndex, newSplit); - newSplit.setParent(parent); - } - } - } public double computeSD(double squaredVal, double val, double size) { if (size > 1) diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/AttributeExpansionSuggestion.java b/moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java similarity index 95% rename from moa/src/main/java/moa/classifiers/rules/multilabel/core/AttributeExpansionSuggestion.java rename to moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java index b39b52ba0..a1e24bbb6 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/AttributeExpansionSuggestion.java +++ b/moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java @@ -17,10 +17,9 @@ * along with this program. If not, see . * */ -package moa.classifiers.rules.multilabel.core; +package moa.classifiers.rules.core; import moa.AbstractMOAObject; -import moa.classifiers.rules.core.Predicate; import moa.core.DoubleVector; /** diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java index 8014b5e20..2672f58f5 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java @@ -36,13 +36,13 @@ import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiLabelLearner; import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; import moa.classifiers.rules.core.anomalydetection.OddsRatioScore; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; import moa.classifiers.rules.multilabel.core.MultiLabelRule; import moa.classifiers.rules.multilabel.core.MultiLabelRuleSet; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.core.voting.MultiLabelVote; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java index 5b192f525..146a6be85 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java @@ -3,9 +3,9 @@ import moa.classifiers.MultiLabelLearner; import moa.classifiers.MultiTargetRegressor; import moa.classifiers.Regressor; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.core.MultiLabelRule; import moa.classifiers.rules.multilabel.core.MultiLabelRuleRegression; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.core.voting.InverseErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java index a2765587b..4a8a18ccf 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java @@ -11,16 +11,18 @@ import com.yahoo.labs.samoa.instances.MultiLabelInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; + import moa.classifiers.MultiLabelLearner; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.attributeclassobservers.NumericAttributeClassObserver; import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; -import moa.classifiers.rules.multilabel.attributeclassobservers.AttributeStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.errormeasurers.AbstractMultiTargetErrorMeasurer; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java index fb96cae96..26ae4e0d9 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java @@ -15,11 +15,12 @@ import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.driftdetection.ChangeDetector; import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.Utils; -import moa.classifiers.rules.multilabel.attributeclassobservers.AttributeStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.functions.AMRulesFunction; import moa.core.AutoExpandVector; import moa.core.DoubleVector; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java index 9312ce86a..6bd641395 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java @@ -14,13 +14,13 @@ import moa.classifiers.core.conditionaltests.InstanceConditionalTest; import moa.classifiers.core.conditionaltests.NumericAttributeBinaryTest; import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.core.RuleActiveLearningNode; import moa.classifiers.rules.core.RuleSplitNode; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; import moa.classifiers.rules.core.conditionaltests.NumericAttributeBinaryRulePredicate; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; import moa.core.StringUtils; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiTargetVarianceRatio.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiTargetVarianceRatio.java index c9a3a9904..4f64f7c44 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiTargetVarianceRatio.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiTargetVarianceRatio.java @@ -1,5 +1,6 @@ package moa.classifiers.rules.multilabel.core.splitcriteria; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.core.Utils; import moa.core.DoubleVector; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java index a2dcd0b7c..74bbeabe8 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java @@ -1,1000 +1,987 @@ -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -======= -<<<<<<< HEAD -/* - * FIMTDD.java - * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia - * @author Aljaž Osojnik - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ - -package moa.classifiers.trees; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -import com.yahoo.labs.samoa.instances.Instance; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; - -import moa.options.ClassOption; -import moa.AbstractMOAObject; -import moa.classifiers.Regressor; -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.conditionaltests.InstanceConditionalTest; -import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.classifiers.AbstractClassifier; -import moa.core.AutoExpandVector; -import moa.core.DoubleVector; -import moa.core.Measurement; -import moa.core.SizeOf; -import moa.core.StringUtils; - -/* - * Implementation of FIMTDD, regression and model trees for data streams. - */ - -public class FIMTDD extends AbstractClassifier implements Regressor { - - private static final long serialVersionUID = 1L; - - protected Node treeRoot; - - protected int leafNodeCount = 0; - protected int splitNodeCount = 0; - - protected double examplesSeen = 0.0; - protected double sumOfValues = 0.0; - protected double sumOfSquares = 0.0; - - protected DoubleVector sumOfAttrValues = new DoubleVector(); - protected DoubleVector sumOfAttrSquares = new DoubleVector(); - - public int maxID = 0; - - //region ================ OPTIONS ================ - - public ClassOption splitCriterionOption = new ClassOption( - "splitCriterion", 's', "Split criterion to use.", - SplitCriterion.class, "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); - - public IntOption gracePeriodOption = new IntOption( - "gracePeriod", 'g', "Number of instances a leaf should observe between split attempts.", - 200, 0, Integer.MAX_VALUE); - - public FloatOption splitConfidenceOption = new FloatOption( - "splitConfidence", 'c', "Allowed error in split decision, values close to 0 will take long to decide.", - 0.0000001, 0.0, 1.0); - - public FloatOption tieThresholdOption = new FloatOption( - "tieThreshold", 't', "Threshold below which a split will be forced to break ties.", - 0.05, 0.0, 1.0); - - public FloatOption PageHinckleyAlphaOption = new FloatOption( - "PageHinckleyAlpha", 'a', "Alpha value to use in the Page Hinckley change detection tests.", - 0.005, 0.0, 1.0); - - public IntOption PageHinckleyThresholdOption = new IntOption( - "PageHinckleyThreshold", 'h', "Threshold value used in the Page Hinckley change detection tests.", - 50, 0, Integer.MAX_VALUE); - - public FloatOption alternateTreeFadingFactorOption = new FloatOption( - "alternateTreeFadingFactor", 'f', "Fading factor used to decide if an alternate tree should replace an original.", - 0.995, 0.0, 1.0); - - public IntOption alternateTreeTMinOption = new IntOption( - "alternateTreeTMin", 'y', "Tmin value used to decide if an alternate tree should replace an original.", - 150, 0, Integer.MAX_VALUE); - - public IntOption alternateTreeTimeOption = new IntOption( - "alternateTreeTime", 'u', "The number of instances used to decide if an alternate tree should be discarded.", - 1500, 0, Integer.MAX_VALUE); - - public FlagOption regressionTreeOption = new FlagOption( - "regressionTree", 'e', "Build a regression tree instead of a model tree."); - - public FloatOption learningRatioOption = new FloatOption( - "learningRatio", 'l', "Learning ratio to used for training the Perceptrons in the leaves.", - 0.003, 0, 1.00); - - public FloatOption learningRateDecayFactorOption = new FloatOption( - "learningRatioDecayFactor", 'd', "Learning rate decay factor (not used when learning rate is constant).", - 0.001, 0, 1.00); - - public FlagOption learningRatioConstOption = new FlagOption( - "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); - - //endregion ================ OPTIONS ================ - - //region ================ CLASSES ================ - - public abstract static class Node extends AbstractMOAObject { - - private static final long serialVersionUID = 1L; - - public int ID; - - protected FIMTDD tree; - - protected boolean changeDetection = true; - - protected Node parent; - - protected Node alternateTree; - protected Node originalNode; - - // The statistics for this node: - // Number of instances that have reached it - protected double examplesSeen; - // Sum of y values - protected double sumOfValues; - // Sum of squared y values - protected double sumOfSquares; - // Sum of absolute errors - protected double sumOfAbsErrors; // Needed for PH tracking of mean error - - public Node(FIMTDD tree) { - this.tree = tree; - ID = tree.maxID; - } - - public void copyStatistics(Node node) { - examplesSeen = node.examplesSeen; - sumOfValues = node.sumOfValues; - sumOfSquares = node.sumOfSquares; - sumOfAbsErrors = node.sumOfAbsErrors; - } - - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); - } - - /** - * Set the parent node - */ - public void setParent(Node parent) { - this.parent = parent; - } - - /** - * Return the parent node - */ - public Node getParent() { - return parent; - } - - public void disableChangeDetection() { - changeDetection = false; - } - - public void restartChangeDetection() { - changeDetection = true; - } - - public void getDescription(StringBuilder sb, int indent) { - - } - - public double getPrediction(Instance inst) { - return 0; - } - - public void describeSubtree(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, "Leaf"); - } - - public int getLevel() { - Node target = this; - int level = 0; - while (target.getParent() != null) { - if (target.skipInLevelCount()) { - target = target.getParent(); - continue; - } - level = level + 1; - target = target.getParent(); - } - if (target.originalNode == null) { - return level; - } else { - return level + originalNode.getLevel(); - } - } - - public void setChild(int parentBranch, Node node) { - } - - public int getChildIndex(Node child) { - return -1; - } - - public int getNumSubtrees() { - return 1; - } - - protected boolean skipInLevelCount() { - return false; - } - } - - public static class LeafNode extends Node { - - private static final long serialVersionUID = 1L; - - public double errorModel = 0.0; - public double errorTargetMean = 0.0; - - // Perceptron model that carries out the actual learning in each node - public FIMTDDPerceptron learningModel; - - protected AutoExpandVector attributeObservers = new AutoExpandVector(); - - protected double examplesSeenAtLastSplitEvaluation = 0; - - /** - * Create a new LeafNode - */ - public LeafNode(FIMTDD tree) { - super(tree); - if (tree.buildingModelTree()) { - learningModel = tree.newLeafModel(); - } - examplesSeen = 0; - sumOfValues = 0; - sumOfSquares = 0; - sumOfAbsErrors = 0; - } - - public void setChild(int parentBranch, Node node) { - } - - public int getChildIndex(Node child) { - return -1; - } - - public int getNumSubtrees() { - return 1; - } - - protected boolean skipInLevelCount() { - return false; - } - - /** - * Method to learn from an instance that passes the new instance to the perceptron learner, - * and also prevents the class value from being truncated to an int when it is passed to the - * attribute observer - */ - public void learnFromInstance(Instance inst, boolean growthAllowed, double prediction) { - //The prediction must be calculated here -- it may be different from the tree's prediction due to alternate trees - - // Update the statistics for this node - // number of instances passing through the node - examplesSeen += inst.weight(); - - // sum of y values - sumOfValues += inst.weight() * inst.classValue(); - - // sum of squared y values - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - - // sum of absolute errors - sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - prediction))); - - if (tree.buildingModelTree()) { - double predictionModel = getPredictionModel(inst); - double predictionTargetMean = getPredictionTargetMean(inst); - - errorModel = errorModel * 0.95 + Math.abs(predictionModel - inst.classValue()); - errorTargetMean = errorTargetMean * 0.95 + Math.abs(predictionTargetMean - inst.classValue()); - - learningModel.updatePerceptron(inst); - } - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); - FIMTDDNumericAttributeClassObserver obs = attributeObservers.get(i); - if (obs == null) { - // At this stage all nominal attributes are ignored - if (inst.attribute(instAttIndex).isNumeric()) { - obs = tree.newNumericClassObserver(); - this.attributeObservers.set(i, obs); - } - } - if (obs != null) { - obs.observeAttributeClass(inst.value(instAttIndex), inst.classValue(), inst.weight()); - } - } - - if (growthAllowed) { - checkForSplit(); - } - } - - /** - * Return the best split suggestions for this node using the given split criteria - */ - public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion) { - - List bestSuggestions = new LinkedList(); - - // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution - double[] nodeSplitDist = new double[] {examplesSeen, sumOfValues, sumOfSquares}; - - for (int i = 0; i < this.attributeObservers.size(); i++) { - FIMTDDNumericAttributeClassObserver obs = this.attributeObservers.get(i); - if (obs != null) { - - // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED - AttributeSplitSuggestion bestSuggestion = null; - if (obs instanceof FIMTDDNumericAttributeClassObserver) { - bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, nodeSplitDist, i, true); - } - - if (bestSuggestion != null) { - bestSuggestions.add(bestSuggestion); - } - } - } - return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); - } - - /** - * Retrieve the class votes using the perceptron learner - */ - public double getPredictionModel(Instance inst) { - return learningModel.prediction(inst); - } - - public double getPredictionTargetMean(Instance inst) { - return (examplesSeen > 0.0) ? sumOfValues / examplesSeen : 0.0; - } - - public double getPrediction(Instance inst) { - if (tree.buildingModelTree()) { - //return getPredictionModel(inst); - return (errorModel < errorTargetMean) ? getPredictionModel(inst) : getPredictionTargetMean(inst); - } else - return getPredictionTargetMean(inst); - } - - public void checkForSplit() { - // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node - if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { - int index = (parent != null) ? parent.getChildIndex(this) : 0; - tree.attemptToSplit(this, parent, index); - - // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation - examplesSeenAtLastSplitEvaluation = examplesSeen; - } - } - - public void describeSubtree(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, "Leaf "); - if (tree.buildingModelTree()) { - learningModel.getModelDescription(out, 0); - } else { - out.append(tree.getClassNameString() + " = " + String.format("%.4f", sumOfValues / examplesSeen)); - StringUtils.appendNewline(out); - } - } - } - - public abstract static class InnerNode extends Node { - // The InnerNode and SplitNode design is used for easy extension in ORTO - private static final long serialVersionUID = 1L; - - protected AutoExpandVector children = new AutoExpandVector(); - - // The error values for the Page Hinckley test - // PHmT = the cumulative sum of the errors - // PHMT = the minimum error value seen so far - protected double PHsum = 0; - protected double PHmin = Double.MAX_VALUE; - - // Keep track of the statistics for loss error calculations - protected double lossExamplesSeen; - protected double lossFadedSumOriginal; - protected double lossFadedSumAlternate; - protected double lossNumQiTests; - protected double lossSumQi; - protected double previousWeight = 0; - - public InnerNode(FIMTDD tree) { - super(tree); - } - - public int numChildren() { - return children.size(); - } - - public Node getChild(int index) { - return children.get(index); - } - - public int getChildIndex(Node child) { - return children.indexOf(child); - } - - public void setChild(int index, Node child) { - children.set(index, child); - } - - public void disableChangeDetection() { - changeDetection = false; - for (Node child : children) { - child.disableChangeDetection(); - } - } - - public void restartChangeDetection() { - if (alternateTree == null) { - changeDetection = true; - PHsum = 0; - PHmin = Integer.MAX_VALUE; - for (Node child : children) - child.restartChangeDetection(); - } - } - - /** - * Check to see if the tree needs updating - */ - public boolean PageHinckleyTest(double error, double threshold) { - // Update the cumulative mT sum - PHsum += error; - - // Update the minimum mT value if the new mT is - // smaller than the current minimum - if(PHsum < PHmin) { - PHmin = PHsum; - } - // Return true if the cumulative value - the current minimum is - // greater than the current threshold (in which case we should adapt) - return PHsum - PHmin > threshold; - } - - public void initializeAlternateTree() { - // Start a new alternate tree, beginning with a learning node - alternateTree = tree.newLeafNode(); - alternateTree.originalNode = this; - - // Set up the blank statistics - // Number of instances reaching this node since the alternate tree was started - lossExamplesSeen = 0; - // Faded squared error (original tree) - lossFadedSumOriginal = 0; - // Faded squared error (alternate tree) - lossFadedSumAlternate = 0; - // Number of evaluations of alternate tree - lossNumQiTests = 0; - // Sum of Qi values - lossSumQi = 0; - // Number of examples at last test - previousWeight = 0; - - // Disable the change detection mechanism bellow this node - disableChangeDetection(); - } - } - - public static class SplitNode extends InnerNode { - - private static final long serialVersionUID = 1L; - - protected InstanceConditionalTest splitTest; - - /** - * Create a new SplitNode - * @param tree - */ - public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { - super(tree); - this.splitTest = splitTest; - } - - public int instanceChildIndex(Instance inst) { - return splitTest.branchForInstance(inst); - } - - public Node descendOneStep(Instance inst) { - return children.get(splitTest.branchForInstance(inst)); - } - - public void describeSubtree(StringBuilder out, int indent) { - for (int branch = 0; branch < children.size(); branch++) { - Node child = getChild(branch); - if (child != null) { - StringUtils.appendIndented(out, indent, "if "); - out.append(this.splitTest.describeConditionForBranch(branch, - tree.getModelContext())); - out.append(": "); - StringUtils.appendNewline(out); - child.describeSubtree(out, indent + 2); - } - } - } - - public double getPrediction(Instance inst) { - return children.get(splitTest.branchForInstance(inst)).getPrediction(inst); - } - } - - public class FIMTDDPerceptron implements Serializable { - - private static final long serialVersionUID = 1L; - - protected FIMTDD tree; - - // The Perception weights - protected double[] weightAttribute; - - // The number of instances contributing to this model - protected double instancesSeen = 0; - - public String getPurposeString() { - return "A perceptron regressor as specified by Ikonomovska et al. used for FIMTDD"; - } - - public FIMTDDPerceptron(FIMTDDPerceptron original) { - this.tree = original.tree; - weightAttribute = original.weightAttribute.clone(); - } - - public FIMTDDPerceptron(FIMTDD tree) { - this.tree = tree; - initializeWeights(); - - } - - public void initializeWeights() { - weightAttribute = new double[tree.getModelContext().numInputAttributes()+1]; - instancesSeen = 0; - for (int j = 0; j < tree.getModelContext().numInputAttributes()+1; j++) { - // The last index corresponds to the constant b - weightAttribute[j] = 2 * tree.classifierRandom.nextDouble() - 1; - } - normalizeWeights(); - } - - /** - * Update the model using the provided instance - */ - public void updatePerceptron(Instance inst) { - - // Update attribute statistics - instancesSeen += inst.weight(); - - // Update weights - double learningRatio = 0.0; - if (tree.learningRatioConstOption.isSet()) { - learningRatio = learningRatioOption.getValue(); - } else { - learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); - } - - // Loop for compatibility with bagging methods - for (int i = 0; i < (int) inst.weight(); i++) { - updateWeights(inst, learningRatio); - } - - } - - public void updateWeights(Instance inst, double learningRatio) { - // Compute the normalized instance and the delta - double[] normalizedInstance = normalizedInstance(inst); - double normalizedPrediction = prediction(normalizedInstance); - double normalizedValue = tree.normalizeTargetValue(inst.classValue()); - double delta = normalizedValue - normalizedPrediction; - for (int i = 0; i < weightAttribute.length; i++) { - weightAttribute[i] += delta * learningRatio * normalizedInstance[i]; - } - - normalizeWeights(); - } - - public void normalizeWeights() { - double sum = 0; - for (int i = 0; i < this.weightAttribute.length; i++) - sum += Math.abs(weightAttribute[i]); - for (int i = 0; i < this.weightAttribute.length; i++) - weightAttribute[i] /= sum; - } - - public double[] normalizedInstance(Instance inst) { - // Normalize Instance - double[] normalizedInstance = new double[inst.numInputAttributes()+1]; - for (int j = 0; j < inst.numInputAttributes(); j++) { - double mean = tree.sumOfAttrValues.getValue(j) / tree.examplesSeen; - double sd = computeSD(tree.sumOfAttrSquares.getValue(j), tree.sumOfAttrValues.getValue(j), tree.examplesSeen); - if (inst.inputAttribute(j).isNumeric() && tree.examplesSeen > 1 && sd > 0.0000001) - normalizedInstance[j] = (inst.valueInputAttribute(j) - mean) / (sd); - else - normalizedInstance[j] = 0; - } - normalizedInstance[inst.numInputAttributes()] = tree.examplesSeen > 1 ? 1 : 0; // Value to be multiplied with the constant factor - return normalizedInstance; - } - - /** - * Output the prediction made by this perceptron on the given instance - */ - public double prediction(double[] instanceValues) { - double ret = 0; - for (int i = 0; i < instanceValues.length; i++) - ret += instanceValues[i] * weightAttribute[i]; - return ret; - } - - protected double prediction(Instance inst) { - double[] normalizedInstance = normalizedInstance(inst); - double normalizedPrediction = prediction(normalizedInstance); - return denormalizePrediction(normalizedPrediction); - } - - private double denormalizePrediction(double normalizedPrediction) { - double mean = tree.sumOfValues / tree.examplesSeen; - double sd = computeSD(tree.sumOfSquares, tree.sumOfValues, tree.examplesSeen); - if (examplesSeen > 1) - return normalizedPrediction * sd + mean; - else - return 0.0; - } - - public void getModelDescription(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, getClassNameString() + " ="); - if (getModelContext() != null) { - for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { - if (getModelContext().attribute(j).isNumeric()) { - out.append((j == 0 || weightAttribute[j] < 0) ? " " : " + "); - out.append(String.format("%.4f", weightAttribute[j])); - out.append(" * "); - out.append(getAttributeNameString(j)); - } - } - out.append(" + " + weightAttribute[getModelContext().numInputAttributes()]); - } - StringUtils.appendNewline(out); - } - } - - - //endregion ================ CLASSES ================ - - //region ================ METHODS ================ - - // region --- Regressor methods - - public String getPurposeString() { - return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; - } - - public void resetLearningImpl() { - this.treeRoot = null; - this.leafNodeCount = 0; - this.splitNodeCount = 0; - this.maxID = 0; - this.examplesSeen = 0; - this.sumOfValues = 0.0; - this.sumOfSquares = 0.0; - - this.sumOfAttrValues = new DoubleVector(); - this.sumOfAttrSquares = new DoubleVector(); - } - - public boolean isRandomizable() { - return true; - } - - public void getModelDescription(StringBuilder out, int indent) { - if (treeRoot != null) treeRoot.describeSubtree(out, indent); - } - - protected Measurement[] getModelMeasurementsImpl() { - return new Measurement[]{ - new Measurement("tree size (leaves)", this.leafNodeCount) - }; - } - - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); - } - - public double[] getVotesForInstance(Instance inst) { - if (treeRoot == null) { - return new double[] {0}; - } - - double prediction = treeRoot.getPrediction(inst); - - return new double[] {prediction}; - } - - public double normalizeTargetValue(double value) { - if (examplesSeen > 1) { - double sd = Math.sqrt((sumOfSquares - ((sumOfValues * sumOfValues)/examplesSeen))/examplesSeen); - double average = sumOfValues / examplesSeen; - if (sd > 0 && examplesSeen > 1) - return (value - average) / sd; - else - return 0.0; - } - return 0.0; - } - - public double getNormalizedError(Instance inst, double prediction) { - double normalPrediction = normalizeTargetValue(prediction); - double normalValue = normalizeTargetValue(inst.classValue()); - return Math.abs(normalValue - normalPrediction); - } - - - /** - * Method for updating (training) the model using a new instance - */ - public void trainOnInstanceImpl(Instance inst) { - checkRoot(); - - double prediction = treeRoot.getPrediction(inst); - double normalError = getNormalizedError(inst, prediction); - - processInstance(inst, treeRoot, prediction, normalError, true, false); - - examplesSeen += inst.weight(); - sumOfValues += inst.weight() * inst.classValue(); - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int aIndex = modelAttIndexToInstanceAttIndex(i, inst); - sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); - sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); - } - - - } - - public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { - Node currentNode = node; - while (true) { - if (currentNode instanceof LeafNode) { - ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); - break; - } else { - currentNode.examplesSeen += inst.weight(); - currentNode.sumOfAbsErrors += inst.weight() * normalError; - InnerNode iNode = (InnerNode) currentNode; - if (!inAlternate && iNode.alternateTree != null) { - boolean altTree = true; - double lossO = Math.pow(inst.classValue() - prediction, 2); - double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); - - // Loop for compatibility with bagging methods - for (int i = 0; i < inst.weight(); i++) { - iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; - iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; - iNode.lossExamplesSeen++; - - double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - iNode.lossSumQi += Qi; - iNode.lossNumQiTests += 1; - } - double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - - if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { - iNode.previousWeight = iNode.lossExamplesSeen; - if (Qi > 0) { - // Switch the subtrees - Node parent = iNode.getParent(); - - if (parent != null) { - Node replacementTree = iNode.alternateTree; - parent.setChild(parent.getChildIndex(iNode), replacementTree); - if (growthAllowed) replacementTree.restartChangeDetection(); - } else { - treeRoot = iNode.alternateTree; - treeRoot.restartChangeDetection(); - } - - currentNode = iNode.alternateTree; - currentNode.originalNode = null; - altTree = false; - } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { - // Remove the alternate tree - iNode.alternateTree = null; - if (growthAllowed) iNode.restartChangeDetection(); - altTree = false; - } - } - - if (altTree) { - growthAllowed = false; - processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); - } - } - - if (false && iNode.changeDetection && !inAlternate) { - if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { - iNode.initializeAlternateTree(); - growthAllowed = false; - } - } - if (currentNode instanceof SplitNode) { - currentNode = ((SplitNode) currentNode).descendOneStep(inst); - } - } - } - } - - // endregion --- Regressor methods - - // region --- Object instatiation methods - - protected FIMTDDNumericAttributeClassObserver newNumericClassObserver() { - return new FIMTDDNumericAttributeClassObserver(); - } - - protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { - maxID++; - return new SplitNode(splitTest, this); - } - - protected LeafNode newLeafNode() { - maxID++; - return new LeafNode(this); - } - - protected FIMTDDPerceptron newLeafModel() { - return new FIMTDDPerceptron(this); - } - - //endregion --- Object instatiation methods - - // region --- Processing methods - - protected void checkRoot() { - if (treeRoot == null) { - treeRoot = newLeafNode(); - leafNodeCount = 1; - } - } - - public static double computeHoeffdingBound(double range, double confidence, double n) { - return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); - } - - public boolean buildingModelTree() { - return !regressionTreeOption.isSet(); - } - - protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { - - // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); - - // Using this criterion, find the best split per attribute and rank the results - AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); - Arrays.sort(bestSplitSuggestions); - - // Declare a variable to determine if any of the splits should be performed - boolean shouldSplit = false; - - // If only one split was returned, use it - if (bestSplitSuggestions.length < 2) { - shouldSplit = bestSplitSuggestions.length > 0; - } else { // Otherwise, consider which of the splits proposed may be worth trying - - // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, this.splitConfidenceOption.getValue(), node.examplesSeen); - // Determine the top two ranked splitting suggestions - AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - - // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), - // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this - // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and - // splitting should occur. - // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit - // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two - // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { - shouldSplit = true; - } - // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - else { - for (int i = 0; i < node.attributeObservers.size(); i++) { - FIMTDDNumericAttributeClassObserver obs = node.attributeObservers.get(i); - if (obs != null) { - obs.removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); - } - } - } -// if (hoeffdingBound < this.tieThresholdOption.getValue() && !(secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound)) { -// System.out.println("Forced to split due to tie at " + this.examplesSeen); -// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); -// } - } - - // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (shouldSplit) { -// System.out.println("splitting node"); -// System.out.println(SizeOf.fullSizeOf(node.attributeObservers) / 1000000.0); -// if (node.parent == null) { -// System.out.println("splitting root node at " + this.examplesSeen); -// } - AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - - SplitNode newSplit = newSplitNode(splitDecision.splitTest); - newSplit.copyStatistics(node); - newSplit.changeDetection = node.changeDetection; - newSplit.ID = node.ID; - leafNodeCount--; - for (int i = 0; i < splitDecision.numSplits(); i++) { - LeafNode newChild = newLeafNode(); - if (buildingModelTree()) { - // Copy the splitting node's perceptron to it's children - newChild.learningModel = new FIMTDDPerceptron((FIMTDDPerceptron) node.learningModel); - - } - newChild.changeDetection = node.changeDetection; - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - leafNodeCount++; - } - if (parent == null && node.originalNode == null) { - treeRoot = newSplit; - } else if (parent == null && node.originalNode != null) { - node.originalNode.alternateTree = newSplit; - } else { - ((SplitNode) parent).setChild(parentIndex, newSplit); - newSplit.setParent(parent); - } - - splitNodeCount++; - } - } - - public double computeSD(double squaredVal, double val, double size) { - if (size > 1) - return Math.sqrt((squaredVal - ((val * val) / size)) / size); - else - return 0.0; - } - - public double scalarProduct(DoubleVector u, DoubleVector v) { - double ret = 0.0; - for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { - ret += u.getValue(i) * v.getValue(i); - } - return ret; - } - //endregion --- Processing methods - - //endregion ================ METHODS ================ -} - +/* + * FIMTDD.java + * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia + * @author Aljaž Osojnik + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package moa.classifiers.trees; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import com.yahoo.labs.samoa.instances.Instance; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; + +import moa.options.ClassOption; +import moa.AbstractMOAObject; +import moa.classifiers.Regressor; +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; +import moa.classifiers.core.conditionaltests.InstanceConditionalTest; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.classifiers.AbstractClassifier; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.Measurement; +import moa.core.SizeOf; +import moa.core.StringUtils; + +/* + * Implementation of FIMTDD, regression and model trees for data streams. + */ + +public class FIMTDD extends AbstractClassifier implements Regressor { + + private static final long serialVersionUID = 1L; + + protected Node treeRoot; + + protected int leafNodeCount = 0; + protected int splitNodeCount = 0; + + protected double examplesSeen = 0.0; + protected double sumOfValues = 0.0; + protected double sumOfSquares = 0.0; + + protected DoubleVector sumOfAttrValues = new DoubleVector(); + protected DoubleVector sumOfAttrSquares = new DoubleVector(); + + public int maxID = 0; + + //region ================ OPTIONS ================ + + public ClassOption splitCriterionOption = new ClassOption( + "splitCriterion", 's', "Split criterion to use.", + SplitCriterion.class, "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); + + public IntOption gracePeriodOption = new IntOption( + "gracePeriod", 'g', "Number of instances a leaf should observe between split attempts.", + 200, 0, Integer.MAX_VALUE); + + public FloatOption splitConfidenceOption = new FloatOption( + "splitConfidence", 'c', "Allowed error in split decision, values close to 0 will take long to decide.", + 0.0000001, 0.0, 1.0); + + public FloatOption tieThresholdOption = new FloatOption( + "tieThreshold", 't', "Threshold below which a split will be forced to break ties.", + 0.05, 0.0, 1.0); + + public FloatOption PageHinckleyAlphaOption = new FloatOption( + "PageHinckleyAlpha", 'a', "Alpha value to use in the Page Hinckley change detection tests.", + 0.005, 0.0, 1.0); + + public IntOption PageHinckleyThresholdOption = new IntOption( + "PageHinckleyThreshold", 'h', "Threshold value used in the Page Hinckley change detection tests.", + 50, 0, Integer.MAX_VALUE); + + public FloatOption alternateTreeFadingFactorOption = new FloatOption( + "alternateTreeFadingFactor", 'f', "Fading factor used to decide if an alternate tree should replace an original.", + 0.995, 0.0, 1.0); + + public IntOption alternateTreeTMinOption = new IntOption( + "alternateTreeTMin", 'y', "Tmin value used to decide if an alternate tree should replace an original.", + 150, 0, Integer.MAX_VALUE); + + public IntOption alternateTreeTimeOption = new IntOption( + "alternateTreeTime", 'u', "The number of instances used to decide if an alternate tree should be discarded.", + 1500, 0, Integer.MAX_VALUE); + + public FlagOption regressionTreeOption = new FlagOption( + "regressionTree", 'e', "Build a regression tree instead of a model tree."); + + public FloatOption learningRatioOption = new FloatOption( + "learningRatio", 'l', "Learning ratio to used for training the Perceptrons in the leaves.", + 0.003, 0, 1.00); + + public FloatOption learningRateDecayFactorOption = new FloatOption( + "learningRatioDecayFactor", 'd', "Learning rate decay factor (not used when learning rate is constant).", + 0.001, 0, 1.00); + + public FlagOption learningRatioConstOption = new FlagOption( + "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public abstract static class Node extends AbstractMOAObject { + + private static final long serialVersionUID = 1L; + + public int ID; + + protected FIMTDD tree; + + protected boolean changeDetection = true; + + protected Node parent; + + protected Node alternateTree; + protected Node originalNode; + + // The statistics for this node: + // Number of instances that have reached it + protected double examplesSeen; + // Sum of y values + protected double sumOfValues; + // Sum of squared y values + protected double sumOfSquares; + // Sum of absolute errors + protected double sumOfAbsErrors; // Needed for PH tracking of mean error + + public Node(FIMTDD tree) { + this.tree = tree; + ID = tree.maxID; + } + + public void copyStatistics(Node node) { + examplesSeen = node.examplesSeen; + sumOfValues = node.sumOfValues; + sumOfSquares = node.sumOfSquares; + sumOfAbsErrors = node.sumOfAbsErrors; + } + + public int calcByteSize() { + return (int) SizeOf.fullSizeOf(this); + } + + /** + * Set the parent node + */ + public void setParent(Node parent) { + this.parent = parent; + } + + /** + * Return the parent node + */ + public Node getParent() { + return parent; + } + + public void disableChangeDetection() { + changeDetection = false; + } + + public void restartChangeDetection() { + changeDetection = true; + } + + public void getDescription(StringBuilder sb, int indent) { + + } + + public double getPrediction(Instance inst) { + return 0; + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf"); + } + + public int getLevel() { + Node target = this; + int level = 0; + while (target.getParent() != null) { + if (target.skipInLevelCount()) { + target = target.getParent(); + continue; + } + level = level + 1; + target = target.getParent(); + } + if (target.originalNode == null) { + return level; + } else { + return level + originalNode.getLevel(); + } + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + } + + public static class LeafNode extends Node { + + private static final long serialVersionUID = 1L; + + public double errorModel = 0.0; + public double errorTargetMean = 0.0; + + // Perceptron model that carries out the actual learning in each node + public FIMTDDPerceptron learningModel; + + protected AutoExpandVector attributeObservers = new AutoExpandVector(); + + protected double examplesSeenAtLastSplitEvaluation = 0; + + /** + * Create a new LeafNode + */ + public LeafNode(FIMTDD tree) { + super(tree); + if (tree.buildingModelTree()) { + learningModel = tree.newLeafModel(); + } + examplesSeen = 0; + sumOfValues = 0; + sumOfSquares = 0; + sumOfAbsErrors = 0; + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + + /** + * Method to learn from an instance that passes the new instance to the perceptron learner, + * and also prevents the class value from being truncated to an int when it is passed to the + * attribute observer + */ + public void learnFromInstance(Instance inst, boolean growthAllowed, double prediction) { + //The prediction must be calculated here -- it may be different from the tree's prediction due to alternate trees + + // Update the statistics for this node + // number of instances passing through the node + examplesSeen += inst.weight(); + + // sum of y values + sumOfValues += inst.weight() * inst.classValue(); + + // sum of squared y values + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + // sum of absolute errors + sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - prediction))); + + if (tree.buildingModelTree()) { + double predictionModel = getPredictionModel(inst); + double predictionTargetMean = getPredictionTargetMean(inst); + + errorModel = errorModel * 0.95 + Math.abs(predictionModel - inst.classValue()); + errorTargetMean = errorTargetMean * 0.95 + Math.abs(predictionTargetMean - inst.classValue()); + + learningModel.updatePerceptron(inst); + } + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); + FIMTDDNumericAttributeClassObserver obs = attributeObservers.get(i); + if (obs == null) { + // At this stage all nominal attributes are ignored + if (inst.attribute(instAttIndex).isNumeric()) { + obs = tree.newNumericClassObserver(); + this.attributeObservers.set(i, obs); + } + } + if (obs != null) { + obs.observeAttributeClass(inst.value(instAttIndex), inst.classValue(), inst.weight()); + } + } + + if (growthAllowed) { + checkForSplit(); + } + } + + /** + * Return the best split suggestions for this node using the given split criteria + */ + public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion) { + + List bestSuggestions = new LinkedList(); + + // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution + double[] nodeSplitDist = new double[] {examplesSeen, sumOfValues, sumOfSquares}; + + for (int i = 0; i < this.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = this.attributeObservers.get(i); + if (obs != null) { + + // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED + AttributeSplitSuggestion bestSuggestion = null; + if (obs instanceof FIMTDDNumericAttributeClassObserver) { + bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, nodeSplitDist, i, true); + } + + if (bestSuggestion != null) { + bestSuggestions.add(bestSuggestion); + } + } + } + return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); + } + + /** + * Retrieve the class votes using the perceptron learner + */ + public double getPredictionModel(Instance inst) { + return learningModel.prediction(inst); + } + + public double getPredictionTargetMean(Instance inst) { + return (examplesSeen > 0.0) ? sumOfValues / examplesSeen : 0.0; + } + + public double getPrediction(Instance inst) { + if (tree.buildingModelTree()) { + //return getPredictionModel(inst); + return (errorModel < errorTargetMean) ? getPredictionModel(inst) : getPredictionTargetMean(inst); + } else + return getPredictionTargetMean(inst); + } + + public void checkForSplit() { + // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node + if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { + int index = (parent != null) ? parent.getChildIndex(this) : 0; + tree.attemptToSplit(this, parent, index); + + // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation + examplesSeenAtLastSplitEvaluation = examplesSeen; + } + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf "); + if (tree.buildingModelTree()) { + learningModel.getModelDescription(out, 0); + } else { + out.append(tree.getClassNameString() + " = " + String.format("%.4f", sumOfValues / examplesSeen)); + StringUtils.appendNewline(out); + } + } + } + + public abstract static class InnerNode extends Node { + // The InnerNode and SplitNode design is used for easy extension in ORTO + private static final long serialVersionUID = 1L; + + protected AutoExpandVector children = new AutoExpandVector(); + + // The error values for the Page Hinckley test + // PHmT = the cumulative sum of the errors + // PHMT = the minimum error value seen so far + protected double PHsum = 0; + protected double PHmin = Double.MAX_VALUE; + + // Keep track of the statistics for loss error calculations + protected double lossExamplesSeen; + protected double lossFadedSumOriginal; + protected double lossFadedSumAlternate; + protected double lossNumQiTests; + protected double lossSumQi; + protected double previousWeight = 0; + + public InnerNode(FIMTDD tree) { + super(tree); + } + + public int numChildren() { + return children.size(); + } + + public Node getChild(int index) { + return children.get(index); + } + + public int getChildIndex(Node child) { + return children.indexOf(child); + } + + public void setChild(int index, Node child) { + children.set(index, child); + } + + public void disableChangeDetection() { + changeDetection = false; + for (Node child : children) { + child.disableChangeDetection(); + } + } + + public void restartChangeDetection() { + if (alternateTree == null) { + changeDetection = true; + PHsum = 0; + PHmin = Integer.MAX_VALUE; + for (Node child : children) + child.restartChangeDetection(); + } + } + + /** + * Check to see if the tree needs updating + */ + public boolean PageHinckleyTest(double error, double threshold) { + // Update the cumulative mT sum + PHsum += error; + + // Update the minimum mT value if the new mT is + // smaller than the current minimum + if(PHsum < PHmin) { + PHmin = PHsum; + } + // Return true if the cumulative value - the current minimum is + // greater than the current threshold (in which case we should adapt) + return PHsum - PHmin > threshold; + } + + public void initializeAlternateTree() { + // Start a new alternate tree, beginning with a learning node + alternateTree = tree.newLeafNode(); + alternateTree.originalNode = this; + + // Set up the blank statistics + // Number of instances reaching this node since the alternate tree was started + lossExamplesSeen = 0; + // Faded squared error (original tree) + lossFadedSumOriginal = 0; + // Faded squared error (alternate tree) + lossFadedSumAlternate = 0; + // Number of evaluations of alternate tree + lossNumQiTests = 0; + // Sum of Qi values + lossSumQi = 0; + // Number of examples at last test + previousWeight = 0; + + // Disable the change detection mechanism bellow this node + disableChangeDetection(); + } + } + + public static class SplitNode extends InnerNode { + + private static final long serialVersionUID = 1L; + + protected InstanceConditionalTest splitTest; + + /** + * Create a new SplitNode + * @param tree + */ + public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { + super(tree); + this.splitTest = splitTest; + } + + public int instanceChildIndex(Instance inst) { + return splitTest.branchForInstance(inst); + } + + public Node descendOneStep(Instance inst) { + return children.get(splitTest.branchForInstance(inst)); + } + + public void describeSubtree(StringBuilder out, int indent) { + for (int branch = 0; branch < children.size(); branch++) { + Node child = getChild(branch); + if (child != null) { + StringUtils.appendIndented(out, indent, "if "); + out.append(this.splitTest.describeConditionForBranch(branch, + tree.getModelContext())); + out.append(": "); + StringUtils.appendNewline(out); + child.describeSubtree(out, indent + 2); + } + } + } + + public double getPrediction(Instance inst) { + return children.get(splitTest.branchForInstance(inst)).getPrediction(inst); + } + } + + public class FIMTDDPerceptron implements Serializable { + + private static final long serialVersionUID = 1L; + + protected FIMTDD tree; + + // The Perception weights + protected double[] weightAttribute; + + // The number of instances contributing to this model + protected double instancesSeen = 0; + + public String getPurposeString() { + return "A perceptron regressor as specified by Ikonomovska et al. used for FIMTDD"; + } + + public FIMTDDPerceptron(FIMTDDPerceptron original) { + this.tree = original.tree; + weightAttribute = original.weightAttribute.clone(); + } + + public FIMTDDPerceptron(FIMTDD tree) { + this.tree = tree; + initializeWeights(); + + } + + public void initializeWeights() { + weightAttribute = new double[tree.getModelContext().numInputAttributes()+1]; + instancesSeen = 0; + for (int j = 0; j < tree.getModelContext().numInputAttributes()+1; j++) { + // The last index corresponds to the constant b + weightAttribute[j] = 2 * tree.classifierRandom.nextDouble() - 1; + } + normalizeWeights(); + } + + /** + * Update the model using the provided instance + */ + public void updatePerceptron(Instance inst) { + + // Update attribute statistics + instancesSeen += inst.weight(); + + // Update weights + double learningRatio = 0.0; + if (tree.learningRatioConstOption.isSet()) { + learningRatio = learningRatioOption.getValue(); + } else { + learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); + } + + // Loop for compatibility with bagging methods + for (int i = 0; i < (int) inst.weight(); i++) { + updateWeights(inst, learningRatio); + } + + } + + public void updateWeights(Instance inst, double learningRatio) { + // Compute the normalized instance and the delta + double[] normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + double normalizedValue = tree.normalizeTargetValue(inst.classValue()); + double delta = normalizedValue - normalizedPrediction; + for (int i = 0; i < weightAttribute.length; i++) { + weightAttribute[i] += delta * learningRatio * normalizedInstance[i]; + } + + normalizeWeights(); + } + + public void normalizeWeights() { + double sum = 0; + for (int i = 0; i < this.weightAttribute.length; i++) + sum += Math.abs(weightAttribute[i]); + for (int i = 0; i < this.weightAttribute.length; i++) + weightAttribute[i] /= sum; + } + + public double[] normalizedInstance(Instance inst) { + // Normalize Instance + double[] normalizedInstance = new double[inst.numInputAttributes()+1]; + for (int j = 0; j < inst.numInputAttributes(); j++) { + double mean = tree.sumOfAttrValues.getValue(j) / tree.examplesSeen; + double sd = computeSD(tree.sumOfAttrSquares.getValue(j), tree.sumOfAttrValues.getValue(j), tree.examplesSeen); + if (inst.inputAttribute(j).isNumeric() && tree.examplesSeen > 1 && sd > 0.0000001) + normalizedInstance[j] = (inst.valueInputAttribute(j) - mean) / (sd); + else + normalizedInstance[j] = 0; + } + normalizedInstance[inst.numInputAttributes()] = tree.examplesSeen > 1 ? 1 : 0; // Value to be multiplied with the constant factor + return normalizedInstance; + } + + /** + * Output the prediction made by this perceptron on the given instance + */ + public double prediction(double[] instanceValues) { + double ret = 0; + for (int i = 0; i < instanceValues.length; i++) + ret += instanceValues[i] * weightAttribute[i]; + return ret; + } + + protected double prediction(Instance inst) { + double[] normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + return denormalizePrediction(normalizedPrediction); + } + + private double denormalizePrediction(double normalizedPrediction) { + double mean = tree.sumOfValues / tree.examplesSeen; + double sd = computeSD(tree.sumOfSquares, tree.sumOfValues, tree.examplesSeen); + if (examplesSeen > 1) + return normalizedPrediction * sd + mean; + else + return 0.0; + } + + public void getModelDescription(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, getClassNameString() + " ="); + if (getModelContext() != null) { + for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { + if (getModelContext().attribute(j).isNumeric()) { + out.append((j == 0 || weightAttribute[j] < 0) ? " " : " + "); + out.append(String.format("%.4f", weightAttribute[j])); + out.append(" * "); + out.append(getAttributeNameString(j)); + } + } + out.append(" + " + weightAttribute[getModelContext().numInputAttributes()]); + } + StringUtils.appendNewline(out); + } + } + + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + // region --- Regressor methods + + public String getPurposeString() { + return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + this.treeRoot = null; + this.leafNodeCount = 0; + this.splitNodeCount = 0; + this.maxID = 0; + this.examplesSeen = 0; + this.sumOfValues = 0.0; + this.sumOfSquares = 0.0; + + this.sumOfAttrValues = new DoubleVector(); + this.sumOfAttrSquares = new DoubleVector(); + } + + public boolean isRandomizable() { + return true; + } + + public void getModelDescription(StringBuilder out, int indent) { + if (treeRoot != null) treeRoot.describeSubtree(out, indent); + } + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("tree size (leaves)", this.leafNodeCount) + }; + } + + public int calcByteSize() { + return (int) SizeOf.fullSizeOf(this); + } + + public double[] getVotesForInstance(Instance inst) { + if (treeRoot == null) { + return new double[] {0}; + } + + double prediction = treeRoot.getPrediction(inst); + + return new double[] {prediction}; + } + + public double normalizeTargetValue(double value) { + if (examplesSeen > 1) { + double sd = Math.sqrt((sumOfSquares - ((sumOfValues * sumOfValues)/examplesSeen))/examplesSeen); + double average = sumOfValues / examplesSeen; + if (sd > 0 && examplesSeen > 1) + return (value - average) / sd; + else + return 0.0; + } + return 0.0; + } + + public double getNormalizedError(Instance inst, double prediction) { + double normalPrediction = normalizeTargetValue(prediction); + double normalValue = normalizeTargetValue(inst.classValue()); + return Math.abs(normalValue - normalPrediction); + } + + + /** + * Method for updating (training) the model using a new instance + */ + public void trainOnInstanceImpl(Instance inst) { + checkRoot(); + + double prediction = treeRoot.getPrediction(inst); + double normalError = getNormalizedError(inst, prediction); + + processInstance(inst, treeRoot, prediction, normalError, true, false); + + examplesSeen += inst.weight(); + sumOfValues += inst.weight() * inst.classValue(); + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int aIndex = modelAttIndexToInstanceAttIndex(i, inst); + sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); + } + + + } + + public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); + break; + } else { + currentNode.examplesSeen += inst.weight(); + currentNode.sumOfAbsErrors += inst.weight() * normalError; + InnerNode iNode = (InnerNode) currentNode; + if (!inAlternate && iNode.alternateTree != null) { + boolean altTree = true; + double lossO = Math.pow(inst.classValue() - prediction, 2); + double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); + + // Loop for compatibility with bagging methods + for (int i = 0; i < inst.weight(); i++) { + iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + iNode.lossExamplesSeen++; + + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + iNode.lossSumQi += Qi; + iNode.lossNumQiTests += 1; + } + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + + if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + iNode.previousWeight = iNode.lossExamplesSeen; + if (Qi > 0) { + // Switch the subtrees + Node parent = iNode.getParent(); + + if (parent != null) { + Node replacementTree = iNode.alternateTree; + parent.setChild(parent.getChildIndex(iNode), replacementTree); + if (growthAllowed) replacementTree.restartChangeDetection(); + } else { + treeRoot = iNode.alternateTree; + treeRoot.restartChangeDetection(); + } + + currentNode = iNode.alternateTree; + currentNode.originalNode = null; + altTree = false; + } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { + // Remove the alternate tree + iNode.alternateTree = null; + if (growthAllowed) iNode.restartChangeDetection(); + altTree = false; + } + } + + if (altTree) { + growthAllowed = false; + processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + } + } + + if (iNode.changeDetection && !inAlternate) { + if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + iNode.initializeAlternateTree(); + growthAllowed = false; + } + } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).descendOneStep(inst); + } + } + } + } + + // endregion --- Regressor methods + + // region --- Object instatiation methods + + protected FIMTDDNumericAttributeClassObserver newNumericClassObserver() { + return new FIMTDDNumericAttributeClassObserver(); + } + + protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + maxID++; + return new SplitNode(splitTest, this); + } + + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } + + protected FIMTDDPerceptron newLeafModel() { + return new FIMTDDPerceptron(this); + } + + //endregion --- Object instatiation methods + + // region --- Processing methods + + protected void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + leafNodeCount = 1; + } + } + + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } + + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } + + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); + + // Using this criterion, find the best split per attribute and rank the results + AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine if any of the splits should be performed + boolean shouldSplit = false; + + // If only one split was returned, use it + if (bestSplitSuggestions.length < 2) { + shouldSplit = bestSplitSuggestions.length > 0; + } else { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, this.splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { + shouldSplit = true; + } + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + else { + for (int i = 0; i < node.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = node.attributeObservers.get(i); + if (obs != null) { + obs.removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); + } + } + } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (shouldSplit) { + AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + + SplitNode newSplit = newSplitNode(splitDecision.splitTest); + newSplit.copyStatistics(node); + newSplit.changeDetection = node.changeDetection; + newSplit.ID = node.ID; + leafNodeCount--; + for (int i = 0; i < splitDecision.numSplits(); i++) { + LeafNode newChild = newLeafNode(); + if (buildingModelTree()) { + // Copy the splitting node's perceptron to it's children + newChild.learningModel = new FIMTDDPerceptron((FIMTDDPerceptron) node.learningModel); + + } + newChild.changeDetection = node.changeDetection; + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + leafNodeCount++; + } + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + ((SplitNode) parent).setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + + splitNodeCount++; + } + } + + public double computeSD(double squaredVal, double val, double size) { + if (size > 1) + return Math.sqrt((squaredVal - ((val * val) / size)) / size); + else + return 0.0; + } + + public double scalarProduct(DoubleVector u, DoubleVector v) { + double ret = 0.0; + for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { + ret += u.getValue(i) * v.getValue(i); + } + return ret; + } + //endregion --- Processing methods + + //endregion ================ METHODS ================ +} + ======= ->>>>>>> Revert "Removed merging artefacts" /* * FIMTDD.java * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia @@ -1964,7 +1951,4 @@ public double scalarProduct(DoubleVector u, DoubleVector v) { //endregion ================ METHODS ================ } -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -======= >>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index d2e697d6e..1808a5466 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -35,21 +35,10 @@ import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.splitcriteria.SplitCriterion; -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -import moa.core.AutoExpandVector; -import moa.core.Measurement; -======= -<<<<<<< HEAD -import moa.classifiers.trees.FIMTDD.InnerNode; -import moa.classifiers.trees.FIMTDD.Node; + import moa.core.AutoExpandVector; import moa.core.Measurement; import moa.core.StringUtils; -======= -import moa.core.AutoExpandVector; -import moa.core.Measurement; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" /* * Implementation of ORTO, option trees for data streams. @@ -132,15 +121,9 @@ public int getNumSubtrees() { public int directionForBestTree() { int d = 0; -<<<<<<< HEAD - double min = Double.MAX_VALUE; - for (int i = 0; i < numChildren(); i++) { - double tmp = getFFRatio(i); -======= double tmp = 0.0, min = Double.MAX_VALUE; for (int i = 0; i < children.size(); i++) { tmp = getFFRatio(i); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa if (tmp < min) { min = tmp; d = i; @@ -149,54 +132,22 @@ public int directionForBestTree() { return d; } -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - public double getPrediction(Instance inst, ORTO tree) { -======= -<<<<<<< HEAD public double getPrediction(Instance inst) { -======= - public double getPrediction(Instance inst, ORTO tree) { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" double[] predictions = new double[numChildren()]; for (int i = 0; i < numChildren(); i++) { predictions[i] = getChild(i).getPrediction(inst); } -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - return aggregate(predictions, tree); - } - - private double aggregate(double[] predictions, ORTO tree) { - if (tree.optionNodeAggregationOption.getChosenIndex() == 0) { // Average -======= -<<<<<<< HEAD return aggregate(predictions); } private double aggregate(double[] predictions) { if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average -======= - return aggregate(predictions, tree); - } - - private double aggregate(double[] predictions, ORTO tree) { - if (tree.optionNodeAggregationOption.getChosenIndex() == 0) { // Average ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" double sum = 0.0; for (int i = 0; i < predictions.length; i++) { sum += predictions[i]; } return sum / predictions.length; -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - } else if (tree.optionNodeAggregationOption.getChosenIndex() == 1) { -======= -<<<<<<< HEAD } else if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 1) { -======= - } else if (tree.optionNodeAggregationOption.getChosenIndex() == 1) { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" int d = directionForBestTree(); return predictions[d]; } else { @@ -211,9 +162,6 @@ public double getFFRatio(int childIndex) { protected boolean skipInLevelCount() { return true; } -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -======= -<<<<<<< HEAD @Override public void describeSubtree(StringBuilder out, int indent) { @@ -226,9 +174,6 @@ public void describeSubtree(StringBuilder out, int indent) { split.describeSubtree(out, indent + 2); } } -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" } //endregion ================ CLASSES ================ @@ -263,15 +208,7 @@ public void processInstance(Instance inst, Node node, double prediction, double Node currentNode = node; while (true) { if (currentNode instanceof LeafNode) { -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); -======= -<<<<<<< HEAD ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); -======= - ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" break; } else { currentNode.examplesSeen += inst.weight(); @@ -280,15 +217,7 @@ public void processInstance(Instance inst, Node node, double prediction, double if (!inAlternate && iNode.alternateTree != null) { boolean altTree = true; double lossO = Math.pow(inst.classValue() - prediction, 2); -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); -======= -<<<<<<< HEAD double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); -======= - double lossA = Math.pow(inst.classValue() - currentNode.alternateTree.getPrediction(inst), 2); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { @@ -308,15 +237,7 @@ public void processInstance(Instance inst, Node node, double prediction, double iNode.previousWeight = iNode.lossExamplesSeen; if (Qi > 0) { // Switch the subtrees -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - Node parent = currentNode.parent; -======= -<<<<<<< HEAD Node parent = iNode.getParent(); -======= - Node parent = currentNode.parent; ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" if (parent != null) { Node replacementTree = iNode.alternateTree; @@ -326,15 +247,7 @@ public void processInstance(Instance inst, Node node, double prediction, double treeRoot = iNode.alternateTree; treeRoot.restartChangeDetection(); } -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); -======= -<<<<<<< HEAD optionNodeCount += iNode.alternateTree.getNumSubtrees() - iNode.getNumSubtrees(); -======= - optionNodeCount += currentNode.alternateTree.getNumSubtrees() - currentNode.getNumSubtrees(); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" removeExcessTrees(); currentNode = iNode.alternateTree; @@ -349,15 +262,7 @@ public void processInstance(Instance inst, Node node, double prediction, double } if (altTree) { growthAllowed = false; // this is the growth of the original tree -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree -======= -<<<<<<< HEAD processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree -======= - processInstance(inst, currentNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" } else if (currentNode instanceof OptionNode) { // this happens when an option node is switched into the tree for (Node child : ((OptionNode) currentNode).children) { @@ -385,44 +290,22 @@ public void processInstance(Instance inst, Node node, double prediction, double } public void processInstanceOptionNode(Instance inst, OptionNode node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -======= -<<<<<<< HEAD node.examplesSeen += inst.weight(); node.sumOfAbsErrors += inst.weight() * normalError; -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" if (node.changeDetection) { double error = Math.abs(prediction - inst.classValue()); node.sumOfAbsErrors += error; if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { node.initializeAlternateTree(); -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -======= -<<<<<<< HEAD growthAllowed = false; -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" } } for (Node child : node.children) { int index = node.getChildIndex(child); double childPrediction = child.getPrediction(inst); -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -======= -<<<<<<< HEAD - node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; - node.optionFFSSL[index] = node.optionFFSSL[index] * optionFadingFactorOption.getValue() + Math.pow(childPrediction - inst.classValue(), 2); - } - for (Node child : node.children) { - processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); -======= ->>>>>>> Revert "Removed merging artefacts" // Loop for compatibility with bagging methods for (int i = 0; i < inst.weight(); i++) { node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; @@ -432,7 +315,6 @@ public void processInstanceOptionNode(Instance inst, OptionNode node, double pre for (Node child : node.children) { processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa } } @@ -450,10 +332,6 @@ protected OptionNode newOptionNode() { // region --- Processing methods protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Initialize the split criterion SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); @@ -461,11 +339,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); List acceptedSplits = new LinkedList(); Arrays.sort(bestSplitSuggestions); -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa // Declare a variable to determine the number of splits to be performed int numSplits = 0; @@ -483,13 +357,6 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -======= -<<<<<<< HEAD - -======= ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and @@ -501,30 +368,16 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { numSplits = 1; acceptedSplits.add(bestSuggestion); } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - for (AttributeSplitSuggestion suggestion : bestSplitSuggestions) { -======= -<<<<<<< HEAD for (int i = 0; i < bestSplitSuggestions.length; i++) { AttributeSplitSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; ->>>>>>> Revert "Removed merging artefacts" - if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { - numSplits++; - acceptedSplits.add(suggestion); - } - } -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -======= - -======= - for (AttributeSplitSuggestion suggestion : bestSplitSuggestions) { if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { numSplits++; acceptedSplits.add(suggestion); + } else { + break; } + } ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" } else if (hoeffdingBound < tieThresholdOption.getValue()) { numSplits = 1; acceptedSplits.add(bestSplitSuggestions[0]); @@ -543,11 +396,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (numSplits > 0) { double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); -<<<<<<< HEAD - if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 0) { -======= if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa AttributeSplitSuggestion splitDecision = acceptedSplits.get(0); SplitNode newSplit = newSplitNode(splitDecision.splitTest); for (int i = 0; i < splitDecision.numSplits(); i++) { @@ -558,25 +407,12 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { leafNodeCount--; innerNodeCount++; leafNodeCount += splitDecision.numSplits(); -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - if (parent == null) { -======= -<<<<<<< HEAD if (parent == null && node.originalNode == null) { ->>>>>>> Revert "Removed merging artefacts" treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; } else { -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - parent.setChild(parent.getChildIndex(node), newSplit); -======= parent.setChild(parentIndex, newSplit); -======= - if (parent == null) { - treeRoot = newSplit; - } else { - parent.setChild(parent.getChildIndex(node), newSplit); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" newSplit.setParent(parent); } } else { @@ -610,15 +446,7 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { if (parent == null) { treeRoot = optionNode; } else { -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 - parent.setChild(parent.getChildIndex(node), optionNode); -======= -<<<<<<< HEAD parent.setChild(parentIndex, optionNode); -======= - parent.setChild(parent.getChildIndex(node), optionNode); ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" optionNode.setParent(parent); } @@ -701,11 +529,4 @@ protected void removeExcessTrees() { // endregion --- Option tree methods //endregion ================ METHODS ================ -<<<<<<< HEAD -} -<<<<<<< 5a48cb8458f9db3cf55cf428d50f81dc14c31ee3 -======= -======= } ->>>>>>> 5c49882b22b3a8314c6dfcc8c026456c887262fa ->>>>>>> Revert "Removed merging artefacts" diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index c7c7b5db0..9b3a1920b 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -59,225 +59,225 @@ */ public class EvaluatePrequentialMultiTarget extends MultiTargetMainTask { - @Override - public String getPurposeString() { - return "Evaluates a classifier on a stream by testing then training with each example in sequence."; - } + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); + public ClassOption learnerOption = new ClassOption("learner", 'l', + "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); - public ClassOption streamOption = new ClassOption("stream", 's', - "Stream to learn from.", MultiTargetInstanceStream.class, - "MultiTargetArffFileStream"); + public ClassOption streamOption = new ClassOption("stream", 's', + "Stream to learn from.", MultiTargetInstanceStream.class, + "MultiTargetArffFileStream"); - public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', - "Classification performance evaluation method.", - MultiTargetPerformanceEvaluator.class, - "BasicMultiTargetPerformanceEvaluator"); + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + MultiTargetPerformanceEvaluator.class, + "BasicMultiTargetPerformanceEvaluator"); - public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', - "Maximum number of instances to test/train on (-1 = no limit).", - 100000000, -1, Integer.MAX_VALUE); + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); - public IntOption timeLimitOption = new IntOption("timeLimit", 't', - "Maximum number of seconds to test/train for (-1 = no limit).", -1, - -1, Integer.MAX_VALUE); + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); - public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", - 'f', - "How many instances between samples of the learning performance.", - 100000, 0, Integer.MAX_VALUE); + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); - public IntOption memCheckFrequencyOption = new IntOption( - "memCheckFrequency", 'q', - "How many instances between memory bound checks.", 100000, 0, - Integer.MAX_VALUE); + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); - public FileOption dumpFileOption = new FileOption("dumpFile", 'd', - "File to append intermediate csv results to.", null, "csv", true); + public FileOption dumpFileOption = new FileOption("dumpFile", 'd', + "File to append intermediate csv results to.", null, "csv", true); - public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', - "File to append output predictions to.", null, "pred", true); + public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', + "File to append output predictions to.", null, "pred", true); - //New for prequential method DEPRECATED - public IntOption widthOption = new IntOption("width", - 'w', "Size of Window", 1000); + //New for prequential method DEPRECATED + public IntOption widthOption = new IntOption("width", + 'w', "Size of Window", 1000); - public FloatOption alphaOption = new FloatOption("alpha", - 'a', "Fading factor or exponential smoothing factor", .01); - //End New for prequential methods + public FloatOption alphaOption = new FloatOption("alpha", + 'a', "Fading factor or exponential smoothing factor", .01); + //End New for prequential methods - @Override - public Class getTaskResultType() { - return LearningCurve.class; - } + @Override + public Class getTaskResultType() { + return LearningCurve.class; + } - @Override - protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { - Learner learner = (Learner) getPreparedClassOption(this.learnerOption); - ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); - LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); - LearningCurve learningCurve = new LearningCurve( - "learning evaluation instances"); + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + Learner learner = (Learner) getPreparedClassOption(this.learnerOption); + ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); + LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); + LearningCurve learningCurve = new LearningCurve( + "learning evaluation instances"); - //New for prequential methods - if (evaluator instanceof WindowClassificationPerformanceEvaluator) { - //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); - if (widthOption.getValue() != 1000) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { - //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { - //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - //End New for prequential methods + //New for prequential methods + if (evaluator instanceof WindowClassificationPerformanceEvaluator) { + //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); + if (widthOption.getValue() != 1000) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { + //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { + //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + //End New for prequential methods - learner.setModelContext(stream.getHeader()); - int maxInstances = this.instanceLimitOption.getValue(); - long instancesProcessed = 0; - int maxSeconds = this.timeLimitOption.getValue(); - int secondsElapsed = 0; - monitor.setCurrentActivity("Evaluating learner...", -1.0); + learner.setModelContext(stream.getHeader()); + int maxInstances = this.instanceLimitOption.getValue(); + long instancesProcessed = 0; + int maxSeconds = this.timeLimitOption.getValue(); + int secondsElapsed = 0; + monitor.setCurrentActivity("Evaluating learner...", -1.0); - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - //File for output predictions - File outputPredictionFile = this.outputPredictionFileOption.getFile(); - PrintStream outputPredictionResultStream = null; - if (outputPredictionFile != null) { - try { - if (outputPredictionFile.exists()) { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile, true), true); - } else { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open prediction result file: " + outputPredictionFile, ex); - } - } - boolean firstDump = true; - boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); - long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - long lastEvaluateStartTime = evaluateStartTime; - double RAMHours = 0.0; - while (stream.hasMoreInstances() - && ((maxInstances < 0) || (instancesProcessed < maxInstances)) - && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { - Example trainInst = stream.nextInstance(); - Example testInst = (Example) trainInst; //.copy(); - //testInst.setClassMissing(); - //double[] prediction = learner.getVotesForInstance(testInst); - Prediction prediction = learner.getPredictionForInstance(testInst); - // Output prediction - if (outputPredictionFile != null) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { - sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); - } - outputPredictionResultStream.println(prediction + "," + sb.toString()); - } + File dumpFile = this.dumpFileOption.getFile(); + PrintStream immediateResultStream = null; + if (dumpFile != null) { + try { + if (dumpFile.exists()) { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile, true), true); + } else { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open immediate result file: " + dumpFile, ex); + } + } + //File for output predictions + File outputPredictionFile = this.outputPredictionFileOption.getFile(); + PrintStream outputPredictionResultStream = null; + if (outputPredictionFile != null) { + try { + if (outputPredictionFile.exists()) { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile, true), true); + } else { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open prediction result file: " + outputPredictionFile, ex); + } + } + boolean firstDump = true; + boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); + long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + long lastEvaluateStartTime = evaluateStartTime; + double RAMHours = 0.0; + while (stream.hasMoreInstances() + && ((maxInstances < 0) || (instancesProcessed < maxInstances)) + && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { + Example trainInst = stream.nextInstance(); + Example testInst = (Example) trainInst; //.copy(); + //testInst.setClassMissing(); + //double[] prediction = learner.getVotesForInstance(testInst); + Prediction prediction = learner.getPredictionForInstance(testInst); + // Output prediction + if (outputPredictionFile != null) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); + } - //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); - evaluator.addResult(testInst, prediction); - learner.trainOnInstance(trainInst); - instancesProcessed++; - if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 - || stream.hasMoreInstances() == false) { - long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); - double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); - double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs - RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours - RAMHours += RAMHoursIncrement; - lastEvaluateStartTime = evaluateTime; - learningCurve.insertEntry(new LearningEvaluation( - new Measurement[]{ - new Measurement( - "learning evaluation instances", - instancesProcessed), - new Measurement( - "evaluation time (" - + (preciseCPUTiming ? "cpu " - : "") + "seconds)", - time), - new Measurement( - "model cost (RAM-Hours)", - RAMHours) - }, - evaluator, learner)); + //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); + evaluator.addResult(testInst, prediction); + learner.trainOnInstance(trainInst); + instancesProcessed++; + if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 + || stream.hasMoreInstances() == false) { + long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); + double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); + double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs + RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours + RAMHours += RAMHoursIncrement; + lastEvaluateStartTime = evaluateTime; + learningCurve.insertEntry(new LearningEvaluation( + new Measurement[]{ + new Measurement( + "learning evaluation instances", + instancesProcessed), + new Measurement( + "evaluation time (" + + (preciseCPUTiming ? "cpu " + : "") + "seconds)", + time), + new Measurement( + "model cost (RAM-Hours)", + RAMHours) + }, + evaluator, learner)); - if (immediateResultStream != null) { - if (firstDump) { - immediateResultStream.println(learningCurve.headerToString()); - firstDump = false; - } - immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); - immediateResultStream.flush(); - } - } - if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { - if (monitor.taskShouldAbort()) { - return null; - } - long estimatedRemainingInstances = stream.estimatedRemainingInstances(); - if (maxInstances > 0) { - long maxRemaining = maxInstances - instancesProcessed; - if ((estimatedRemainingInstances < 0) - || (maxRemaining < estimatedRemainingInstances)) { - estimatedRemainingInstances = maxRemaining; - } - } - monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 - : (double) instancesProcessed - / (double) (instancesProcessed + estimatedRemainingInstances)); - if (monitor.resultPreviewRequested()) { - monitor.setLatestResultPreview(learningCurve.copy()); - } - secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() - - evaluateStartTime); - } - } - StringBuilder sb= new StringBuilder(); - learner.getDescription(sb, 0); - System.out.println(sb.toString()); - if (immediateResultStream != null) { - immediateResultStream.close(); - } - if (outputPredictionResultStream != null) { - outputPredictionResultStream.close(); - } - return learningCurve; - } + if (immediateResultStream != null) { + if (firstDump) { + immediateResultStream.println(learningCurve.headerToString()); + firstDump = false; + } + immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); + immediateResultStream.flush(); + } + } + if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { + if (monitor.taskShouldAbort()) { + return null; + } + long estimatedRemainingInstances = stream.estimatedRemainingInstances(); + if (maxInstances > 0) { + long maxRemaining = maxInstances - instancesProcessed; + if ((estimatedRemainingInstances < 0) + || (maxRemaining < estimatedRemainingInstances)) { + estimatedRemainingInstances = maxRemaining; + } + } + monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 + : (double) instancesProcessed + / (double) (instancesProcessed + estimatedRemainingInstances)); + if (monitor.resultPreviewRequested()) { + monitor.setLatestResultPreview(learningCurve.copy()); + } + secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() + - evaluateStartTime); + } + } + StringBuilder sb= new StringBuilder(); + learner.getDescription(sb, 0); + System.out.println(sb.toString()); + if (immediateResultStream != null) { + immediateResultStream.close(); + } + if (outputPredictionResultStream != null) { + outputPredictionResultStream.close(); + } + return learningCurve; + } } diff --git a/weka-package/pom.xml b/weka-package/pom.xml index 6cd73530c..693727f08 100644 --- a/weka-package/pom.xml +++ b/weka-package/pom.xml @@ -6,7 +6,7 @@ nz.ac.waikato.cms.moa moa-pom - 2012.09-SNAPSHOT + 2014.04 weka-package From 1b6cdbfea6bcbe57e38e4d151de39992caa346bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Wed, 23 Mar 2016 11:06:20 +0100 Subject: [PATCH 25/33] Intermediary commit for multi-label changes --- .../labs/samoa/instances/ArffLoader.java | 15 +- .../yahoo/labs/samoa/instances/Attribute.java | 510 ++++++++++-------- .../samoa/instances/AttributeStructure.java | 7 + .../labs/samoa/instances/DAGStructure.java | 86 +++ .../instances/HierarhicalInstanceImpl.java | 452 ++++++++++++++++ .../yahoo/labs/samoa/instances/Instance.java | 11 + .../labs/samoa/instances/InstanceImpl.java | 31 +- .../samoa/instances/InstanceInformation.java | 9 + .../labs/samoa/instances/InstancesHeader.java | 4 + ...lInstance.java => StructuredInstance.java} | 4 +- .../moa/classifiers/AbstractClassifier.java | 11 +- .../AbstractMultiLabelLearner.java | 10 +- .../moa/classifiers/MultiLabelLearner.java | 6 +- .../java/moa/classifiers/meta/OzaBag.java | 2 +- .../LocalMultiTargetClassifier.java | 16 +- .../multilabel/MEKAClassifier.java | 28 +- .../multilabel/MajorityLabelset.java | 15 +- .../multilabel/MultilabelHoeffdingTree.java | 11 +- .../splitcriteria/ICVarianceReduction.java | 1 - .../WeightedICVarianceReduction.java | 46 ++ .../classifiers/multilabel/meta/MLOzaBag.java | 126 +++++ .../multilabel/meta/MLOzaBagAdwin.java | 182 +++++++ .../classifiers/multilabel/meta/MTOzaBag.java | 40 +- .../multilabel/trees/ISOUPOptionTree.java | 319 +++++++++-- .../multilabel/trees/ISOUPTree.java | 428 ++++++++------- .../BasicMultiTargetRegressor.java | 8 +- .../functions/MultiTargetNoChange.java | 6 +- .../rules/core/NominalRulePredicate.java | 15 +- .../rules/core/NumericRulePredicate.java | 16 +- .../moa/classifiers/rules/core/Predicate.java | 2 + .../AbstractAnomalyDetector.java | 4 +- .../AnomalinessRatioScore.java | 4 +- .../anomalydetection/AnomalyDetector.java | 4 +- .../anomalydetection/NoAnomalyDetection.java | 4 +- .../core/anomalydetection/OddsRatioScore.java | 4 +- .../NominalAttributeBinaryRulePredicate.java | 9 + .../NumericAttributeBinaryRulePredicate.java | 7 + .../rules/functions/Perceptron.java | 2 +- .../multilabel/AMRulesMultiLabelLearner.java | 10 +- .../multilabel/core/LearningLiteral.java | 12 +- .../core/LearningLiteralRegression.java | 4 +- .../rules/multilabel/core/MultiLabelRule.java | 12 +- .../AbstractMultiLabelErrorMeasurer.java | 4 +- .../AbstractMultiTargetErrorMeasurer.java | 4 +- .../MultiLabelErrorMeasurer.java | 4 +- .../AdaptiveMultiTargetRegressor.java | 6 +- .../meta/MultiLabelRandomAMRules.java | 6 +- .../java/moa/classifiers/trees/FIMTDD.java | 37 +- .../main/java/moa/classifiers/trees/ORTO.java | 5 +- .../BasicMultiTargetPerformanceEvaluator.java | 4 +- ...tWindowRegressionPerformanceEvaluator.java | 4 +- ...dowClassificationPerformanceEvaluator.java | 152 ++++++ .../main/java/moa/streams/ArffFileStream.java | 9 +- 53 files changed, 2117 insertions(+), 611 deletions(-) create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/AttributeStructure.java create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/DAGStructure.java create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java rename moa/src/main/java/com/yahoo/labs/samoa/instances/{MultiLabelInstance.java => StructuredInstance.java} (87%) create mode 100644 moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/WeightedICVarianceReduction.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/meta/MLOzaBag.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/meta/MLOzaBagAdwin.java create mode 100644 moa/src/main/java/moa/evaluation/MultilabelWindowClassificationPerformanceEvaluator.java diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java index 124b1d5d6..a6bddce59 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java @@ -352,10 +352,6 @@ private InstanceInformation getHeader() { //commented JD //this.range.setUpper(10000); //TO DO: Create a new range object with isInRange that does not need the upper limit String relation = "file stream"; - //System.out.println("RELATION " + relation); - //inputAttributes = new ArrayList(); - //outputAttributes = new ArrayList(); - //ArrayList auxAttributes = new ArrayList();//JD int numAttributes = 0; try { @@ -405,6 +401,17 @@ private InstanceInformation getHeader() { }*/ auxAttributes.add(new Attribute(name, attributeLabels)); numAttributes++; + } else if (streamTokenizer.sval != null && streamTokenizer.sval.toUpperCase() == "HIERARCHICAL") { + streamTokenizer.nextToken(); + DAGStructure attributeStructure = new DAGStructure(); + if (streamTokenizer.ttype == '{') { + while(streamTokenizer.ttype == '}') { + streamTokenizer.nextToken(); + System.out.println(streamTokenizer.sval); + } + + } + } else { // Add attribute //commented JD diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java index 5b05ad652..44d552dba 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java @@ -25,94 +25,84 @@ */ public class Attribute implements Serializable { - /** The keyword used to denote the start of an arff attribute declaration */ - public final static String ARFF_ATTRIBUTE = "@attribute"; + /** The keyword used to denote the start of an arff attribute declaration */ + public final static String ARFF_ATTRIBUTE = "@attribute"; - /** A keyword used to denote a numeric attribute */ - public final static String ARFF_ATTRIBUTE_INTEGER = "integer"; + /** A keyword used to denote a numeric attribute */ + public final static String ARFF_ATTRIBUTE_INTEGER = "integer"; - /** A keyword used to denote a numeric attribute */ - public final static String ARFF_ATTRIBUTE_REAL = "real"; + /** A keyword used to denote a numeric attribute */ + public final static String ARFF_ATTRIBUTE_REAL = "real"; - /** A keyword used to denote a numeric attribute */ - public final static String ARFF_ATTRIBUTE_NUMERIC = "numeric"; + /** A keyword used to denote a numeric attribute */ + public final static String ARFF_ATTRIBUTE_NUMERIC = "numeric"; - /** The keyword used to denote a string attribute */ - public final static String ARFF_ATTRIBUTE_STRING = "string"; + /** The keyword used to denote a string attribute */ + public final static String ARFF_ATTRIBUTE_STRING = "string"; - /** The keyword used to denote a date attribute */ - public final static String ARFF_ATTRIBUTE_DATE = "date"; + /** The keyword used to denote a date attribute */ + public final static String ARFF_ATTRIBUTE_DATE = "date"; - /** The keyword used to denote a relation-valued attribute */ - public final static String ARFF_ATTRIBUTE_RELATIONAL = "relational"; + /** The keyword used to denote a (nominal) hierarchical attribute */ + public final static String ARFF_ATTRIBUTE_HIERARCHICAL = "hierarchical"; - /** The keyword used to denote the end of the declaration of a subrelation */ - public final static String ARFF_END_SUBRELATION = "@end"; + /** The keyword used to denote a relation-valued attribute */ + public final static String ARFF_ATTRIBUTE_RELATIONAL = "relational"; - /** Strings longer than this will be stored compressed. */ - private static final int STRING_COMPRESS_THRESHOLD = 200; + /** The keyword used to denote the end of the declaration of a subrelation */ + public final static String ARFF_END_SUBRELATION = "@end"; - /** - * The is nominal. - */ - protected boolean isNominal; + /** Strings longer than this will be stored compressed. */ + private static final int STRING_COMPRESS_THRESHOLD = 200; - /** - * The is numeric. - */ - protected boolean isNumeric; + /** + * The is nominal. + */ + protected boolean isNominal; - /** - * The is date. - */ - protected boolean isDate; + /** + * The is numeric. + */ + protected boolean isNumeric; - /** - * Date format specification for date attributes - */ - protected SimpleDateFormat m_DateFormat; - - /** - * The name. - */ - protected String name; + /** + * The is date. + */ + protected boolean isDate; - /** - * The attribute values. - */ - protected List attributeValues; + /** + * The is hierarchical. + */ + protected boolean isHierarchical; - /** - * Gets the attribute values. - * - * @return the attribute values - */ - public List getAttributeValues() { - return attributeValues; - } - - - /** - * Instantiates a new attribute. - * - * @param string the string - */ - public Attribute(String string) { - this.name = string; - this.isNumeric = true; - } + /** + * Date format specification for date attributes + */ + protected SimpleDateFormat m_DateFormat; /** - * Instantiates a new attribute. - * - * @param attributeName the attribute name - * @param attributeValues the attribute values + * The index. */ - public Attribute(String attributeName, List attributeValues) { - this.name = attributeName; - this.attributeValues = attributeValues; - this.isNominal = true; - } + protected int index; + + /** + * The attribute values. + */ + protected List attributeValues; + + /** + * The attribute structure. + */ + protected AttributeStructure attributeStructure; + + /** + * Gets the attribute values. + * + * @return the attribute values + */ + public List getAttributeValues() { + return attributeValues; + } /** * Instantiates a new attribute. @@ -121,7 +111,8 @@ public Attribute(String attributeName, List attributeValues) { * @param dateFormat the format of the date used */ public Attribute(String attributeName, String dateFormat) { - this.name = attributeName; + this.name = attributeName; + this.index = -1; this.valuesStringAttribute = null; this.isDate = true; @@ -139,160 +130,239 @@ public Attribute() { this(""); } - /** - * Checks if is nominal. - * - * @return true, if is nominal - */ - public boolean isNominal() { - return this.isNominal; - } - - /** - * Name. - * - * @return the string - */ - public String name() { - return this.name; - } - - /** - * Value. - * - * @param value the value - * @return the string - */ - public String value(int value) { - return attributeValues.get(value); - } - - /** - * Checks if is numeric. - * - * @return true, if is numeric - */ - public boolean isNumeric() { - return isNumeric; - } - - /** - * Num values. - * - * @return the int - */ - public int numValues() { - if (isNumeric()) { - return 0; - } else { - return attributeValues.size(); - } - } + /** + * Instantiates a new attribute. + * + * @param string the string + */ + public Attribute(String string) { + this.name = string; + this.isNumeric = true; + } + + /** + * Instantiates a new attribute. + * + * @param attributeName the attribute name + * @param attributeValues the attribute values + */ + public Attribute(String attributeName, List attributeValues) { + this.name = attributeName; + this.attributeValues = attributeValues; + this.isNominal = true; + } + + /** + * Instantiates a new attribute. + * + * @param attributeName the attribute name + * @param dateFormat the format of the date used + */ + public Attribute(String attributeName, String dateFormat) { + this.name = attributeName; + this.index = -1; + this.valuesStringAttribute = null; + this.isDate = true; + + if (dateFormat != null) { + m_DateFormat = new SimpleDateFormat(dateFormat); + } else { + m_DateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + } + } + + /** + * Instantiates a new attribute. + * + * @param attributeName the attribute name + * @param attributeValues the attribute values + * @param attributeStructure the attribute structure + */ + public Attribute(String attributeName, List attributeValues, AttributeStructure attributeStructure) { + this.name = attributeName; + this.attributeValues = attributeValues; + this.attributeStructure = attributeStructure; + this.isHierarchical = true; + } + /** + * Instantiates a new attribute. + */ + public Attribute() { + this(""); + } + + /** + * Checks if is nominal. + * + * @return true, if is nominal + */ + public boolean isNominal() { + return this.isNominal; + } /** * Index. * * @return the int */ -// public int index() { //RuleClassifier -// return this.index; -// } - - /** - * Format date. - * - * @param value the value - * @return the string - */ - String formatDate(double value) { - return this.m_DateFormat.format(new Date((long) value)); - } - - /** - * Checks if is date. - * - * @return true, if is date - */ - boolean isDate() { - return isDate; + public int index() { //RuleClassifier + return this.index; } - /** - * The values string attribute. - */ - private Map valuesStringAttribute; - - /** - * Index of value. - * - * @param value the value - * @return the int - */ - public final int indexOfValue(String value) { - - if (isNominal() == false) { - return -1; - } - if (this.valuesStringAttribute == null) { - this.valuesStringAttribute = new HashMap(); - int count = 0; - for (String stringValue : attributeValues) { - this.valuesStringAttribute.put(stringValue, count); - count++; - } - } - Integer val = (Integer) this.valuesStringAttribute.get(value); - if (val == null) { - return -1; - } else { - return val.intValue(); - } - } - - /** - * Returns a description of this attribute in ARFF format. Quotes - * strings if they contain whitespace characters, or if they - * are a question mark. - * - * @return a description of this attribute as a string - */ - public final String toString() { - - StringBuffer text = new StringBuffer(); - - text.append(ARFF_ATTRIBUTE).append(" ").append(Utils.quote(this.name())).append(" "); - - if (this.isNominal){ - text.append('{'); - Enumeration enu = enumerateValues(); - while (enu.hasMoreElements()) { - text.append(Utils.quote((String) enu.nextElement())); - if (enu.hasMoreElements()) - text.append(','); - } - text.append('}'); - } else if (this.isNumeric){ - text.append(ARFF_ATTRIBUTE_NUMERIC); - } else if (this.isDate){ - text.append(ARFF_ATTRIBUTE_DATE).append(" ").append(Utils.quote(m_DateFormat.toPattern())); - } else{ - text.append("UNKNOW"); - } - - return text.toString(); - } - - /** - * Returns an enumeration of all the attribute's values if the - * attribute is nominal, null otherwise. - * - * @return enumeration of all the attribute's values - */ - public final /*@ pure @*/ Enumeration enumerateValues() { - - if (this.isNominal()) { - return Collections.enumeration(this.attributeValues); - } - return null; - } + /** + * Value. + * + * @param value the value + * @return the string + */ + public String value(int value) { + return attributeValues.get(value); + } + + /** + * Checks if is numeric. + * + * @return true, if is numeric + */ + public boolean isNumeric() { + return isNumeric; + } + + /** + * Num values. + * + * @return the int + */ + public int numValues() { + if (isNumeric()) { + return 0; + } else { + return attributeValues.size(); + } + } + + /** + * Checks if is hierarchical. + * + * @return true, if is hierarchical + */ + public boolean isHierarchical() { + return this.isHierarchical; + } + + + /** + * Index. + * + * @return the int + */ + public int index() { //RuleClassifier + return this.index; + } + + /** + * Format date. + * + * @param value the value + * @return the string + */ + String formatDate(double value) { + return this.m_DateFormat.format(new Date((long) value)); + } + + /** + * Checks if is date. + * + * @return true, if is date + */ + boolean isDate() { + return isDate; + } + + /** + * The values string attribute. + */ + private Map valuesStringAttribute; + + /** + * Index of value. + * + * @param value the value + * @return the int + */ + public final int indexOfValue(String value) { + + if (!isNominal()) { + return -1; + } + // TODO check how this affects hierarchies + if (this.valuesStringAttribute == null) { + this.valuesStringAttribute = new HashMap(); + int count = 0; + for (String stringValue : attributeValues) { + this.valuesStringAttribute.put(stringValue, count); + count++; + } + } + Integer val = (Integer) this.valuesStringAttribute.get(value); + if (val == null) { + return -1; + } else { + return val.intValue(); + } + } + + /** + * Returns a description of this attribute in ARFF format. Quotes + * strings if they contain whitespace characters, or if they + * are a question mark. + * + * @return a description of this attribute as a string + */ + public final String toString() { + + StringBuffer text = new StringBuffer(); + + text.append(ARFF_ATTRIBUTE).append(" ").append(Utils.quote(this.name())).append(" "); + + if (this.isNominal){ + text.append('{'); + Enumeration enu = enumerateValues(); + while (enu.hasMoreElements()) { + text.append(Utils.quote((String) enu.nextElement())); + if (enu.hasMoreElements()) + text.append(','); + } + text.append('}'); + } else if (this.isNumeric){ + text.append(ARFF_ATTRIBUTE_NUMERIC); + } else if (this.isDate){ + text.append(ARFF_ATTRIBUTE_DATE).append(" ").append(Utils.quote(m_DateFormat.toPattern())); + } else if (this.isHierarchical) { + text.append(ARFF_ATTRIBUTE_HIERARCHICAL).append(" "); + + text.append("{"); + // TODO output hierarchy + text.append("}"); + + } else { + text.append("UNKNOW"); + } + + return text.toString(); + } + + /** + * Returns an enumeration of all the attribute's values if the + * attribute is nominal, null otherwise. + * + * @return enumeration of all the attribute's values + */ + public final /*@ pure @*/ Enumeration enumerateValues() { + + if (this.isNominal()) { + return Collections.enumeration(this.attributeValues); + } + return null; + } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributeStructure.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributeStructure.java new file mode 100644 index 000000000..afcd53e38 --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributeStructure.java @@ -0,0 +1,7 @@ +package com.yahoo.labs.samoa.instances; + +import java.io.Serializable; + +public interface AttributeStructure extends Serializable { + +} diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/DAGStructure.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/DAGStructure.java new file mode 100644 index 000000000..b26cd433c --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/DAGStructure.java @@ -0,0 +1,86 @@ +package com.yahoo.labs.samoa.instances; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DAGStructure implements AttributeStructure { + public Node root; + + public Map nodes; + + public int type; + + public static int HIERARCHY_TYPE = 0; + public static int DAG_TYPE = 1; + + public DAGStructure() { + this.type = DAGStructure.HIERARCHY_TYPE; + this.nodes = new HashMap(); + this.root = null; + } + + public boolean hasNode(String description) { + return nodes.containsKey(description); + } + + public void addNode(String description) { + nodes.put(description, new Node(description)); + } + + public void addChild(String parent, String child) { + Node p = nodes.get(parent); + Node c = nodes.get(child); + p.addChild(c); + c.addAncestor(p); + if (c.ancestors.size() > 1) { + this.type = DAGStructure.DAG_TYPE; + } + } + + public void setRoot(String description) { + if (this.nodes.containsKey(description)) { + this.root = this.nodes.get(description); + } + } + + public class Node { + public String description; + + public List ancestors; + public List children; + + public Node(String description) { + this.description = description; + this.ancestors = new ArrayList(); + this.children = new ArrayList(); + } + + public void addAncestor(Node ancestor) { + this.ancestors.add(ancestor); + } + + public void addChild(Node child) { + this.ancestors.add(child); + } + + public boolean isRoot() { + // Should only be called when the structure is built + return this.ancestors.isEmpty(); + } + + public double getLevel() { + // Check how this is done when a DAG is used instead of a hierarchy + if (this.isRoot()) return 0; + else { + double total = Integer.MAX_VALUE; + for (Node ancestor : this.ancestors) { + total = total + ancestor.getLevel(); + } + return total / ancestors.size() + 1; + } + } + } + +} diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java new file mode 100644 index 000000000..c9ed7728c --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java @@ -0,0 +1,452 @@ +/* + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package com.yahoo.labs.samoa.instances; + +import moa.AbstractMOAObject; + +/** + * The Class InstanceImpl. + * + * @author abifet + */ +public class HierarhicalInstanceImpl implements StructuredInstance { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * The weight. + */ + protected double weight; + + /** + * The instance data. + */ + protected InstanceData instanceData; + + /** + * The instance information. + */ + protected InstancesHeader instanceHeader; + + /** + * Instantiates a new instance. + * + * @param inst the inst + */ + public HierarhicalInstanceImpl(HierarhicalInstanceImpl inst) { + this.weight = inst.weight; + this.instanceData = inst.instanceData.copy(); + this.instanceHeader = inst.instanceHeader; + } + + //Dense + /** + * Instantiates a new instance. + * + * @param weight the weight + * @param res the res + */ + public HierarhicalInstanceImpl(double weight, double[] res) { + this.weight = weight; + this.instanceData = new DenseInstanceData(res); + } + + //Sparse + /** + * Instantiates a new instance. + * + * @param weight the weight + * @param attributeValues the attribute values + * @param indexValues the index values + * @param numberAttributes the number attributes + */ + public HierarhicalInstanceImpl(double weight, double[] attributeValues, int[] indexValues, int numberAttributes) { + this.weight = weight; + this.instanceData = new SparseInstanceData(attributeValues, indexValues, numberAttributes); + } + + /** + * Instantiates a new instance. + * + * @param weight the weight + * @param instanceData the instance data + */ + public HierarhicalInstanceImpl(double weight, InstanceData instanceData) { + this.weight = weight; + this.instanceData = instanceData; + } + + /** + * Instantiates a new instance. + * + * @param numAttributes the num attributes + */ + public HierarhicalInstanceImpl(int numAttributes) { + this.instanceData = new DenseInstanceData(new double[numAttributes]); //JD + this.weight = 1; + } + + /** + * Weight. + * + * @return the double + */ + @Override + public double weight() { + return weight; + } + + /** + * Sets the weight. + * + * @param weight the new weight + */ + @Override + public void setWeight(double weight) { + this.weight = weight; + } + + /** + * Attribute. + * + * @param instAttIndex the inst att index + * @return the attribute + */ + @Override + public Attribute attribute(int instAttIndex) { + return this.instanceHeader.attribute(instAttIndex); + } + + /** + * Delete attribute at. + * + * @param i the i + */ + @Override + public void deleteAttributeAt(int i) { + //throw new UnsupportedOperationException("Not yet implemented"); + this.instanceData.deleteAttributeAt(i); + } + + /** + * Insert attribute at. + * + * @param i the i + */ + @Override + public void insertAttributeAt(int i) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * Num attributes. + * + * @return the int + */ + @Override + public int numAttributes() { + return this.instanceData.numAttributes(); + } + + /** + * Value. + * + * @param instAttIndex the inst att index + * @return the double + */ + @Override + public double value(int instAttIndex) { + return this.instanceData.value(instAttIndex); + } + + /** + * Checks if is missing. + * + * @param instAttIndex the inst att index + * @return true, if is missing + */ + @Override + public boolean isMissing(int instAttIndex) { + return this.instanceData.isMissing(instAttIndex); + } + + /** + * Num values. + * + * @return the int + */ + @Override + public int numValues() { + return this.instanceData.numValues(); + } + + /** + * Index. + * + * @param i the i + * @return the int + */ + @Override + public int index(int i) { + return this.instanceData.index(i); + } + + /** + * Value sparse. + * + * @param i the i + * @return the double + */ + @Override + public double valueSparse(int i) { + return this.instanceData.valueSparse(i); + } + + /** + * Checks if is missing sparse. + * + * @param p the p + * @return true, if is missing sparse + */ + @Override + public boolean isMissingSparse(int p) { + return this.instanceData.isMissingSparse(p); + } + + /** + * Value. + * + * @param attribute the attribute + * @return the double + */ + @Override + public double value(Attribute attribute) { + return value(attribute.index()); + + } + + /** + * String value. + * + * @param i the i + * @return the string + */ + @Override + public String stringValue(int i) { + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * To double array. + * + * @return the double[] + */ + @Override + public double[] toDoubleArray() { + return this.instanceData.toDoubleArray(); + } + + /** + * Sets the value. + * + * @param numAttribute the num attribute + * @param d the d + */ + @Override + public void setValue(int numAttribute, double d) { + this.instanceData.setValue(numAttribute, d); + } + + /** + * Class value. + * + * @return the double + */ + @Override + public double classValue() { + return this.instanceData.value(classIndex()); + } + + /** + * Class index. + * + * @return the int + */ + @Override + public int classIndex() { + int classIndex = instanceHeader.classIndex(); + return classIndex != Integer.MAX_VALUE ? classIndex : 0; + } + + /** + * Num classes. + * + * @return the int + */ + @Override + public int numClasses() { + return this.instanceHeader.numClasses(); + } + + /** + * Class is missing. + * + * @return true, if successful + */ + @Override + public boolean classIsMissing() { + return this.instanceData.isMissing(classIndex()); + } + + /** + * Class attribute. + * + * @return the attribute + */ + @Override + public Attribute classAttribute() { + return this.instanceHeader.attribute(classIndex()); + } + + /** + * Sets the class value. + * + * @param d the new class value + */ + @Override + public void setClassValue(double d) { + this.setValue(classIndex(), d); + } + + /** + * Copy. + * + * @return the instance + */ + @Override + public Instance copy() { + HierarhicalInstanceImpl inst = new HierarhicalInstanceImpl(this); + return inst; + } + + /** + * Dataset. + * + * @return the instances + */ + @Override + public Instances dataset() { + return this.instanceHeader; + } + + /** + * Sets the dataset. + * + * @param dataset the new dataset + */ + @Override + public void setDataset(Instances dataset) { + this.instanceHeader = new InstancesHeader(dataset); + } + + /** + * Adds the sparse values. + * + * @param indexValues the index values + * @param attributeValues the attribute values + * @param numberAttributes the number attributes + */ + @Override + public void addSparseValues(int[] indexValues, double[] attributeValues, int numberAttributes) { + this.instanceData = new SparseInstanceData(attributeValues, indexValues, numberAttributes); //??? + } + + /** + * Text representation of a InstanceImpl. + */ + @Override + public String toString() { + double[] aux = this.instanceData.toDoubleArray(); + StringBuilder str = new StringBuilder(); + for (int i = 0; i < aux.length; i++) { + str.append(aux[i]).append(" "); + } + + return str.toString(); + } + + @Override + public int numInputAttributes() { + return this.instanceHeader.numInputAttributes(); + } + + @Override + public int numOutputAttributes() { + return numberOutputTargets(); + } + + @Override + public int numberOutputTargets() { + return this.instanceHeader.numOutputAttributes(); + } + + @Override + public double classValue(int instAttIndex) { + return valueOutputAttribute(instAttIndex); + } + + @Override + public void setClassValue(int indexClass, double valueAttribute) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + this.instanceData.setValue(instanceInformation.outputAttributeIndex(indexClass), valueAttribute); + + } + + @Override + public Attribute outputAttribute(int outputIndex) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + return instanceInformation.outputAttribute(outputIndex); + } + + @Override + public Attribute inputAttribute(int attributeIndex) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + return instanceInformation.inputAttribute(attributeIndex); + } + + @Override + public double valueInputAttribute(int attributeIndex) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + return this.instanceData.value(instanceInformation.inputAttributeIndex(attributeIndex)); + } + + @Override + public double valueOutputAttribute(int attributeIndex) { + InstanceInformation instanceInformation = this.instanceHeader.getInstanceInformation(); + return this.instanceData.value(instanceInformation.outputAttributeIndex(attributeIndex)); + } + + public int structureType() { + return Instance.STRUCTURE_TYPE_HIERARHICAL; + } + + public AttributeStructure getStructure() { + return this.instanceHeader.getInstanceStructure(); + } +} \ No newline at end of file diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java index 928ad4c5a..e85621700 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java @@ -17,6 +17,8 @@ import java.io.Serializable; +import moa.AbstractMOAObject; + /** * The Interface Instance. * @@ -24,6 +26,11 @@ */ public interface Instance extends Serializable { + public static int STRUCTURE_TYPE_SINGLE_TARGET = 0; + public static int STRUCTURE_TYPE_MULTI_TARGET = 1; + public static int STRUCTURE_TYPE_TIME_SERIES = 2; + public static int STRUCTURE_TYPE_HIERARHICAL = 3; + /** * Gets the weight of the instance. * @@ -327,5 +334,9 @@ public interface Instance extends Serializable { * @return the value */ public double valueOutputAttribute(int attributeIndex); + + public int structureType(); + + public AttributeStructure getStructure(); } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java index 59c88d5b8..6cfb34dbd 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java @@ -15,8 +15,6 @@ */ package com.yahoo.labs.samoa.instances; -import java.text.SimpleDateFormat; - /** * The Class InstanceImpl. * @@ -128,10 +126,6 @@ public Attribute attribute(int instAttIndex) { return this.instanceHeader.attribute(instAttIndex); } - public int indexOfAttribute(Attribute attribute){ - return this.instanceHeader.indexOf(attribute); - } - /** * Delete attribute at. * @@ -139,6 +133,7 @@ public int indexOfAttribute(Attribute attribute){ */ @Override public void deleteAttributeAt(int i) { + //throw new UnsupportedOperationException("Not yet implemented"); this.instanceData.deleteAttributeAt(i); } @@ -235,8 +230,8 @@ public boolean isMissingSparse(int p) { */ @Override public double value(Attribute attribute) { - int index = this.instanceHeader.indexOf(attribute); - return value(index); + return value(attribute.index()); + } /** @@ -409,7 +404,7 @@ public int numInputAttributes() { public int numOutputAttributes() { return numberOutputTargets(); } - + @Override public int numberOutputTargets() { return this.instanceHeader.numOutputAttributes(); @@ -461,16 +456,12 @@ public void setMissing(Attribute attribute) { int index = this.instanceHeader.indexOf(attribute); this.setMissing(index); } - - @Override - public boolean isMissing(Attribute attribute) { - int index = this.instanceHeader.indexOf(attribute); - return this.isMissing(index); + + public int structureType() { + return (numOutputAttributes() > 1) ? Instance.STRUCTURE_TYPE_MULTI_TARGET : Instance.STRUCTURE_TYPE_SINGLE_TARGET; } - - @Override - public void setValue(Attribute attribute, double value) { - int index = this.instanceHeader.indexOf(attribute); - this.setValue(index, value); + + public AttributeStructure getStructure() { + return null; } -} +} \ No newline at end of file diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java index dd59d6f27..7a8aae816 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java @@ -18,6 +18,8 @@ import java.io.Serializable; import java.util.List; +import moa.AbstractMOAObject; + /** * The Class InstanceInformation. * @@ -31,6 +33,8 @@ public class InstanceInformation implements Serializable { protected String relationName; protected AttributesInformation attributesInformation; + + protected AttributeStructure structure = null; /** * The class index. @@ -58,6 +62,7 @@ public Attribute outputAttribute(int w) { public InstanceInformation(InstanceInformation chunk) { this.relationName = chunk.relationName; this.attributesInformation = chunk.attributesInformation; + this.structure = chunk.structure; this.classIndex = chunk.classIndex; } @@ -212,5 +217,9 @@ public void setAttributes(List v, List indexValues) { this.attributesInformation.setAttributes(v,indexValues); } + + public AttributeStructure getStructure() { + return this.structure; + } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java index e4088a237..6086fa888 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java @@ -123,4 +123,8 @@ public int numOutputAttributes() { public InstanceInformation getInstanceInformation() { return this.instanceInformation; } + + public AttributeStructure getInstanceStructure() { + return this.instanceInformation.getStructure(); + } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelInstance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java similarity index 87% rename from moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelInstance.java rename to moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java index 0978bd332..279d6baed 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelInstance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java @@ -16,12 +16,12 @@ package com.yahoo.labs.samoa.instances; /** - * The Interface MultiLabelInstance. + * The Interface StructuredInstance. * * @author abifet */ -public interface MultiLabelInstance extends Instance { +public interface StructuredInstance extends Instance { } \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/AbstractClassifier.java b/moa/src/main/java/moa/classifiers/AbstractClassifier.java index 9511a24f6..ee1c01c47 100644 --- a/moa/src/main/java/moa/classifiers/AbstractClassifier.java +++ b/moa/src/main/java/moa/classifiers/AbstractClassifier.java @@ -85,14 +85,15 @@ public AbstractClassifier() { } @Override - public void prepareForUseImpl(TaskMonitor monitor, - ObjectRepository repository) { + public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { if (this.randomSeedOption != null) { this.randomSeed = this.randomSeedOption.getValue(); } - if (!trainingHasStarted()) { - resetLearning(); - } + + // resetLearning should not be called if the classifier has not yet received the context +// if (!trainingHasStarted()) { +// resetLearning(); +// } } diff --git a/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java b/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java index 641228cf0..3fefdd9ce 100644 --- a/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java @@ -2,7 +2,7 @@ import moa.core.Example; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; public abstract class AbstractMultiLabelLearner extends AbstractClassifier implements MultiLabelLearner { @@ -13,11 +13,11 @@ public abstract class AbstractMultiLabelLearner extends AbstractClassifier imple private static final long serialVersionUID = 1L; @Override - abstract public void trainOnInstanceImpl(MultiLabelInstance instance); + abstract public void trainOnInstanceImpl(StructuredInstance instance); @Override public void trainOnInstanceImpl(Instance instance) { - trainOnInstanceImpl((MultiLabelInstance) instance); + trainOnInstanceImpl((StructuredInstance) instance); } @Override @@ -27,10 +27,10 @@ public Prediction getPredictionForInstance(Example example) { @Override public Prediction getPredictionForInstance(Instance inst) { - return getPredictionForInstance((MultiLabelInstance) inst); + return getPredictionForInstance((StructuredInstance) inst); } - abstract public Prediction getPredictionForInstance(MultiLabelInstance inst); + abstract public Prediction getPredictionForInstance(StructuredInstance inst); @Override public double[] getVotesForInstance(Instance inst) { diff --git a/moa/src/main/java/moa/classifiers/MultiLabelLearner.java b/moa/src/main/java/moa/classifiers/MultiLabelLearner.java index b42a37085..ee875ee60 100644 --- a/moa/src/main/java/moa/classifiers/MultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/MultiLabelLearner.java @@ -1,12 +1,12 @@ package moa.classifiers; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; public interface MultiLabelLearner extends Classifier{ - public void trainOnInstanceImpl(MultiLabelInstance instance); + public void trainOnInstanceImpl(StructuredInstance instance); - public Prediction getPredictionForInstance(MultiLabelInstance instance); + public Prediction getPredictionForInstance(StructuredInstance instance); } diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBag.java b/moa/src/main/java/moa/classifiers/meta/OzaBag.java index d7c935590..9ca3dd639 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBag.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBag.java @@ -70,9 +70,9 @@ public String getPurposeString() { public void resetLearningImpl() { this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); - baseLearner.resetLearning(); for (int i = 0; i < this.ensemble.length; i++) { this.ensemble[i] = baseLearner.copy(); + } } diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index c23396899..4c78071f9 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -1,15 +1,13 @@ package moa.classifiers.multilabel; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; -import java.util.Vector; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -36,7 +34,6 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner @Override public boolean isRandomizable() { - // TODO Auto-generated method stub return true; } @@ -51,8 +48,8 @@ private void makeHeaders() { if (headers == null) { headers = new ArrayList(); for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { - List attributes = new LinkedList(); - List indexValues = new LinkedList(); + List attributes = new ArrayList(); + List indexValues = new ArrayList(); for (int i = 0; i < getModelContext().numInputAttributes(); i++) { attributes.add(getModelContext().inputAttribute(i)); indexValues.add(i); @@ -67,7 +64,7 @@ private void makeHeaders() { } } - private Instance getSTInstance(MultiLabelInstance inst, int target) { + private Instance getSTInstance(StructuredInstance inst, int target) { double[] instanceData = new double[getModelContext().numInputAttributes() + 1]; for (int i = 0; i < inst.numInputAttributes(); i++) instanceData[i] = inst.valueInputAttribute(i); @@ -78,8 +75,7 @@ private Instance getSTInstance(MultiLabelInstance inst, int target) { } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { - // TODO Auto-generated method stub + public void trainOnInstanceImpl(StructuredInstance instance) { initializeClassifiers(); for (int j = 0; j < instance.numberOutputTargets(); j++) { @@ -90,7 +86,7 @@ public void trainOnInstanceImpl(MultiLabelInstance instance) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance inst) { + public Prediction getPredictionForInstance(StructuredInstance inst) { initializeClassifiers(); MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); diff --git a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java index 7691b603f..8d5aed722 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java @@ -1,7 +1,7 @@ /* * MEKAClassifier.java * Copyright (C) 2012 University of Waikato, Hamilton, New Zealand - * @author Jesse Read + * @author Jesse Read (jesse@tsc.uc3m.es) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; @@ -111,6 +111,9 @@ public void trainOnInstanceImpl(MultiLabelInstance samoaInstance) { //System.exit(1); } this.isClassificationEnabled = true; + } else { + System.err.println("Only suports UpdateableClassifiers for now."); + System.exit(1); } else { /* @@ -130,10 +133,30 @@ public void trainOnInstanceImpl(MultiLabelInstance samoaInstance) { @Override public double[] getVotesForInstance(Instance samoaInstance) { + + @Override + public void trainOnInstanceImpl(MultiLabelInstance samoaInstance) { weka.core.Instance inst = this.instanceConverter.wekaInstance(samoaInstance); + //System.out.println(""+m_L); // <-- this is correct + //System.out.println(""+inst.classIndex()); // <--- this one is wrong + inst.dataset().setClassIndex(m_L); // <-- so, fix it! double votes[] = new double[L]; + //System.out.println(inst.classIndex()); + try { + //System.out.println("UPDATE WITH instances of "+instancesBuffer.classIndex()+" labels :\n"+inst); + ((UpdateableClassifier) classifier).updateClassifier(inst); + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + + @Override + public double[] getVotesForInstance(Instance samoaInstance) { + weka.core.Instance inst = this.instanceConverter.wekaInstance(samoaInstance); + double votes[] = null; try { votes = this.classifier.distributionForInstance(inst); } catch(Exception e) { @@ -141,7 +164,6 @@ public double[] getVotesForInstance(Instance samoaInstance) { //e.printStackTrace(); //System.exit(1); } - return votes; } diff --git a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java index 8810b36ab..23cea6b0b 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java @@ -24,7 +24,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.Measurement; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import moa.classifiers.AbstractMultiLabelLearner; @@ -60,7 +60,7 @@ public void resetLearningImpl() { } @Override - public void trainOnInstanceImpl(MultiLabelInstance x) { + public void trainOnInstanceImpl(StructuredInstance x) { int L = x.numberOutputTargets(); MultiLabelPrediction y = new MultiLabelPrediction(L); @@ -80,7 +80,16 @@ public void trainOnInstanceImpl(MultiLabelInstance x) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance x){ + //public double[] getVotesForInstance(Instance x) { + public Prediction getPredictionForInstance(StructuredInstance x){ + + System.out.println("-------- start MC vote ---------------"); + int L = x.numOutputAttributes(); //x.classIndex() + 1; + if (m_L != L) { + System.err.println("set L = " + L); + m_L = L; + predictionArray = new double[m_L]; + } if (this.majorityLabelset == null) { int L = x.numberOutputTargets(); diff --git a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java index 544e6f0d5..08a7141ac 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java @@ -30,7 +30,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import java.util.LinkedList; @@ -149,9 +149,11 @@ public void learnFromInstance(Instance inst, HoeffdingTree ht) { } for (int l : labels){ obs.observeAttributeClass(inst.valueInputAttribute(i), l, inst.weight()); + //obs.observeAttributeClass(inst.value(instAttIndex), 0, inst.weight()); } } } + } public void describeSubtree(HoeffdingTree ht, StringBuilder out, int indent) { @@ -182,11 +184,11 @@ protected void deactivateLearningNode(ActiveLearningNode toDeactivate, @Override public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance((MultiLabelInstance)example.getData()); + return getPredictionForInstance((StructuredInstance)example.getData()); } @Override - public Prediction getPredictionForInstance(MultiLabelInstance inst){ + public Prediction getPredictionForInstance(StructuredInstance inst){ if (this.treeRoot != null) { FoundNode foundNode = this.treeRoot.filterInstanceToLeaf(inst, null, -1); @@ -215,7 +217,7 @@ public void trainOnInstance(Instance inst) { } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { trainOnInstanceImpl((Instance) instance); } @@ -229,5 +231,4 @@ public static List getRelevantLabels(Instance x) { } return classValues; } - } diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java index 176f3dfd0..24f9839b0 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/ICVarianceReduction.java @@ -1,6 +1,5 @@ package moa.classifiers.multilabel.core.splitcriteria; -import moa.classifiers.rules.core.Utils; import moa.core.DoubleVector; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/WeightedICVarianceReduction.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/WeightedICVarianceReduction.java new file mode 100644 index 000000000..9d5d181ea --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/WeightedICVarianceReduction.java @@ -0,0 +1,46 @@ +package moa.classifiers.multilabel.core.splitcriteria; + +import moa.core.DoubleVector; +import moa.core.ObjectRepository; +import moa.tasks.TaskMonitor; + +/** + * Weighted intra cluster variance reduction split criterion + * @author Aljaž Osojnik + * + */ + +public class WeightedICVarianceReduction extends ICVarianceReduction { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public DoubleVector weights; + + public WeightedICVarianceReduction(DoubleVector targetWeights) { + super(); + this.weights = targetWeights; + } + + @Override + public double getMeritOfSplit(DoubleVector[] preSplitDist, DoubleVector[][] postSplitDists) { + double error=0; + int numOutputs=preSplitDist.length; + for (int i=0; i. + * + */ +package moa.classifiers.multilabel.meta; + +import moa.classifiers.Classifier; +import moa.classifiers.meta.OzaBag; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.StructuredInstance; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +import com.yahoo.labs.samoa.instances.Prediction; +import moa.classifiers.MultiLabelLearner; +import moa.classifiers.MultiTargetRegressor; +import moa.core.Example; + +/** + * OzaBag for Multi-label data. + * + * @author Jesse Read (jesse@tsc.uc3m.es) + * @version $Revision: 1 $ + */ +public class MLOzaBag extends OzaBag implements MultiLabelLearner, MultiTargetRegressor{ + + protected int m_L = -1; + + //protected Random random = null; + + /* + * @Override public void resetLearningImpl() { super.resetLearningImpl(); + * //this.random = new Random(randomSeedOption.getValue()); } + */ + @Override + public void resetLearningImpl() { + this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; + Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); + baseLearner.resetLearning(); + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i] = baseLearner.copy(); + } + } + + @Override + public void setModelContext(InstancesHeader raw_header) { + + //set the multilabel model context + this.modelContext = raw_header; + + m_L = raw_header.classIndex() + 1; + + // reset ensemble + this.resetLearningImpl(); + + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i].setModelContext(raw_header); + this.ensemble[i].resetLearning(); + } + } + + @Override // @note don't need this here + public boolean isRandomizable() { + return true; + } + + @Override + public double[] getVotesForInstance(Instance x) { + + int L = x.classIndex() + 1; + if (m_L != L) { + m_L = L; + } + + double y[] = new double[m_L]; + + for (int i = 0; i < this.ensemble.length; i++) { + double w[] = this.ensemble[i].getVotesForInstance(x); + for (int j = 0; j < w.length; j++) { + y[j] += w[j]; + } + } + + return y; + } + + @Override + public void trainOnInstanceImpl(StructuredInstance instance) { + trainOnInstanceImpl((Instance) instance); + } + + @Override + public Prediction getPredictionForInstance(Example example) { + return getPredictionForInstance((StructuredInstance)example.getData()); + } + + @Override + public Prediction getPredictionForInstance(StructuredInstance instance) { + + double[] predictionArray = this.getVotesForInstance(instance); + + //System.out.println("y = "+Arrays.toString(predictionArray)); + + Prediction prediction = new MultiLabelPrediction(predictionArray.length); + for (int j = 0; j < predictionArray.length; j++){ + prediction.setVote(j, 1, predictionArray[j]); + //prediction.setVote(j, 0, 1. - predictionArray[j]); + } + return prediction; + } + +} diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MLOzaBagAdwin.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MLOzaBagAdwin.java new file mode 100644 index 000000000..65e25b533 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MLOzaBagAdwin.java @@ -0,0 +1,182 @@ +/* + * MLOzaBagAdwin.java + * Copyright (C) 2012 University of Waikato, Hamilton, New Zealand + * @author Jesse Read (jesse@tsc.uc3m.es) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.classifiers.multilabel.meta; + +import moa.classifiers.Classifier; +import moa.classifiers.core.driftdetection.ADWIN; +import moa.classifiers.meta.OzaBagAdwin; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.MiscUtils; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.StructuredInstance; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +import com.yahoo.labs.samoa.instances.Prediction; +import moa.classifiers.MultiLabelLearner; +import moa.classifiers.MultiTargetRegressor; +import moa.core.Example; + +/** + * MLOzaBagAdwin: Changes the way to compute accuracy as an input for Adwin + * + * @author Jesse Read (jesse@tsc.uc3m.es) + * @version $Revision: 1 $ + */ +public class MLOzaBagAdwin extends OzaBagAdwin implements MultiLabelLearner, MultiTargetRegressor { + + protected int m_L = -1; + + @Override + public void setModelContext(InstancesHeader raw_header) { + + //set the multilabel model context + this.modelContext = raw_header; + m_L = raw_header.classIndex() + 1; + + // reset ensemble + this.resetLearningImpl(); + + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i].setModelContext(raw_header); + this.ensemble[i].resetLearning(); + } + } + + @Override + public void trainOnInstanceImpl(Instance inst) { + + boolean Change = false; + for (int i = 0; i < this.ensemble.length; i++) { + int k = MiscUtils.poisson(1.0, this.classifierRandom); + if (k > 0) { + Instance weightedInst = (Instance) inst.copy(); + weightedInst.setWeight(inst.weight() * k); + this.ensemble[i].trainOnInstance(weightedInst); + } + double[] prediction = this.ensemble[i].getVotesForInstance(inst); + //Compute accuracy + double actual[] = new double[prediction.length]; + for (short j = 0; j < prediction.length; j++) { + actual[j] = inst.value(j); + } + // calculate + int p_sum = 0, r_sum = 0; + int set_union = 0; + int set_inter = 0; + double t = 0.01; + for (int j = 0; j < prediction.length; j++) { + int p = (prediction[j] >= t) ? 1 : 0; + int R = (int) actual[j]; + if (p == 1) { + p_sum++; + // predt 1, real 1 + if (R == 1) { + set_inter++; + set_union++; + } // predt 1, real 0 + else { + set_union++; + } + } else { + // predt 0, real 1 + if (R == 1) { + set_union++; + } // predt 0, real 0 + else { + } + } + } + double accuracy = 0.0; + if (set_union > 0) //avoid NaN + { + accuracy = ((double) set_inter / (double) set_union); + } + double ErrEstim = this.ADError[i].getEstimation(); + if (this.ADError[i].setInput(1.0 - accuracy)) { + if (this.ADError[i].getEstimation() > ErrEstim) { + Change = true; + } + } + } + if (Change) { + System.err.println("change!"); + double max = 0.0; + int imax = -1; + for (int i = 0; i < this.ensemble.length; i++) { + if (max < this.ADError[i].getEstimation()) { + max = this.ADError[i].getEstimation(); + imax = i; + } + } + if (imax != -1) { + + this.ensemble[imax] = null; + this.ensemble[imax] = (Classifier) getPreparedClassOption(this.baseLearnerOption); + this.ensemble[imax].setModelContext(this.modelContext); + this.ensemble[imax].trainOnInstance(inst); + this.ADError[imax] = new ADWIN(); + } + } + } + + @Override + public double[] getVotesForInstance(Instance x) { + + int L = x.classIndex() + 1; + if (m_L != L) { + m_L = L; + } + + double y[] = new double[m_L]; + + for (int i = 0; i < this.ensemble.length; i++) { + double w[] = this.ensemble[i].getVotesForInstance(x); + for (int j = 0; j < w.length; j++) { + y[j] += w[j]; + } + } + + return y; + } + + @Override + public void trainOnInstanceImpl(StructuredInstance instance) { + trainOnInstanceImpl((Instance) instance); + } + + @Override + public Prediction getPredictionForInstance(Example example) { + return getPredictionForInstance((StructuredInstance) example.getData()); + } + + @Override + public Prediction getPredictionForInstance(StructuredInstance instance) { + + double[] predictionArray = this.getVotesForInstance(instance); + + //System.out.println("y = "+Arrays.toString(predictionArray)); + Prediction prediction = new MultiLabelPrediction(predictionArray.length); + for (int j = 0; j < predictionArray.length; j++) { + prediction.setVote(j, 1, predictionArray[j]); + //prediction.setVote(j, 0, 1. - predictionArray[j]); + } + return prediction; + } + +} diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java index 2594f61be..b4675887f 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/MTOzaBag.java @@ -21,7 +21,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -41,7 +41,12 @@ */ public class MTOzaBag extends OzaBag implements MultiLabelLearner, MultiTargetRegressor { - public MTOzaBag() { + /** + * + */ + private static final long serialVersionUID = 1L; + + public MTOzaBag() { super(); this.baseLearnerOption = new ClassOption("baseLearner", 'l', "Classifier to train.", MultiLabelLearner.class, "multilabel.trees.ISOUPTree"); @@ -51,23 +56,9 @@ public MTOzaBag() { public void resetLearningImpl() { this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; MultiLabelLearner baseLearner = (MultiLabelLearner) getPreparedClassOption(this.baseLearnerOption); - baseLearner.resetLearning(); + baseLearner.setModelContext(this.modelContext); for (int i = 0; i < this.ensemble.length; i++) { this.ensemble[i] = baseLearner.copy(); - } - } - - @Override - public void setModelContext(InstancesHeader raw_header) { - - //set the multilabel model context - this.modelContext = raw_header; - - // reset ensemble - this.resetLearningImpl(); - - for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i].setModelContext(raw_header); this.ensemble[i].resetLearning(); } } @@ -77,14 +68,15 @@ public boolean isRandomizable() { return true; } - public Prediction getPredictionForInstance(MultiLabelInstance inst) { - DoubleVector[][] predictions = new DoubleVector[this.ensemble.length][getModelContext().numOutputAttributes()]; + public Prediction getPredictionForInstance(StructuredInstance inst) { + int numTargets = getModelContext().numOutputAttributes(); + DoubleVector[][] predictions = new DoubleVector[this.ensemble.length][numTargets]; for (int i = 0; i < this.ensemble.length; i++) { Prediction basePrediction = this.ensemble[i].getPredictionForInstance(inst); predictions[i] = ((MultiLabelPrediction) basePrediction).getPrediction(); } - DoubleVector[] prediction = new DoubleVector[getModelContext().numOutputAttributes()]; - for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + DoubleVector[] prediction = new DoubleVector[numTargets]; + for (int j = 0; j < numTargets; j++) { prediction[j] = new DoubleVector(); for (int i = 0; i < this.ensemble.length; i++) { prediction[j].addValues(predictions[i][j]); @@ -94,7 +86,7 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { return new MultiLabelPrediction(prediction); } - public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) { + public Prediction getPredictionForInstanceUsingN(StructuredInstance inst, int n) { int actual = Math.max(1, Math.min(n, this.ensemble.length)); DoubleVector[][] predictions = new DoubleVector[actual][getModelContext().numOutputAttributes()]; for (int i = 0; i < actual; i++) { @@ -113,13 +105,13 @@ public Prediction getPredictionForInstanceUsingN(MultiLabelInstance inst, int n) } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { trainOnInstanceImpl((Instance) instance); } @Override public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance((MultiLabelInstance)example.getData()); + return getPredictionForInstance((StructuredInstance)example.getData()); } } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java index a0ce07563..da8fdadd3 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPOptionTree.java @@ -1,12 +1,31 @@ package moa.classifiers.multilabel.trees; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Stack; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; + +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; +import moa.classifiers.multilabel.core.splitcriteria.ICVarianceReduction; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.multilabel.core.splitcriteria.WeightedICVarianceReduction; +import moa.classifiers.multilabel.trees.ISOUPTree.LeafNode; +import moa.classifiers.multilabel.trees.ISOUPTree.MultitargetPerceptron; +import moa.classifiers.multilabel.trees.ISOUPTree.Node; +import moa.classifiers.multilabel.trees.ISOUPTree.SplitNode; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; +import moa.classifiers.trees.FIMTDD.InnerNode; +import moa.classifiers.trees.ORTO.OptionNode; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; +import moa.core.StringUtils; public class ISOUPOptionTree extends ISOUPTree { @@ -15,7 +34,7 @@ public class ISOUPOptionTree extends ISOUPTree { private int optionNodeCount = 0; private int numTrees = 1; - + //region ================ OPTIONS ================ public IntOption maxTreesOption = new IntOption( @@ -38,7 +57,7 @@ public class ISOUPOptionTree extends ISOUPTree { public MultiChoiceOption optionNodeAggregationOption = new MultiChoiceOption( "optionNodeAggregation", - 'o', + 'p', "The aggregation method used to combine predictions in option nodes.", new String[]{"average", "bestTree"}, new String[]{"Average", "Best tree"}, 0); @@ -51,16 +70,16 @@ public class ISOUPOptionTree extends ISOUPTree { //endregion ================ OPTIONS ================ //region ================ CLASSES ================ - + public static class OptionNode extends InnerNode { /** * */ private static final long serialVersionUID = 1L; - + protected AutoExpandVector optionFFSSL; protected AutoExpandVector optionFFSeen; - + public OptionNode(ISOUPTree tree) { super(tree); } @@ -77,7 +96,7 @@ public void resetFF() { } } } - + public int getNumSubtrees() { int num = 0; for (Node child : children) { @@ -85,15 +104,15 @@ public int getNumSubtrees() { } return num; } - - public double[] getPrediction(MultiLabelInstance inst) { + + public double[] getPrediction(StructuredInstance inst) { double[][] predictions = new double[numChildren()][tree.getModelContext().numOutputAttributes()]; for (int i = 0; i < numChildren(); i++) { predictions[i] = getChild(i).getPrediction(inst); } return aggregate(predictions); } - + private double[] aggregate(double[][] predictions) { if (((ISOUPOptionTree) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average double[] sums = new double[tree.getModelContext().numOutputAttributes()]; @@ -111,7 +130,7 @@ private double[] aggregate(double[][] predictions) { return new double[] {}; } } - + public int directionForBestTree() { int d = 0; double min = Double.MAX_VALUE; @@ -128,22 +147,34 @@ public int directionForBestTree() { } return d; } - + public double getFFRatio(int childIndex, int targetIndex) { return optionFFSSL.get(childIndex).getValue(targetIndex) / optionFFSeen.get(childIndex).getValue(targetIndex); } - + protected boolean skipInLevelCount() { return true; } + + public void describeSubtree(StringBuilder out, int indent) { + for (int branch = 0; branch < children.size(); branch++) { + Node child = getChild(branch); + if (child != null) { + StringUtils.appendIndented(out, indent, "option"); + out.append(branch); + StringUtils.appendNewline(out); + child.describeSubtree(out, indent + 2); + } + } + } } - + //endregion ================ CLASSES ================ - + //region ================ METHODS ================ - + public String getPurposeString() { - return "Implementation of the ORTO tree as described by Ikonomovska et al."; + return "Implementation of the iSOUPOptionTree"; } public void resetLearningImpl() { @@ -151,7 +182,7 @@ public void resetLearningImpl() { this.optionNodeCount = 0; } - + protected Measurement[] getModelMeasurementsImpl() { return new Measurement[]{ new Measurement("number of subtrees", this.numTrees), @@ -159,9 +190,18 @@ protected Measurement[] getModelMeasurementsImpl() { //new Measurement("tree size (leaves)", this.leafNodeCount), new Measurement("number of option nodes", this.optionNodeCount),}; } - + + // region --- Object instantiation methods + + protected OptionNode newOptionNode() { + maxID++; + return new OptionNode(this); + } + + // endregion --- Object instantiation methods + @Override - public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + public void processInstance(StructuredInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { if (node instanceof OptionNode) { processInstanceOptionNode(inst, (OptionNode) node, prediction, normalError, growthAllowed, inAlternate); } else { @@ -225,7 +265,7 @@ public void processInstance(MultiLabelInstance inst, Node node, double[] predict // break; // } // } - + // if (iNode.changeDetection && !inAlternate) { // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { // iNode.initializeAlternateTree(); @@ -240,18 +280,18 @@ public void processInstance(MultiLabelInstance inst, Node node, double[] predict } } } - + } - - public void processInstanceOptionNode(MultiLabelInstance inst, OptionNode node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { -// if (node.changeDetection) { -// double error = Math.abs(prediction - inst.classValue()); -// node.sumOfAbsErrors += error; -// -// if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { -// node.initializeAlternateTree(); -// } -// } + + public void processInstanceOptionNode(StructuredInstance inst, OptionNode node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + // if (node.changeDetection) { + // double error = Math.abs(prediction - inst.classValue()); + // node.sumOfAbsErrors += error; + // + // if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + // node.initializeAlternateTree(); + // } + // } for (Node child : node.children) { int i = node.getChildIndex(child); @@ -266,7 +306,220 @@ public void processInstanceOptionNode(MultiLabelInstance inst, OptionNode node, processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); } } - + //endregion ================ METHODS ================ + protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) { + //System.out.println("Evaluating splits"); + //System.out.println(examplesSeen); + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + MultiLabelSplitCriterion splitCriterion = new WeightedICVarianceReduction(targetWeights); + + // Using this criterion, find the best split per attribute and rank the results + AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option + List acceptedSplits = new LinkedList(); + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine the number of splits to be performed + int numSplits = 0; + + // If only one split was returned, use it + if (bestSplitSuggestions.length == 1) { + numSplits = 1; + acceptedSplits.add(bestSplitSuggestions[0]); + } else if (bestSplitSuggestions.length > 1) { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + //System.out.print(hoeffdingBound); + //System.out.print(" "); + ///System.out.println(secondBestSuggestion.merit / bestSuggestion.merit); + if (secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) { + numSplits = 1; + acceptedSplits.add(bestSuggestion); + } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { + for (int i = 0; i < bestSplitSuggestions.length; i++) { + AttributeExpansionSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; + if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { + numSplits++; + acceptedSplits.add(suggestion); + } else { + break; + } + } + + } else if (hoeffdingBound < this.tieThresholdOption.getValue()) { + numSplits = 1; + acceptedSplits.add(bestSuggestion); + } + else { + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + // TODO pruning is currently disabled + for (int i = 0; i < node.attributeObservers.size(); i++) { + AttributeStatisticsObserver obs = node.attributeObservers.get(i); + if (obs != null) { + if (getModelContext().attribute(i).isNumeric()); + //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); + if (getModelContext().attribute(i).isNominal()); + // TODO nominal class observers + } + } + } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (numSplits > 0) { + double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); + log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); + + if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { + AttributeExpansionSuggestion splitDecision = acceptedSplits.get(0); + SplitNode newSplit = newSplitNode(splitDecision.getPredicate()); + newSplit.ID = node.ID; + + for (int i = 0; i < 2 /* TODO Hardcoded for Predicate class */; i++) { + LeafNode newChild = newLeafNode(); + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + //leafNodeCount--; + //innerNodeCount++; + //leafNodeCount += splitDecision.numSplits(); + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + parent.setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + } else { + + OptionNode optionNode = newOptionNode(); + optionNode.ID = node.ID; + + //leafNodeCount--; + int j = 0; + + for (AttributeExpansionSuggestion splitDecision : acceptedSplits) { + if (j > optionFactor || maxTreesOption.getValue() - numTrees <= 0) { + break; + } + SplitNode newSplit = newSplitNode(splitDecision.getPredicate()); + for (int i = 0; i < 2 /* TODO Hardcoded for Predicate class */; i++) { + LeafNode newChild = newLeafNode(); + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + + //leafNodeCount += splitDecision.numSplits(); + //innerNodeCount++; + numTrees++; + + newSplit.setParent(optionNode); + optionNode.setChild(j, newSplit); + j++; + } + + //innerNodeCount++; + optionNodeCount++; + + if (parent == null) { + treeRoot = optionNode; + } else { + parent.setChild(parentIndex, optionNode); + optionNode.setParent(parent); + } + + optionNode.resetFF(); + } + } + } + + // region --- Option tree methods + protected Node findWorstOption() { + Stack stack = new Stack(); + stack.add(treeRoot); + + double ratio = Double.MIN_VALUE; + Node out = null; + + while (!stack.empty()) { + Node node = stack.pop(); + if (node.getParent() instanceof OptionNode) { + OptionNode myParent = (OptionNode) node.getParent(); + int nodeIndex = myParent.getChildIndex(node); + DoubleVector nodeRatios = new DoubleVector(); + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + nodeRatios.setValue(i, myParent.getFFRatio(nodeIndex, i)); + } + double nodeRatio = nodeRatios.sumOfValues() / nodeRatios.numValues(); + + if (nodeRatio > ratio) { + ratio = nodeRatio; + out = node; + } + } + if (node instanceof InnerNode) { + for (Node child : ((InnerNode) node).children) { + stack.add(child); + } + } + } + + return out; + } + + protected void removeExcessTrees() { + while (numTrees > maxTreesOption.getValue()) { + Node option = findWorstOption(); + OptionNode parent = (OptionNode) option.parent; + int index = parent.getChildIndex(option); + + if (parent.children.size() == 2) { + parent.children.remove(index); + for (Node chld : parent.children) { + chld.parent = parent.parent; + parent.parent.setChild(parent.parent.getChildIndex(parent), chld); + } + } else { + AutoExpandVector children = new AutoExpandVector(); + AutoExpandVector optionFFSSL = new AutoExpandVector(); + AutoExpandVector optionFFSeen = new AutoExpandVector(); + + int seen = 0; + + for (int i = 0; i < parent.children.size() - 1; i++) { + if (parent.getChild(i) != option) { + children.add(parent.getChild(i)); + optionFFSSL.set(i, parent.optionFFSSL.get(i + seen)); + optionFFSeen.set(i, parent.optionFFSeen.get(i + seen)); + } else { + seen = 1; + } + } + + parent.children = children; + parent.optionFFSSL = optionFFSSL; + parent.optionFFSeen = optionFFSeen; + + assert parent.children.size() == parent.optionFFSSL.size(); + } + numTrees--; + } + } + } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index 4ce0c89b6..db8bf9843 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -29,27 +29,31 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.Vector; +import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import moa.AbstractMOAObject; import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelBSTree; +import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelNominalAttributeObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; +import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; import moa.classifiers.multilabel.core.splitcriteria.ICVarianceReduction; +import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.multilabel.core.splitcriteria.WeightedICVarianceReduction; +import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.Predicate; -import moa.classifiers.rules.multilabel.attributeclassobservers.AttributeStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.MultiLabelBSTree; -import moa.classifiers.rules.multilabel.attributeclassobservers.MultiLabelNominalAttributeObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NominalStatisticsObserver; -import moa.classifiers.rules.multilabel.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.rules.multilabel.core.AttributeExpansionSuggestion; -import moa.classifiers.rules.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; @@ -57,7 +61,7 @@ import moa.core.StringUtils; /** - * iSOUPTrees class for structured output prediction. + * iSOUPTree class for structured output prediction. * * @author Aljaž Osojnik (aljaz.osojnik@ijs.si) * @version $Revision: 1 $ @@ -68,7 +72,7 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR public Node treeRoot; - private double examplesSeen = 0.0; + protected double examplesSeen = 0.0; private DoubleVector sumOfValues = new DoubleVector(); private DoubleVector sumOfSquares = new DoubleVector(); @@ -76,6 +80,8 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR private DoubleVector sumOfAttrSquares = new DoubleVector(); public int maxID = 0; + + public DoubleVector targetWeights; //region ================ OPTIONS ================ @@ -154,6 +160,13 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR 'n', "Don't normalize."); + public FlagOption randomForestBaseModelOption = new FlagOption( + "randomForestBaseModel", + 'z', + "Use the learner as a base model in a random forest."); + + public FileOption weightFile = new FileOption("targetWeightFile", 'w', "File with the weights of the targets.", null, null, false); + //endregion ================ OPTIONS ================ //region ================ CLASSES ================ @@ -169,7 +182,7 @@ public abstract static class Node extends AbstractMOAObject { protected ISOUPTree tree; // The parent of this particular node - protected SplitNode parent; + protected InnerNode parent; protected Node alternateTree; protected Node originalNode; @@ -191,6 +204,7 @@ public abstract static class Node extends AbstractMOAObject { public Node(ISOUPTree tree) { this.tree = tree; + this.ID = tree.maxID; } public void copyStatistics(Node node) { @@ -206,7 +220,7 @@ public int calcByteSize() { /** * Set the parent node */ - public void setParent(SplitNode parent) { + public void setParent(InnerNode parent) { this.parent = parent; } @@ -227,10 +241,10 @@ public void restartChangeDetection() { public void getDescription(StringBuilder sb, int i) {} - public double[] getPrediction(MultiLabelInstance inst) { + public double[] getPrediction(StructuredInstance inst) { return null; } - + public void describeSubtree(StringBuilder out, int indent) { StringUtils.appendIndented(out, indent, "Leaf"); } @@ -278,6 +292,8 @@ public static class LeafNode extends Node { public DoubleVector errorP = new DoubleVector(); public DoubleVector errorM = new DoubleVector(); + + public List inputIndexes = null; protected double examplesSeenAtLastSplitEvaluation = 0; @@ -289,18 +305,40 @@ public LeafNode(ISOUPTree tree) { if (tree.buildingModelTree()) { learningModel = tree.newLeafModel(); } + initializeInputIndexes(); examplesSeen = 0; sumOfValues = new DoubleVector(); sumOfSquares = new DoubleVector(); } + public void initializeInputIndexes() { + List indexes = new Vector(); + int numAttrs = tree.getModelContext().numInputAttributes(); + for (int i = 0; i < numAttrs; i++) { + indexes.add(i, i); + } + if (tree.buildingRandomForestTree()) { + // Select the first sqrt(n) attribute indexes + for (int i = 0; i < Math.ceil(Math.sqrt(numAttrs)); i++) { + int swap = i + tree.classifierRandom.nextInt(numAttrs - i); + int temp = indexes.get(i); + indexes.set(i, indexes.get(swap)); + indexes.set(swap, temp); + } + inputIndexes = indexes.subList(0, (int) Math.ceil(Math.sqrt(numAttrs))); + } else { + inputIndexes = indexes; + } + } + /** * Method to learn from an instance that passes the new instance to the perceptron learner, * and also prevents the class value from being truncated to an int when it is passed to the * attribute observer */ - public void learnFromInstance(MultiLabelInstance inst, double[] prediction, boolean growthAllowed) { + public void learnFromInstance(StructuredInstance inst, double[] prediction, boolean growthAllowed) { // Update the statistics for this node + double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; double[] predictionM = getPredictionTargetMean(inst); @@ -319,9 +357,10 @@ public void learnFromInstance(MultiLabelInstance inst, double[] prediction, bool errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - inst.valueOutputAttribute(i))); } } + if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); - for (int i = 0; i < inst.numInputAttributes(); i++) { + for (int i : inputIndexes) { AttributeStatisticsObserver obs = attributeObservers.get(i); if (obs == null) { // At this stage all nominal attributes are ignored @@ -360,7 +399,7 @@ public AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCri List bestSuggestions = new LinkedList(); - for (int i = 0; i < attributeObservers.size(); i++) { + for (int i : inputIndexes) { AttributeStatisticsObserver obs = attributeObservers.get(i); if (obs != null) { DoubleVector[] preSplitStatistics = new DoubleVector[tree.getModelContext().numOutputAttributes()]; @@ -385,11 +424,11 @@ public AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCri /** * Retrieve the class votes using the perceptron learner */ - public double[] getPredictionModel(MultiLabelInstance inst) { + public double[] getPredictionModel(StructuredInstance inst) { return learningModel.prediction(inst); } - public double[] getPredictionTargetMean(MultiLabelInstance inst) { + public double[] getPredictionTargetMean(StructuredInstance inst) { double[] pred = new double[inst.numOutputAttributes()]; for (int i = 0; i < inst.numOutputAttributes(); i++) { if (examplesSeen > 0) { @@ -401,7 +440,7 @@ public double[] getPredictionTargetMean(MultiLabelInstance inst) { return pred; } - public double[] getPrediction(MultiLabelInstance inst) { + public double[] getPrediction(StructuredInstance inst) { if (tree.buildingModelTree()) { double[] predictionP = getPredictionModel(inst); double[] predictionM = getPredictionTargetMean(inst); @@ -436,11 +475,14 @@ public void checkForSplit() { } public void describeSubtree(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, "Leaf "); + StringUtils.appendIndented(out, indent, "Leaf"); + StringUtils.appendNewline(out); + if (tree.buildingModelTree()) { - learningModel.getModelDescription(out, 0); + learningModel.getModelDescription(out, indent + 2); } else { //out.append(tree.getClassNameString() + " = " + String.format("%.4f", (sumOfValues / examplesSeen))); + out.append("Leaf node"); StringUtils.appendNewline(out); } } @@ -455,7 +497,7 @@ public static abstract class InnerNode extends Node { // Sum of absolute errors protected DoubleVector sumOfAbsErrors = new DoubleVector(); // Needed for PH tracking of mean error - + protected DoubleVector PHsums = new DoubleVector(); protected DoubleVector PHmins = new DoubleVector(); @@ -565,7 +607,7 @@ public SplitNode(Predicate predicate, ISOUPTree tree) { ID = tree.maxID; } - public int instanceChildIndex(MultiLabelInstance inst) { + public int instanceChildIndex(StructuredInstance inst) { return (predicate.evaluate(inst)) ? 0 : 1; } @@ -575,7 +617,7 @@ public void describeSubtree(StringBuilder out, int indent) { if (child != null) { if (branch == 0) { StringUtils.appendIndented(out, indent, "if "); - this.predicate.getDescription(out, 0); + this.predicate.getDescription(out, 0, tree.getModelContext()); } else { StringUtils.appendIndented(out, indent, "else"); } @@ -586,7 +628,7 @@ public void describeSubtree(StringBuilder out, int indent) { } } - public double[] getPrediction(MultiLabelInstance inst) { + public double[] getPrediction(StructuredInstance inst) { return children.get(predicate.evaluate(inst) ? 0 : 1).getPrediction(inst); } } @@ -633,10 +675,10 @@ public void initializeWeights() { /** * Update the model using the provided instance */ - public void updatePerceptron(MultiLabelInstance inst) { + public void updatePerceptron(StructuredInstance inst) { // Update attribute statistics instancesSeen += inst.weight(); - + // Update weights double learningRatio = 0.0; if (tree.learningRatioConstOption.isSet()) { @@ -651,7 +693,7 @@ public void updatePerceptron(MultiLabelInstance inst) { } } - public void updateWeights(MultiLabelInstance inst, double learningRatio) { + public void updateWeights(StructuredInstance inst, double learningRatio) { if (instancesSeen > 1.0) { // Compute the normalized instance and the delta double[] normalizedInput = tree.normalizedInputVector(inst); @@ -692,7 +734,7 @@ public double[] prediction(double[] instanceValues) { return out; } - private double[] prediction(MultiLabelInstance inst) { + private double[] prediction(StructuredInstance inst) { double[] normalizedInput = tree.normalizedInputVector(inst); double[] normalizedPrediction = prediction(normalizedInput); return denormalizePrediction(normalizedPrediction); @@ -714,18 +756,18 @@ private double[] denormalizePrediction(double[] normalizedPrediction) { } public void getModelDescription(StringBuilder out, int indent) { - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { - StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "]"); - if (getModelContext() != null) { - for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { - if (getModelContext().attribute(j).isNumeric()) { - out.append((j == 0 || weights[i][j] < 0) ? " " : " + "); - out.append(String.format("%.4f", weights[i][j])); + if (getModelContext() != null) { + for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "] ="); + for (int j = 0; j < getModelContext().numInputAttributes(); j++) { + if (getModelContext().inputAttribute(j).isNumeric()) { + out.append((j == 0 && weights[i][j] >= 0) ? " " : (weights[i][j] < 0) ? " - " : " + "); + out.append(String.format("%.4f", Math.abs(weights[i][j]))); out.append(" * "); - out.append(getAttributeNameString(j)); + out.append(getModelContext().inputAttribute(j).name()); } } - out.append(" + " + weights[i][getModelContext().numOutputAttributes()]); + out.append((weights[i][getModelContext().numInputAttributes()] < 0 ? " - " : " + ") + String.format("%.4f", Math.abs(weights[i][getModelContext().numInputAttributes()]))); } StringUtils.appendNewline(out); } @@ -737,7 +779,9 @@ public void getModelDescription(StringBuilder out, int indent) { //region ================ METHODS ================ // Regressor methods - public ISOUPTree() {} + public ISOUPTree() { + super(); + } public String getPurposeString() { return "Implementation of the iSOUP-Tree algorithm as described by Osojnik et al."; @@ -751,8 +795,19 @@ public void resetLearningImpl() { sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); + loadWeights(); } + public void loadWeights() { + targetWeights = new DoubleVector(); + try { + List lines = Files.readAllLines(Paths.get(weightFile.getValue()), Charset.defaultCharset()); + for (int i = 0 ; i < lines.size(); i++) targetWeights.setValue(i, Double.valueOf(lines.get(i))); + } catch (Exception e) { + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) targetWeights.setValue(i, 1.0); + } + } + public boolean isRandomizable() { return true; } @@ -760,7 +815,7 @@ public boolean isRandomizable() { public void getModelDescription(StringBuilder out, int indent) { if (treeRoot != null) treeRoot.describeSubtree(out, indent); } - + protected Measurement[] getModelMeasurementsImpl() { return new Measurement[]{ //new Measurement("tree size (nodes)", this.leafNodeCount + this.splitNodeCount), @@ -776,7 +831,7 @@ public int calcByteSize() { return size; } - public Prediction getPredictionForInstance(MultiLabelInstance inst) { + public Prediction getPredictionForInstance(StructuredInstance inst) { checkRoot(); double[] predictionVector = treeRoot.getPrediction(inst); MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); @@ -786,7 +841,7 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { return prediction; } - public double[] normalizedInputVector(MultiLabelInstance inst) { + public double[] normalizedInputVector(StructuredInstance inst) { // Normalize Instance double[] normalizedInput = new double[inst.numInputAttributes()+1]; if (normalize()) { @@ -816,7 +871,7 @@ public double[] normalizedInputVector(MultiLabelInstance inst) { return normalizedInput; } - public double[] normalizedTargetVector(MultiLabelInstance inst) { + public double[] normalizedTargetVector(StructuredInstance inst) { double[] out = new double[getModelContext().numOutputAttributes()]; if (normalize()) { for (int i = 0; i < inst.numOutputAttributes(); i++) { @@ -853,7 +908,7 @@ public double[] normalizeTargetVector(double[] pred) { } - public double normalizeTargetValue(MultiLabelInstance inst, int i) { + public double normalizeTargetValue(StructuredInstance inst, int i) { if (normalize()) { if (examplesSeen > 1) { double value = inst.valueOutputAttribute(i); @@ -882,7 +937,7 @@ public double normalizeTargetValue(double value, int i) { } else return value; } - public double[] getNormalizedError(MultiLabelInstance inst, double[] prediction) { + public double[] getNormalizedError(StructuredInstance inst, double[] prediction) { double[] normalPrediction = normalizeTargetVector(prediction); double[] normalValue = normalizedTargetVector(inst); double[] out = new double[getModelContext().numOutputAttributes()]; @@ -896,9 +951,9 @@ public double[] getNormalizedError(MultiLabelInstance inst, double[] prediction) /** * Method for updating (training) the model using a new instance */ - public void trainOnInstanceImpl(MultiLabelInstance inst) { - if (inst.weight() > 0) { - checkRoot(); + public void trainOnInstanceImpl(StructuredInstance inst) { + if (inst.weight() > 0) { + checkRoot(); double[] prediction = treeRoot.getPrediction(inst); double[] normalError = getNormalizedError(inst, prediction); @@ -918,108 +973,108 @@ public void trainOnInstanceImpl(MultiLabelInstance inst) { } } - public void processInstance(MultiLabelInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { - Node currentNode = node; - while (true) { - if (currentNode instanceof LeafNode) { - ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); - break; - } else { - currentNode.examplesSeen += inst.weight(); - //currentNode.sumOfAbsErrors.addValues(normalError); - // SplitNode iNode = (SplitNode) currentNode; - // if (!inAlternate && iNode.alternateTree != null) { - // boolean altTree = true; - // double lossO = Math.pow(inst.valueOutputAttribute() - prediction, 2); - // double lossA = Math.pow(inst.valueOutputAttribute() - iNode.alternateTree.getPrediction(inst), 2); - // - // iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; - // iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; - // iNode.lossExamplesSeen++; - // - // double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - // double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - // iNode.lossSumQi += Qi; - // iNode.lossNumQiTests += 1; - // double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - // - // if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { - // iNode.previousWeight = iNode.lossExamplesSeen; - // if (Qi > 0) { - // SplitNode parent = currentNode.getParent(); - // - // if (parent != null) { - // Node replacementTree = iNode.alternateTree; - // parent.setChild(parent.getChildIndex(currentNode), replacementTree); - // if (growthAllowed) replacementTree.restartChangeDetection(); - // } else { - // treeRoot = iNode.alternateTree; - // treeRoot.restartChangeDetection(); - // } - // - // currentNode = iNode.alternateTree; - // altTree = false; - // } else if ( - // (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) - // || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() - // ) { - // iNode.alternateTree = null; - // if (growthAllowed) iNode.restartChangeDetection(); - // altTree = false; - // } - // } - // - // if (altTree) { - // growthAllowed = false; - // processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); - // } - // } - - // if (iNode.changeDetection && !inAlternate) { - // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { - // iNode.initializeAlternateTree(this); - // } - // } - if (currentNode instanceof SplitNode) { - currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); - } else { // if the replaced alternate tree is just a leaf node - ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); - break; - } - } - } - } + public void processInstance(StructuredInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } else { + currentNode.examplesSeen += inst.weight(); + //currentNode.sumOfAbsErrors.addValues(normalError); + // SplitNode iNode = (SplitNode) currentNode; + // if (!inAlternate && iNode.alternateTree != null) { + // boolean altTree = true; + // double lossO = Math.pow(inst.valueOutputAttribute() - prediction, 2); + // double lossA = Math.pow(inst.valueOutputAttribute() - iNode.alternateTree.getPrediction(inst), 2); + // + // iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + // iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + // iNode.lossExamplesSeen++; + // + // double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + // double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // iNode.lossSumQi += Qi; + // iNode.lossNumQiTests += 1; + // double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // + // if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + // iNode.previousWeight = iNode.lossExamplesSeen; + // if (Qi > 0) { + // SplitNode parent = currentNode.getParent(); + // + // if (parent != null) { + // Node replacementTree = iNode.alternateTree; + // parent.setChild(parent.getChildIndex(currentNode), replacementTree); + // if (growthAllowed) replacementTree.restartChangeDetection(); + // } else { + // treeRoot = iNode.alternateTree; + // treeRoot.restartChangeDetection(); + // } + // + // currentNode = iNode.alternateTree; + // altTree = false; + // } else if ( + // (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) + // || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() + // ) { + // iNode.alternateTree = null; + // if (growthAllowed) iNode.restartChangeDetection(); + // altTree = false; + // } + // } + // + // if (altTree) { + // growthAllowed = false; + // processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + // } + // } + + // if (iNode.changeDetection && !inAlternate) { + // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + // iNode.initializeAlternateTree(this); + // } + // } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); + } else { // if the replaced alternate tree is just a leaf node + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } + } + } + } - //region --- Object instatiation methods + //region --- Object instatiation methods - protected NumericStatisticsObserver newNumericClassObserver() { - return new MultiLabelBSTree(); - } + protected NumericStatisticsObserver newNumericClassObserver() { + return new MultiLabelBSTree(); + } - public NominalStatisticsObserver newNominalClassObserver() { - return new MultiLabelNominalAttributeObserver(); - } + public NominalStatisticsObserver newNominalClassObserver() { + return new MultiLabelNominalAttributeObserver(); + } - // protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { - // maxID++; - // return new SplitNode(splitTest, this); - // } + // protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + // maxID++; + // return new SplitNode(splitTest, this); + // } - protected SplitNode newSplitNode(Predicate predicate) { - maxID++; - return new SplitNode(predicate, this); - } + protected SplitNode newSplitNode(Predicate predicate) { + maxID++; + return new SplitNode(predicate, this); + } - protected LeafNode newLeafNode() { - maxID++; - return new LeafNode(this); - } + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } public MultitargetPerceptron newLeafModel() { return new MultitargetPerceptron(this); } - //endregion --- Object instatiation methods + //endregion --- Object instatiation methods //region --- Processing methods protected void checkRoot() { @@ -1028,42 +1083,44 @@ protected void checkRoot() { } } - public static double computeHoeffdingBound(double range, double confidence, double n) { - return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); - } + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(((range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } - public boolean buildingModelTree() { - return !regressionTreeOption.isSet(); - } + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } + + public boolean buildingRandomForestTree() { + return randomForestBaseModelOption.isSet(); + } - public boolean normalize() { - return !doNotNormalizeOption.isSet(); - } + public boolean normalize() { + return !doNotNormalizeOption.isSet(); + } - protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) { - //System.out.println("Evaluating splits"); - //System.out.println(examplesSeen); - // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - MultiLabelSplitCriterion splitCriterion = new ICVarianceReduction(); + protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) { + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + MultiLabelSplitCriterion splitCriterion = new WeightedICVarianceReduction(targetWeights); - // Using this criterion, find the best split per attribute and rank the results - AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option - Arrays.sort(bestSplitSuggestions); + // Using this criterion, find the best split per attribute and rank the results + AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option + Arrays.sort(bestSplitSuggestions); - // Declare a variable to determine if any of the splits should be performed - boolean shouldSplit = false; + // Declare a variable to determine if any of the splits should be performed + boolean shouldSplit = false; - // If only one split was returned, use it - if (bestSplitSuggestions.length < 2) { - shouldSplit = bestSplitSuggestions.length > 0; - } else { // Otherwise, consider which of the splits proposed may be worth trying + // If only one split was returned, use it + if (bestSplitSuggestions.length < 2) { + shouldSplit = bestSplitSuggestions.length > 0; + } else { // Otherwise, consider which of the splits proposed may be worth trying - // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); - // Determine the top two ranked splitting suggestions - AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this @@ -1099,6 +1156,7 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; SplitNode newSplit = newSplitNode(splitDecision.predicate); + newSplit.ID = node.ID; newSplit.copyStatistics(node); newSplit.changeDetection = node.changeDetection; newSplit.ID = node.ID; @@ -1124,23 +1182,21 @@ protected void attemptToSplit(LeafNode node, SplitNode parent, int parentIndex) } } + public double computeSD(double squaredVal, double val, double size) { + if (size > 1) + return Math.sqrt((squaredVal - ((val * val) / size)) / size); + else + return 0.0; + } + public static double scalarProduct(DoubleVector u, DoubleVector v) { + double ret = 0.0; + for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { + ret += u.getValue(i) * v.getValue(i); + } + return ret; + } + //endregion --- Processing methods - public double computeSD(double squaredVal, double val, double size) { - if (size > 1) - return Math.sqrt((squaredVal - ((val * val) / size)) / size); - else - return 0.0; - } - - public static double scalarProduct(DoubleVector u, DoubleVector v) { - double ret = 0.0; - for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { - ret += u.getValue(i) * v.getValue(i); - } - return ret; - } - //endregion --- Processing methods - - //endregion ================ METHODS ================ + //endregion ================ METHODS ================ } diff --git a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java index 56c3985a5..93c1c94a1 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java @@ -16,7 +16,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -47,7 +47,7 @@ public void resetLearningImpl() { } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { if (this.hasStarted == false){ this.ensemble = new Classifier[instance.numberOutputTargets()]; Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); @@ -65,7 +65,7 @@ public void trainOnInstanceImpl(MultiLabelInstance instance) { protected InstancesHeader[] header; - protected Instance transformInstance(MultiLabelInstance inst, int outputIndex) { + protected Instance transformInstance(StructuredInstance inst, int outputIndex) { if (header == null) { this.header = new InstancesHeader[this.ensemble.length]; } @@ -128,7 +128,7 @@ public void getModelDescription(StringBuilder out, int indent) { @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { Prediction prediction=null; if (this.hasStarted){ prediction=new MultiLabelPrediction(ensemble.length); diff --git a/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java b/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java index 0f61f4e73..9f08ed855 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java +++ b/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java @@ -4,7 +4,7 @@ import com.yahoo.labs.samoa.instances.DenseInstanceData; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -37,7 +37,7 @@ public void resetLearningImpl() { } @Override - public void trainOnInstanceImpl(MultiLabelInstance inst) { + public void trainOnInstanceImpl(StructuredInstance inst) { int numOutputs = inst.numberOutputTargets(); Prediction prediction = new MultiLabelPrediction(numOutputs); @@ -65,7 +65,7 @@ public boolean isRandomizable() { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance inst) { + public Prediction getPredictionForInstance(StructuredInstance inst) { //return (lastSeenClasses!=null) ? this.lastSeenClasses : new MultiLabelPrediction(); return (lastSeenClasses!=null) ? this.lastSeenClasses : null; } diff --git a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java index 8d835fb5a..fb5505ef7 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java @@ -1,7 +1,8 @@ package moa.classifiers.rules.core; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; import moa.core.StringUtils; @@ -23,10 +24,10 @@ public NominalRulePredicate(int inputAttributeIndex, double attributeValue, bool } @Override public boolean evaluate(Instance instance){ - return evaluate((MultiLabelInstance) instance); + return evaluate((StructuredInstance) instance); } - public boolean evaluate(MultiLabelInstance instance) { + public boolean evaluate(StructuredInstance instance) { if (instance.isMissing(inputAttributeIndex)) { return false; } @@ -68,5 +69,11 @@ public int getAttributeIndex() { public boolean isEqualOrLess() { return isEqual; } - + @Override + public void getDescription(StringBuilder sb, int indent, InstancesHeader header) { + if(isEqual) + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, inputAttributeIndex) + " == " + attributeValue); + else + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, inputAttributeIndex) + " <> " + attributeValue); + } } diff --git a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java index 6084fbae6..8387610c0 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java @@ -1,7 +1,8 @@ package moa.classifiers.rules.core; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; import moa.core.StringUtils; @@ -23,10 +24,10 @@ public NumericRulePredicate(int inputAttributeIndex, double attributeValue, bool } @Override public boolean evaluate(Instance instance){ - return evaluate((MultiLabelInstance) instance); + return evaluate((StructuredInstance) instance); } - public boolean evaluate(MultiLabelInstance instance) { + public boolean evaluate(StructuredInstance instance) { if (instance.isMissing(inputAttributeIndex)) { return false; } @@ -69,5 +70,14 @@ public boolean isEqualOrLess() { return isEqualOrLower; } + public double getAttributeValue() { + return attributeValue; + } + @Override + public void getDescription(StringBuilder sb, int indent, InstancesHeader header) { + if(isEqualOrLower) + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, inputAttributeIndex) + " <= " + attributeValue); + else + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, inputAttributeIndex) + " > " + attributeValue); } } diff --git a/moa/src/main/java/moa/classifiers/rules/core/Predicate.java b/moa/src/main/java/moa/classifiers/rules/core/Predicate.java index f7f120d5d..75517efc3 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/Predicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/Predicate.java @@ -20,6 +20,7 @@ package moa.classifiers.rules.core; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; public interface Predicate { @@ -28,5 +29,6 @@ public interface Predicate { public int getAttributeIndex(); public boolean isEqualOrLess(); public void getDescription(StringBuilder sb, int indent); + public void getDescription(StringBuilder sb, int indent, InstancesHeader header); } diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java index dea1adf2c..13a4f85ba 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java @@ -1,7 +1,7 @@ package moa.classifiers.rules.core.anomalydetection; import moa.options.AbstractOptionHandler; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; public abstract class AbstractAnomalyDetector extends AbstractOptionHandler implements AnomalyDetector { @@ -12,7 +12,7 @@ public abstract class AbstractAnomalyDetector extends AbstractOptionHandler impl private static final long serialVersionUID = 1L; @Override - public abstract boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance); + public abstract boolean updateAndCheckAnomalyDetection(StructuredInstance instance); @Override public AnomalyDetector copy() { diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java index 211fbbc29..9297ebe1e 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java @@ -11,7 +11,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; public class AnomalinessRatioScore extends AbstractAnomalyDetector { @@ -54,7 +54,7 @@ public class AnomalinessRatioScore extends AbstractAnomalyDetector { @Override - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance) { boolean isAnomaly=false; if(probabilityFunction==null){ weightSeen=0.0; diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalyDetector.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalyDetector.java index f4d4647d7..6e9361842 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalyDetector.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalyDetector.java @@ -1,5 +1,5 @@ package moa.classifiers.rules.core.anomalydetection; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.options.OptionHandler; @@ -18,7 +18,7 @@ public interface AnomalyDetector extends OptionHandler { * * @return true if anomaly is detected and false otherwise */ - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance); + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance); @Override diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java index e7e44a113..722f15dfa 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java @@ -2,7 +2,7 @@ import moa.core.ObjectRepository; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; public class NoAnomalyDetection extends AbstractAnomalyDetector{ @@ -17,7 +17,7 @@ public void getDescription(StringBuilder sb, int indent) { } @Override - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance) { return false; } diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java index 08d846ea9..53cc8556c 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java @@ -11,7 +11,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; public class OddsRatioScore extends AbstractAnomalyDetector { @@ -48,7 +48,7 @@ public class OddsRatioScore extends AbstractAnomalyDetector { private ProbabilityFunction probabilityFunction; @Override - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance) { boolean isAnomaly=false; if(probabilityFunction==null){ weightSeen=0.0; diff --git a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java index 49a82a67d..df2405a5a 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java @@ -20,6 +20,7 @@ package moa.classifiers.rules.core.conditionaltests; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.core.conditionaltests.NominalAttributeBinaryTest; import moa.classifiers.rules.core.Predicate; @@ -78,6 +79,14 @@ public int getAttributeIndex() { public boolean isEqualOrLess() { return state; } + + @Override + public void getDescription(StringBuilder sb, int indent, InstancesHeader header) { + if(state) + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, attIndex) + " = " + attValue); + else + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, attIndex) + " <> " + attValue); + } } diff --git a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java index 90560586b..37650e7ca 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java @@ -169,4 +169,11 @@ public boolean isEqualOrLess() { return state; } + @Override + public void getDescription(StringBuilder sb, int indent, InstancesHeader header) { + String compareChar = (operator == 0) ? "=" : (operator == 1) ? "<=" : ">"; + StringUtils.appendIndented(sb, indent, InstancesHeader.getAttributeNameString(header, attIndex) + compareChar + attValue); + } + + } diff --git a/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java b/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java index 45ae75b74..a5e48b1a8 100644 --- a/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java +++ b/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java @@ -25,7 +25,7 @@ import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.classifiers.AbstractClassifier; import moa.classifiers.Regressor; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java index 2672f58f5..44a24ae5f 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java @@ -55,7 +55,7 @@ import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; @@ -147,7 +147,7 @@ public AMRulesMultiLabelLearner(double attributesPercentage) { @Override - public Prediction getPredictionForInstance(MultiLabelInstance inst) { + public Prediction getPredictionForInstance(StructuredInstance inst) { /*MultiLabelVote vote=getVotes(inst); if(vote!=null) return vote.getVote(); @@ -166,7 +166,7 @@ public Prediction getPredictionForInstance(MultiLabelInstance inst) { * returns the prediction of the instance. * Called in WeightedRandomRules */ - public ErrorWeightedVoteMultiLabel getVotes(MultiLabelInstance instance) { + public ErrorWeightedVoteMultiLabel getVotes(StructuredInstance instance) { ErrorWeightedVoteMultiLabel errorWeightedVote=newErrorWeightedVote(); //DoubleVector combinedVote = new DoubleVector(); debug("Test",3); @@ -237,7 +237,7 @@ public boolean isRandomizable(){ private double numInstances; //Just for statistics @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { /** * AMRules Algorithm * @@ -398,7 +398,7 @@ protected void debug(String string, int level) { } } - protected void VerboseToConsole(MultiLabelInstance inst) { + protected void VerboseToConsole(StructuredInstance inst) { if(VerbosityOption.getValue()>=5){ System.out.println(); System.out.println("I) Dataset: "+inst.dataset().getRelationName()); diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java index 4a8a18ccf..9c179d2f6 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java @@ -8,7 +8,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -95,9 +95,9 @@ public LearningLiteral(int [] outputsToLearn){ this.outputsToLearn=outputsToLearn.clone(); } - abstract public void trainOnInstance(MultiLabelInstance instance); + abstract public void trainOnInstance(StructuredInstance instance); - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { if (learner!=null) return learner.getPredictionForInstance(instance); else @@ -107,7 +107,7 @@ public Prediction getPredictionForInstance(MultiLabelInstance instance) { public abstract boolean tryToExpand(double splitConfidence, double tieThresholdOption); - public boolean updateAndCheckChange(MultiLabelInstance instance) { + public boolean updateAndCheckChange(StructuredInstance instance) { boolean hasChanged=false; if (hasStarted){ if (changeDetectors==null){ @@ -133,7 +133,7 @@ public boolean updateAndCheckChange(MultiLabelInstance instance) { protected abstract double[] getNormalizedErrors(Prediction prediction, Instance inst); - public boolean updateAndCheckAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAndCheckAnomalyDetection(StructuredInstance instance) { if(hasStarted) return anomalyDetector.updateAndCheckAnomalyDetection(instance); else @@ -239,7 +239,7 @@ public void setAttributesPercentage(double attributesPercentage) { this.attributesPercentage=attributesPercentage; } - protected void initializeAttibutesMask(MultiLabelInstance inst) { + protected void initializeAttibutesMask(StructuredInstance inst) { int numInputAttributes=inst.numInputAttributes(); int numAttributesSelected=(int)Math.round(numInputAttributes*attributesPercentage/100); diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java index 26ae4e0d9..f9e2c5c82 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java @@ -2,7 +2,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; import java.util.Arrays; @@ -157,7 +157,7 @@ private AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCr } @Override - public void trainOnInstance(MultiLabelInstance instance) { + public void trainOnInstance(StructuredInstance instance) { if (attributesMask==null) initializeAttibutesMask(instance); diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java index 6bd641395..0fb2aba8b 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Random; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; import moa.AbstractMOAObject; @@ -63,7 +63,7 @@ public void setRuleNumberID(int ruleNumberID) { this.ruleNumberID = ruleNumberID; } - public boolean isCovering(MultiLabelInstance inst) { + public boolean isCovering(StructuredInstance inst) { boolean isCovering = true; for (Literal l : literalList) { if (l.evaluate(inst) == false) { @@ -90,15 +90,15 @@ public void getDescription(StringBuilder out, int indent) { StringUtils.appendNewline(out); } - public boolean updateChangeDetection(MultiLabelInstance instance) { + public boolean updateChangeDetection(StructuredInstance instance) { return this.learningLiteral.updateAndCheckChange(instance); } - public boolean updateAnomalyDetection(MultiLabelInstance instance) { + public boolean updateAnomalyDetection(StructuredInstance instance) { return this.learningLiteral.updateAndCheckAnomalyDetection(instance); } - public void trainOnInstance(MultiLabelInstance instance) { + public void trainOnInstance(StructuredInstance instance) { learningLiteral.trainOnInstance(instance); } @@ -114,7 +114,7 @@ public LearningLiteral getLearningNode() { return learningLiteral.getErrors(); } - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { return learningLiteral.getPredictionForInstance(instance); } diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java index ddcad8f6c..b96ddd2a7 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java @@ -5,7 +5,7 @@ import moa.tasks.TaskMonitor; import com.github.javacliparser.FloatOption; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; public abstract class AbstractMultiLabelErrorMeasurer extends AbstractOptionHandler implements MultiTargetErrorMeasurer{ @@ -27,7 +27,7 @@ public void addPrediction(Prediction prediction, Prediction trueClass){ addPrediction(prediction, trueClass); } - abstract public void addPrediction(Prediction prediction, MultiLabelInstance inst); + abstract public void addPrediction(Prediction prediction, StructuredInstance inst); abstract public double getCurrentError(); diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java index 97ee491ac..5b2bc3be8 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java @@ -1,6 +1,6 @@ package moa.classifiers.rules.multilabel.errormeasurers; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -11,7 +11,7 @@ public abstract class AbstractMultiTargetErrorMeasurer extends AbstractMultiLabe */ private static final long serialVersionUID = 1L; - public void addPrediction(Prediction prediction, MultiLabelInstance inst){ + public void addPrediction(Prediction prediction, StructuredInstance inst){ int numOutputs=inst.numberOutputTargets(); Prediction trueClass= new MultiLabelPrediction(numOutputs); for (int i=0; i= tree.gracePeriodOption.getValue()) { int index = (parent != null) ? parent.getChildIndex(this) : 0; - tree.attemptToSplit(this, parent, index); + tree.attemptToSplit(this, parent, index, inst, prediction); // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation examplesSeenAtLastSplitEvaluation = examplesSeen; @@ -553,6 +552,7 @@ public String getPurposeString() { public FIMTDDPerceptron(FIMTDDPerceptron original) { this.tree = original.tree; weightAttribute = original.weightAttribute.clone(); + instancesSeen = original.instancesSeen / 2; } public FIMTDDPerceptron(FIMTDD tree) { @@ -742,6 +742,18 @@ public double getNormalizedError(Instance inst, double prediction) { return Math.abs(normalValue - normalPrediction); } + + public void updateStatistics(Instance inst) { + examplesSeen += inst.weight(); + sumOfValues += inst.weight() * inst.classValue(); + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int aIndex = modelAttIndexToInstanceAttIndex(i, inst); + sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); + } + } /** * Method for updating (training) the model using a new instance @@ -754,16 +766,7 @@ public void trainOnInstanceImpl(Instance inst) { processInstance(inst, treeRoot, prediction, normalError, true, false); - examplesSeen += inst.weight(); - sumOfValues += inst.weight() * inst.classValue(); - sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); - - for (int i = 0; i < inst.numAttributes() - 1; i++) { - int aIndex = modelAttIndexToInstanceAttIndex(i, inst); - sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); - sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); - } - + updateStatistics(inst); } @@ -867,7 +870,7 @@ protected FIMTDDPerceptron newLeafModel() { // region --- Processing methods - protected void checkRoot() { + public void checkRoot() { if (treeRoot == null) { treeRoot = newLeafNode(); leafNodeCount = 1; @@ -882,7 +885,7 @@ public boolean buildingModelTree() { return !regressionTreeOption.isSet(); } - protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex, Instance inst, double prediction) { // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index 1808a5466..34108ef59 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -331,7 +331,7 @@ protected OptionNode newOptionNode() { // region --- Processing methods - protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex, Instance inst, double prediction) { // Initialize the split criterion SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); @@ -376,11 +376,10 @@ protected void attemptToSplit(LeafNode node, Node parent, int parentIndex) { } else { break; } - } } else if (hoeffdingBound < tieThresholdOption.getValue()) { numSplits = 1; - acceptedSplits.add(bestSplitSuggestions[0]); + acceptedSplits.add(bestSuggestion); } else { // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer for (int i = 0; i < node.attributeObservers.size(); i++) { AttributeClassObserver obs = node.attributeObservers.get(i); diff --git a/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java index aec992e29..5b87a670b 100644 --- a/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java @@ -27,7 +27,7 @@ import com.yahoo.labs.samoa.instances.DenseInstanceData; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; /** @@ -59,7 +59,7 @@ public void reset() { @Override public void addResult(Example example, Prediction prediction) { - MultiLabelInstance inst = (MultiLabelInstance) example.getData(); + StructuredInstance inst = (StructuredInstance) example.getData(); if (numberOutputs == 0) { numberOutputs = inst.numberOutputTargets(); } diff --git a/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java index 2b43a72a6..24d45642d 100644 --- a/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java @@ -30,7 +30,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; /** @@ -152,7 +152,7 @@ public void prepareForUseImpl(TaskMonitor monitor, @Override public void addResult(Example testInst, Prediction prediction) { - MultiLabelInstance inst=(MultiLabelInstance) testInst.getData(); + StructuredInstance inst=(StructuredInstance) testInst.getData(); double weight = inst.weight(); if (numberOutputs == 0) { numberOutputs = inst.numberOutputTargets(); diff --git a/moa/src/main/java/moa/evaluation/MultilabelWindowClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/MultilabelWindowClassificationPerformanceEvaluator.java new file mode 100644 index 000000000..b26c131c0 --- /dev/null +++ b/moa/src/main/java/moa/evaluation/MultilabelWindowClassificationPerformanceEvaluator.java @@ -0,0 +1,152 @@ +/* + * ClassificationPerformanceEvaluator.java + * Copyright (C) 2012 University of Waikato, Hamilton, New Zealand + * @author Jesse Read (jesse@tsc.uc3m.es) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.evaluation; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import moa.core.Example; +import moa.core.Measurement; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.StructuredInstance; +import com.yahoo.labs.samoa.instances.Prediction; + +/** + * Multilabel Window Classification Performance Evaluator. + * + * @author Jesse Read (jesse@tsc.uc3m.es) + * @version $Revision: 1 $ + */ +public class MultilabelWindowClassificationPerformanceEvaluator extends WindowClassificationPerformanceEvaluator implements MultiTargetPerformanceEvaluator { + + /** running sum of accuracy */ + double sumAccuracy = 0.0; + double sumHamming = 0.0; + + /** running number of examples */ + int sumExamples = 0; + + /** preset threshold */ + private double t = 0.5; + + @Override + public void reset() { + sumAccuracy = 0.0; + sumHamming = 0.0; + sumExamples = 0; + } + + @Override + public void reset(int L) { + numClasses = L; + reset(); + } + + /** + * Add a Result. NOTE: In theory, the size of y[] could change, although we + * do not take into account this possibility *yet*. (for this, we would have + * to use y[] differently, another format for y[] e.g. HashMap, or store + * more info in x) + */ + @Override + public void addResult(Example example, double[] p_y) { + + //int L = example.numOutputAttributes(); // <-- doesn't work! + int L = p_y.length; + + Instance x = example.getData(); + if (p_y.length < 2) { + System.err.println("FATAL ERROR: Not enough labels, we've lost track of the number of labels."); + System.exit(1); + } + + //System.out.println("------- new result -------------"); + //System.out.println("x = "+x); + //System.out.println("p(y) = "+Arrays.toString(p_y)); + + // Threshold to binary output (optional) + int y[] = new int[L]; + for(int j = 0; j < L; j++) { + y[j] = (p_y[j] > t) ? 1 : 0; + } + //System.out.println("y = "+Arrays.toString(y)); + + sumExamples++; + int correct = 0; + for(int j = 0; j < y.length; j++) { + //int y_true = //]example.valueOutputAttribute(j); // <-- doesn't work! + int y_true = (int)x.value(j); + //int y_pred = (p_y[j] > t) ? 1 : 0; + if (y_true == y[j]) + correct++; + } + + // Hamming Score + sumHamming+=(correct/(double)L); + + // Exact Match + if (correct == L) + sumAccuracy++; + } + + + @Override + public void addResult(Example example, Prediction prediction) { + + StructuredInstance inst = (StructuredInstance) example.getData(); + if (inst.weight() > 0.0) { + int numberOutputs = inst.numOutputAttributes(); + if (numberOutputs <= 1) { + System.err.println("FATAL ERROR: This is not a multi-label dataset!"); + System.exit(1); + } + if (prediction.numOutputAttributes()==0) { + System.err.println("FATAL ERROR: This is not a multi-label prediction!"); + System.exit(1); + } + double[] result = new double[numberOutputs]; + for (int i = 0; i< prediction.size();i++){ + result[i] = prediction.getVote(i,1); + } + addResult(example, result); + } + //System.out.println(inst.classValue()+", "+prediction); + } + + @Override + public Measurement[] getPerformanceMeasurements() { + + // gather measurements + Measurement m[] = new Measurement[]{ + new Measurement("Exact Match", sumAccuracy/sumExamples), + new Measurement("Hamming Score", sumHamming/sumExamples), + }; + + // reset + reset(); + + return m; + } + + @Override + public void getDescription(StringBuilder sb, int indent) { + sb.append("Multi-label Window Classification Performance Evaluator"); + } +} diff --git a/moa/src/main/java/moa/streams/ArffFileStream.java b/moa/src/main/java/moa/streams/ArffFileStream.java index c701d431d..408c6d2da 100644 --- a/moa/src/main/java/moa/streams/ArffFileStream.java +++ b/moa/src/main/java/moa/streams/ArffFileStream.java @@ -41,8 +41,7 @@ * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * @version $Revision: 7 $ */ -public class ArffFileStream extends AbstractOptionHandler implements - InstanceStream { +public class ArffFileStream extends AbstractOptionHandler implements InstanceStream { @Override public String getPurposeString() { @@ -82,8 +81,7 @@ public ArffFileStream(String arffFileName, int classIndex) { } @Override - public void prepareForUseImpl(TaskMonitor monitor, - ObjectRepository repository) { + public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { restart(); } @@ -127,8 +125,7 @@ public void restart() { InputStream fileStream = new FileInputStream(this.arffFileOption.getFile()); this.fileProgressMonitor = new InputStreamProgressMonitor( fileStream); - this.fileReader = new BufferedReader(new InputStreamReader( - this.fileProgressMonitor)); + this.fileReader = new BufferedReader(new InputStreamReader(this.fileProgressMonitor)); int classIndex = this.classIndexOption.getValue(); this.instances = new Instances(this.fileReader, 1, classIndex); if (classIndex < 0) { From 90e39b23cb3c310558c808dc37f49adc6c8b780c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Thu, 24 Mar 2016 13:16:58 +0100 Subject: [PATCH 26/33] Instance, InstanceHeader, ArffReader, etc. rework --- .../labs/samoa/instances/ArffLoader.java | 147 ++-- .../instances/HierarhicalInstanceImpl.java | 452 ------------ .../yahoo/labs/samoa/instances/Instance.java | 12 +- .../labs/samoa/instances/InstanceImpl.java | 17 +- .../samoa/instances/InstanceInformation.java | 127 ++-- .../yahoo/labs/samoa/instances/Instances.java | 582 --------------- .../labs/samoa/instances/InstancesHeader.java | 674 ++++++++++++++++-- .../instances/MultiTargetArffLoader.java | 43 +- .../com/yahoo/labs/samoa/instances/Range.java | 1 + .../SamoaToWekaInstanceConverter.java | 4 +- .../samoa/instances/StructuredInstance.java | 3 + .../WekaToSamoaInstanceConverter.java | 12 +- .../moa/classifiers/AbstractClassifier.java | 20 +- .../bayes/NaiveBayesMultinomial.java | 4 +- .../InstanceConditionalTest.java | 3 +- .../NominalAttributeBinaryTest.java | 1 + .../NominalAttributeMultiwayTest.java | 1 + .../NumericAttributeBinaryTest.java | 1 + .../main/java/moa/classifiers/lazy/kNN.java | 9 +- .../java/moa/classifiers/lazy/kNNwithPAW.java | 4 +- .../classifiers/lazy/kNNwithPAWandADWIN.java | 4 +- .../neighboursearch/DistanceFunction.java | 6 +- .../neighboursearch/EuclideanDistance.java | 6 +- .../lazy/neighboursearch/KDTree.java | 22 +- .../lazy/neighboursearch/LinearNNSearch.java | 10 +- .../NearestNeighbourSearch.java | 12 +- .../neighboursearch/NormalizableDistance.java | 10 +- .../kdtrees/KDTreeNodeSplitter.java | 8 +- .../kdtrees/KMeansInpiredMethod.java | 8 +- .../main/java/moa/classifiers/meta/ADACC.java | 6 +- .../meta/AccuracyUpdatedEnsemble.java | 8 +- .../meta/AccuracyWeightedEnsemble.java | 16 +- .../moa/classifiers/meta/RandomRules.java | 4 +- .../meta/TemporallyAugmentedClassifier.java | 13 +- .../moa/classifiers/meta/WEKAClassifier.java | 2 +- .../LocalMultiTargetClassifier.java | 1 + .../multilabel/MEKAClassifier.java | 6 +- .../multilabel/MajorityLabelset.java | 9 - .../multilabel/MultilabelHoeffdingTree.java | 3 +- .../multilabel/meta/OzaBagAdwinML.java | 6 +- .../classifiers/multilabel/meta/OzaBagML.java | 6 +- .../multilabel/trees/ISOUPTree.java | 5 + .../BasicMultiTargetRegressor.java | 4 +- .../rules/core/NominalRulePredicate.java | 1 + .../rules/core/NumericRulePredicate.java | 1 + .../NominalAttributeBinaryRulePredicate.java | 1 + .../NumericAttributeBinaryRulePredicate.java | 1 + .../rules/meta/RandomAMRulesOld.java | 1 - .../moa/clusterers/AbstractClusterer.java | 4 +- .../main/java/moa/clusterers/Clusterer.java | 2 +- moa/src/main/java/moa/clusterers/CobWeb.java | 14 +- .../clusterers/WekaClusteringAlgorithm.java | 10 +- .../moa/core/MultilabelInstancesHeader.java | 4 +- moa/src/main/java/moa/core/SizeOf.java | 2 +- .../core/utils/AttributeDefinitionUtil.java | 121 ++++ .../main/java/moa/core/utils/Converter.java | 8 +- .../BasicMultiLabelPerformanceEvaluator.java | 4 +- .../visualization/RunOutlierVisualizer.java | 4 +- .../moa/gui/visualization/RunVisualizer.java | 4 +- .../moa/gui/visualization/WekaExplorer.java | 4 +- .../main/java/moa/streams/ArffFileStream.java | 55 +- .../moa/streams/CachedInstancesStream.java | 6 +- .../moa/streams/ConceptDriftRealStream.java | 13 +- .../java/moa/streams/ConceptDriftStream.java | 3 +- .../main/java/moa/streams/ExampleStream.java | 3 +- .../main/java/moa/streams/FilteredStream.java | 3 +- .../java/moa/streams/MultiFilteredStream.java | 2 +- .../moa/streams/MultiLabelFilteredStream.java | 4 +- .../streams/MultiTargetArffFileStream.java | 290 ++++---- .../moa/streams/clustering/FileStream.java | 43 +- .../clustering/RandomRBFGeneratorEvents.java | 4 +- .../streams/clustering/SimpleCSVStream.java | 6 +- .../moa/streams/filters/AddNoiseFilter.java | 3 +- .../java/moa/streams/filters/RBFFilter.java | 7 +- .../java/moa/streams/filters/ReLUFilter.java | 6 +- .../RemoveDiscreteAttributeFilter.java | 4 +- .../filters/ReplacingMissingValuesFilter.java | 1 + .../filters/SelectAttributesFilter.java | 16 +- .../streams/generators/AgrawalGenerator.java | 4 +- .../generators/HyperplaneGenerator.java | 4 +- .../moa/streams/generators/LEDGenerator.java | 4 +- .../streams/generators/LEDGeneratorDrift.java | 1 + .../generators/RandomRBFGenerator.java | 4 +- .../generators/RandomTreeGenerator.java | 4 +- .../moa/streams/generators/SEAGenerator.java | 4 +- .../streams/generators/STAGGERGenerator.java | 4 +- .../streams/generators/WaveformGenerator.java | 4 +- .../generators/WaveformGeneratorDrift.java | 1 + .../cd/AbstractConceptDriftGenerator.java | 4 +- .../multilabel/MetaMultilabelGenerator.java | 7 +- .../multilabel/MultilabelArffFileStream.java | 4 +- .../java/moa/tasks/CacheShuffledStream.java | 4 +- .../moa/tasks/EvaluateInterleavedChunks.java | 4 +- .../tasks/EvaluatePeriodicHeldOutTest.java | 4 +- .../instances/MultiTargetArffLoaderTest.java | 31 +- .../AbstractClassifierTestCase.java | 14 +- .../filters/SelectAttributesFilterTest.java | 4 +- 97 files changed, 1355 insertions(+), 1702 deletions(-) delete mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/HierarhicalInstanceImpl.java delete mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/Instances.java create mode 100644 moa/src/main/java/moa/core/utils/AttributeDefinitionUtil.java diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java index a6bddce59..c427141d8 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java @@ -20,10 +20,13 @@ import java.io.Reader; import java.io.StreamTokenizer; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import moa.core.utils.AttributeDefinitionUtil; + /** * The Class ArffLoader. Loads an Arff file with sparse or dense format. */ @@ -41,8 +44,9 @@ public class ArffLoader { */ protected StreamTokenizer streamTokenizer; + /** - * Instantiates a new arff loader. + * Instantiates a new arff loader. Constructor for backwards compatibility. * * @param reader the reader * @param size the size @@ -50,39 +54,43 @@ public class ArffLoader { */ public ArffLoader(Reader reader, int size, int classAttribute) { // size is not used - this(reader); - if (classAttribute < 0) { - this.instanceInformation.setClassIndex(this.instanceInformation.numAttributes() - 1); - //System.out.print(this.instanceInformation.classIndex()); - } else if (classAttribute > 0) { - this.instanceInformation.setClassIndex(classAttribute - 1); - } + this(reader,String.valueOf(classAttribute)); } - protected Range range; /** * Instantiates a new arff loader. * * @param reader the reader - * @param range - * @param size the size - * @param classAttribute the class attribute + * @param outputDefinition the string definition of output attributes + * @param inputDefinition the string definition of input attributes */ - public ArffLoader(Reader reader) { - this(reader, null); + public ArffLoader(Reader reader, String outputDefinition, String inputDefinition) { + BufferedReader br = new BufferedReader(reader); + + //Init streamTokenizer + streamTokenizer = new StreamTokenizer(br); + streamTokenizer.resetSyntax(); + streamTokenizer.whitespaceChars(0, ' '); + streamTokenizer.wordChars(' ' + 1, '\u00FF'); + streamTokenizer.whitespaceChars(',', ','); + streamTokenizer.commentChar('%'); + streamTokenizer.quoteChar('"'); + streamTokenizer.quoteChar('\''); + streamTokenizer.ordinaryChar('{'); + streamTokenizer.ordinaryChar('}'); + streamTokenizer.eolIsSignificant(true); + + this.instanceInformation = this.getHeader(outputDefinition, inputDefinition); } /** * Instantiates a new arff loader. * * @param reader the reader - * @param range - * @param size the size - * @param classAttribute the class attribute + * @param outputDefinition the string definition of output attributes (others are taken as inputs) */ - public ArffLoader(Reader reader, Range range) { - this.range = range; + public ArffLoader(Reader reader, String outputDefinition) { BufferedReader br = new BufferedReader(reader); //Init streamTokenizer @@ -98,23 +106,9 @@ public ArffLoader(Reader reader, Range range) { streamTokenizer.ordinaryChar('}'); streamTokenizer.eolIsSignificant(true); - this.instanceInformation = this.getHeader(); - - if (range != null) { //is MultiLabel - this.instanceInformation.setRangeOutputIndices(range); - } - - } - - /** - * Gets the structure. - * - * @return the structure - */ - public InstanceInformation getStructure() { - return this.instanceInformation; + this.instanceInformation = this.getHeader(outputDefinition, AttributeDefinitionUtil.nonIgnoredDefinition); } - + /** * Reads instance. It detects if it is dense or sparse. * @@ -144,7 +138,6 @@ public Instance readInstance() { */ public Instance readInstanceDense() { Instance instance = newDenseInstance(this.instanceInformation.numAttributes()); - //System.out.println(this.instanceInformation.numAttributes()); int numAttribute = 0; try { while (numAttribute == 0 && streamTokenizer.ttype != StreamTokenizer.TT_EOF) { @@ -196,7 +189,7 @@ protected void setValue(Instance instance, int numAttribute, double value, boole valueAttribute = value; //System.out.println(value +"/"+valueAttribute+" "); } - if (this.instanceInformation.classIndex() == numAttribute) { + if (this.instanceInformation.numOutputAttributes() == 1 && this.instanceInformation.classIndex() == numAttribute) { setClassValue(instance, valueAttribute); //System.out.println(value +"<"+this.instanceInformation.classIndex()+">"); } else { @@ -219,17 +212,11 @@ private Instance readInstanceSparse() { ArrayList attributeValues = new ArrayList(); List indexValues = new ArrayList(); try { - //while (streamTokenizer.ttype != StreamTokenizer.TT_EOF) { - streamTokenizer.nextToken(); // Remove the '{' char //For each line while (streamTokenizer.ttype != StreamTokenizer.TT_EOL && streamTokenizer.ttype != StreamTokenizer.TT_EOF) { while (streamTokenizer.ttype != '}') { //For each item - //streamTokenizer.nextToken(); - //while (streamTokenizer.ttype != '}'){ - //System.out.println(streamTokenizer.nval +"-"+ streamTokenizer.sval); - //numAttribute = (int) streamTokenizer.nval; if (streamTokenizer.ttype == StreamTokenizer.TT_NUMBER) { numAttribute = (int) streamTokenizer.nval; } else { @@ -342,25 +329,20 @@ private Instance readDenseInstanceSparse() { } return instance; } - - //protected List inputAttributes; - // protected List outputAttributes; protected List auxAttributes; - private InstanceInformation getHeader() { - //commented JD - //this.range.setUpper(10000); //TO DO: Create a new range object with isInRange that does not need the upper limit + private InstanceInformation getHeader(String outputDefinition, String inputDefinition) { String relation = "file stream"; auxAttributes = new ArrayList();//JD int numAttributes = 0; + List inputIndexes = new ArrayList(); + List outputIndexes = new ArrayList(); try { streamTokenizer.nextToken(); while (streamTokenizer.ttype != StreamTokenizer.TT_EOF) { //For each line - //if (streamTokenizer.ttype == '@') { if (streamTokenizer.ttype == StreamTokenizer.TT_WORD && streamTokenizer.sval.startsWith("@") == true) { - //streamTokenizer.nextToken(); String token = streamTokenizer.sval.toUpperCase(); if (token.startsWith("@RELATION")) { streamTokenizer.nextToken(); @@ -369,13 +351,11 @@ private InstanceInformation getHeader() { } else if (token.startsWith("@ATTRIBUTE")) { streamTokenizer.nextToken(); String name = streamTokenizer.sval; - //System.out.println("* " + name); if (name == null) { name = Double.toString(streamTokenizer.nval); } streamTokenizer.nextToken(); String type = streamTokenizer.sval; - // System.out.println("* " + name + ":" + type + " "); if (streamTokenizer.ttype == '{') { streamTokenizer.nextToken(); List attributeLabels = new ArrayList(); @@ -391,35 +371,21 @@ private InstanceInformation getHeader() { streamTokenizer.nextToken(); } - // System.out.println(); - //attributes.add(new Attribute(name, attributeLabels)); - //commented JD - /* if (this.range.isInRange(numAttribute)) { - outputAttributes.add(new Attribute(name, attributeLabels)); - } else { - inputAttributes.add(new Attribute(name, attributeLabels)); - }*/ auxAttributes.add(new Attribute(name, attributeLabels)); numAttributes++; - } else if (streamTokenizer.sval != null && streamTokenizer.sval.toUpperCase() == "HIERARCHICAL") { - streamTokenizer.nextToken(); - DAGStructure attributeStructure = new DAGStructure(); - if (streamTokenizer.ttype == '{') { - while(streamTokenizer.ttype == '}') { - streamTokenizer.nextToken(); - System.out.println(streamTokenizer.sval); - } - - } - +// } else if (streamTokenizer.sval != null && streamTokenizer.sval.toUpperCase() == "HIERARCHICAL") { +// streamTokenizer.nextToken(); +// DAGStructure attributeStructure = new DAGStructure(); +// if (streamTokenizer.ttype == '{') { +// while(streamTokenizer.ttype != '}') { +// streamTokenizer.nextToken(); +// System.out.println(streamTokenizer.sval); +// } +// +// } +// } else { - // Add attribute - //commented JD - /*if (this.range.isInRange(numAttribute)) { - outputAttributes.add(new Attribute(name)); - } else { - inputAttributes.add(new Attribute(name)); - }*/ + auxAttributes.add(new Attribute(name)); numAttributes++; } @@ -432,29 +398,16 @@ private InstanceInformation getHeader() { } streamTokenizer.nextToken(); } - if (range != null) { - this.range.setUpper(numAttributes); - } - /*if (range==null) //is single-target. All instances should go to inputAtrributes (see setClassIndex(int) from InstanceInformation ) - inputAttributes=auxAttributes; - else//is multi-target - { - this.range.setUpper(numAttribute); - for (int i=0; i outputIndexes; + protected List inputIndexes; + + public Attribute inputAttribute(int w) { return this.attributesInformation.attribute(inputAttributeIndex(w)); } @@ -54,6 +47,8 @@ public Attribute outputAttribute(int w) { return this.attributesInformation.attribute(outputAttributeIndex(w)); } + + /** * Instantiates a new instance information. * @@ -61,9 +56,9 @@ public Attribute outputAttribute(int w) { */ public InstanceInformation(InstanceInformation chunk) { this.relationName = chunk.relationName; + this.outputIndexes = chunk.outputIndexes; + this.inputIndexes = chunk.inputIndexes; this.attributesInformation = chunk.attributesInformation; - this.structure = chunk.structure; - this.classIndex = chunk.classIndex; } /** @@ -72,16 +67,38 @@ public InstanceInformation(InstanceInformation chunk) { * @param st the st * @param v the v */ - public InstanceInformation(String st, List input) { + public InstanceInformation(String st, List attributes, List outputIndexes, List inputIndexes) { + this.relationName = st; + this.outputIndexes = outputIndexes; + this.inputIndexes = inputIndexes; + this.attributesInformation = new AttributesInformation(attributes, attributes.size()); + } + + public InstanceInformation(String st, List input, List indexes) { this.relationName = st; - this.attributesInformation = new AttributesInformation(input, input.size()); + this.outputIndexes = new ArrayList(); + this.inputIndexes = new ArrayList(); + this.attributesInformation = new AttributesInformation(input, indexes, indexes.size()); } + public InstanceInformation(String st, List input) { + this.relationName = st; + this.outputIndexes = new ArrayList(); + this.inputIndexes = new ArrayList(); + List indexes = new ArrayList(); + for (int i = 0; i < input.size(); i++) { + indexes.add(i); + } + this.attributesInformation = new AttributesInformation(input, indexes, indexes.size()); + } + /** * Instantiates a new instance information. */ public InstanceInformation() { this.relationName = null; + this.inputIndexes = null; + this.outputIndexes = null; this.attributesInformation = null; } @@ -104,15 +121,16 @@ public String getRelationName() { * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#classIndex() */ public int classIndex() { - return this.classIndex; + if (this.outputIndexes.size() > 1) + throw new UnsupportedOperationException("This instance has multiple output attributes."); + return this.outputIndexes.get(0); } - /* (non-Javadoc) - * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#setClassIndex(int) - */ - public void setClassIndex(int classIndex) { - this.classIndex = classIndex; + public void setClassIndex(int index) { + this.outputIndexes = new ArrayList(); + this.outputIndexes.add(index); } + /* (non-Javadoc) * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#classAttribute() @@ -163,63 +181,48 @@ public void setAttributes(List v) { } public int inputAttributeIndex(int index) { - int ret = 0; - if (classIndex == Integer.MAX_VALUE) {//Multi Label - if(index index ? index : index + 1; - } - return ret; + // Returns actual instance attribute index! + return inputIndexes.get(index); } - public int outputAttributeIndex(int attributeIndex) { - int ret = 0; - if (classIndex == Integer.MAX_VALUE) {//Multi Label - ret=attributeIndex+range.getStart(); //JD - Range should be a "block" - } else { //Single Label - ret = classIndex; - } - return ret; + public int outputAttributeIndex(int index) { + // Returns actual instance attribute index! + return outputIndexes.get(index); } public int numInputAttributes() { - int ret = 0; - if (classIndex == Integer.MAX_VALUE) {//Multi Label - ret=this.numAttributes()-range.getSelectionLength(); //JD - } else { //Single Label - ret = this.numAttributes() - 1; - } - return ret; + return inputIndexes.size(); } public int numOutputAttributes() { - int ret = 0; - if (classIndex == Integer.MAX_VALUE) {//Multi Label - ret=range.getSelectionLength(); //JD - } else { //Single Label - ret = 1; - } - return ret; - } - public void setRangeOutputIndices(Range range) { - this.setClassIndex(Integer.MAX_VALUE); - this.range = range; + return outputIndexes.size(); } public void setAttributes(List v, List indexValues) { if(this.attributesInformation==null) this.attributesInformation= new AttributesInformation(); this.attributesInformation.setAttributes(v,indexValues); - + } + + public void setOutputIndexes(List outputIndexes) { + this.outputIndexes = outputIndexes; } - public AttributeStructure getStructure() { - return this.structure; + public void setInputIndexes(List inputIndexes) { + this.inputIndexes = inputIndexes; + } + + /** + * Sets all non-output attributes as input attributes. + */ + public void setInputIndexes() { + this.inputIndexes = new ArrayList(); + for (int i = 0; i < attributesInformation.indexValues.size(); i++) { + if (!outputIndexes.contains(attributesInformation.indexValues.get(i))) { + inputIndexes.add(attributesInformation.indexValues.get(i)); + } + } } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instances.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instances.java deleted file mode 100644 index 559e3bdfd..000000000 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instances.java +++ /dev/null @@ -1,582 +0,0 @@ -/* - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ -package com.yahoo.labs.samoa.instances; - -import java.io.Reader; -import java.io.Serializable; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Random; -import moa.core.Utils; - -/** - * The Class Instances. - * - * @author abifet - */ -public class Instances implements Serializable { - - /** - * The keyword used to denote the start of an arff header - */ - public final static String ARFF_RELATION = "@relation"; - - /** - * The keyword used to denote the start of the arff data section - */ - public final static String ARFF_DATA = "@data"; - - private static final long serialVersionUID = 8110510475535581577L; - /** - * The instance information. - */ - protected InstanceInformation instanceInformation; - /** - * The instances. - */ - protected List instances; - - /** - * The arff. - */ - protected ArffLoader arff; - - /** - * A Hash that stores the indices of features. - */ - protected HashMap hsAttributesIndices; - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - */ - public Instances(Instances chunk) { - this(chunk, chunk.numInstances()); - chunk.copyInstances(0, this, chunk.numInstances()); - this.computeAttributesIndices(); - } - - /** - * Instantiates a new instances. - */ - public Instances() { - } - - /** - * Instantiates a new instances. - * - * @param reader the reader - * @param size the size - * @param classAttribute the class attribute - */ - public Instances(Reader reader, int size, int classAttribute) { - arff = new ArffLoader(reader, 0, classAttribute); - this.instanceInformation = arff.getStructure(); - this.instances = new ArrayList(); - this.computeAttributesIndices(); - } - - /** - * Instantiates a new instances. - * - * @param reader the reader - * @param range - */ - public Instances(Reader reader, Range range) { - this.arff = new MultiTargetArffLoader(reader, range); - this.instanceInformation = arff.getStructure(); - this.instances = new ArrayList(); - this.computeAttributesIndices(); - } - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - * @param capacity the capacity - */ - public Instances(Instances chunk, int capacity) { - this.instanceInformation = chunk.instanceInformation(); - if (capacity < 0) { - capacity = 0; - } - this.instances = new ArrayList(capacity); - this.computeAttributesIndices(); - } - - /** - * Instantiates a new instances. - * - * @param st the st - * @param v the v - * @param capacity the capacity - */ - public Instances(String st, List v, int capacity) { - this.instanceInformation = new InstanceInformation(st, v); - this.instances = new ArrayList(capacity); - this.computeAttributesIndices(); - } - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - * @param first the first instance - * @param toCopy the j - */ - public Instances(Instances chunk, int first, int toCopy) { - - this(chunk, toCopy); - - if ((first < 0) || ((first + toCopy) > chunk.numInstances())) { - throw new IllegalArgumentException("Parameters first and/or toCopy out " - + "of range"); - } - chunk.copyInstances(first, this, toCopy); - this.computeAttributesIndices(); - } - - /** - * Instantiates a new instances. - * - * @param st the st - * @param capacity the capacity - */ - public Instances(StringReader st, int capacity) { - this.instances = new ArrayList(capacity); - this.computeAttributesIndices(); - } - - //Information Instances - /** - * Sets the relation name. - * - * @param string the new relation name - */ - public void setRelationName(String string) { - this.instanceInformation.setRelationName(string); - } - - /** - * Gets the relation name. - * - * @return the relation name - */ - public String getRelationName() { - return this.instanceInformation.getRelationName(); - } - - /** - * Class index. - * - * @return the int - */ - public int classIndex() { - return this.instanceInformation.classIndex(); - } - - /** - * Sets the class index. - * - * @param classIndex the new class index - */ - public void setClassIndex(int classIndex) { - this.instanceInformation.setClassIndex(classIndex); - } - - /** - * Class attribute. - * - * @return the attribute - */ - public Attribute classAttribute() { - return this.instanceInformation.classAttribute(); - } - - /** - * Num attributes. - * - * @return the int - */ - public int numAttributes() { - return this.instanceInformation.numAttributes(); - } - - /** - * Attribute. - * - * @param w the w - * @return the attribute - */ - public Attribute attribute(int w) { - return this.instanceInformation.attribute(w); - } - - /** - * Num classes. - * - * @return the int - */ - public int numClasses() { - return this.instanceInformation.numClasses(); - } - - /** - * Delete attribute at. - * - * @param integer the integer - */ - public void deleteAttributeAt(Integer integer) { - this.instanceInformation.deleteAttributeAt(integer); - } - - /** - * Insert attribute at. - * - * @param attribute the attribute - * @param i the i - */ - public void insertAttributeAt(Attribute attribute, int i) { - if (this.instanceInformation == null) { - this.instanceInformation = new InstanceInformation(); - } - this.instanceInformation.insertAttributeAt(attribute, i); - } - - //List of Instances - /** - * Instance. - * - * @param num the num - * @return the instance - */ - public Instance instance(int num) { - return this.instances.get(num); - } - - /** - * Num instances. - * - * @return the int - */ - public int numInstances() { - return this.instances.size(); - } - - /** - * Adds the. - * - * @param inst the inst - */ - public void add(Instance inst) { - this.instances.add(inst.copy()); - } - - /** - * Randomize. - * - * @param random the random - */ - public void randomize(Random random) { - for (int j = numInstances() - 1; j > 0; j--) { - swap(j, random.nextInt(j + 1)); - } - } - - /** - * Stratify. - * - * @param numFolds the num folds - */ - public void stratify(int numFolds) { - - if (classAttribute().isNominal()) { - - // sort by class - int index = 1; - while (index < numInstances()) { - Instance instance1 = instance(index - 1); - for (int j = index; j < numInstances(); j++) { - Instance instance2 = instance(j); - if ((instance1.classValue() == instance2.classValue()) - || (instance1.classIsMissing() - && instance2.classIsMissing())) { - swap(index, j); - index++; - } - } - index++; - } - stratStep(numFolds); - } - } - - protected void stratStep(int numFolds) { - ArrayList newVec = new ArrayList(this.instances.size()); - int start = 0, j; - - // create stratified batch - while (newVec.size() < numInstances()) { - j = start; - while (j < numInstances()) { - newVec.add(instance(j)); - j = j + numFolds; - } - start++; - } - this.instances = newVec; - } - - /** - * Train cv. - * - * @param numFolds the num folds - * @param numFold - * @param n the n - * @param random the random - * @return the instances - */ - public Instances trainCV(int numFolds, int numFold, Random random) { - Instances train = trainCV(numFolds, numFold); - train.randomize(random); - return train; - } - - public Instances trainCV(int numFolds, int numFold) { - int numInstForFold, first, offset; - Instances train; - - numInstForFold = numInstances() / numFolds; - if (numFold < numInstances() % numFolds) { - numInstForFold++; - offset = numFold; - } else { - offset = numInstances() % numFolds; - } - train = new Instances(this, numInstances() - numInstForFold); - first = numFold * (numInstances() / numFolds) + offset; - copyInstances(0, train, first); - copyInstances(first + numInstForFold, train, - numInstances() - first - numInstForFold); - return train; - } - - protected void copyInstances(int from, Instances dest, int num) { - for (int i = 0; i < num; i++) { - dest.add(instance(from + i)); - } - } - - /** - * Test cv. - * - * @param numFolds the num folds - * @param numFold the num fold - * @return the instances - */ - public Instances testCV(int numFolds, int numFold) { - - int numInstForFold, first, offset; - Instances test; - - numInstForFold = numInstances() / numFolds; - if (numFold < numInstances() % numFolds) { - numInstForFold++; - offset = numFold; - } else { - offset = numInstances() % numFolds; - } - test = new Instances(this, numInstForFold); - first = numFold * (numInstances() / numFolds) + offset; - copyInstances(first, test, numInstForFold); - return test; - } - - /* public Instances dataset() { - throw new UnsupportedOperationException("Not yet implemented"); - }*/ - /** - * Mean or mode. - * - * @param j the j - * @return the double - */ - public double meanOrMode(int j) { - throw new UnsupportedOperationException("Not yet implemented"); //CobWeb - } - - /** - * Read instance. - * - * @param fileReader the file reader - * @return true, if successful - */ - public boolean readInstance(Reader fileReader) { - - //ArffReader arff = new ArffReader(reader, this, m_Lines, 1); - Instance inst = arff.readInstance(); - if (inst != null) { - inst.setDataset(this); - add(inst); - return true; - } else { - return false; - } - } - - /** - * Delete. - */ - public void delete() { - this.instances = new ArrayList(); - } - - /** - * Delete. - */ - public void delete(int index) { - this.instances.remove(index); - } - - /** - * Swap. - * - * @param i the i - * @param j the j - */ - public void swap(int i, int j) { - Instance in = instances.get(i); - instances.set(i, instances.get(j)); - instances.set(j, in); - } - - /** - * Instance information. - * - * @return the instance information - */ - private InstanceInformation instanceInformation() { - return this.instanceInformation; - } - - public Attribute attribute(String name) { - - for (int i = 0; i < numAttributes(); i++) { - if (attribute(i).name().equals(name)) { - return attribute(i); - } - } - return null; - } - - public int size() { - return this.numInstances(); - } - - public void set(int i, Instance inst) { - this.instances.set(i, inst); - } - - public Instance get(int k) { - return this.instance(k); - } - - public void setRangeOutputIndices(Range range) { - this.instanceInformation.setRangeOutputIndices(range); - - } - - public void setAttributes(List v) { - if (this.instanceInformation == null) { - this.instanceInformation = new InstanceInformation(); - } - this.instanceInformation.setAttributes(v); - } - - public void setAttributes(List v, List indexValues) { - if (this.instanceInformation == null) { - this.instanceInformation = new InstanceInformation(); - } - this.instanceInformation.setAttributes(v, indexValues); - } - - /** - * Returns the dataset as a string in ARFF format. Strings are quoted if - * they contain whitespace characters, or if they are a question mark. - * - * @return the dataset in ARFF format as a string - */ - public String toString() { - - StringBuffer text = new StringBuffer(); - - text.append(ARFF_RELATION).append(" "). - append(Utils.quote(this.instanceInformation.getRelationName())).append("\n\n"); - for (int i = 0; i < numAttributes(); i++) { - text.append(attribute(i).toString()).append("\n"); - } - text.append("\n").append(ARFF_DATA).append("\n"); - - text.append(stringWithoutHeader()); - return text.toString(); - } - - /** - * Returns the instances in the dataset as a string in ARFF format. Strings - * are quoted if they contain whitespace characters, or if they are a - * question mark. - * - * @return the dataset in ARFF format as a string - */ - protected String stringWithoutHeader() { - - StringBuffer text = new StringBuffer(); - - for (int i = 0; i < numInstances(); i++) { - text.append(instance(i)); - if (i < numInstances() - 1) { - text.append('\n'); - } - } - return text.toString(); - - } - - /** - * Returns the index of an Attribute. - * - * @param att, the attribute. - */ - protected int indexOf(Attribute att) { - return this.hsAttributesIndices.get(att.name()); - } - - /** - * Completes the hashset with attributes indices. - */ - private void computeAttributesIndices() { - this.hsAttributesIndices = new HashMap(); - // iterates through all existing attributes - // and sets an unique identifier for each one of them - for (int i = 0; i < this.numAttributes(); i++) { - hsAttributesIndices.put(this.attribute(i).name(), i); - } - } - -} diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java index 6086fa888..421cbb74e 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java @@ -15,116 +15,642 @@ */ package com.yahoo.labs.samoa.instances; +import java.io.Reader; +import java.io.Serializable; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.junit.experimental.theories.Theories; + +import moa.core.Utils; + /** - * Class for storing the header or context of a data stream. It allows to know - * the number of attributes and classes. + * The Class Instances. * - * @version $Revision: 7 $ + * @author abifet */ -public class InstancesHeader extends Instances { +public class InstancesHeader implements Serializable { + /** The keyword used to denote the start of an arff header */ + public final static String ARFF_RELATION = "@relation"; + + /** The keyword used to denote the start of the arff data section */ + public final static String ARFF_DATA = "@data"; + private static final long serialVersionUID = 1L; - public InstancesHeader(Instances i) { - super(i, 0); + /** + * The instance information. + */ + protected InstanceInformation instanceInformation; + /** + * The instances. + */ + protected List instances; + + /** + * The arff. + */ + protected ArffLoader arff; + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + */ + public InstancesHeader(InstancesHeader chunk) { + this(chunk, chunk.numInstances()); + chunk.copyInstances(0, this, chunk.numInstances()); } + /** + * Instantiates a new instances. + */ public InstancesHeader() { - super(); } - public static String getClassNameString(InstancesHeader context) { - if (context == null) { - return "[class]"; - } - return "[class:" + context.classAttribute().name() + "]"; + /** + * Instantiates a new instances. + * + * @param reader the reader + * @param size the size + * @param classAttribute the class attribute + */ + public InstancesHeader(Reader reader, int size, int classAttribute) { + arff = new ArffLoader(reader, String.valueOf(classAttribute)); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); } - public static String getClassLabelString(InstancesHeader context, - int classLabelIndex) { - if ((context == null) || (classLabelIndex >= context.numClasses())) { - return ""; + public InstancesHeader(Reader reader, String outputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + public InstancesHeader(Reader reader, String outputDefinition, String inputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + public InstancesHeader(Reader reader, int size, String outputDefinition, String inputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + /** + * Instantiates a new instances. + * + * @param reader the reader + * @param range + */ +// public Instances(Reader reader, Range range) { +// this.arff = new MultiTargetArffLoader(reader, range); +// this.instanceInformation = arff.getStructure(); +// this.instances = new ArrayList(); +// } + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + * @param capacity the capacity + */ + public InstancesHeader(InstancesHeader chunk, int capacity) { + this.instanceInformation = chunk.instanceInformation(); + if (capacity < 0) { + capacity = 0; } - return ""; + this.instances = new ArrayList(capacity); } - // is impervious to class index changes - attIndex is true attribute index - // regardless of class position - public static String getAttributeNameString(InstancesHeader context, - int attIndex) { - if ((context == null) || (attIndex >= context.numAttributes())) { - return "[att " + (attIndex + 1) + "]"; + /** + * Instantiates a new instances. + * + * @param st the st + * @param v the v + * @param capacity the capacity + */ + public InstancesHeader(String st, List v, int capacity) { + this.instanceInformation = new InstanceInformation(st, v); + } + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + * @param first the first instance + * @param toCopy the j + */ + public InstancesHeader(InstancesHeader chunk, int first, int toCopy) { + + this(chunk, toCopy); + + if ((first < 0) || ((first + toCopy) > chunk.numInstances())) { + throw new IllegalArgumentException("Parameters first and/or toCopy out " + + "of range"); } - int instAttIndex = attIndex < context.classIndex() ? attIndex - : attIndex + 1; - return "[att " + (attIndex + 1) + ":" - + context.attribute(instAttIndex).name() + "]"; + chunk.copyInstances(first, this, toCopy); + } + + /** + * Instantiates a new instances. + * + * @param st the st + * @param capacity the capacity + */ + public InstancesHeader(StringReader st, int capacity) { + this.instances = new ArrayList(capacity); + } + + //Information Instances + /** + * Sets the relation name. + * + * @param string the new relation name + */ + public void setRelationName(String string) { + this.instanceInformation.setRelationName(string); } - public static String getInputAttributeNameString(InstancesHeader context, - int attIndex) { - if ((context == null) || (attIndex >= context.numInputAttributes())) { - return "[att " + (attIndex + 1) + "]"; + /** + * Gets the relation name. + * + * @return the relation name + */ + public String getRelationName() { + return this.instanceInformation.getRelationName(); + } + + /** + * Class index. + * + * @return the int + */ + public int classIndex() { + return this.instanceInformation.classIndex(); + } + + /** + * Sets the class index. Also sets all other attributes as input attributes for backward compatibility. + * + * @param classIndex the new class index + */ + public void setClassIndex(int classIndex) { + this.instanceInformation.setClassIndex(classIndex); + this.instanceInformation.setInputIndexes(); + } + + public void setOutputIndexes(List outputIndexes) { + this.instanceInformation.setOutputIndexes(outputIndexes); + } + + public void setInputIndexes(List inputIndexes) { + this.instanceInformation.setInputIndexes(inputIndexes); + } + + /** + * Sets all non-output attributes as input attributes. + */ + public void setInputIndexes() { + this.instanceInformation.setInputIndexes(); + } + + /** + * Class attribute. + * + * @return the attribute + */ + public Attribute classAttribute() { + return this.instanceInformation.classAttribute(); + } + + /** + * Num attributes. + * + * @return the int + */ + public int numAttributes() { + return this.instanceInformation.numAttributes(); + } + + /** + * Attribute. + * + * @param w the w + * @return the attribute + */ + public Attribute attribute(int w) { + return this.instanceInformation.attribute(w); + } + + /** + * Num classes. + * + * @return the int + */ + public int numClasses() { + return this.instanceInformation.numClasses(); + } + + /** + * Delete attribute at. + * + * @param integer the integer + */ + public void deleteAttributeAt(Integer integer) { + this.instanceInformation.deleteAttributeAt(integer); + } + + /** + * Insert attribute at. + * + * @param attribute the attribute + * @param i the i + */ + public void insertAttributeAt(Attribute attribute, int i) { + if (this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.insertAttributeAt(attribute, i); + } + + //List of Instances + /** + * Instance. + * + * @param num the num + * @return the instance + */ + public Instance instance(int num) { + return this.instances.get(num); + } + + /** + * Num instances. + * + * @return the int + */ + public int numInstances() { + return this.instances.size(); + } + + /** + * Adds the. + * + * @param inst the inst + */ + public void add(Instance inst) { + this.instances.add(inst.copy()); + } + + /** + * Randomize. + * + * @param random the random + */ + public void randomize(Random random) { + for (int j = numInstances() - 1; j > 0; j--) { + swap(j, random.nextInt(j + 1)); } - int instAttIndex = attIndex; - return "[att " + (attIndex + 1) + ":" - + context.inputAttribute(instAttIndex).name() + "]"; - } - - // is impervious to class index changes - attIndex is true attribute index - // regardless of class position - public static String getNominalValueString(InstancesHeader context, - int attIndex, int valIndex) { - if (context != null) { - int instAttIndex = attIndex < context.classIndex() ? attIndex - : attIndex + 1; - if ((instAttIndex < context.numAttributes()) - && (valIndex < context.attribute(instAttIndex).numValues())) { - return "{val " + (valIndex + 1) + ":" - + context.attribute(instAttIndex).value(valIndex) + "}"; + } + + /** + * Stratify. + * + * @param numFolds the num folds + */ + public void stratify(int numFolds) { + + if (classAttribute().isNominal()) { + + // sort by class + int index = 1; + while (index < numInstances()) { + Instance instance1 = instance(index - 1); + for (int j = index; j < numInstances(); j++) { + Instance instance2 = instance(j); + if ((instance1.classValue() == instance2.classValue()) + || (instance1.classIsMissing() + && instance2.classIsMissing())) { + swap(index, j); + index++; + } + } + index++; } + stratStep(numFolds); } - return "{val " + (valIndex + 1) + "}"; - } - - // is impervious to class index changes - attIndex is true attribute index - // regardless of class position - public static String getNumericValueString(InstancesHeader context, - int attIndex, double value) { - if (context != null) { - int instAttIndex = attIndex < context.classIndex() ? attIndex - : attIndex + 1; - if (instAttIndex < context.numAttributes()) { - if (context.attribute(instAttIndex).isDate()) { - return context.attribute(instAttIndex).formatDate(value); - } + } + + protected void stratStep(int numFolds) { + ArrayList newVec = new ArrayList(this.instances.size()); + int start = 0, j; + + // create stratified batch + while (newVec.size() < numInstances()) { + j = start; + while (j < numInstances()) { + newVec.add(instance(j)); + j = j + numFolds; } + start++; + } + this.instances = newVec; + } + + /** + * Train cv. + * + * @param numFolds the num folds + * @param numFold + * @param n the n + * @param random the random + * @return the instances + */ + public InstancesHeader trainCV(int numFolds, int numFold, Random random) { + InstancesHeader train = trainCV(numFolds, numFold); + train.randomize(random); + return train; + } + + public InstancesHeader trainCV(int numFolds, int numFold) { + int numInstForFold, first, offset; + InstancesHeader train; + + numInstForFold = numInstances() / numFolds; + if (numFold < numInstances() % numFolds) { + numInstForFold++; + offset = numFold; + } else { + offset = numInstances() % numFolds; + } + train = new InstancesHeader(this, numInstances() - numInstForFold); + first = numFold * (numInstances() / numFolds) + offset; + copyInstances(0, train, first); + copyInstances(first + numInstForFold, train, + numInstances() - first - numInstForFold); + return train; + } + + protected void copyInstances(int from, InstancesHeader dest, int num) { + for (int i = 0; i < num; i++) { + dest.add(instance(from + i)); + } + } + + /** + * Test cv. + * + * @param numFolds the num folds + * @param numFold the num fold + * @return the instances + */ + public InstancesHeader testCV(int numFolds, int numFold) { + + int numInstForFold, first, offset; + InstancesHeader test; + + numInstForFold = numInstances() / numFolds; + if (numFold < numInstances() % numFolds) { + numInstForFold++; + offset = numFold; + } else { + offset = numInstances() % numFolds; } - return Double.toString(value); + test = new InstancesHeader(this, numInstForFold); + first = numFold * (numInstances() / numFolds) + offset; + copyInstances(first, test, numInstForFold); + return test; } - public Attribute inputAttribute(int w) { - return this.instanceInformation.inputAttribute(w); + /* public Instances dataset() { + throw new UnsupportedOperationException("Not yet implemented"); + }*/ + /** + * Mean or mode. + * + * @param j the j + * @return the double + */ + public double meanOrMode(int j) { + throw new UnsupportedOperationException("Not yet implemented"); //CobWeb } - public Attribute outputAttribute(int w) { - return this.instanceInformation.outputAttribute(w); + /** + * Read instance. + * + * @param fileReader the file reader + * @return true, if successful + */ + public boolean readInstance(Reader fileReader) { + + //ArffReader arff = new ArffReader(reader, this, m_Lines, 1); + Instance inst = arff.readInstance(); + if (inst != null) { + inst.setDataset(this); + add(inst); + return true; + } else { + return false; + } } - public int numInputAttributes() { - return this.instanceInformation.numInputAttributes(); + /** + * Delete. + */ + public void delete() { + this.instances = new ArrayList(); + } + + /** + * Delete. + */ + public void delete(int index) { + this.instances.remove(index); } - public int numOutputAttributes() { - return this.instanceInformation.numOutputAttributes(); + + /** + * Swap. + * + * @param i the i + * @param j the j + */ + public void swap(int i, int j) { + Instance in = instances.get(i); + instances.set(i, instances.get(j)); + instances.set(j, in); } - public InstanceInformation getInstanceInformation() { + /** + * Instance information. + * + * @return the instance information + */ + private InstanceInformation instanceInformation() { return this.instanceInformation; } + + public Attribute attribute(String name) { + + for (int i = 0; i < numAttributes(); i++) { + if (attribute(i).name().equals(name)) { + return attribute(i); + } + } + return null; + } + + public int size() { + return this.numInstances(); + } + + public void set(int i, Instance inst) { + this.instances.set(i, inst); + } + + public Instance get(int k) { + return this.instance(k); + } + +// public void setRangeOutputIndices(Range range) { +// this.instanceInformation.setRangeOutputIndices(range); +// +// } + + public void setAttributes(List v) { + if(this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.setAttributes(v); + } + + public void setAttributes(List v, List indexValues) { + if(this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.setAttributes(v, indexValues); + } + + /** + * Returns the dataset as a string in ARFF format. Strings + * are quoted if they contain whitespace characters, or if they + * are a question mark. + * + * @return the dataset in ARFF format as a string + */ + public String toString() { + + StringBuffer text = new StringBuffer(); + + text.append(ARFF_RELATION).append(" "). + append(Utils.quote( this.instanceInformation.getRelationName())).append("\n\n"); + for (int i = 0; i < numAttributes(); i++) { + text.append(attribute(i).toString()).append("\n"); + } + text.append("\n").append(ARFF_DATA).append("\n"); + + text.append(stringWithoutHeader()); + return text.toString(); + } + + /** + * Returns the instances in the dataset as a string in ARFF format. Strings + * are quoted if they contain whitespace characters, or if they + * are a question mark. + * + * @return the dataset in ARFF format as a string + */ + protected String stringWithoutHeader() { - public AttributeStructure getInstanceStructure() { - return this.instanceInformation.getStructure(); + StringBuffer text = new StringBuffer(); + + for (int i = 0; i < numInstances(); i++) { + text.append(instance(i)); + if (i < numInstances() - 1) { + text.append('\n'); + } } + return text.toString(); + + } + + public Attribute inputAttribute(int w) { + return this.instanceInformation.inputAttribute(w); + } + + public Attribute outputAttribute(int w) { + return this.instanceInformation.outputAttribute(w); + } + + public int numInputAttributes() { + return this.instanceInformation.numInputAttributes(); + } + + public int numOutputAttributes() { + return this.instanceInformation.numOutputAttributes(); + } + + public InstanceInformation getInstanceInformation() { + return this.instanceInformation; + } + + public static String getClassNameString(InstancesHeader context) { + if (context == null) { + return "[class]"; + } + return "[class:" + context.classAttribute().name() + "]"; + } + + public static String getClassLabelString(InstancesHeader context, int classLabelIndex) { + if ((context == null) || (classLabelIndex >= context.numClasses())) { + return ""; + } + return ""; + } + + public static String getAttributeNameString(InstancesHeader context, int attIndex) { + if ((context == null) || (attIndex >= context.numAttributes())) { + return "[att " + (attIndex + 1) + "]"; + } + return "[att " + (attIndex + 1) + ":" + + context.attribute(attIndex).name() + "]"; + } + + public static String getInputAttributeNameString(InstancesHeader context, int attIndex) { + if ((context == null) || (attIndex >= context.numInputAttributes())) { + return "[att " + (attIndex + 1) + "]"; + } + return "[att " + (attIndex + 1) + ":" + + context.inputAttribute(attIndex).name() + "]"; + } + + public static String getNominalValueString(InstancesHeader context, int attIndex, int valIndex) { + if (context != null) { + if ((attIndex < context.numInputAttributes()) + && (valIndex < context.inputAttribute(attIndex).numValues())) { + return "{val " + (valIndex + 1) + ":" + + context.inputAttribute(attIndex).value(valIndex) + "}"; + } + } + return "{val " + (valIndex + 1) + "}"; + } + + public static String getNumericValueString(InstancesHeader context, int attIndex, double value) { + if (context != null) { + int instAttIndex = attIndex < context.classIndex() ? attIndex + : attIndex + 1; + if (instAttIndex < context.numAttributes()) { + if (context.attribute(instAttIndex).isDate()) { + return context.attribute(instAttIndex).formatDate(value); + } + } + } + return Double.toString(value); + } + + } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoader.java index fc7392e68..a0a4b0b48 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoader.java @@ -19,24 +19,31 @@ public class MultiTargetArffLoader extends ArffLoader { - public MultiTargetArffLoader(Reader reader) { - super(reader); - } + public MultiTargetArffLoader(Reader reader, String outputDefinition, String inputDefinition) { + super(reader, outputDefinition, inputDefinition); + // TODO Auto-generated constructor stub + } - public MultiTargetArffLoader(Reader reader, Range range) { - super(reader, range); - } - - @Override - protected Instance newSparseInstance(double d, double[] res) { - return new SparseInstance(d, res); // TODO - } - - @Override - protected Instance newDenseInstance(int numAttributes) { - // numAttributes is this.instanceInformation.numAttributes() - this.range.setUpper(numAttributes); - return new DenseInstance(numAttributes); - } +// DEPRECATED + +// public MultiTargetArffLoader(Reader reader) { +// super(reader); +// } +// +// public MultiTargetArffLoader(Reader reader, Range range) { +// super(reader, range); +// } +// +// @Override +// protected Instance newSparseInstance(double d, double[] res) { +// return new SparseInstance(d, res); // TODO +// } +// +// @Override +// protected Instance newDenseInstance(int numAttributes) { +// // numAttributes is this.instanceInformation.numAttributes() +// this.range.setUpper(numAttributes); +// return new DenseInstance(numAttributes); +// } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java index ab27c38fb..d02e5fbbc 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java @@ -1,3 +1,4 @@ + /* * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/SamoaToWekaInstanceConverter.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/SamoaToWekaInstanceConverter.java index f94851d93..3ef342875 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/SamoaToWekaInstanceConverter.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/SamoaToWekaInstanceConverter.java @@ -77,7 +77,7 @@ public weka.core.Instance wekaInstance(Instance inst) { * @param instances the instances * @return the weka.core. instances */ - public weka.core.Instances wekaInstances(Instances instances) { + public weka.core.Instances wekaInstances(InstancesHeader instances) { weka.core.Instances wekaInstances = wekaInstancesInformation(instances); //We assume that we have only one WekaInstanceInformation for SamoaToWekaInstanceConverter this.wekaInstanceInformation = wekaInstances; @@ -93,7 +93,7 @@ public weka.core.Instances wekaInstances(Instances instances) { * @param instances the instances * @return the weka.core. instances */ - public weka.core.Instances wekaInstancesInformation(Instances instances) { + public weka.core.Instances wekaInstancesInformation(InstancesHeader instances) { weka.core.Instances wekaInstances; ArrayList attInfo = new ArrayList(); for (int i = 0; i < instances.numAttributes(); i++) { diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java index 279d6baed..9867f74ca 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java @@ -19,6 +19,9 @@ * The Interface StructuredInstance. * * @author abifet + * + * A placeholder for structured instances. + * */ public interface StructuredInstance extends Instance { diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/WekaToSamoaInstanceConverter.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/WekaToSamoaInstanceConverter.java index f49d7397d..1937f6274 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/WekaToSamoaInstanceConverter.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/WekaToSamoaInstanceConverter.java @@ -26,7 +26,7 @@ */ public class WekaToSamoaInstanceConverter implements Serializable{ - protected Instances samoaInstanceInformation; + protected InstancesHeader samoaInstanceInformation; /** * Samoa instance from weka instance. @@ -65,8 +65,8 @@ public Instance samoaInstance(weka.core.Instance inst) { * @param instances the instances * @return the instances */ - public Instances samoaInstances(weka.core.Instances instances) { - Instances samoaInstances = samoaInstancesInformation(instances); + public InstancesHeader samoaInstances(weka.core.Instances instances) { + InstancesHeader samoaInstances = samoaInstancesInformation(instances); //We assume that we have only one samoaInstanceInformation for WekaToSamoaInstanceConverter this.samoaInstanceInformation = samoaInstances; for (int i = 0; i < instances.numInstances(); i++) { @@ -81,13 +81,13 @@ public Instances samoaInstances(weka.core.Instances instances) { * @param instances the instances * @return the instances */ - public Instances samoaInstancesInformation(weka.core.Instances instances) { - Instances samoaInstances; + public InstancesHeader samoaInstancesInformation(weka.core.Instances instances) { + InstancesHeader samoaInstances; List attInfo = new ArrayList(); for (int i = 0; i < instances.numAttributes(); i++) { attInfo.add(samoaAttribute(i, instances.attribute(i))); } - samoaInstances = new Instances(instances.relationName(), attInfo, 0); + samoaInstances = new InstancesHeader(instances.relationName(), attInfo, 0); samoaInstances.setClassIndex(instances.classIndex()); return samoaInstances; } diff --git a/moa/src/main/java/moa/classifiers/AbstractClassifier.java b/moa/src/main/java/moa/classifiers/AbstractClassifier.java index ee1c01c47..fb8daca38 100644 --- a/moa/src/main/java/moa/classifiers/AbstractClassifier.java +++ b/moa/src/main/java/moa/classifiers/AbstractClassifier.java @@ -44,7 +44,7 @@ import com.yahoo.labs.samoa.instances.DenseInstanceData; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -68,7 +68,7 @@ public String getPurposeString() { protected int randomSeed = 1; /** Option for randomizable learners to change the random seed */ - protected IntOption randomSeedOption; + public IntOption randomSeedOption; /** Random Generator used in randomizable learners */ public Random classifierRandom; @@ -91,9 +91,9 @@ public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) } // resetLearning should not be called if the classifier has not yet received the context -// if (!trainingHasStarted()) { -// resetLearning(); -// } + if (!trainingHasStarted()) { + resetLearning(); + } } @@ -120,7 +120,7 @@ public Prediction getPredictionForInstance(Instance inst){ @Override public void setModelContext(InstancesHeader ih) { - if ((ih != null) && (ih.classIndex() < 0)) { + if ((ih != null) && (ih.numOutputAttributes() < 1)) { throw new IllegalArgumentException( "Context for a classifier must include a class to learn"); } @@ -131,6 +131,10 @@ public void setModelContext(InstancesHeader ih) { "New context is not compatible with existing model"); } this.modelContext = ih; + this.modelContextSet(); + } + + public void modelContextSet() { } @Override @@ -170,7 +174,7 @@ public void resetLearning() { public void trainOnInstance(Instance inst) { boolean isTraining = (inst.weight() > 0.0); if (this instanceof SemiSupervisedLearner == false && - inst.classIsMissing() == true){ + inst.missingOutputs() == true){ isTraining = false; } if (isTraining) { @@ -430,7 +434,7 @@ protected static int modelAttIndexToInstanceAttIndex(int index, * @return the index of the attribute in the instances */ protected static int modelAttIndexToInstanceAttIndex(int index, - Instances insts) { + InstancesHeader insts) { return insts.classIndex() > index ? index : index + 1; } } diff --git a/moa/src/main/java/moa/classifiers/bayes/NaiveBayesMultinomial.java b/moa/src/main/java/moa/classifiers/bayes/NaiveBayesMultinomial.java index 523e8d6c8..5e474770e 100644 --- a/moa/src/main/java/moa/classifiers/bayes/NaiveBayesMultinomial.java +++ b/moa/src/main/java/moa/classifiers/bayes/NaiveBayesMultinomial.java @@ -28,7 +28,7 @@ import moa.core.StringUtils; import moa.core.Utils; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Class for building and using a multinomial Naive @@ -77,7 +77,7 @@ public String getPurposeString() { /** * copy of header information for use in toString method */ - protected Instances m_headerInfo; + protected InstancesHeader m_headerInfo; /** * number of class values diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/InstanceConditionalTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/InstanceConditionalTest.java index fad4d9a30..9d5160136 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/InstanceConditionalTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/InstanceConditionalTest.java @@ -20,8 +20,9 @@ package moa.classifiers.core.conditionaltests; import moa.AbstractMOAObject; -import com.yahoo.labs.samoa.instances.InstancesHeader; + import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Abstract conditional test for instances to use to split nodes in Hoeffding trees. diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeBinaryTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeBinaryTest.java index 73498ff6b..519ec6a42 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeBinaryTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeBinaryTest.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Nominal binary conditional test for instances to use to split nodes in Hoeffding trees. diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeMultiwayTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeMultiwayTest.java index 003cf416c..a0dd5ff7b 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeMultiwayTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeMultiwayTest.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Nominal multi way conditional test for instances to use to split nodes in Hoeffding trees. diff --git a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java index d8cb5e8c3..597a7c07f 100644 --- a/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java +++ b/moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Numeric binary conditional test for instances to use to split nodes in Hoeffding trees. diff --git a/moa/src/main/java/moa/classifiers/lazy/kNN.java b/moa/src/main/java/moa/classifiers/lazy/kNN.java index da99909e9..1cf765b1d 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNN.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNN.java @@ -24,7 +24,6 @@ import moa.classifiers.lazy.neighboursearch.NearestNeighbourSearch; import moa.core.Measurement; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; @@ -62,12 +61,12 @@ public String getPurposeString() { return "kNN: special."; } - protected Instances window; + protected InstancesHeader window; @Override public void setModelContext(InstancesHeader context) { try { - this.window = new Instances(context,0); //new StringReader(context.toString()) + this.window = new InstancesHeader(context,0); //new StringReader(context.toString()) this.window.setClassIndex(context.classIndex()); } catch(Exception e) { System.err.println("Error: no Model Context available."); @@ -86,7 +85,7 @@ public void trainOnInstanceImpl(Instance inst) { if (inst.classValue() > C) C = (int)inst.classValue(); if (this.window == null) { - this.window = new Instances(inst.dataset()); + this.window = new InstancesHeader(inst.dataset()); } if (this.limitOption.getValue() <= this.window.numInstances()) { this.window.delete(0); @@ -106,7 +105,7 @@ public double[] getVotesForInstance(Instance inst) { search.setInstances(this.window); } if (this.window.numInstances()>0) { - Instances neighbours = search.kNearestNeighbours(inst,Math.min(kOption.getValue(),this.window.numInstances())); + InstancesHeader neighbours = search.kNearestNeighbours(inst,Math.min(kOption.getValue(),this.window.numInstances())); for(int i = 0; i < neighbours.numInstances(); i++) { v[(int)neighbours.instance(i).classValue()]++; } diff --git a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java index 9d7103053..6b78777a3 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java @@ -19,7 +19,7 @@ import moa.classifiers.core.driftdetection.ADWIN; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * k Nearest Neighbor ADAPTIVE with PAW.

@@ -57,7 +57,7 @@ public void trainOnInstanceImpl(Instance inst) { C = (int) inst.classValue(); } if (this.window == null) { - this.window = new Instances(inst.dataset()); + this.window = new InstancesHeader(inst.dataset()); } for (int i = 0; i < this.window.size(); i++) { diff --git a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java index 1ff1b2412..65e9266ed 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java @@ -20,7 +20,7 @@ import java.util.ArrayList; import moa.classifiers.core.driftdetection.ADWIN; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * k Nearest Neighbor ADAPTIVE with ADWIN+PAW.

@@ -67,7 +67,7 @@ public void trainOnInstanceImpl(Instance inst) { } // ADWIN if (this.window == null) { - this.window = new Instances(inst.dataset()); + this.window = new InstancesHeader(inst.dataset()); } if (this.timeStamp == null) { diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/DistanceFunction.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/DistanceFunction.java index 9df3b3a4c..ef0723941 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/DistanceFunction.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/DistanceFunction.java @@ -22,7 +22,7 @@ package moa.classifiers.lazy.neighboursearch; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Interface for any class that can compute and return distances between two @@ -38,14 +38,14 @@ public interface DistanceFunction { * * @param insts the instances to use */ - public void setInstances(Instances insts); + public void setInstances(InstancesHeader insts); /** * returns the instances currently set. * * @return the current instances */ - public Instances getInstances(); + public InstancesHeader getInstances(); /** * Sets the range of attributes to use in the calculation of the distance. diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/EuclideanDistance.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/EuclideanDistance.java index f21197d81..ac9743bbc 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/EuclideanDistance.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/EuclideanDistance.java @@ -22,7 +22,7 @@ package moa.classifiers.lazy.neighboursearch; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** @@ -92,7 +92,7 @@ public EuclideanDistance() { * * @param data the instances the distance function should work on */ - public EuclideanDistance(Instances data) { + public EuclideanDistance(InstancesHeader data) { super(data); } @@ -195,7 +195,7 @@ public double getMiddle(double[] ranges) { * @return the index of the closest point * @throws Exception if something goes wrong */ - public int closestPoint(Instance instance, Instances allPoints, + public int closestPoint(Instance instance, InstancesHeader allPoints, int[] pointList) throws Exception { double minDist = Integer.MAX_VALUE; int bestPoint = 0; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java index 3a44f2b70..b3b6d7a0d 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java @@ -27,7 +27,7 @@ import moa.classifiers.lazy.neighboursearch.kdtrees.KDTreeNodeSplitter; import moa.classifiers.lazy.neighboursearch.kdtrees.SlidingMidPointOfWidestSide; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; @@ -151,7 +151,7 @@ public KDTree() { * @param insts The instances/points on which the BallTree * should be built on. */ - public KDTree(Instances insts) { + public KDTree(InstancesHeader insts) { super(insts); } @@ -166,7 +166,7 @@ public KDTree(Instances insts) { * @param instances The instances to build the tree on * @throws Exception if something goes wrong */ - protected void buildKDTree(Instances instances) throws Exception { + protected void buildKDTree(InstancesHeader instances) throws Exception { checkMissing(instances); if (m_EuclideanDistance == null) @@ -325,13 +325,13 @@ protected void findNearestNeighbours(Instance target, KDTreeNode node, int k, * one neighbours at the kth boundary). * @throws Exception if the nearest neighbour could not be found. */ - public Instances kNearestNeighbours(Instance target, int k) throws Exception { + public InstancesHeader kNearestNeighbours(Instance target, int k) throws Exception { checkMissing(target); MyHeap heap = new MyHeap(k); findNearestNeighbours(target, m_Root, k, heap, 0.0); - Instances neighbours = new Instances(m_Instances, (heap.size() + heap + InstancesHeader neighbours = new InstancesHeader(m_Instances, (heap.size() + heap .noOfKthNearest())); m_DistanceList = new double[heap.size() + heap.noOfKthNearest()]; int[] indices = new int[heap.size() + heap.noOfKthNearest()]; @@ -399,7 +399,7 @@ public double[] getDistances() throws Exception { * @throws Exception If some error occurs while * building the KDTree */ - public void setInstances(Instances instances) throws Exception { + public void setInstances(InstancesHeader instances) throws Exception { super.setInstances(instances); buildKDTree(instances); } @@ -527,7 +527,7 @@ public void addInstanceInfo(Instance instance) { * @param instances the instances to check * @throws Exception if missing values are encountered */ - protected void checkMissing(Instances instances) throws Exception { + protected void checkMissing(InstancesHeader instances) throws Exception { for (int i = 0; i < instances.numInstances(); i++) { Instance ins = instances.instance(i); for (int j = 0; j < ins.numValues(); j++) { @@ -698,7 +698,7 @@ public void setMeasurePerformance(boolean measurePerformance) { * @throws Exception If there is some problem * assigning instances to centers. */ - public void centerInstances(Instances centers, int[] assignments, double pc) + public void centerInstances(InstancesHeader centers, int[] assignments, double pc) throws Exception { int[] centList = new int[centers.numInstances()]; @@ -719,7 +719,7 @@ public void centerInstances(Instances centers, int[] assignments, double pc) * @throws Exception If there is some problem assigning * instances to centers. */ - protected void determineAssignments(KDTreeNode node, Instances centers, + protected void determineAssignments(KDTreeNode node, InstancesHeader centers, int[] candidates, int[] assignments, double pc) throws Exception { // reduce number of owners for current hyper rectangle @@ -752,7 +752,7 @@ protected void determineAssignments(KDTreeNode node, Instances centers, * @return list of owners * @throws Exception If some problem occurs in refining. */ - protected int[] refineOwners(KDTreeNode node, Instances centers, + protected int[] refineOwners(KDTreeNode node, InstancesHeader centers, int[] candidates) throws Exception { int[] owners = new int[candidates.length]; @@ -907,7 +907,7 @@ protected boolean candidateIsFullOwner(KDTreeNode node, Instance candidate, * @param assignments index list of last assignments * @throws Exception If there is error assigning the instances. */ - public void assignSubToCenters(KDTreeNode node, Instances centers, + public void assignSubToCenters(KDTreeNode node, InstancesHeader centers, int[] centList, int[] assignments) throws Exception { // todo: undecided situations int numCent = centList.length; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/LinearNNSearch.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/LinearNNSearch.java index 59b1f07bb..3c51f26c5 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/LinearNNSearch.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/LinearNNSearch.java @@ -22,7 +22,7 @@ import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; //import weka.core.Option; //import weka.core.RevisionUtils; //import weka.core.Utils; @@ -73,7 +73,7 @@ public LinearNNSearch() { * * @param insts the instances to use */ - public LinearNNSearch(Instances insts) { + public LinearNNSearch(InstancesHeader insts) { super(insts); m_DistanceFunction.setInstances(insts); } @@ -143,7 +143,7 @@ public Instance nearestNeighbour(Instance target) throws Exception { * @return the k nearest neighbors * @throws Exception if the neighbours could not be found. */ - public Instances kNearestNeighbours(Instance target, int kNN) throws Exception { + public InstancesHeader kNearestNeighbours(Instance target, int kNN) throws Exception { //debug boolean print=false; @@ -182,7 +182,7 @@ else if(distance == temp.distance) { } } - Instances neighbours = new Instances(m_Instances, (heap.size()+heap.noOfKthNearest())); + InstancesHeader neighbours = new InstancesHeader(m_Instances, (heap.size()+heap.noOfKthNearest())); m_Distances = new double[heap.size()+heap.noOfKthNearest()]; int [] indices = new int[heap.size()+heap.noOfKthNearest()]; int i=1; MyHeapElement h; @@ -240,7 +240,7 @@ public double[] getDistances() throws Exception { * training set. * @throws Exception if setting of instances fails */ - public void setInstances(Instances insts) throws Exception { + public void setInstances(InstancesHeader insts) throws Exception { m_Instances = insts; m_DistanceFunction.setInstances(insts); } diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java index 5b8402c35..ddefd58ae 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java @@ -22,7 +22,7 @@ import java.io.Serializable; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Abstract class for nearest neighbour search. All algorithms (classes) that @@ -482,7 +482,7 @@ public NeighborNode getLast() { } /** The neighbourhood of instances to find neighbours in. */ - protected Instances m_Instances; + protected InstancesHeader m_Instances; /** The number of neighbours to find. */ protected int m_kNN; @@ -504,7 +504,7 @@ public NearestNeighbourSearch() { * * @param insts The set of instances that constitute the neighbourhood. */ - public NearestNeighbourSearch(Instances insts) { + public NearestNeighbourSearch(InstancesHeader insts) { this(); m_Instances = insts; } @@ -592,7 +592,7 @@ public boolean getMeasurePerformance() { * @return the k nearest neighbors * @throws Exception if the neighbours could not be found. */ - public abstract Instances kNearestNeighbours(Instance target, int k) throws Exception; + public abstract InstancesHeader kNearestNeighbours(Instance target, int k) throws Exception; /** * Returns the distances of the k nearest neighbours. The kNearestNeighbours @@ -629,7 +629,7 @@ public void addInstanceInfo(Instance ins) { * @param insts the instances to use * @throws Exception if setting fails */ - public void setInstances(Instances insts) throws Exception { + public void setInstances(InstancesHeader insts) throws Exception { m_Instances = insts; } @@ -638,7 +638,7 @@ public void setInstances(Instances insts) throws Exception { * * @return the current instances */ - public Instances getInstances() { + public InstancesHeader getInstances() { return m_Instances; } diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java index 0c815a686..7800a8576 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java @@ -23,7 +23,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Represents the abstract ancestor for normalizable distance functions, like @@ -48,7 +48,7 @@ public abstract class NormalizableDistance public static final int R_WIDTH = 2; /** the instances used internally. */ - protected Instances m_Data = null; + protected InstancesHeader m_Data = null; /** True if normalization is turned off (default false).*/ protected boolean m_DontNormalize = false; @@ -78,7 +78,7 @@ public NormalizableDistance() { * * @param data the instances the distance function should work on */ - public NormalizableDistance(Instances data) { + public NormalizableDistance(InstancesHeader data) { setInstances(data); } @@ -230,7 +230,7 @@ protected void initializeAttributeIndices() { * * @param insts the instances to use */ - public void setInstances(Instances insts) { + public void setInstances(InstancesHeader insts) { m_Data = insts; invalidate(); } @@ -240,7 +240,7 @@ public void setInstances(Instances insts) { * * @return the current instances */ - public Instances getInstances() { + public InstancesHeader getInstances() { return m_Data; } diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java index 431cfd972..f69760c9f 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java @@ -25,7 +25,7 @@ import java.util.Vector; import moa.classifiers.lazy.neighboursearch.EuclideanDistance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Class that splits up a KDTreeNode. @@ -37,7 +37,7 @@ public abstract class KDTreeNodeSplitter implements Serializable { /** The instances that'll be used for tree construction. */ - protected Instances m_Instances; + protected InstancesHeader m_Instances; /** The distance function used for building the tree. */ protected EuclideanDistance m_EuclideanDistance; @@ -78,7 +78,7 @@ public KDTreeNodeSplitter() { * @param e The EuclideanDistance object that is used * in tree contruction. */ - public KDTreeNodeSplitter(int[] instList, Instances insts, EuclideanDistance e) { + public KDTreeNodeSplitter(int[] instList, InstancesHeader insts, EuclideanDistance e) { m_InstList = instList; m_Instances = insts; m_EuclideanDistance = e; @@ -155,7 +155,7 @@ public abstract void splitNode(KDTreeNode node, int numNodesCreated, * to be) built. * @param inst The training instances. */ - public void setInstances(Instances inst) { + public void setInstances(InstancesHeader inst) { m_Instances = inst; } diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java index 6e19a86a0..6d834c9be 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java @@ -21,7 +21,7 @@ package moa.classifiers.lazy.neighboursearch.kdtrees; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** @@ -227,7 +227,7 @@ public void splitNode(KDTreeNode node, int numNodesCreated, * that should be partitioned. * @return the index of the middle element */ - protected static int partition(Instances insts, int[] index, int attidx, int l, int r) { + protected static int partition(InstancesHeader insts, int[] index, int attidx, int l, int r) { double pivot = insts.instance(index[(l + r) / 2]).value(attidx); int help; @@ -270,7 +270,7 @@ protected static int partition(Instances insts, int[] index, int attidx, int l, * @param right The end index of the portion of the master index * array that needs to be sorted. */ - protected static void quickSort(Instances insts, int[] indices, int attidx, int left, int right) { + protected static void quickSort(InstancesHeader insts, int[] indices, int attidx, int left, int right) { if (left < right) { int middle = partition(insts, indices, attidx, left, right); @@ -295,7 +295,7 @@ protected static void quickSort(Instances insts, int[] indices, int attidx, int * @throws Exception If the indices of the instances * are not in sorted order. */ - private static void checkSort(Instances insts, int[] indices, int attidx, + private static void checkSort(InstancesHeader insts, int[] indices, int attidx, int start, int end) throws Exception { for(int i=start+1; i<=end; i++) { if( insts.instance(indices[i-1]).value(attidx) > diff --git a/moa/src/main/java/moa/classifiers/meta/ADACC.java b/moa/src/main/java/moa/classifiers/meta/ADACC.java index 3c000f353..8aa324af8 100644 --- a/moa/src/main/java/moa/classifiers/meta/ADACC.java +++ b/moa/src/main/java/moa/classifiers/meta/ADACC.java @@ -23,7 +23,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.Classifier; import moa.core.Measurement; @@ -74,7 +74,7 @@ public String getPurposeString() { /** * Last chunk of data of size (tau_size) to compute the stability index */ - protected Instances recentChunk; + protected InstancesHeader recentChunk; /** * Threshold values for the stability index and concept equivalence */ @@ -112,7 +112,7 @@ protected void initVariables(){ public void trainOnInstanceImpl(Instance inst) { if (recentChunk == null) - recentChunk = new Instances(this.getModelContext()); + recentChunk = new InstancesHeader(this.getModelContext()); if (recentChunk.size() < this.tau_size) recentChunk.add(inst); diff --git a/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java index c017c5fe7..f9764fa19 100644 --- a/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java @@ -29,7 +29,7 @@ import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * The revised version of the Accuracy Updated Ensemble as proposed by @@ -94,7 +94,7 @@ public class AccuracyUpdatedEnsemble extends AbstractClassifier { /** * Current chunk of instances. */ - protected Instances currentChunk; + protected InstancesHeader currentChunk; @Override public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { @@ -247,7 +247,7 @@ protected double computeMseR() { * @param chunk chunk of examples * @return the computed error. */ - protected double computeMse(Classifier learner, Instances chunk) { + protected double computeMse(Classifier learner, InstancesHeader chunk) { double mse_i = 0; double f_ci; @@ -348,7 +348,7 @@ private int getPoorestClassifierIndex() { */ private void initVariables() { if (this.currentChunk == null) { - this.currentChunk = new Instances(this.getModelContext()); + this.currentChunk = new InstancesHeader(this.getModelContext()); } if (this.classDistributions == null) { diff --git a/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java index ddcd76d70..df7e6fea1 100644 --- a/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java @@ -30,7 +30,7 @@ import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.Utils; /** @@ -119,7 +119,7 @@ public int compare(double[] o1, double[] o2) { protected Classifier candidateClassifier; - protected Instances currentChunk; + protected InstancesHeader currentChunk; @Override public void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { @@ -168,7 +168,7 @@ public void trainOnInstanceImpl(Instance inst) { */ private void initVariables() { if (this.currentChunk == null) { - this.currentChunk = new Instances(this.getModelContext()); + this.currentChunk = new InstancesHeader(this.getModelContext()); } if (this.classDistributions == null) { @@ -243,18 +243,18 @@ protected void processChunk() { * @param useMseR Determines whether to use the MSEr threshold. * @return Candidate classifier weight. */ - protected double computeCandidateWeight(Classifier candidate, Instances chunk, int numFolds) { + protected double computeCandidateWeight(Classifier candidate, InstancesHeader chunk, int numFolds) { double candidateWeight = 0.0; Random random = new Random(1); - Instances randData = new Instances(chunk); + InstancesHeader randData = new InstancesHeader(chunk); randData.randomize(random); if (randData.classAttribute().isNominal()) { randData.stratify(numFolds); } for (int n = 0; n < numFolds; n++) { - Instances train = randData.trainCV(numFolds, n, random); - Instances test = randData.testCV(numFolds, n); + InstancesHeader train = randData.trainCV(numFolds, n, random); + InstancesHeader test = randData.testCV(numFolds, n); Classifier learner = candidate.copy(); @@ -282,7 +282,7 @@ protected double computeCandidateWeight(Classifier candidate, Instances chunk, i * @param useMseR Determines whether to use the MSEr threshold. * @return The given classifier's weight. */ - protected double computeWeight(Classifier learner, Instances chunk) { + protected double computeWeight(Classifier learner, InstancesHeader chunk) { double mse_i = 0; double mse_r = 0; diff --git a/moa/src/main/java/moa/classifiers/meta/RandomRules.java b/moa/src/main/java/moa/classifiers/meta/RandomRules.java index 694b8b37e..e170e1ef7 100644 --- a/moa/src/main/java/moa/classifiers/meta/RandomRules.java +++ b/moa/src/main/java/moa/classifiers/meta/RandomRules.java @@ -25,7 +25,7 @@ import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.AbstractClassifier; @@ -174,7 +174,7 @@ protected Instance transformInstance(Instance inst, int classifierIndex) { //System.out.println("Number of attributes: "+this.numAttributes+ ","+inst.numAttributes()); //JD System.out.println("Number of attributes: "+this.numAttributes+ ","+(inst.numAttributes()-1)); attributes.addElement(inst.classAttribute()); - this.dataset[ensembleIndex] = new InstancesHeader(new Instances( + this.dataset[ensembleIndex] = new InstancesHeader(new InstancesHeader( getCLICreationString(InstanceStream.class), attributes, 0)); this.dataset[ensembleIndex].setClassIndex(this.numAttributes); this.ensemble[ensembleIndex].setModelContext(this.dataset[ensembleIndex]); diff --git a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java index c39b0ae84..eac49168d 100644 --- a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java @@ -25,13 +25,15 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; - -import com.yahoo.labs.samoa.instances.*; import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.Measurement; import moa.core.Utils; import moa.options.ClassOption; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Include labels of previous instances into the training data @@ -63,7 +65,7 @@ public String getPurposeString() { protected double[] oldLabels; - protected Instances header; + protected InstancesHeader header; public FlagOption labelDelayOption = new FlagOption("labelDelay", 'd', "Labels arrive with Delay. Use predictions instead of true Labels."); @@ -95,7 +97,7 @@ public void addOldLabel(double newPrediction) { } } - public void initHeader(Instances dataset) { + public void initHeader(InstancesHeader dataset) { int numLabels = this.numOldLabelsOption.getValue(); Attribute target = dataset.classAttribute(); @@ -122,14 +124,13 @@ public void initHeader(Instances dataset) { attrs.add(newAttribute); } } - this.header = new Instances("extended_" + dataset.getRelationName(), attrs, 0); + this.header = new InstancesHeader("extended_" + dataset.getRelationName(), attrs, 0); this.header.setClassIndex(numLabels + dataset.classIndex()); } public Instance extendWithOldLabels(Instance instance) { if (this.header == null) { initHeader(instance.dataset()); - this.baseLearner.setModelContext(new InstancesHeader(this.header)); } int numLabels = this.oldLabels.length; if (numLabels == 0) { diff --git a/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java b/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java index 13bb3e338..d9ac321c8 100644 --- a/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java @@ -27,7 +27,7 @@ import weka.classifiers.Classifier; import weka.classifiers.UpdateableClassifier; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; /** diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 4c78071f9..070665e55 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -7,6 +7,7 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; diff --git a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java index 8d5aed722..0544bdfb9 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java @@ -30,7 +30,7 @@ import weka.classifiers.Classifier; import weka.classifiers.UpdateableClassifier; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; import com.yahoo.labs.samoa.instances.StructuredInstance; @@ -90,7 +90,7 @@ public void resetLearningImpl() { } @Override - public void trainOnInstanceImpl(MultiLabelInstance samoaInstance) { + public void trainOnInstanceImpl(StructuredInstance samoaInstance) { // Convert Samoa instance to Weka instance (as used in Meka) L = samoaInstance.numberOutputTargets(); @@ -168,7 +168,7 @@ public double[] getVotesForInstance(Instance samoaInstance) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance samoaInstance) { + public Prediction getPredictionForInstance(StructuredInstance samoaInstance) { MultiLabelPrediction prediction = new MultiLabelPrediction(L); diff --git a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java index 23cea6b0b..135f8f88e 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java @@ -80,16 +80,7 @@ public void trainOnInstanceImpl(StructuredInstance x) { } @Override - //public double[] getVotesForInstance(Instance x) { public Prediction getPredictionForInstance(StructuredInstance x){ - - System.out.println("-------- start MC vote ---------------"); - int L = x.numOutputAttributes(); //x.classIndex() + 1; - if (m_L != L) { - System.err.println("set L = " + L); - m_L = L; - predictionArray = new double[m_L]; - } if (this.majorityLabelset == null) { int L = x.numberOutputTargets(); diff --git a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java index 08a7141ac..9a8bf0e96 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java @@ -28,7 +28,6 @@ import moa.core.StringUtils; import moa.core.utils.Converter; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; @@ -212,7 +211,7 @@ public void trainOnInstance(Instance inst) { boolean isTraining = (inst.weight() > 0.0); if (isTraining) { this.trainingWeightSeenByModel += inst.weight(); - trainOnInstanceImpl((MultiLabelInstance) inst); + trainOnInstanceImpl((StructuredInstance) inst); } } diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagAdwinML.java b/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagAdwinML.java index d07673f02..a94b89b6f 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagAdwinML.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagAdwinML.java @@ -25,7 +25,7 @@ import moa.core.InstanceExample; import moa.core.MiscUtils; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import moa.classifiers.MultiLabelLearner; @@ -84,7 +84,7 @@ public void trainOnInstanceImpl(Instance inst) { } @Override - public void trainOnInstanceImpl(MultiLabelInstance instance) { + public void trainOnInstanceImpl(StructuredInstance instance) { trainOnInstanceImpl((Instance) instance); } @@ -101,7 +101,7 @@ public double[] getVotesForInstance(Instance inst) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { return getPredictionForInstance((new InstanceExample(instance))); } diff --git a/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagML.java b/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagML.java index 66c9c470a..20acefa4e 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagML.java +++ b/moa/src/main/java/moa/classifiers/multilabel/meta/OzaBagML.java @@ -22,7 +22,7 @@ import moa.classifiers.meta.OzaBag; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import moa.classifiers.MultiLabelLearner; @@ -43,7 +43,7 @@ public class OzaBagML extends OzaBag implements MultiLabelLearner, MultiTargetRe //Training @Override - public void trainOnInstanceImpl(MultiLabelInstance inst) { + public void trainOnInstanceImpl(StructuredInstance inst) { trainOnInstanceImpl((Instance) inst); } @@ -119,7 +119,7 @@ public static double[] compileVotes(Classifier h[], Instance inst) { } @Override - public Prediction getPredictionForInstance(MultiLabelInstance instance) { + public Prediction getPredictionForInstance(StructuredInstance instance) { return getPredictionForInstance((new InstanceExample(instance))); } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index db8bf9843..28b52d3b9 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -795,6 +795,11 @@ public void resetLearningImpl() { sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); + + } + + @Override + public void modelContextSet() { loadWeights(); } diff --git a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java index 93c1c94a1..edad24332 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java @@ -14,7 +14,7 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; @@ -77,7 +77,7 @@ protected Instance transformInstance(StructuredInstance inst, int outputIndex) { } //System.out.println("Number of attributes: "+this.numAttributes+ ","+inst.numAttributes()); attributes.addElement(inst.outputAttribute(outputIndex)); - this.header[outputIndex] = new InstancesHeader(new Instances( + this.header[outputIndex] = new InstancesHeader(new InstancesHeader( getCLICreationString(InstanceStream.class), attributes, 0)); this.header[outputIndex].setClassIndex(attributes.size()-1); this.ensemble[outputIndex].setModelContext(this.header[outputIndex]); diff --git a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java index fb5505ef7..7e5febe56 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java @@ -2,6 +2,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java index 8387610c0..a6b313c12 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java @@ -2,6 +2,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java index df2405a5a..93d962149 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.core.conditionaltests.NominalAttributeBinaryTest; import moa.classifiers.rules.core.Predicate; diff --git a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java index 37650e7ca..ff4c0c350 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java @@ -21,6 +21,7 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.core.conditionaltests.InstanceConditionalBinaryTest; import moa.classifiers.rules.core.Predicate; diff --git a/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java b/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java index b860ad10e..8828c1d84 100644 --- a/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java +++ b/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java @@ -29,7 +29,6 @@ import com.github.javacliparser.MultiChoiceOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.AbstractClassifier; diff --git a/moa/src/main/java/moa/clusterers/AbstractClusterer.java b/moa/src/main/java/moa/clusterers/AbstractClusterer.java index db3a2a8a4..a8f23f48e 100644 --- a/moa/src/main/java/moa/clusterers/AbstractClusterer.java +++ b/moa/src/main/java/moa/clusterers/AbstractClusterer.java @@ -34,7 +34,7 @@ import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public abstract class AbstractClusterer extends AbstractOptionHandler implements Clusterer { @@ -286,7 +286,7 @@ protected static int modelAttIndexToInstanceAttIndex(int index, } protected static int modelAttIndexToInstanceAttIndex(int index, - Instances insts) { + InstancesHeader insts) { return insts.classIndex() > index ? index : index + 1; } diff --git a/moa/src/main/java/moa/clusterers/Clusterer.java b/moa/src/main/java/moa/clusterers/Clusterer.java index 36bdbf79c..b018b421f 100644 --- a/moa/src/main/java/moa/clusterers/Clusterer.java +++ b/moa/src/main/java/moa/clusterers/Clusterer.java @@ -21,11 +21,11 @@ import moa.MOAObject; import moa.cluster.Clustering; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.Measurement; import moa.gui.AWTRenderable; import moa.options.OptionHandler; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; public interface Clusterer extends MOAObject, OptionHandler, AWTRenderable { diff --git a/moa/src/main/java/moa/clusterers/CobWeb.java b/moa/src/main/java/moa/clusterers/CobWeb.java index c6c451098..03e34a5f9 100644 --- a/moa/src/main/java/moa/clusterers/CobWeb.java +++ b/moa/src/main/java/moa/clusterers/CobWeb.java @@ -30,7 +30,7 @@ import com.github.javacliparser.IntOption; import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import weka.core.AttributeStats; import weka.experiment.Stats; import weka.filters.unsupervised.attribute.Add; @@ -73,7 +73,7 @@ private class CNode implements Serializable { /** * Instances at this node */ - protected Instances m_clusterInstances = null; + protected InstancesHeader m_clusterInstances = null; /** * Children of this node */ @@ -107,7 +107,7 @@ public CNode(int numAttributes, Instance leafInstance) { if (m_clusterInstances == null) { //System.out.println(leafInstance.numAttributes()+"-"+leafInstance.value(0)+"-"+leafInstance.value(1)+"-"+leafInstance.value(2)); //System.out.println(leafInstance.numAttributes()+"-"+leafInstance.attribute(0).type()+"-"+leafInstance.attribute(1).type()+"-"+leafInstance.attribute(2).type()); - m_clusterInstances = new Instances(leafInstance.dataset(), 1); + m_clusterInstances = new InstancesHeader(leafInstance.dataset(), 1); } m_clusterInstances.add(leafInstance); updateStats(leafInstance, false); @@ -122,7 +122,7 @@ protected void addInstance(Instance newInstance) { // Add the instance to this cluster if (m_clusterInstances == null) { - m_clusterInstances = new Instances(newInstance.dataset(), 1); + m_clusterInstances = new InstancesHeader(newInstance.dataset(), 1); m_clusterInstances.add(newInstance); updateStats(newInstance, false); return; @@ -196,7 +196,7 @@ private double cuScoreForBestTwoMerged(CNode merged, double mergedCU = -Double.MAX_VALUE; // consider merging the best and second // best. - merged.m_clusterInstances = new Instances(m_clusterInstances, 1); + merged.m_clusterInstances = new InstancesHeader(m_clusterInstances, 1); merged.addChildNode(a); merged.addChildNode(b); @@ -620,11 +620,11 @@ protected String dumpData() { //throws Exception { // construct instances string with cluster numbers attached CNode tempNode = new CNode(m_numAttributes); - tempNode.m_clusterInstances = new Instances(m_clusterInstances, 1); + tempNode.m_clusterInstances = new InstancesHeader(m_clusterInstances, 1); for (int i = 0; i < m_children.size(); i++) { tempNode.addChildNode((CNode) m_children.elementAt(i)); } - Instances tempInst = tempNode.m_clusterInstances; + InstancesHeader tempInst = tempNode.m_clusterInstances; tempNode = null; Add af = new Add(); diff --git a/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java b/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java index 774e675dc..978290119 100644 --- a/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java +++ b/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java @@ -33,7 +33,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; import weka.core.Utils; @@ -52,7 +52,7 @@ public class WekaClusteringAlgorithm extends AbstractClusterer { private Class[] clustererClasses; - private Instances instances; + private InstancesHeader instances; private weka.clusterers.AbstractClusterer clusterer; @@ -136,7 +136,7 @@ public Clustering getClusteringResult() { clusterer.buildClusterer(wekaInstances); int numClusters = clusterer.numberOfClusters(); - Instances dataset = getDataset(instances.numAttributes(), numClusters); + InstancesHeader dataset = getDataset(instances.numAttributes(), numClusters); List newInstances = new ArrayList() ; //Instances(dataset); for (int i = 0; i < wekaInstances.numInstances(); i++) { @@ -159,7 +159,7 @@ public Clustering getClusteringResult() { return clustering; } - public Instances getDataset(int numdim, int numclass) { + public InstancesHeader getDataset(int numdim, int numclass) { FastVector attributes = new FastVector(); for (int i = 0; i < numdim; i++) { attributes.addElement(new Attribute("att" + (i + 1))); @@ -173,7 +173,7 @@ public Instances getDataset(int numdim, int numclass) { attributes.addElement(new Attribute("class", classLabels)); } - Instances myDataset = new Instances("horizion", attributes, 0); + InstancesHeader myDataset = new InstancesHeader("horizion", attributes, 0); if (numclass > 0) { myDataset.setClassIndex(myDataset.numAttributes() - 1); } diff --git a/moa/src/main/java/moa/core/MultilabelInstancesHeader.java b/moa/src/main/java/moa/core/MultilabelInstancesHeader.java index cc7e57c59..b8dc3b3c2 100644 --- a/moa/src/main/java/moa/core/MultilabelInstancesHeader.java +++ b/moa/src/main/java/moa/core/MultilabelInstancesHeader.java @@ -19,7 +19,7 @@ */ package moa.core; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; /** @@ -33,7 +33,7 @@ public class MultilabelInstancesHeader extends InstancesHeader { private int m_NumLabels = -1; - public MultilabelInstancesHeader(Instances i, int numLabels) { + public MultilabelInstancesHeader(InstancesHeader i, int numLabels) { super(i); m_NumLabels = numLabels; } diff --git a/moa/src/main/java/moa/core/SizeOf.java b/moa/src/main/java/moa/core/SizeOf.java index 6e7b4e168..ff3def4c8 100644 --- a/moa/src/main/java/moa/core/SizeOf.java +++ b/moa/src/main/java/moa/core/SizeOf.java @@ -34,7 +34,7 @@ public class SizeOf { protected static Boolean m_Present; /** - * Checks whteher the agent is present. + * Checks whether the agent is present. * * @return true if the agent is present, false otherwise */ diff --git a/moa/src/main/java/moa/core/utils/AttributeDefinitionUtil.java b/moa/src/main/java/moa/core/utils/AttributeDefinitionUtil.java new file mode 100644 index 000000000..a47df6c0d --- /dev/null +++ b/moa/src/main/java/moa/core/utils/AttributeDefinitionUtil.java @@ -0,0 +1,121 @@ +package moa.core.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class AttributeDefinitionUtil { + //public static String definitionTotal = "(!?-?[0-9]+?)|(!?[0-9]+?-[0-9]+?)|(!?-?[0-9]+?~-?[0-9]+?)"; + + public static String nonIgnoredDefinition = "0"; + + public static String definitionSingle = "-?[0-9]+?"; + public static String definitionPositiveRange = "-?[0-9]+?-[0-9]+?"; + public static String definitionArbitraryRange = "-?[0-9]+?~-?[0-9]+?"; + + public static String getDefinitionTotal() { + return "(!?" + definitionSingle + ")|" + "(!?" + definitionPositiveRange + ")|" + "(!?" + definitionArbitraryRange + ")"; + } + + public static List parseDefinition(String definition, int numAttributes, List ignoredAttributes) { + List ret = new ArrayList(); + if (Pattern.matches(definitionArbitraryRange, definition)) { + String[] split = definition.split("~"); + int start = Integer.valueOf(split[0]); + int end = Integer.valueOf(split[1]); + if (start < 0) { + start = numAttributes + start + 1; // + 1 for so that -1 maps to last attribute + } + if (end < 0) { + end = numAttributes + end + 1; // + 1 for so that -1 maps to last attribute + } + start = Math.max(0, start); + end = Math.max(0, end); + if (start == end) { + System.err.println("[Warning] Strage attribute range definition '" + definition + "', start equals end"); + } + Integer i = start; + if (start <= end) + while(i <= end) { + if (!ignoredAttributes.contains(i - 1)) ret.add(i - 1); + i++; + } + else + System.err.println("[Warning] Strage attribute range definition '" + definition + "', end smaller of start, ignoring..."); + } else if (Pattern.matches(definitionPositiveRange, definition)) { + String[] split = definition.split("-"); + int start = Integer.valueOf(split[0]); + int end = Integer.valueOf(split[1]); + if (start == 0 || end == 0) { + throw new UnsupportedOperationException("Attribute definition range error - start or end equals 0: " + definition); + } + if (start == end) { + System.err.println("[Warning] Strage attribute range definition '" + definition + "', start equals end"); + } + Integer i = start; + if (start <= end) + while(i <= end) { + if (!ignoredAttributes.contains(i - 1)) ret.add(i - 1); + i++; + } + else + System.err.println("[Warning] Strage attribute range definition '" + definition + "', end smaller of start, ignoring..."); + } else if (Pattern.matches(definitionSingle, definition)) { + int index = Integer.valueOf(definition); + if (index == 0) { + // Add all non-ignored attributes + for (Integer i = 0; i < numAttributes; i++) + if (!ignoredAttributes.contains(i)) ret.add(i); + } else { + if (index < 0){ + index = numAttributes + index + 1; + if (index <= 0) { + throw new UnsupportedOperationException("Attribute definition range error - negative index overflows the number of attributes: " + definition); + } + } + if (!ignoredAttributes.contains(index - 1)) ret.add(index - 1); + } + } + return ret; + } + + public static List parseAttributeDefinition(String attributeDefinition, int numAttributes, List ignoredAttributes) { + List ret = new ArrayList(); + if (ignoredAttributes == null) ignoredAttributes = new ArrayList(); + if (attributeDefinition != "") { + String[] definitions = attributeDefinition.split("[,;]"); + Pattern definitionsPattern = Pattern.compile(getDefinitionTotal()); + for (int i = 0; i < definitions.length; i++) { + String definition = definitions[i]; + boolean negative = false; + if (definition.isEmpty()) { + continue; + } + if (!definitionsPattern.matcher(definition).matches()) throw new UnsupportedOperationException("The attribute definition '" + definition + "' is not recognised."); + + if (definition.startsWith("!")) { + definition = definition.substring(1); + negative = true; + } + + List candidates = parseDefinition(definition, numAttributes, ignoredAttributes); + if (negative) { + for (Integer j : candidates) { + if (ret.contains(j)) ret.remove(j); + } + } else { + for (Integer j : candidates) { + if (!ret.contains(j)) ret.add(j); + } + } + } + } else { + // Add all non-ignored attributes (this is the default behavior for input attributes) + for (Integer i = 0; i < numAttributes; i++) + if (!ignoredAttributes.contains(i)) ret.add(i); + } + return ret; + } + + +} diff --git a/moa/src/main/java/moa/core/utils/Converter.java b/moa/src/main/java/moa/core/utils/Converter.java index 3e3110557..a3f976c38 100755 --- a/moa/src/main/java/moa/core/utils/Converter.java +++ b/moa/src/main/java/moa/core/utils/Converter.java @@ -23,7 +23,7 @@ import java.util.List; import moa.AbstractMOAObject; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Converter. This class can be used to convert a multi-label instance into a @@ -34,7 +34,7 @@ */ public class Converter extends AbstractMOAObject { - protected Instances m_InstancesTemplate = null; + protected InstancesHeader m_InstancesTemplate = null; protected int m_L = -1; @@ -49,8 +49,8 @@ public Converter(int n) { m_L = n; } - public Instances createTemplate(Instances i) { - this.m_InstancesTemplate = new Instances(i, 0, 0); + public InstancesHeader createTemplate(InstancesHeader i) { + this.m_InstancesTemplate = new InstancesHeader(i, 0, 0); return this.m_InstancesTemplate; } diff --git a/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java index 6f677c93c..33e6b18d1 100644 --- a/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java @@ -24,7 +24,7 @@ import moa.core.Measurement; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; /** @@ -57,7 +57,7 @@ public void reset() { @Override public void addResult(Example example, Prediction y) { - MultiLabelInstance x = (MultiLabelInstance) example.getData(); + StructuredInstance x = (StructuredInstance) example.getData(); if (L == 0) { L = x.numberOutputTargets(); diff --git a/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java b/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java index 380b31204..ce611e1ba 100644 --- a/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java +++ b/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java @@ -59,7 +59,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public class RunOutlierVisualizer implements Runnable, ActionListener, ClusterEventListener{ /** the pause interval, being read from the gui at startup */ @@ -646,7 +646,7 @@ public void weka() { for(int i = 0; i < dims; i++) attributes.addElement( new Attribute("att" + i) ); - Instances instances = new Instances("trainset",attributes,0); + InstancesHeader instances = new InstancesHeader("trainset",attributes,0); for(int c = 0; c < wekaClustering.size(); c++){ Cluster cluster = wekaClustering.get(c); diff --git a/moa/src/main/java/moa/gui/visualization/RunVisualizer.java b/moa/src/main/java/moa/gui/visualization/RunVisualizer.java index e95cb7551..1e08cab18 100644 --- a/moa/src/main/java/moa/gui/visualization/RunVisualizer.java +++ b/moa/src/main/java/moa/gui/visualization/RunVisualizer.java @@ -52,7 +52,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import moa.core.FastVector; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public class RunVisualizer implements Runnable, ActionListener, ClusterEventListener{ @@ -606,7 +606,7 @@ public void weka() { for(int i = 0; i < dims; i++) attributes.addElement( new Attribute("att" + i) ); - Instances instances = new Instances("trainset",attributes,0); + InstancesHeader instances = new InstancesHeader("trainset",attributes,0); for(int c = 0; c < wekaClustering.size(); c++){ Cluster cluster = wekaClustering.get(c); diff --git a/moa/src/main/java/moa/gui/visualization/WekaExplorer.java b/moa/src/main/java/moa/gui/visualization/WekaExplorer.java index 7825f5433..cfc1d5254 100644 --- a/moa/src/main/java/moa/gui/visualization/WekaExplorer.java +++ b/moa/src/main/java/moa/gui/visualization/WekaExplorer.java @@ -36,7 +36,7 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; @@ -46,7 +46,7 @@ public class WekaExplorer { /** for monitoring the Memory consumption */ private static Memory m_Memory = new Memory(true); - public WekaExplorer(Instances instances) { + public WekaExplorer(InstancesHeader instances) { //weka.core.logging.Logger.log(weka.core.logging.Logger.Level.INFO, "Logging started"); try { javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); diff --git a/moa/src/main/java/moa/streams/ArffFileStream.java b/moa/src/main/java/moa/streams/ArffFileStream.java index 408c6d2da..5d0d10ef9 100644 --- a/moa/src/main/java/moa/streams/ArffFileStream.java +++ b/moa/src/main/java/moa/streams/ArffFileStream.java @@ -21,7 +21,8 @@ import com.github.javacliparser.FileOption; import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instances; +import com.github.javacliparser.StringOption; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import java.io.BufferedReader; import java.io.FileInputStream; @@ -41,7 +42,7 @@ * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * @version $Revision: 7 $ */ -public class ArffFileStream extends AbstractOptionHandler implements InstanceStream { +public class ArffFileStream extends AbstractOptionHandler implements InstanceStream, MultiTargetInstanceStream { @Override public String getPurposeString() { @@ -53,13 +54,26 @@ public String getPurposeString() { public FileOption arffFileOption = new FileOption("arffFile", 'f', "ARFF file to load.", null, "arff", false); - public IntOption classIndexOption = new IntOption( - "classIndex", - 'c', - "Class index of data. 0 for none or -1 for last attribute in file.", - -1, -1, Integer.MAX_VALUE); +// public IntOption classIndexOption = new IntOption( +// "classIndex", +// 'c', +// "Class index of data. 0 for none or -1 for last attribute in file.", +// -1, -1, Integer.MAX_VALUE); + + public StringOption outputIndexesOption = new StringOption( + "outputIndexes", + 'c', + "Indices of output (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges.", + "-1"); + + public StringOption inputIndexesOption = new StringOption( + "inputIndexes", + 'i', + "Indices of input (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges. Leave blank for all non-output attributes.", + ""); - protected Instances instances; + + protected InstancesHeader instances; protected Reader fileReader; @@ -76,7 +90,22 @@ public ArffFileStream() { public ArffFileStream(String arffFileName, int classIndex) { this.arffFileOption.setValue(arffFileName); - this.classIndexOption.setValue(classIndex); + this.outputIndexesOption.setValue(Integer.toString(classIndex)); + this.inputIndexesOption.setValue(""); + restart(); + } + + + public ArffFileStream(String arffFileName, String outputIndexes) { + this.arffFileOption.setValue(arffFileName); + this.outputIndexesOption.setValue(outputIndexes); + restart(); + } + + public ArffFileStream(String arffFileName, String outputIndexes, String inputIndexes) { + this.arffFileOption.setValue(arffFileName); + this.outputIndexesOption.setValue(outputIndexes); + this.inputIndexesOption.setValue(inputIndexes); restart(); } @@ -126,13 +155,7 @@ public void restart() { this.fileProgressMonitor = new InputStreamProgressMonitor( fileStream); this.fileReader = new BufferedReader(new InputStreamReader(this.fileProgressMonitor)); - int classIndex = this.classIndexOption.getValue(); - this.instances = new Instances(this.fileReader, 1, classIndex); - if (classIndex < 0) { - this.instances.setClassIndex(this.instances.numAttributes() - 1); - } else if (this.classIndexOption.getValue() > 0) { - this.instances.setClassIndex(this.classIndexOption.getValue() - 1); - } + this.instances = new InstancesHeader(this.fileReader, 1, this.outputIndexesOption.getValue(), this.inputIndexesOption.getValue()); this.numInstancesRead = 0; this.lastInstanceRead = null; this.hitEndOfFile = !readNextInstanceFromFile(); diff --git a/moa/src/main/java/moa/streams/CachedInstancesStream.java b/moa/src/main/java/moa/streams/CachedInstancesStream.java index 4faa60832..bb618fac8 100644 --- a/moa/src/main/java/moa/streams/CachedInstancesStream.java +++ b/moa/src/main/java/moa/streams/CachedInstancesStream.java @@ -23,7 +23,7 @@ import moa.core.InstanceExample; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator for representing a stream that is cached in memory. @@ -38,11 +38,11 @@ public class CachedInstancesStream extends AbstractMOAObject implements private static final long serialVersionUID = 1L; - protected Instances toStream; + protected InstancesHeader toStream; protected int streamPos; - public CachedInstancesStream(Instances toStream) { + public CachedInstancesStream(InstancesHeader toStream) { this.toStream = toStream; } diff --git a/moa/src/main/java/moa/streams/ConceptDriftRealStream.java b/moa/src/main/java/moa/streams/ConceptDriftRealStream.java index fd7b8c313..46c30398a 100644 --- a/moa/src/main/java/moa/streams/ConceptDriftRealStream.java +++ b/moa/src/main/java/moa/streams/ConceptDriftRealStream.java @@ -23,13 +23,16 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import java.util.ArrayList; +import java.util.List; import java.util.Random; import moa.core.InstanceExample; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; +import moa.core.utils.AttributeDefinitionUtil; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; import com.github.javacliparser.FloatOption; @@ -111,8 +114,8 @@ public void prepareForUseImpl(TaskMonitor monitor, } // generate header - Instances first = this.inputStream.getHeader(); - Instances second = this.driftStream.getHeader(); + InstancesHeader first = this.inputStream.getHeader(); + InstancesHeader second = this.driftStream.getHeader(); FastVector newAttributes = new FastVector(); for (int i = 0; i < first.numAttributes() - 1; i++) { newAttributes.addElement(first.attribute(i)); @@ -130,9 +133,11 @@ public void prepareForUseImpl(TaskMonitor monitor, } newAttributes.addElement(classLabels); - this.streamHeader = new InstancesHeader(new Instances( + this.streamHeader = new InstancesHeader(new InstancesHeader( getCLICreationString(InstanceStream.class), newAttributes, 0)); this.streamHeader.setClassIndex(this.streamHeader.numAttributes() - 1); + // TODO adapt for multi-target streaming + this.streamHeader.setInputIndexes(); restart(); } diff --git a/moa/src/main/java/moa/streams/ConceptDriftStream.java b/moa/src/main/java/moa/streams/ConceptDriftStream.java index c0775b447..19ff13c49 100644 --- a/moa/src/main/java/moa/streams/ConceptDriftStream.java +++ b/moa/src/main/java/moa/streams/ConceptDriftStream.java @@ -22,8 +22,6 @@ import java.util.Random; import moa.core.Example; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; @@ -31,6 +29,7 @@ import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator that adds concept drift to examples in a stream. diff --git a/moa/src/main/java/moa/streams/ExampleStream.java b/moa/src/main/java/moa/streams/ExampleStream.java index f5e9ec500..20877597a 100644 --- a/moa/src/main/java/moa/streams/ExampleStream.java +++ b/moa/src/main/java/moa/streams/ExampleStream.java @@ -21,8 +21,9 @@ import moa.MOAObject; import moa.core.Example; -import com.yahoo.labs.samoa.instances.InstancesHeader; + import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Interface representing a data stream of examples. diff --git a/moa/src/main/java/moa/streams/FilteredStream.java b/moa/src/main/java/moa/streams/FilteredStream.java index 1eb0803a5..6cf072f88 100644 --- a/moa/src/main/java/moa/streams/FilteredStream.java +++ b/moa/src/main/java/moa/streams/FilteredStream.java @@ -19,8 +19,9 @@ */ package moa.streams; -import moa.core.Example; import com.yahoo.labs.samoa.instances.InstancesHeader; + +import moa.core.Example; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/streams/MultiFilteredStream.java b/moa/src/main/java/moa/streams/MultiFilteredStream.java index 6e35c4994..befa684b6 100644 --- a/moa/src/main/java/moa/streams/MultiFilteredStream.java +++ b/moa/src/main/java/moa/streams/MultiFilteredStream.java @@ -21,7 +21,6 @@ import moa.core.Example; import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; @@ -31,6 +30,7 @@ import moa.streams.filters.StreamFilter; import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Class for representing a stream that is filtered. diff --git a/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java b/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java index d63b0e451..f7c8bdf79 100644 --- a/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java +++ b/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java @@ -19,6 +19,8 @@ */ package moa.streams; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; @@ -29,8 +31,6 @@ import moa.streams.filters.StreamFilter; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.InstancesHeader; - /** * Class for representing a stream that is filtered. * diff --git a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java index 4eb9dbff0..80e2ae84f 100644 --- a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java +++ b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java @@ -20,7 +20,7 @@ package moa.streams; import com.github.javacliparser.FileOption; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import java.io.BufferedReader; import java.io.FileInputStream; @@ -41,149 +41,151 @@ * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * @version $Revision: 7 $ */ -public class MultiTargetArffFileStream extends AbstractOptionHandler implements +public class MultiTargetArffFileStream extends ArffFileStream implements MultiTargetInstanceStream { - @Override - public String getPurposeString() { - return "A stream read from an ARFF file."; - } - - private static final long serialVersionUID = 1L; - - public FileOption arffFileOption = new FileOption("arffFile", 'f', - "ARFF file to load.", null, "arff", false); - - public RangeOption outputAttributesOption = new RangeOption( - "outputAttributes", - 'c', - "Output attributes: n for first n attributes, -n for last n attributes For example, 2 for the two first attributes, -2 for the two last attributes.", - "-1"); - - protected Instances instances; - - protected Reader fileReader; - - protected boolean hitEndOfFile; - - protected InstanceExample lastInstanceRead; - - protected int numInstancesRead; - - protected InputStreamProgressMonitor fileProgressMonitor; - - public MultiTargetArffFileStream() { - } - - // jesse - public MultiTargetArffFileStream(String arffFileName, String classIndices) { - this.arffFileOption.setValue(arffFileName); - this.outputAttributesOption.setValue(classIndices); - restart(); - } - - /* - public ArffFileStream(String arffFileName, int classIndex) { - this.arffFileOption.setValue(arffFileName); - this.outputAttributesOption.setValue(classIndex); - restart(); - } - */ - - @Override - public void prepareForUseImpl(TaskMonitor monitor, - ObjectRepository repository) { - restart(); - } - - @Override - public InstancesHeader getHeader() { - return new InstancesHeader(this.instances); - } - - @Override - public long estimatedRemainingInstances() { - double progressFraction = this.fileProgressMonitor.getProgressFraction(); - if ((progressFraction > 0.0) && (this.numInstancesRead > 0)) { - return (long) ((this.numInstancesRead / progressFraction) - this.numInstancesRead); - } - return -1; - } - - @Override - public boolean hasMoreInstances() { - return !this.hitEndOfFile; - } - - @Override - public InstanceExample nextInstance() { - InstanceExample prevInstance = this.lastInstanceRead; - this.hitEndOfFile = !readNextInstanceFromFile(); - return prevInstance; - } - - @Override - public boolean isRestartable() { - return true; - } - - @Override - public void restart() { - try { - if (this.fileReader != null) { - this.fileReader.close(); - } - InputStream fileStream = new FileInputStream(this.arffFileOption.getFile()); - this.fileProgressMonitor = new InputStreamProgressMonitor( - fileStream); - this.fileReader = new BufferedReader(new InputStreamReader( - this.fileProgressMonitor)); - // jesse ----- - /*int cs[] = this.outputAttributesOption.getRange(); - if (cs.length == 1) { - // single label - int c = cs[0]; - this.instances = new Instances(this.fileReader, 1, c); - if (c < 0) { - this.instances.setClassIndex(this.instances.numAttributes() - 1); - } else if (c > 0) { - this.instances.setClassIndex(c - 1); - } - } - else {*/ - // multi-label since cs[] contains _multipe_ class indices, e.g., cs[] = {9,10,11} - // what to do here? - this.instances = new Instances(this.fileReader, this.outputAttributesOption.getRange()); - //} - this.numInstancesRead = 0; - this.lastInstanceRead = null; - this.hitEndOfFile = !readNextInstanceFromFile(); - } catch (IOException ioe) { - throw new RuntimeException("ArffFileStream restart failed.", ioe); - } - } - - protected boolean readNextInstanceFromFile() { - try { - if (this.instances.readInstance(this.fileReader)) { - this.lastInstanceRead = new InstanceExample(this.instances.instance(0)); - this.instances.delete(); // keep instances clean - this.numInstancesRead++; - return true; - } - if (this.fileReader != null) { - this.fileReader.close(); - this.fileReader = null; - } - return false; - } catch (IOException ioe) { - throw new RuntimeException( - "ArffFileStream failed to read instance from stream.", ioe); - } - } - - @Override - public void getDescription(StringBuilder sb, int indent) { - // TODO Auto-generated method stub - } + // deprecated + +// @Override +// public String getPurposeString() { +// return "A stream read from an ARFF file."; +// } +// +// private static final long serialVersionUID = 1L; +// +// public FileOption arffFileOption = new FileOption("arffFile", 'f', +// "ARFF file to load.", null, "arff", false); +// +// public RangeOption outputAttributesOption = new RangeOption( +// "outputAttributes", +// 'c', +// "Output attributes: n for first n attributes, -n for last n attributes For example, 2 for the two first attributes, -2 for the two last attributes.", +// "-1"); +// +// protected Instances instances; +// +// protected Reader fileReader; +// +// protected boolean hitEndOfFile; +// +// protected InstanceExample lastInstanceRead; +// +// protected int numInstancesRead; +// +// protected InputStreamProgressMonitor fileProgressMonitor; +// +// public MultiTargetArffFileStream() { +// } +// +// // jesse +// public MultiTargetArffFileStream(String arffFileName, String classIndices) { +// this.arffFileOption.setValue(arffFileName); +// this.outputAttributesOption.setValue(classIndices); +// restart(); +// } +// +// /* +// public ArffFileStream(String arffFileName, int classIndex) { +// this.arffFileOption.setValue(arffFileName); +// this.outputAttributesOption.setValue(classIndex); +// restart(); +// } +// */ +// +// @Override +// public void prepareForUseImpl(TaskMonitor monitor, +// ObjectRepository repository) { +// restart(); +// } +// +// @Override +// public InstancesHeader getHeader() { +// return new InstancesHeader(this.instances); +// } +// +// @Override +// public long estimatedRemainingInstances() { +// double progressFraction = this.fileProgressMonitor.getProgressFraction(); +// if ((progressFraction > 0.0) && (this.numInstancesRead > 0)) { +// return (long) ((this.numInstancesRead / progressFraction) - this.numInstancesRead); +// } +// return -1; +// } +// +// @Override +// public boolean hasMoreInstances() { +// return !this.hitEndOfFile; +// } +// +// @Override +// public InstanceExample nextInstance() { +// InstanceExample prevInstance = this.lastInstanceRead; +// this.hitEndOfFile = !readNextInstanceFromFile(); +// return prevInstance; +// } +// +// @Override +// public boolean isRestartable() { +// return true; +// } +// +// @Override +// public void restart() { +// try { +// if (this.fileReader != null) { +// this.fileReader.close(); +// } +// InputStream fileStream = new FileInputStream(this.arffFileOption.getFile()); +// this.fileProgressMonitor = new InputStreamProgressMonitor( +// fileStream); +// this.fileReader = new BufferedReader(new InputStreamReader( +// this.fileProgressMonitor)); +// // jesse ----- +// /*int cs[] = this.outputAttributesOption.getRange(); +// if (cs.length == 1) { +// // single label +// int c = cs[0]; +// this.instances = new Instances(this.fileReader, 1, c); +// if (c < 0) { +// this.instances.setClassIndex(this.instances.numAttributes() - 1); +// } else if (c > 0) { +// this.instances.setClassIndex(c - 1); +// } +// } +// else {*/ +// // multi-label since cs[] contains _multipe_ class indices, e.g., cs[] = {9,10,11} +// // what to do here? +// this.instances = new Instances(this.fileReader, this.outputAttributesOption.getRange()); +// //} +// this.numInstancesRead = 0; +// this.lastInstanceRead = null; +// this.hitEndOfFile = !readNextInstanceFromFile(); +// } catch (IOException ioe) { +// throw new RuntimeException("ArffFileStream restart failed.", ioe); +// } +// } +// +// protected boolean readNextInstanceFromFile() { +// try { +// if (this.instances.readInstance(this.fileReader)) { +// this.lastInstanceRead = new InstanceExample(this.instances.instance(0)); +// this.instances.delete(); // keep instances clean +// this.numInstancesRead++; +// return true; +// } +// if (this.fileReader != null) { +// this.fileReader.close(); +// this.fileReader = null; +// } +// return false; +// } catch (IOException ioe) { +// throw new RuntimeException( +// "ArffFileStream failed to read instance from stream.", ioe); +// } +// } +// +// @Override +// public void getDescription(StringBuilder sb, int indent) { +// // TODO Auto-generated method stub +// } } diff --git a/moa/src/main/java/moa/streams/clustering/FileStream.java b/moa/src/main/java/moa/streams/clustering/FileStream.java index 9b122de65..7ef557add 100644 --- a/moa/src/main/java/moa/streams/clustering/FileStream.java +++ b/moa/src/main/java/moa/streams/clustering/FileStream.java @@ -43,10 +43,12 @@ import com.github.javacliparser.IntOption; import com.github.javacliparser.ListOption; import com.github.javacliparser.Option; +import com.github.javacliparser.StringOption; + import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public class FileStream extends ClusteringStream{ @@ -63,12 +65,24 @@ public String getPurposeString() { public FileOption arffFileOption = new FileOption("arffFile", 'f', "ARFF file to load.", defaultfile, "arff", false); - public IntOption classIndexOption = new IntOption( - "classIndex", - 'c', - "Class index of data. 0 for none or -1 for last attribute in file.", - -1, -1, Integer.MAX_VALUE); - +// public IntOption classIndexOption = new IntOption( +// "classIndex", +// 'c', +// "Class index of data. 0 for none or -1 for last attribute in file.", +// -1, -1, Integer.MAX_VALUE); + + public StringOption outputIndicesOption = new StringOption( + "outputIndices", + 'c', + "Indices of output (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges.", + "-1"); + + public StringOption inputIndicesOption = new StringOption( + "outputIndices", + 'i', + "Indices of input (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges. Leave blank for all non-output attributes.", + ""); + public FlagOption normalizeOption = new FlagOption("normalize", 'n', "Numerical data will be normalized to 0-1 " + @@ -90,7 +104,7 @@ public String getPurposeString() { - protected Instances instances; + protected InstancesHeader instances; protected Reader fileReader; @@ -104,7 +118,7 @@ public String getPurposeString() { private Integer[] removeAttributes = null; - private Instances filteredDataset = null; + private InstancesHeader filteredDataset = null; private ArrayList valuesMinMaxDiff = null; @@ -155,12 +169,7 @@ public void restart() { InputStream fileStream = new FileInputStream(arffFileOption.getFile()); fileProgressMonitor = new InputStreamProgressMonitor(fileStream); fileReader = new BufferedReader(new InputStreamReader(fileProgressMonitor)); - instances = new Instances(fileReader, 1, this.classIndexOption.getValue()); - if (classIndexOption.getValue() < 0) { - instances.setClassIndex(instances.numAttributes() - 1); - } else if (classIndexOption.getValue() > 0) { - instances.setClassIndex(classIndexOption.getValue() - 1); - } + instances = new InstancesHeader(fileReader, 1, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); //use hashset to delete duplicates and attributes numbers that aren't valid @@ -206,7 +215,7 @@ public void restart() { } //create filtered dataset - filteredDataset = new Instances(instances); + filteredDataset = new InstancesHeader(instances); for (int i = removeAttributes.length-1; i >= 0 ; i--) { filteredDataset.deleteAttributeAt(removeAttributes[i]); if(true){ @@ -278,7 +287,7 @@ protected ArrayList readMinMaxDiffValues(HashSet ignoredAttri InputStream fileStream = new FileInputStream(arffFileOption.getFile()); InputStreamProgressMonitor fileProgressMonitor = new InputStreamProgressMonitor(fileStream); Reader fileReader = new BufferedReader(new InputStreamReader(fileProgressMonitor)); - Instances instances = new Instances(fileReader, 1, this.classIndexOption.getValue()); + InstancesHeader instances = new InstancesHeader(fileReader, 1, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); valuesMinMaxDiff = new ArrayList(); for (int i = 0; i < instances.numAttributes()-ignoredAttributes.size(); i++) { diff --git a/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java b/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java index 4ade99a71..84b15eebc 100644 --- a/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java +++ b/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java @@ -47,7 +47,7 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; public class RandomRBFGeneratorEvents extends ClusteringStream { @@ -510,7 +510,7 @@ protected void generateHeader() { // 2013/06/02: Noise label if (noiseLevelOption.getValue() > 0) classLabels.add("noise"); // The last label = "noise" attributes.add(new Attribute("class", classLabels)); - streamHeader = new InstancesHeader(new Instances(getCLICreationString(InstanceStream.class), attributes, 0)); + streamHeader = new InstancesHeader(new InstancesHeader(getCLICreationString(InstanceStream.class), attributes, 0)); streamHeader.setClassIndex(streamHeader.numAttributes() - 1); } diff --git a/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java b/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java index d554e0eaf..fe46621be 100644 --- a/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java +++ b/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java @@ -33,7 +33,7 @@ import com.github.javacliparser.StringOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.InputStreamProgressMonitor; @@ -61,7 +61,7 @@ public class SimpleCSVStream extends ClusteringStream { public FlagOption classIndexOption = new FlagOption("classIndex", 'c', "Last attribute is class index."); - protected Instances dataset; + protected InstancesHeader dataset; protected BufferedReader fileReader; @@ -252,7 +252,7 @@ public void restart() { ArrayList classLabels = new ArrayList(); classLabels.add("0"); attributes.add(new Attribute("class", classLabels)); - this.dataset = new Instances(csvFileOption.getFile().getName(), + this.dataset = new InstancesHeader(csvFileOption.getFile().getName(), attributes, 0); this.dataset.setClassIndex(this.numAttributes - 1); numAttsOption = new IntOption("numAtts", 'a', "", diff --git a/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java b/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java index 3caa94559..c7968e479 100644 --- a/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java +++ b/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java @@ -25,10 +25,11 @@ import moa.core.DoubleVector; import moa.core.GaussianEstimator; import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Filter for adding random noise to examples in a stream. diff --git a/moa/src/main/java/moa/streams/filters/RBFFilter.java b/moa/src/main/java/moa/streams/filters/RBFFilter.java index 4b9901d83..bf90b324c 100644 --- a/moa/src/main/java/moa/streams/filters/RBFFilter.java +++ b/moa/src/main/java/moa/streams/filters/RBFFilter.java @@ -11,7 +11,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Range; @@ -88,7 +88,7 @@ private void initialize(Instance instance) { } // initialize instance space - Instances ds = new Instances(); + InstancesHeader ds = new InstancesHeader(); List v = new ArrayList(h); List indexValues = new ArrayList(h); @@ -101,9 +101,6 @@ private void initialize(Instance instance) { ds.setAttributes(v,indexValues); - Range r= new Range("start-end"); - //r.setUpper(h); - ds.setRangeOutputIndices(r); dataset=(new InstancesHeader(ds)); dataset.setClassIndex(h); System.out.println(""+dataset); diff --git a/moa/src/main/java/moa/streams/filters/ReLUFilter.java b/moa/src/main/java/moa/streams/filters/ReLUFilter.java index f50c6ac60..3f6eb7f55 100644 --- a/moa/src/main/java/moa/streams/filters/ReLUFilter.java +++ b/moa/src/main/java/moa/streams/filters/ReLUFilter.java @@ -11,7 +11,7 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Range; @@ -99,7 +99,7 @@ private void initialize(Instance instance) { } // initialize instance space - Instances ds = new Instances(); + InstancesHeader ds = new InstancesHeader(); List v = new ArrayList(H); List indexValues = new ArrayList(H); @@ -112,8 +112,6 @@ private void initialize(Instance instance) { ds.setAttributes(v,indexValues); - Range r= new Range("start-end"); - ds.setRangeOutputIndices(r); dataset=(new InstancesHeader(ds)); dataset.setClassIndex(H); diff --git a/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java b/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java index fa80d5230..f2143f080 100644 --- a/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java +++ b/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java @@ -25,7 +25,7 @@ import moa.streams.InstanceStream; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SparseInstance; import moa.core.FastVector; @@ -74,7 +74,7 @@ public InstanceExample nextInstance() { } attributes.addElement(inst.classAttribute()); numericAttributes.add(inst.classIndex()); - this.streamHeader = new InstancesHeader(new Instances( + this.streamHeader = new InstancesHeader(new InstancesHeader( getCLICreationString(InstanceStream.class), attributes, 0)); this.streamHeader.setClassIndex(this.streamHeader.numAttributes() - 1); diff --git a/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java b/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java index 29aa407bc..fefe7f955 100644 --- a/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java +++ b/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java @@ -23,6 +23,7 @@ import com.github.javacliparser.MultiChoiceOption; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; + import java.util.Collections; import java.util.Comparator; import java.util.HashMap; diff --git a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java index 808f3641f..b5905e34a 100644 --- a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java +++ b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import moa.core.Example; import moa.core.InstanceExample; import moa.streams.MultiTargetInstanceStream; @@ -10,11 +11,12 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; -import com.yahoo.labs.samoa.instances.Instances; +import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Range; public class SelectAttributesFilter extends AbstractMultiLabelStreamFilter implements MultiLabelStreamFilter{ + /** * */ @@ -48,15 +50,18 @@ private void initialize(Instance instance) { inputsSelected=getSelection(inputStringOption.getValue()); outputsSelected=getSelection(outputStringOption.getValue()); int totAttributes=inputsSelected.numValues()+outputsSelected.numValues(); - Instances ds= new Instances(); + InstancesHeader ds= new InstancesHeader(); List v = new ArrayList(totAttributes); List indexValues = new ArrayList(totAttributes); int ct=0; + List inputIndexes = new ArrayList(); + List outputIndexes = new ArrayList(); for (int i=0; i> evaluator, Classifier scheme) { + protected InspectionData[] inspect(InstancesHeader data, int[] inspectionPoints, LearningPerformanceEvaluator> evaluator, Classifier scheme) { InspectionData[] result; int i; int point; @@ -178,6 +177,7 @@ protected InspectionData[] inspect(Instances data, int[] inspectionPoints, Learn result = new InspectionData[inspectionPoints.length]; scheme.prepareForUse(); + scheme.setModelContext(data); point = 0; for (i = 0; i < data.numInstances(); i++) { @@ -296,7 +296,7 @@ protected String createOutputFilename(String input, int no) { * Compares the processed data against previously saved output data. */ public void testRegression() { - Instances data; + InstancesHeader data; InspectionData[] processed; boolean ok; String regression; diff --git a/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java b/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java index 4d6879edf..02ee87bf6 100644 --- a/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java +++ b/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java @@ -1,6 +1,8 @@ package moa.streams.filters; import static org.junit.Assert.assertEquals; + +import moa.streams.ArffFileStream; import moa.streams.MultiTargetArffFileStream; import org.junit.BeforeClass; @@ -14,7 +16,7 @@ public class SelectAttributesFilterTest { @BeforeClass public static void setUpBeforeClass() throws Exception { - MultiTargetArffFileStream stream=new MultiTargetArffFileStream(ClassLoader.getSystemResource("moa/classifiers/data/small_regression.arff").getPath(), "4-6"); + ArffFileStream stream=new ArffFileStream(ClassLoader.getSystemResource("moa/classifiers/data/small_regression.arff").getPath(), "4-6"); filter= new SelectAttributesFilter(); filter.setInputStream(stream); filter.inputStringOption.setValue("2-5,8"); From c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Thu, 24 Mar 2016 13:45:02 +0100 Subject: [PATCH 27/33] AttributeInformation streamlining and other fixes --- .../com/github/javacliparser/RangeOption.java | 57 - .../labs/samoa/instances/ArffLoader.java | 17 - .../yahoo/labs/samoa/instances/Attribute.java | 5 + .../instances/AttributesInformation.java | 83 +- .../labs/samoa/instances/DenseInstance.java | 5 + .../samoa/instances/DenseInstanceData.java | 5 + .../yahoo/labs/samoa/instances/Instance.java | 2 - .../labs/samoa/instances/InstanceImpl.java | 5 + .../samoa/instances/InstanceInformation.java | 65 +- .../labs/samoa/instances/InstancesHeader.java | 1165 ++++++++--------- .../samoa/instances/MultiLabelPrediction.java | 5 + .../com/yahoo/labs/samoa/instances/Range.java | 110 -- .../LocalMultiTargetClassifier.java | 11 +- .../main/java/moa/streams/ArffFileStream.java | 2 +- .../streams/MultiTargetArffFileStream.java | 1 - .../moa/streams/clustering/FileStream.java | 14 +- .../java/moa/streams/filters/RBFFilter.java | 7 +- .../java/moa/streams/filters/ReLUFilter.java | 7 +- .../filters/SelectAttributesFilter.java | 9 +- .../AbstractClassifierTestCase.java | 4 - 20 files changed, 668 insertions(+), 911 deletions(-) delete mode 100644 moa/src/main/java/com/github/javacliparser/RangeOption.java delete mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java diff --git a/moa/src/main/java/com/github/javacliparser/RangeOption.java b/moa/src/main/java/com/github/javacliparser/RangeOption.java deleted file mode 100644 index 56f4da850..000000000 --- a/moa/src/main/java/com/github/javacliparser/RangeOption.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2007 University of Waikato. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ - -package com.github.javacliparser; - -import java.util.Arrays; -import com.yahoo.labs.samoa.instances.Range; - -/** - * Range option. - * - * @author Jesse Read (jesse@tsc.uc3m.es) - * @version $Revision: 7 $ - */ -public class RangeOption extends StringOption { - - private static final long serialVersionUID = 1L; - - public RangeOption(String name, char cliChar, String purpose, String defaultValue) { - super(name, cliChar, purpose, defaultValue); - } - - /* - * This class will be like StringOption, but expect a string of numbers like Weka's Range - * e.g., 1,2,5-9,end will return something like [0,1,4,5,6,7,8,-1] which we will use later indicate e.g. multiple class attributes - */ - - public void setRange(int indices[]) { - this.currentVal = Arrays.toString(indices); // "[1,2,3]" - this.currentVal = this.currentVal.substring(1,this.currentVal.length()-1); // "1,2,3" - } - - public Range getRange() { - return new Range(this.getValue()); - } - - /*public int[] getRange() { - Range r = new Range(this.getValue()); - return r.getSelection(); - }*/ - -} - diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java index c427141d8..fa92fc81e 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/ArffLoader.java @@ -20,7 +20,6 @@ import java.io.Reader; import java.io.StreamTokenizer; import java.util.ArrayList; -import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -285,35 +284,25 @@ private void setSparseValue(Instance instance, List indexValues, List attributeLabels = new ArrayList(); @@ -363,10 +348,8 @@ private InstanceInformation getHeader(String outputDefinition, String inputDefin if (streamTokenizer.sval != null) { attributeLabels.add(streamTokenizer.sval); - // System.out.print(streamTokenizer.sval + ","); } else { attributeLabels.add(Double.toString(streamTokenizer.nval)); - //System.out.print(streamTokenizer.nval + ","); } streamTokenizer.nextToken(); diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java index 44d552dba..b4bd6dee2 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java @@ -25,6 +25,11 @@ */ public class Attribute implements Serializable { + /** + * + */ + private static final long serialVersionUID = -3739913325563469730L; + /** The keyword used to denote the start of an arff attribute declaration */ public final static String ARFF_ATTRIBUTE = "@attribute"; diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributesInformation.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributesInformation.java index 8fcbb1330..dae542dd4 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributesInformation.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/AttributesInformation.java @@ -16,7 +16,6 @@ package com.yahoo.labs.samoa.instances; import java.io.Serializable; -import java.util.ArrayList; import java.util.List; /** @@ -27,16 +26,15 @@ * @version $Revision: 7 $ */ public class AttributesInformation implements Serializable { + /** + * + */ + private static final long serialVersionUID = 1666190771085863695L; - /** + /** * The attribute information. */ protected List attributes; - protected List indexValues; - /** - * The number of attributes. - */ - protected int numberAttributes; /** * The attribute used for default for numerical values @@ -45,29 +43,14 @@ public class AttributesInformation implements Serializable { public AttributesInformation(AttributesInformation chunk) { this.attributes = chunk.attributes; - this.indexValues = chunk.indexValues; - this.numberAttributes = chunk.numberAttributes; } - public AttributesInformation(List v, List i, int numberAttributes) { + public AttributesInformation(List v) { this.attributes = v; - this.indexValues = i; - this.numberAttributes = numberAttributes; - } - - public AttributesInformation(List v, int numberAttributes) { - this.attributes = v; - this.indexValues = new ArrayList(numberAttributes); - for (int i = 0; i < numberAttributes; i++) { - this.indexValues.add(i); - } - this.numberAttributes = numberAttributes; } public AttributesInformation() { this.attributes = null; - this.indexValues = null; - this.numberAttributes = 0; this.defaultNumericAttribute = null; } @@ -82,17 +65,11 @@ public Attribute attribute(int indexAttribute) { //All attributes are numeric return defaultNumericAttribute(); } - int location = locateIndex(indexAttribute); - if (location == -1) { - //if there is not attribute information, it is numeric - return defaultNumericAttribute(); - } - return attributes.get(location); + return attributes.get(indexAttribute); } - public void add(Attribute attribute, int value) { + public void add(Attribute attribute) { this.attributes.add(attribute); - this.indexValues.add(value); } /** @@ -102,40 +79,6 @@ public void add(Attribute attribute, int value) { */ public void setAttributes(List v) { this.attributes = v; - this.numberAttributes=v.size(); - } - - /** - * Locates the greatest index that is not greater than the given index. - * - * @return the internal index of the attribute index. Returns -1 if no index - * with this property could be found - */ - public int locateIndex(int index) { - - int min = 0; - int max = this.indexValues.size() - 1; - - if (max == -1) { - return -1; - } - - // Binary search - while ((this.indexValues.get(min) <= index) && (this.indexValues.get(max) >= index)) { - int current = (max + min) / 2; - if (this.indexValues.get(current) > index) { - max = current - 1; - } else if (this.indexValues.get(current) < index) { - min = current + 1; - } else { - return current; - } - } - if (this.indexValues.get(max) < index) { - return max; - } else { - return min - 1; - } } private Attribute defaultNumericAttribute() { @@ -145,10 +88,8 @@ private Attribute defaultNumericAttribute() { return this.defaultNumericAttribute; } - public void setAttributes(List v, List indexValues) { - this.attributes = v; - this.numberAttributes=v.size(); - this.indexValues=indexValues; - } - + public int numAttributes() { + return attributes.size(); + } + } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstance.java index bae288728..f8bc4b60d 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstance.java @@ -21,6 +21,11 @@ public class DenseInstance extends InstanceImpl { /** + * + */ + private static final long serialVersionUID = 2470663722464623836L; + + /** * Instantiates a new dense instance. * * @param weight the weight diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstanceData.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstanceData.java index c4ec564ff..200e450a3 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstanceData.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/DenseInstanceData.java @@ -22,6 +22,11 @@ public class DenseInstanceData implements InstanceData{ /** + * + */ + private static final long serialVersionUID = 8799186995568094103L; + + /** * Instantiates a new dense instance data. * * @param array the array diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java index 8d71cea66..d855144a7 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java @@ -17,8 +17,6 @@ import java.io.Serializable; -import moa.AbstractMOAObject; - /** * The Interface Instance. * diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java index e5fd9321a..434e9492b 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java @@ -23,6 +23,11 @@ public class InstanceImpl implements MultiLabelInstance { /** + * + */ + private static final long serialVersionUID = -7908832747696137766L; + + /** * The weight. */ protected double weight; diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java index d9d769f77..ebb0d8940 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceInformation.java @@ -19,8 +19,6 @@ import java.util.ArrayList; import java.util.List; -import moa.AbstractMOAObject; - /** * The Class InstanceInformation. * @@ -28,7 +26,9 @@ */ public class InstanceInformation implements Serializable { - /** + private static final long serialVersionUID = 4240189973932498979L; + + /** * The dataset's name. */ protected String relationName; @@ -39,15 +39,25 @@ public class InstanceInformation implements Serializable { protected List inputIndexes; + /** + * Returns the input attribute. + * + * @param w the input attribute index (indexes only input attributes) + * @return the input attribute. + */ public Attribute inputAttribute(int w) { return this.attributesInformation.attribute(inputAttributeIndex(w)); } + /** + * Returns the output attribute. + * + * @param w the output attribute index (indexes only output attributes) + * @return the output attribute. + */ public Attribute outputAttribute(int w) { return this.attributesInformation.attribute(outputAttributeIndex(w)); } - - /** * Instantiates a new instance information. @@ -71,27 +81,16 @@ public InstanceInformation(String st, List attributes, List this.relationName = st; this.outputIndexes = outputIndexes; this.inputIndexes = inputIndexes; - this.attributesInformation = new AttributesInformation(attributes, attributes.size()); + this.attributesInformation = new AttributesInformation(attributes); } - public InstanceInformation(String st, List input, List indexes) { - this.relationName = st; - this.outputIndexes = new ArrayList(); - this.inputIndexes = new ArrayList(); - this.attributesInformation = new AttributesInformation(input, indexes, indexes.size()); - } - public InstanceInformation(String st, List input) { this.relationName = st; this.outputIndexes = new ArrayList(); this.inputIndexes = new ArrayList(); - List indexes = new ArrayList(); - for (int i = 0; i < input.size(); i++) { - indexes.add(i); - } - this.attributesInformation = new AttributesInformation(input, indexes, indexes.size()); + this.attributesInformation = new AttributesInformation(input); } - + /** * Instantiates a new instance information. */ @@ -143,7 +142,7 @@ public Attribute classAttribute() { * @see com.yahoo.labs.samoa.instances.InstanceInformationInterface#numAttributes() */ public int numAttributes() { - return this.attributesInformation.numberAttributes; + return this.attributesInformation.numAttributes(); } /* (non-Javadoc) @@ -175,7 +174,7 @@ public void insertAttributeAt(Attribute attribute, int i) { } public void setAttributes(List v) { - if(this.attributesInformation==null) + if(this.attributesInformation == null) this.attributesInformation= new AttributesInformation(); this.attributesInformation.setAttributes(v); } @@ -198,17 +197,21 @@ public int numOutputAttributes() { return outputIndexes.size(); } - - public void setAttributes(List v, List indexValues) { - if(this.attributesInformation==null) - this.attributesInformation= new AttributesInformation(); - this.attributesInformation.setAttributes(v,indexValues); - } - + + /** + * Sets the output attribute indexes, i.e., the targets. + * + * @param outputIndexes + */ public void setOutputIndexes(List outputIndexes) { this.outputIndexes = outputIndexes; } + /** + * Sets the input attribute indexes. + * + * @param inputIndexes + */ public void setInputIndexes(List inputIndexes) { this.inputIndexes = inputIndexes; } @@ -218,9 +221,9 @@ public void setInputIndexes(List inputIndexes) { */ public void setInputIndexes() { this.inputIndexes = new ArrayList(); - for (int i = 0; i < attributesInformation.indexValues.size(); i++) { - if (!outputIndexes.contains(attributesInformation.indexValues.get(i))) { - inputIndexes.add(attributesInformation.indexValues.get(i)); + for (int i = 0; i < attributesInformation.numAttributes(); i++) { + if (!outputIndexes.contains(i)) { + inputIndexes.add(i); } } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java index 421cbb74e..30401fdf5 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstancesHeader.java @@ -22,8 +22,6 @@ import java.util.List; import java.util.Random; -import org.junit.experimental.theories.Theories; - import moa.core.Utils; /** @@ -33,624 +31,625 @@ */ public class InstancesHeader implements Serializable { - /** The keyword used to denote the start of an arff header */ - public final static String ARFF_RELATION = "@relation"; - - /** The keyword used to denote the start of the arff data section */ - public final static String ARFF_DATA = "@data"; - - private static final long serialVersionUID = 1L; - - /** - * The instance information. - */ - protected InstanceInformation instanceInformation; - /** - * The instances. - */ - protected List instances; - - /** - * The arff. - */ - protected ArffLoader arff; - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - */ - public InstancesHeader(InstancesHeader chunk) { - this(chunk, chunk.numInstances()); - chunk.copyInstances(0, this, chunk.numInstances()); - } - - /** - * Instantiates a new instances. - */ - public InstancesHeader() { - } - - /** - * Instantiates a new instances. - * - * @param reader the reader - * @param size the size - * @param classAttribute the class attribute - */ - public InstancesHeader(Reader reader, int size, int classAttribute) { - arff = new ArffLoader(reader, String.valueOf(classAttribute)); - this.instanceInformation = arff.instanceInformation; - this.instances = new ArrayList(); - } - - public InstancesHeader(Reader reader, String outputDefinition) { - this.arff = new ArffLoader(reader, outputDefinition); - this.instanceInformation = arff.instanceInformation; - this.instances = new ArrayList(); - } - - public InstancesHeader(Reader reader, String outputDefinition, String inputDefinition) { - this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); - this.instanceInformation = arff.instanceInformation; - this.instances = new ArrayList(); - } - - public InstancesHeader(Reader reader, int size, String outputDefinition, String inputDefinition) { - this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); - this.instanceInformation = arff.instanceInformation; - this.instances = new ArrayList(); - } - - /** - * Instantiates a new instances. - * - * @param reader the reader - * @param range - */ -// public Instances(Reader reader, Range range) { -// this.arff = new MultiTargetArffLoader(reader, range); -// this.instanceInformation = arff.getStructure(); -// this.instances = new ArrayList(); -// } - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - * @param capacity the capacity - */ - public InstancesHeader(InstancesHeader chunk, int capacity) { - this.instanceInformation = chunk.instanceInformation(); - if (capacity < 0) { - capacity = 0; - } - this.instances = new ArrayList(capacity); - } - - /** - * Instantiates a new instances. - * - * @param st the st - * @param v the v - * @param capacity the capacity - */ - public InstancesHeader(String st, List v, int capacity) { - this.instanceInformation = new InstanceInformation(st, v); - } - - /** - * Instantiates a new instances. - * - * @param chunk the chunk - * @param first the first instance - * @param toCopy the j - */ - public InstancesHeader(InstancesHeader chunk, int first, int toCopy) { - - this(chunk, toCopy); - - if ((first < 0) || ((first + toCopy) > chunk.numInstances())) { - throw new IllegalArgumentException("Parameters first and/or toCopy out " - + "of range"); - } - chunk.copyInstances(first, this, toCopy); - } - - /** - * Instantiates a new instances. - * - * @param st the st - * @param capacity the capacity - */ - public InstancesHeader(StringReader st, int capacity) { - this.instances = new ArrayList(capacity); - } - - //Information Instances - /** - * Sets the relation name. - * - * @param string the new relation name - */ - public void setRelationName(String string) { - this.instanceInformation.setRelationName(string); - } - - /** - * Gets the relation name. - * - * @return the relation name - */ - public String getRelationName() { - return this.instanceInformation.getRelationName(); - } - - /** - * Class index. - * - * @return the int - */ - public int classIndex() { - return this.instanceInformation.classIndex(); - } - - /** - * Sets the class index. Also sets all other attributes as input attributes for backward compatibility. - * - * @param classIndex the new class index - */ - public void setClassIndex(int classIndex) { - this.instanceInformation.setClassIndex(classIndex); - this.instanceInformation.setInputIndexes(); - } - - public void setOutputIndexes(List outputIndexes) { - this.instanceInformation.setOutputIndexes(outputIndexes); - } - - public void setInputIndexes(List inputIndexes) { - this.instanceInformation.setInputIndexes(inputIndexes); - } + /** The keyword used to denote the start of an arff header */ + public final static String ARFF_RELATION = "@relation"; + + /** The keyword used to denote the start of the arff data section */ + public final static String ARFF_DATA = "@data"; + + private static final long serialVersionUID = 1L; + + /** + * The instance information. + */ + protected InstanceInformation instanceInformation; + /** + * The instances. + */ + protected List instances; + + /** + * The arff. + */ + protected ArffLoader arff; + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + */ + public InstancesHeader(InstancesHeader chunk) { + this(chunk, chunk.numInstances()); + chunk.copyInstances(0, this, chunk.numInstances()); + } + + /** + * Instantiates a new instances. + */ + public InstancesHeader() { + } + + /** + * Instantiates a new instances. + * + * @param reader the reader + * @param size the size + * @param classAttribute the class attribute + */ + public InstancesHeader(Reader reader, int size, int classAttribute) { + arff = new ArffLoader(reader, String.valueOf(classAttribute)); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + /** + * Instantiates a new intances header. + * + * @param reader + * @param outputDefinition defines the output attributes (others are treated as inputs) + */ + public InstancesHeader(Reader reader, String outputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + /** + * Instantiates a new intances header. + * + * @param reader + * @param outputDefinition defines the output attributes + * @param inputDefinition defines the input attributes + */ + public InstancesHeader(Reader reader, String outputDefinition, String inputDefinition) { + this.arff = new ArffLoader(reader, outputDefinition, inputDefinition); + this.instanceInformation = arff.instanceInformation; + this.instances = new ArrayList(); + } + + /** + * Instantiates a new instances. + * + * @param reader the reader + * @param range + */ + // public Instances(Reader reader, Range range) { + // this.arff = new MultiTargetArffLoader(reader, range); + // this.instanceInformation = arff.getStructure(); + // this.instances = new ArrayList(); + // } + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + * @param capacity the capacity + */ + public InstancesHeader(InstancesHeader chunk, int capacity) { + this.instanceInformation = chunk.instanceInformation(); + if (capacity < 0) { + capacity = 0; + } + this.instances = new ArrayList(capacity); + } + + /** + * Instantiates a new instances. + * + * @param st the st + * @param v the v + * @param capacity the capacity + */ + public InstancesHeader(String st, List v, int capacity) { + this.instanceInformation = new InstanceInformation(st, v); + } + + /** + * Instantiates a new instances. + * + * @param chunk the chunk + * @param first the first instance + * @param toCopy the j + */ + public InstancesHeader(InstancesHeader chunk, int first, int toCopy) { + + this(chunk, toCopy); + + if ((first < 0) || ((first + toCopy) > chunk.numInstances())) { + throw new IllegalArgumentException("Parameters first and/or toCopy out " + + "of range"); + } + chunk.copyInstances(first, this, toCopy); + } + + /** + * Instantiates a new instances. + * + * @param st the st + * @param capacity the capacity + */ + public InstancesHeader(StringReader st, int capacity) { + this.instances = new ArrayList(capacity); + } + + //Information Instances + /** + * Sets the relation name. + * + * @param string the new relation name + */ + public void setRelationName(String string) { + this.instanceInformation.setRelationName(string); + } + + /** + * Gets the relation name. + * + * @return the relation name + */ + public String getRelationName() { + return this.instanceInformation.getRelationName(); + } + + /** + * Class index. + * + * @return the int + */ + public int classIndex() { + return this.instanceInformation.classIndex(); + } + + /** + * Sets the class index. Also sets all other attributes as input attributes for backward compatibility. + * + * @param classIndex the new class index + */ + public void setClassIndex(int classIndex) { + this.instanceInformation.setClassIndex(classIndex); + this.instanceInformation.setInputIndexes(); + } + + public void setOutputIndexes(List outputIndexes) { + this.instanceInformation.setOutputIndexes(outputIndexes); + } + + public void setInputIndexes(List inputIndexes) { + this.instanceInformation.setInputIndexes(inputIndexes); + } /** * Sets all non-output attributes as input attributes. */ public void setInputIndexes() { - this.instanceInformation.setInputIndexes(); - } - - /** - * Class attribute. - * - * @return the attribute - */ - public Attribute classAttribute() { - return this.instanceInformation.classAttribute(); - } - - /** - * Num attributes. - * - * @return the int - */ - public int numAttributes() { - return this.instanceInformation.numAttributes(); - } - - /** - * Attribute. - * - * @param w the w - * @return the attribute - */ - public Attribute attribute(int w) { - return this.instanceInformation.attribute(w); - } - - /** - * Num classes. - * - * @return the int - */ - public int numClasses() { - return this.instanceInformation.numClasses(); - } - - /** - * Delete attribute at. - * - * @param integer the integer - */ - public void deleteAttributeAt(Integer integer) { - this.instanceInformation.deleteAttributeAt(integer); - } - - /** - * Insert attribute at. - * - * @param attribute the attribute - * @param i the i - */ - public void insertAttributeAt(Attribute attribute, int i) { - if (this.instanceInformation==null) - this.instanceInformation= new InstanceInformation(); - this.instanceInformation.insertAttributeAt(attribute, i); - } - - //List of Instances - /** - * Instance. - * - * @param num the num - * @return the instance - */ - public Instance instance(int num) { - return this.instances.get(num); - } - - /** - * Num instances. - * - * @return the int - */ - public int numInstances() { - return this.instances.size(); - } - - /** - * Adds the. - * - * @param inst the inst - */ - public void add(Instance inst) { - this.instances.add(inst.copy()); - } - - /** - * Randomize. - * - * @param random the random - */ - public void randomize(Random random) { - for (int j = numInstances() - 1; j > 0; j--) { - swap(j, random.nextInt(j + 1)); - } - } - - /** - * Stratify. - * - * @param numFolds the num folds - */ - public void stratify(int numFolds) { - - if (classAttribute().isNominal()) { - - // sort by class - int index = 1; - while (index < numInstances()) { - Instance instance1 = instance(index - 1); - for (int j = index; j < numInstances(); j++) { - Instance instance2 = instance(j); - if ((instance1.classValue() == instance2.classValue()) - || (instance1.classIsMissing() - && instance2.classIsMissing())) { - swap(index, j); - index++; - } - } - index++; - } - stratStep(numFolds); - } - } - - protected void stratStep(int numFolds) { - ArrayList newVec = new ArrayList(this.instances.size()); - int start = 0, j; - - // create stratified batch - while (newVec.size() < numInstances()) { - j = start; - while (j < numInstances()) { - newVec.add(instance(j)); - j = j + numFolds; - } - start++; - } - this.instances = newVec; - } - - /** - * Train cv. - * - * @param numFolds the num folds - * @param numFold - * @param n the n - * @param random the random - * @return the instances - */ - public InstancesHeader trainCV(int numFolds, int numFold, Random random) { - InstancesHeader train = trainCV(numFolds, numFold); - train.randomize(random); - return train; - } - - public InstancesHeader trainCV(int numFolds, int numFold) { - int numInstForFold, first, offset; - InstancesHeader train; - - numInstForFold = numInstances() / numFolds; - if (numFold < numInstances() % numFolds) { - numInstForFold++; - offset = numFold; - } else { - offset = numInstances() % numFolds; - } - train = new InstancesHeader(this, numInstances() - numInstForFold); - first = numFold * (numInstances() / numFolds) + offset; - copyInstances(0, train, first); - copyInstances(first + numInstForFold, train, - numInstances() - first - numInstForFold); - return train; - } - - protected void copyInstances(int from, InstancesHeader dest, int num) { - for (int i = 0; i < num; i++) { - dest.add(instance(from + i)); - } - } - - /** - * Test cv. - * - * @param numFolds the num folds - * @param numFold the num fold - * @return the instances - */ - public InstancesHeader testCV(int numFolds, int numFold) { - - int numInstForFold, first, offset; - InstancesHeader test; - - numInstForFold = numInstances() / numFolds; - if (numFold < numInstances() % numFolds) { - numInstForFold++; - offset = numFold; - } else { - offset = numInstances() % numFolds; - } - test = new InstancesHeader(this, numInstForFold); - first = numFold * (numInstances() / numFolds) + offset; - copyInstances(first, test, numInstForFold); - return test; - } - - /* public Instances dataset() { + this.instanceInformation.setInputIndexes(); + } + + /** + * Class attribute. + * + * @return the attribute + */ + public Attribute classAttribute() { + return this.instanceInformation.classAttribute(); + } + + /** + * Num attributes. + * + * @return the int + */ + public int numAttributes() { + return this.instanceInformation.numAttributes(); + } + + /** + * Attribute. + * + * @param w the w + * @return the attribute + */ + public Attribute attribute(int w) { + return this.instanceInformation.attribute(w); + } + + /** + * Num classes. + * + * @return the int + */ + public int numClasses() { + return this.instanceInformation.numClasses(); + } + + /** + * Delete attribute at. + * + * @param integer the integer + */ + public void deleteAttributeAt(Integer integer) { + this.instanceInformation.deleteAttributeAt(integer); + } + + /** + * Insert attribute at. + * + * @param attribute the attribute + * @param i the i + */ + public void insertAttributeAt(Attribute attribute, int i) { + if (this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.insertAttributeAt(attribute, i); + } + + //List of Instances + /** + * Instance. + * + * @param num the num + * @return the instance + */ + public Instance instance(int num) { + return this.instances.get(num); + } + + /** + * Num instances. + * + * @return the int + */ + public int numInstances() { + return this.instances.size(); + } + + /** + * Adds the. + * + * @param inst the inst + */ + public void add(Instance inst) { + this.instances.add(inst.copy()); + } + + /** + * Randomize. + * + * @param random the random + */ + public void randomize(Random random) { + for (int j = numInstances() - 1; j > 0; j--) { + swap(j, random.nextInt(j + 1)); + } + } + + /** + * Stratify. + * + * @param numFolds the num folds + */ + public void stratify(int numFolds) { + + if (classAttribute().isNominal()) { + + // sort by class + int index = 1; + while (index < numInstances()) { + Instance instance1 = instance(index - 1); + for (int j = index; j < numInstances(); j++) { + Instance instance2 = instance(j); + if ((instance1.classValue() == instance2.classValue()) + || (instance1.classIsMissing() + && instance2.classIsMissing())) { + swap(index, j); + index++; + } + } + index++; + } + stratStep(numFolds); + } + } + + protected void stratStep(int numFolds) { + ArrayList newVec = new ArrayList(this.instances.size()); + int start = 0, j; + + // create stratified batch + while (newVec.size() < numInstances()) { + j = start; + while (j < numInstances()) { + newVec.add(instance(j)); + j = j + numFolds; + } + start++; + } + this.instances = newVec; + } + + /** + * Train cv. + * + * @param numFolds the num folds + * @param numFold + * @param n the n + * @param random the random + * @return the instances + */ + public InstancesHeader trainCV(int numFolds, int numFold, Random random) { + InstancesHeader train = trainCV(numFolds, numFold); + train.randomize(random); + return train; + } + + public InstancesHeader trainCV(int numFolds, int numFold) { + int numInstForFold, first, offset; + InstancesHeader train; + + numInstForFold = numInstances() / numFolds; + if (numFold < numInstances() % numFolds) { + numInstForFold++; + offset = numFold; + } else { + offset = numInstances() % numFolds; + } + train = new InstancesHeader(this, numInstances() - numInstForFold); + first = numFold * (numInstances() / numFolds) + offset; + copyInstances(0, train, first); + copyInstances(first + numInstForFold, train, + numInstances() - first - numInstForFold); + return train; + } + + protected void copyInstances(int from, InstancesHeader dest, int num) { + for (int i = 0; i < num; i++) { + dest.add(instance(from + i)); + } + } + + /** + * Test cv. + * + * @param numFolds the num folds + * @param numFold the num fold + * @return the instances + */ + public InstancesHeader testCV(int numFolds, int numFold) { + + int numInstForFold, first, offset; + InstancesHeader test; + + numInstForFold = numInstances() / numFolds; + if (numFold < numInstances() % numFolds) { + numInstForFold++; + offset = numFold; + } else { + offset = numInstances() % numFolds; + } + test = new InstancesHeader(this, numInstForFold); + first = numFold * (numInstances() / numFolds) + offset; + copyInstances(first, test, numInstForFold); + return test; + } + + /* public Instances dataset() { throw new UnsupportedOperationException("Not yet implemented"); }*/ - /** - * Mean or mode. - * - * @param j the j - * @return the double - */ - public double meanOrMode(int j) { - throw new UnsupportedOperationException("Not yet implemented"); //CobWeb - } - - /** - * Read instance. - * - * @param fileReader the file reader - * @return true, if successful - */ - public boolean readInstance(Reader fileReader) { - - //ArffReader arff = new ArffReader(reader, this, m_Lines, 1); - Instance inst = arff.readInstance(); - if (inst != null) { - inst.setDataset(this); - add(inst); - return true; - } else { - return false; - } - } - - /** - * Delete. - */ - public void delete() { - this.instances = new ArrayList(); - } - - /** - * Delete. - */ - public void delete(int index) { - this.instances.remove(index); - } - - - /** - * Swap. - * - * @param i the i - * @param j the j - */ - public void swap(int i, int j) { - Instance in = instances.get(i); - instances.set(i, instances.get(j)); - instances.set(j, in); - } - - /** - * Instance information. - * - * @return the instance information - */ - private InstanceInformation instanceInformation() { - return this.instanceInformation; - } - - public Attribute attribute(String name) { - - for (int i = 0; i < numAttributes(); i++) { - if (attribute(i).name().equals(name)) { - return attribute(i); - } - } - return null; - } - - public int size() { - return this.numInstances(); - } - - public void set(int i, Instance inst) { - this.instances.set(i, inst); - } - - public Instance get(int k) { - return this.instance(k); - } - -// public void setRangeOutputIndices(Range range) { -// this.instanceInformation.setRangeOutputIndices(range); -// -// } - - public void setAttributes(List v) { - if(this.instanceInformation==null) - this.instanceInformation= new InstanceInformation(); - this.instanceInformation.setAttributes(v); - } - - public void setAttributes(List v, List indexValues) { - if(this.instanceInformation==null) - this.instanceInformation= new InstanceInformation(); - this.instanceInformation.setAttributes(v, indexValues); - } - - /** - * Returns the dataset as a string in ARFF format. Strings - * are quoted if they contain whitespace characters, or if they - * are a question mark. - * - * @return the dataset in ARFF format as a string - */ - public String toString() { - - StringBuffer text = new StringBuffer(); - - text.append(ARFF_RELATION).append(" "). - append(Utils.quote( this.instanceInformation.getRelationName())).append("\n\n"); - for (int i = 0; i < numAttributes(); i++) { - text.append(attribute(i).toString()).append("\n"); - } - text.append("\n").append(ARFF_DATA).append("\n"); - - text.append(stringWithoutHeader()); - return text.toString(); - } - - /** - * Returns the instances in the dataset as a string in ARFF format. Strings - * are quoted if they contain whitespace characters, or if they - * are a question mark. - * - * @return the dataset in ARFF format as a string - */ - protected String stringWithoutHeader() { - - StringBuffer text = new StringBuffer(); - - for (int i = 0; i < numInstances(); i++) { - text.append(instance(i)); - if (i < numInstances() - 1) { - text.append('\n'); - } - } - return text.toString(); - - } + /** + * Mean or mode. + * + * @param j the j + * @return the double + */ + public double meanOrMode(int j) { + throw new UnsupportedOperationException("Not yet implemented"); //CobWeb + } + + /** + * Read instance. + * + * @param fileReader the file reader + * @return true, if successful + */ + public boolean readInstance(Reader fileReader) { + + //ArffReader arff = new ArffReader(reader, this, m_Lines, 1); + Instance inst = arff.readInstance(); + if (inst != null) { + inst.setDataset(this); + add(inst); + return true; + } else { + return false; + } + } + + /** + * Delete. + */ + public void delete() { + this.instances = new ArrayList(); + } + + /** + * Delete. + */ + public void delete(int index) { + this.instances.remove(index); + } + + + /** + * Swap. + * + * @param i the i + * @param j the j + */ + public void swap(int i, int j) { + Instance in = instances.get(i); + instances.set(i, instances.get(j)); + instances.set(j, in); + } + + /** + * Instance information. + * + * @return the instance information + */ + private InstanceInformation instanceInformation() { + return this.instanceInformation; + } + + public Attribute attribute(String name) { + + for (int i = 0; i < numAttributes(); i++) { + if (attribute(i).name().equals(name)) { + return attribute(i); + } + } + return null; + } + + public int size() { + return this.numInstances(); + } + + public void set(int i, Instance inst) { + this.instances.set(i, inst); + } + + public Instance get(int k) { + return this.instance(k); + } + + // public void setRangeOutputIndices(Range range) { + // this.instanceInformation.setRangeOutputIndices(range); + // + // } + + public void setAttributes(List v) { + if(this.instanceInformation==null) + this.instanceInformation= new InstanceInformation(); + this.instanceInformation.setAttributes(v); + } + + /** + * Returns the dataset as a string in ARFF format. Strings + * are quoted if they contain whitespace characters, or if they + * are a question mark. + * + * @return the dataset in ARFF format as a string + */ + public String toString() { + + StringBuffer text = new StringBuffer(); + + text.append(ARFF_RELATION).append(" "). + append(Utils.quote( this.instanceInformation.getRelationName())).append("\n\n"); + for (int i = 0; i < numAttributes(); i++) { + text.append(attribute(i).toString()).append("\n"); + } + text.append("\n").append(ARFF_DATA).append("\n"); + + text.append(stringWithoutHeader()); + return text.toString(); + } + + /** + * Returns the instances in the dataset as a string in ARFF format. Strings + * are quoted if they contain whitespace characters, or if they + * are a question mark. + * + * @return the dataset in ARFF format as a string + */ + protected String stringWithoutHeader() { + + StringBuffer text = new StringBuffer(); + + for (int i = 0; i < numInstances(); i++) { + text.append(instance(i)); + if (i < numInstances() - 1) { + text.append('\n'); + } + } + return text.toString(); + + } public Attribute inputAttribute(int w) { - return this.instanceInformation.inputAttribute(w); + return this.instanceInformation.inputAttribute(w); } public Attribute outputAttribute(int w) { - return this.instanceInformation.outputAttribute(w); + return this.instanceInformation.outputAttribute(w); } public int numInputAttributes() { - return this.instanceInformation.numInputAttributes(); + return this.instanceInformation.numInputAttributes(); } public int numOutputAttributes() { - return this.instanceInformation.numOutputAttributes(); + return this.instanceInformation.numOutputAttributes(); } public InstanceInformation getInstanceInformation() { - return this.instanceInformation; + return this.instanceInformation; } public static String getClassNameString(InstancesHeader context) { - if (context == null) { - return "[class]"; - } - return "[class:" + context.classAttribute().name() + "]"; + if (context == null) { + return "[class]"; + } + return "[class:" + context.classAttribute().name() + "]"; } public static String getClassLabelString(InstancesHeader context, int classLabelIndex) { - if ((context == null) || (classLabelIndex >= context.numClasses())) { - return ""; - } - return ""; + if ((context == null) || (classLabelIndex >= context.numClasses())) { + return ""; + } + return ""; } public static String getAttributeNameString(InstancesHeader context, int attIndex) { - if ((context == null) || (attIndex >= context.numAttributes())) { - return "[att " + (attIndex + 1) + "]"; - } - return "[att " + (attIndex + 1) + ":" - + context.attribute(attIndex).name() + "]"; + if ((context == null) || (attIndex >= context.numAttributes())) { + return "[att " + (attIndex + 1) + "]"; + } + return "[att " + (attIndex + 1) + ":" + + context.attribute(attIndex).name() + "]"; } public static String getInputAttributeNameString(InstancesHeader context, int attIndex) { - if ((context == null) || (attIndex >= context.numInputAttributes())) { - return "[att " + (attIndex + 1) + "]"; - } - return "[att " + (attIndex + 1) + ":" - + context.inputAttribute(attIndex).name() + "]"; + if ((context == null) || (attIndex >= context.numInputAttributes())) { + return "[att " + (attIndex + 1) + "]"; + } + return "[att " + (attIndex + 1) + ":" + + context.inputAttribute(attIndex).name() + "]"; } public static String getNominalValueString(InstancesHeader context, int attIndex, int valIndex) { - if (context != null) { - if ((attIndex < context.numInputAttributes()) - && (valIndex < context.inputAttribute(attIndex).numValues())) { - return "{val " + (valIndex + 1) + ":" - + context.inputAttribute(attIndex).value(valIndex) + "}"; - } - } - return "{val " + (valIndex + 1) + "}"; + if (context != null) { + if ((attIndex < context.numInputAttributes()) + && (valIndex < context.inputAttribute(attIndex).numValues())) { + return "{val " + (valIndex + 1) + ":" + + context.inputAttribute(attIndex).value(valIndex) + "}"; + } + } + return "{val " + (valIndex + 1) + "}"; } public static String getNumericValueString(InstancesHeader context, int attIndex, double value) { - if (context != null) { - int instAttIndex = attIndex < context.classIndex() ? attIndex - : attIndex + 1; - if (instAttIndex < context.numAttributes()) { - if (context.attribute(instAttIndex).isDate()) { - return context.attribute(instAttIndex).formatDate(value); - } - } - } - return Double.toString(value); - } - - + if (context != null) { + int instAttIndex = attIndex < context.classIndex() ? attIndex + : attIndex + 1; + if (instAttIndex < context.numAttributes()) { + if (context.attribute(instAttIndex).isDate()) { + return context.attribute(instAttIndex).formatDate(value); + } + } + } + return Double.toString(value); + } + + } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java index 12b35c5a3..7e8fb2bdc 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/MultiLabelPrediction.java @@ -18,6 +18,11 @@ import java.io.Serializable; public class MultiLabelPrediction implements Prediction, Serializable { + /** + * + */ + private static final long serialVersionUID = 1413498152667626736L; + protected DoubleVector [] prediction; public MultiLabelPrediction() { diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java deleted file mode 100644 index d02e5fbbc..000000000 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Range.java +++ /dev/null @@ -1,110 +0,0 @@ - -/* - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ -package com.yahoo.labs.samoa.instances; - -import java.io.Serializable; - -public class Range implements Serializable { - - //Only works for ranges "start-end" - private int start = 0; - private int end = 0; - private int upperLimit = 0; - private final String rangeText; - - public Range(String range) { - this.rangeText = range; - //this.setRange(range); //needs upperLimit - } - - /** - * Sets the range from a string representation. - * - * @param range the start and end string - * - */ - public void setRange(String range) { - String single = range.trim(); - int hyphenIndex = range.indexOf('-'); - - if (hyphenIndex > 0) { - this.start = rangeSingle(range.substring(0, hyphenIndex)); - this.end = rangeSingle(range.substring(hyphenIndex + 1)); - } else { - int number = rangeSingle(range); - if (number >= 0) { // first n attributes - this.start = 0; - this.end = number; - } else { // last n attributes - this.start = this.upperLimit + number > 0 ? this.upperLimit + number : 0; - this.end = this.upperLimit - 1; - } - } - } - - /** - * Translates a single string selection into it's internal 0-based - * equivalent. - * - * @param single the string representing the selection (eg: 1 first last) - * @return the number corresponding to the selected value - */ - protected /*@pure@*/ int rangeSingle(/*@non_null@*/String singleSelection) { - - String single = singleSelection.trim(); - if (single.toLowerCase().equals("first")) { - return 0; - } - if (single.toLowerCase().equals("last") || single.toLowerCase().equals("-1")) { - return -1; - } - int index = Integer.parseInt(single); - if (index >= 1) { //Non for negatives - index--; - } - return index; - } - - boolean isInRange(int value) { - boolean ret = false; - if (value >= start && value <= end) { - ret = true; - } - return ret; - } - - int getSelectionLength() { - return end - start + 1; - } - - public void setUpper(int attributeNumber) { - this.upperLimit = attributeNumber; - this.setRange(this.rangeText); - } - - //JD - public int getStart() { - return start; - } - - //JD - - public int getEnd() { - return end; - } - -} diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 070665e55..7ac2b2825 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -7,7 +7,6 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; @@ -23,6 +22,11 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner implements MultiLabelClassifier, MultiTargetRegressor { + /** + * + */ + private static final long serialVersionUID = 5437749202546674734L; + public ClassOption classifierOption = new ClassOption( "classifier", 'c', @@ -50,15 +54,12 @@ private void makeHeaders() { headers = new ArrayList(); for (int target = 0; target < getModelContext().numOutputAttributes(); target++) { List attributes = new ArrayList(); - List indexValues = new ArrayList(); for (int i = 0; i < getModelContext().numInputAttributes(); i++) { attributes.add(getModelContext().inputAttribute(i)); - indexValues.add(i); } attributes.add(getModelContext().outputAttribute(target)); - indexValues.add(getModelContext().numInputAttributes()); InstancesHeader STHeader = new InstancesHeader(); - STHeader.setAttributes(attributes, indexValues); + STHeader.setAttributes(attributes); STHeader.setClassIndex(getModelContext().numInputAttributes()); headers.add(STHeader); } diff --git a/moa/src/main/java/moa/streams/ArffFileStream.java b/moa/src/main/java/moa/streams/ArffFileStream.java index 5d0d10ef9..81d639198 100644 --- a/moa/src/main/java/moa/streams/ArffFileStream.java +++ b/moa/src/main/java/moa/streams/ArffFileStream.java @@ -155,7 +155,7 @@ public void restart() { this.fileProgressMonitor = new InputStreamProgressMonitor( fileStream); this.fileReader = new BufferedReader(new InputStreamReader(this.fileProgressMonitor)); - this.instances = new InstancesHeader(this.fileReader, 1, this.outputIndexesOption.getValue(), this.inputIndexesOption.getValue()); + this.instances = new InstancesHeader(this.fileReader, this.outputIndexesOption.getValue(), this.inputIndexesOption.getValue()); this.numInstancesRead = 0; this.lastInstanceRead = null; this.hitEndOfFile = !readNextInstanceFromFile(); diff --git a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java index 80e2ae84f..9ade14c76 100644 --- a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java +++ b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java @@ -28,7 +28,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; -import com.github.javacliparser.RangeOption; // jesse import moa.core.InputStreamProgressMonitor; import moa.core.InstanceExample; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/streams/clustering/FileStream.java b/moa/src/main/java/moa/streams/clustering/FileStream.java index 7ef557add..bd8458fff 100644 --- a/moa/src/main/java/moa/streams/clustering/FileStream.java +++ b/moa/src/main/java/moa/streams/clustering/FileStream.java @@ -38,6 +38,8 @@ import moa.core.InstanceExample; import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; +import moa.core.utils.AttributeDefinitionUtil; + import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; @@ -48,7 +50,6 @@ import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class FileStream extends ClusteringStream{ @@ -65,11 +66,6 @@ public String getPurposeString() { public FileOption arffFileOption = new FileOption("arffFile", 'f', "ARFF file to load.", defaultfile, "arff", false); -// public IntOption classIndexOption = new IntOption( -// "classIndex", -// 'c', -// "Class index of data. 0 for none or -1 for last attribute in file.", -// -1, -1, Integer.MAX_VALUE); public StringOption outputIndicesOption = new StringOption( "outputIndices", @@ -81,7 +77,7 @@ public String getPurposeString() { "outputIndices", 'i', "Indices of input (class) attributes. Can be provided in a comma or semicolon separated list of single values or ranges. Leave blank for all non-output attributes.", - ""); + AttributeDefinitionUtil.nonIgnoredDefinition); public FlagOption normalizeOption = new FlagOption("normalize", 'n', @@ -169,7 +165,7 @@ public void restart() { InputStream fileStream = new FileInputStream(arffFileOption.getFile()); fileProgressMonitor = new InputStreamProgressMonitor(fileStream); fileReader = new BufferedReader(new InputStreamReader(fileProgressMonitor)); - instances = new InstancesHeader(fileReader, 1, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); + instances = new InstancesHeader(fileReader, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); //use hashset to delete duplicates and attributes numbers that aren't valid @@ -287,7 +283,7 @@ protected ArrayList readMinMaxDiffValues(HashSet ignoredAttri InputStream fileStream = new FileInputStream(arffFileOption.getFile()); InputStreamProgressMonitor fileProgressMonitor = new InputStreamProgressMonitor(fileStream); Reader fileReader = new BufferedReader(new InputStreamReader(fileProgressMonitor)); - InstancesHeader instances = new InstancesHeader(fileReader, 1, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); + InstancesHeader instances = new InstancesHeader(fileReader, this.outputIndicesOption.getValue(), this.inputIndicesOption.getValue()); valuesMinMaxDiff = new ArrayList(); for (int i = 0; i < instances.numAttributes()-ignoredAttributes.size(); i++) { diff --git a/moa/src/main/java/moa/streams/filters/RBFFilter.java b/moa/src/main/java/moa/streams/filters/RBFFilter.java index bf90b324c..df300eb65 100644 --- a/moa/src/main/java/moa/streams/filters/RBFFilter.java +++ b/moa/src/main/java/moa/streams/filters/RBFFilter.java @@ -5,15 +5,12 @@ import java.util.Random; import moa.core.InstanceExample; -import moa.streams.MultiTargetInstanceStream; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Range; public class RBFFilter extends AbstractStreamFilter { @@ -53,14 +50,12 @@ public InstanceExample nextInstance() { int d = x.numAttributes(); int h = numLatentOption.getValue(); - int j_c = x.classIndex(); for(int k = 0; k < h; k++) { double sum_k = 0.; for(int j = 0; j < d; j++) { sum_k += (x.value(j) - c[k]); } - double v = sum_k / Math.pow(r[k],2); z.setValue(k,Math.exp(-sum_k)); } z.setValue(h,x.classValue()); @@ -100,7 +95,7 @@ private void initialize(Instance instance) { indexValues.add(h); - ds.setAttributes(v,indexValues); + ds.setAttributes(v); dataset=(new InstancesHeader(ds)); dataset.setClassIndex(h); System.out.println(""+dataset); diff --git a/moa/src/main/java/moa/streams/filters/ReLUFilter.java b/moa/src/main/java/moa/streams/filters/ReLUFilter.java index 3f6eb7f55..4023e2194 100644 --- a/moa/src/main/java/moa/streams/filters/ReLUFilter.java +++ b/moa/src/main/java/moa/streams/filters/ReLUFilter.java @@ -4,16 +4,11 @@ import java.util.List; import java.util.Random; -import moa.core.InstanceExample; -import moa.streams.MultiTargetInstanceStream; - import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Range; public class ReLUFilter extends AbstractStreamFilter { @@ -111,7 +106,7 @@ private void initialize(Instance instance) { indexValues.add(H); - ds.setAttributes(v,indexValues); + ds.setAttributes(v); dataset=(new InstancesHeader(ds)); dataset.setClassIndex(H); diff --git a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java index b5905e34a..5270011e2 100644 --- a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java +++ b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java @@ -3,17 +3,13 @@ import java.util.ArrayList; import java.util.List; -import moa.core.Example; import moa.core.InstanceExample; -import moa.streams.MultiTargetInstanceStream; import com.github.javacliparser.StringOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Range; public class SelectAttributesFilter extends AbstractMultiLabelStreamFilter implements MultiLabelStreamFilter{ @@ -52,7 +48,6 @@ private void initialize(Instance instance) { int totAttributes=inputsSelected.numValues()+outputsSelected.numValues(); InstancesHeader ds= new InstancesHeader(); List v = new ArrayList(totAttributes); - List indexValues = new ArrayList(totAttributes); int ct=0; List inputIndexes = new ArrayList(); List outputIndexes = new ArrayList(); @@ -60,7 +55,6 @@ private void initialize(Instance instance) { { for (int j=inputsSelected.getStart(i); j<=inputsSelected.getEnd(i);j++){ v.add(instance.attribute(j-1)); - indexValues.add(ct); inputIndexes.add(ct); ct++; } @@ -70,12 +64,11 @@ private void initialize(Instance instance) { { for (int j=outputsSelected.getStart(i); j<=outputsSelected.getEnd(i);j++){ v.add(instance.attribute(j-1)); - indexValues.add(ct); outputIndexes.add(ct); ct++; } } - ds.setAttributes(v,indexValues); + ds.setAttributes(v); ds.setOutputIndexes(outputIndexes); ds.setInputIndexes(inputIndexes); dataset=(new InstancesHeader(ds)); diff --git a/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java b/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java index 5c99a5e92..4987e2718 100644 --- a/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java +++ b/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java @@ -21,7 +21,6 @@ import java.io.BufferedReader; import java.io.FileInputStream; -import java.io.FileReader; import java.io.InputStreamReader; import java.io.Reader; @@ -35,11 +34,8 @@ import moa.test.TmpFile; import weka.core.MOAUtils; -import com.yahoo.labs.samoa.instances.ArffLoader; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Range; /** * Ancestor for all classifier test cases. From bdffa94288880631866d7a98275a1266d3f3b60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Tue, 10 Jan 2017 14:30:50 +0100 Subject: [PATCH 28/33] Instances rework, new iSOUPTree models and import cleanup --- moa/.settings/org.eclipse.jdt.core.prefs | 13 +- .../github/javacliparser/JavaCLIParser.java | 1 - .../gui/ClassOptionEditComponent.java | 3 +- .../ClassOptionWithNamesEditComponent.java | 3 +- .../gui/FileOptionEditComponent.java | 1 + .../gui/ListOptionEditComponent.java | 4 +- .../gui/OptionsConfigurationPanel.java | 8 +- .../labs/samoa/instances/ArffLoader.java | 1 + .../yahoo/labs/samoa/instances/Attribute.java | 7 +- .../yahoo/labs/samoa/instances/Instance.java | 34 +- .../labs/samoa/instances/InstanceImpl.java | 22 + .../samoa/instances/InstanceInformation.java | 1 - .../labs/samoa/instances/InstancesHeader.java | 13 + .../samoa/instances/MultiLabelPrediction.java | 3 +- .../SamoaToWekaInstanceConverter.java | 2 +- moa/src/main/java/moa/AbstractMOAObject.java | 6 +- moa/src/main/java/moa/DoTask.java | 10 +- moa/src/main/java/moa/MOAObject.java | 2 +- .../moa/classifiers/AbstractClassifier.java | 34 +- .../AbstractMultiLabelLearner.java | 5 +- .../main/java/moa/classifiers/Classifier.java | 7 +- .../moa/classifiers/MultiLabelLearner.java | 2 +- .../classifiers/active/ActiveClassifier.java | 10 +- .../moa/classifiers/bayes/NaiveBayes.java | 3 +- .../bayes/NaiveBayesMultinomial.java | 6 +- .../core/AttributeSplitSuggestion.java | 2 +- ...naryTreeNumericAttributeClassObserver.java | 1 + ...mericAttributeClassObserverRegression.java | 1 + .../FIMTDDNumericAttributeClassObserver.java | 61 +- ...GaussianNumericAttributeClassObserver.java | 12 +- ...ldKhannaNumericAttributeClassObserver.java | 6 +- .../NominalAttributeClassObserver.java | 7 +- .../VFMLNumericAttributeClassObserver.java | 8 +- .../InstanceConditionalTest.java | 4 +- .../NominalAttributeBinaryTest.java | 1 - .../NominalAttributeMultiwayTest.java | 1 - .../NumericAttributeBinaryTest.java | 1 - .../driftdetection/ADWINChangeDetector.java | 1 + .../core/driftdetection/CusumDM.java | 1 + .../classifiers/core/driftdetection/DDM.java | 1 + .../core/driftdetection/EWMAChartDM.java | 1 + .../EnsembleDriftDetectionMethods.java | 1 + .../GeometricMovingAverageDM.java | 1 + .../core/driftdetection/HDDM_A_Test.java | 1 + .../core/driftdetection/HDDM_W_Test.java | 1 + .../core/driftdetection/PageHinkleyDM.java | 1 + .../driftdetection/SEEDChangeDetector.java | 1 + .../SeqDrift1ChangeDetector.java | 8 +- .../SeqDrift2ChangeDetector.java | 8 +- .../splitcriteria/InfoGainSplitCriterion.java | 1 + .../drift/DriftDetectionMethodClassifier.java | 6 +- .../classifiers/functions/MajorityClass.java | 3 +- .../moa/classifiers/functions/NoChange.java | 3 +- .../moa/classifiers/functions/Perceptron.java | 5 +- .../java/moa/classifiers/functions/SGD.java | 9 +- .../classifiers/functions/SGDMultiClass.java | 7 +- .../moa/classifiers/functions/SPegasos.java | 7 +- .../main/java/moa/classifiers/lazy/kNN.java | 10 +- .../java/moa/classifiers/lazy/kNNwithPAW.java | 1 - .../classifiers/lazy/kNNwithPAWandADWIN.java | 4 +- .../lazy/neighboursearch/KDTree.java | 6 +- .../NearestNeighbourSearch.java | 1 + .../neighboursearch/NormalizableDistance.java | 1 - .../kdtrees/KDTreeNodeSplitter.java | 3 +- .../main/java/moa/classifiers/meta/ADACC.java | 7 +- .../meta/AccuracyUpdatedEnsemble.java | 7 +- .../meta/AccuracyWeightedEnsemble.java | 16 +- .../main/java/moa/classifiers/meta/DACC.java | 11 +- .../moa/classifiers/meta/LeveragingBag.java | 13 +- .../classifiers/meta/LimAttClassifier.java | 18 +- .../java/moa/classifiers/meta/OCBoost.java | 10 +- .../meta/OnlineAccuracyUpdatedEnsemble.java | 1 + .../classifiers/meta/OnlineSmoothBoost.java | 1 + .../java/moa/classifiers/meta/OzaBag.java | 14 +- .../java/moa/classifiers/meta/OzaBagASHT.java | 35 +- .../moa/classifiers/meta/OzaBagAdwin.java | 10 +- .../java/moa/classifiers/meta/OzaBoost.java | 8 +- .../moa/classifiers/meta/OzaBoostAdwin.java | 11 +- .../moa/classifiers/meta/PairedLearners.java | 9 +- .../moa/classifiers/meta/RandomRules.java | 3 +- .../meta/TemporallyAugmentedClassifier.java | 14 +- .../moa/classifiers/meta/WEKAClassifier.java | 8 +- .../meta/WeightedMajorityAlgorithm.java | 17 +- .../LocalMultiTargetClassifier.java | 46 +- .../multilabel/MEKAClassifier.java | 22 +- .../multilabel/MajorityLabelset.java | 9 +- .../multilabel/MultilabelHoeffdingTree.java | 17 +- .../MultiLabelBSTree.java | 72 +- .../MultiLabelBSTreePCT.java | 270 +++++++ .../MultiLabelNominalAttributeObserver.java | 4 +- .../splitcriteria/ICVarianceReduction.java | 8 +- .../PCTWeightedICVarianceReduction.java | 76 ++ .../classifiers/multilabel/meta/MTOzaBag.java | 16 +- .../multilabel/meta/OzaBagAdwinML.java | 109 ++- .../classifiers/multilabel/meta/OzaBagML.java | 13 +- .../multilabel/trees/ISOUPOptionTree.java | 68 +- .../multilabel/trees/ISOUPTree.java | 688 +++++++++++------- .../multilabel/trees/ISOUPTreeRF.java | 46 ++ .../BasicMultiTargetRegressor.java | 15 +- .../functions/MultiTargetNoChange.java | 6 +- .../rules/AMRulesRegressorOld.java | 3 +- .../classifiers/rules/AbstractAMRules.java | 8 +- .../moa/classifiers/rules/Predicates.java | 3 +- .../classifiers/rules/RuleClassification.java | 6 +- .../moa/classifiers/rules/RuleClassifier.java | 13 +- .../rules/RuleClassifierNBayes.java | 4 +- .../rules/core/NominalRulePredicate.java | 1 - .../rules/core/NumericRulePredicate.java | 1 - .../java/moa/classifiers/rules/core/Rule.java | 8 +- .../rules/core/RuleActiveLearningNode.java | 2 +- .../rules/core/RuleActiveRegressionNode.java | 12 +- .../moa/classifiers/rules/core/Utils.java | 5 + .../AbstractAnomalyDetector.java | 3 +- .../AnomalinessRatioScore.java | 10 +- .../anomalydetection/NoAnomalyDetection.java | 3 +- .../core/anomalydetection/OddsRatioScore.java | 10 +- .../CantellisInequality.java | 3 - .../ChebyshevInequality.java | 3 - .../probabilityfunctions/GaussInequality.java | 3 - ...TDDNumericAttributeClassLimitObserver.java | 4 +- .../NominalAttributeBinaryRulePredicate.java | 1 - .../NumericAttributeBinaryRulePredicate.java | 1 - .../SDRSplitCriterionAMRules.java | 1 - .../SDRSplitCriterionAMRulesNode.java | 2 - .../voting/AbstractErrorWeightedVote.java | 1 + .../errormeasurers/MeanAbsoluteDeviation.java | 1 - .../errormeasurers/RootMeanSquaredError.java | 2 - .../rules/functions/AMRulesLearner.java | 4 +- .../rules/functions/Perceptron.java | 2 - .../rules/functions/TargetMean.java | 2 +- .../rules/meta/RandomAMRulesOld.java | 7 +- .../multilabel/AMRulesMultiLabelLearner.java | 13 +- .../AMRulesMultiTargetRegressor.java | 2 - .../multilabel/core/LearningLiteral.java | 9 +- .../core/LearningLiteralRegression.java | 15 +- .../rules/multilabel/core/MultiLabelRule.java | 8 +- .../AbstractErrorWeightedVoteMultiLabel.java | 1 - .../voting/ErrorWeightedVoteMultiLabel.java | 2 - .../AbstractMultiLabelErrorMeasurer.java | 8 +- .../AbstractMultiTargetErrorMeasurer.java | 2 +- .../MultiLabelErrorMeasurer.java | 2 +- .../RootMeanSquaredErrorMT.java | 3 - .../AdaptiveMultiTargetRegressor.java | 7 +- .../MultiLabelTargetMeanRegressor.java | 1 - .../meta/MultiLabelRandomAMRules.java | 18 +- .../trees/AdaHoeffdingOptionTree.java | 3 +- .../moa/classifiers/trees/DecisionStump.java | 3 +- .../java/moa/classifiers/trees/FIMTDD.java | 46 +- .../trees/HoeffdingAdaptiveTree.java | 4 +- .../trees/HoeffdingOptionTree.java | 12 +- .../moa/classifiers/trees/HoeffdingTree.java | 14 +- .../trees/HoeffdingTreeClassifLeaves.java | 4 +- .../trees/LimAttHoeffdingTree.java | 3 +- .../main/java/moa/classifiers/trees/ORTO.java | 7 +- .../trees/RandomHoeffdingTree.java | 3 +- moa/src/main/java/moa/cluster/CFCluster.java | 1 + moa/src/main/java/moa/cluster/Cluster.java | 4 +- moa/src/main/java/moa/cluster/Clustering.java | 6 +- .../main/java/moa/cluster/SphereCluster.java | 1 + .../moa/clusterers/AbstractClusterer.java | 10 +- .../java/moa/clusterers/ClusterGenerator.java | 4 +- .../main/java/moa/clusterers/Clusterer.java | 5 +- moa/src/main/java/moa/clusterers/CobWeb.java | 10 +- moa/src/main/java/moa/clusterers/KMeans.java | 1 + .../clusterers/WekaClusteringAlgorithm.java | 13 +- .../moa/clusterers/clustream/Clustream.java | 8 +- .../clusterers/clustream/ClustreamKernel.java | 5 +- .../moa/clusterers/clustream/WithKmeans.java | 7 +- .../moa/clusterers/clustree/ClusKernel.java | 5 +- .../moa/clusterers/clustree/ClusTree.java | 11 +- .../clusterers/denstream/MicroCluster.java | 3 +- .../moa/clusterers/denstream/WithDBSCAN.java | 9 +- .../clusterers/macro/NonConvexCluster.java | 3 +- .../outliers/AbstractC/AbstractC.java | 6 +- .../outliers/AbstractC/AbstractCBase.java | 3 +- .../outliers/AbstractC/ISBIndex.java | 1 + .../outliers/AbstractC/MyMTree.java | 1 + .../clusterers/outliers/AbstractC/Test.java | 3 +- .../outliers/Angiulli/ApproxSTORM.java | 6 +- .../outliers/Angiulli/ExactSTORM.java | 6 +- .../outliers/Angiulli/ISBIndex.java | 1 + .../clusterers/outliers/Angiulli/MyMTree.java | 1 + .../outliers/Angiulli/STORMBase.java | 6 +- .../clusterers/outliers/Angiulli/Test.java | 3 +- .../clusterers/outliers/AnyOut/AnyOut.java | 4 +- .../outliers/AnyOut/AnyOutCore.java | 6 +- .../clusterers/outliers/MCOD/ISBIndex.java | 1 + .../moa/clusterers/outliers/MCOD/MCOD.java | 8 +- .../clusterers/outliers/MCOD/MCODBase.java | 3 +- .../outliers/MCOD/MTreeMicroClusters.java | 1 + .../outliers/MCOD/MTreeStreamObjects.java | 1 + .../outliers/MCOD/MicroCluster.java | 1 + .../moa/clusterers/outliers/MCOD/Test.java | 3 +- .../outliers/MyBaseOutlierDetector.java | 6 +- .../outliers/SimpleCOD/ISBIndex.java | 1 + .../outliers/SimpleCOD/MyMTree.java | 1 + .../outliers/SimpleCOD/SimpleCOD.java | 6 +- .../outliers/SimpleCOD/SimpleCODBase.java | 1 + .../clusterers/outliers/SimpleCOD/Test.java | 3 +- .../moa/clusterers/outliers/TestSpeed.java | 3 +- .../outliers/utils/mtree/MTree.java | 1 + .../utils/mtree/PromotionFunctions.java | 1 + .../java/moa/clusterers/streamkm/Point.java | 4 +- .../moa/clusterers/streamkm/StreamKM.java | 3 +- .../java/moa/core/AutoClassDiscovery.java | 2 +- .../main/java/moa/core/AutoExpandVector.java | 2 +- .../moa/core/MultilabelInstancesHeader.java | 1 - moa/src/main/java/moa/core/Utils.java | 8 - .../main/java/moa/core/utils/Converter.java | 4 +- .../main/java/moa/evaluation/Accuracy.java | 1 + ...winClassificationPerformanceEvaluator.java | 1 - ...sicClassificationPerformanceEvaluator.java | 12 +- ...BasicConceptDriftPerformanceEvaluator.java | 1 - .../BasicMultiLabelPerformanceEvaluator.java | 8 +- .../BasicMultiTargetPerformanceEvaluator.java | 11 +- .../BasicRegressionPerformanceEvaluator.java | 7 +- .../java/moa/evaluation/CMM_GTAnalysis.java | 4 +- .../evaluation/ChangeDetectionMeasures.java | 1 + .../ClassificationPerformanceEvaluator.java | 3 +- ...WMAClassificationPerformanceEvaluator.java | 13 - .../moa/evaluation/EntropyCollection.java | 1 + moa/src/main/java/moa/evaluation/F1.java | 1 + ...torClassificationPerformanceEvaluator.java | 12 - moa/src/main/java/moa/evaluation/General.java | 4 +- .../moa/evaluation/LearningEvaluation.java | 4 +- .../LearningPerformanceEvaluator.java | 1 - .../moa/evaluation/MeasureCollection.java | 1 + .../java/moa/evaluation/MembershipMatrix.java | 1 + .../MultiTargetPerformanceEvaluator.java | 3 +- ...tWindowRegressionPerformanceEvaluator.java | 13 +- .../moa/evaluation/OutlierPerformance.java | 2 +- .../RegressionPerformanceEvaluator.java | 3 +- moa/src/main/java/moa/evaluation/SSQ.java | 1 + .../main/java/moa/evaluation/Separation.java | 7 +- .../moa/evaluation/SilhouetteCoefficient.java | 2 +- .../moa/evaluation/StatisticalCollection.java | 1 + ...dowClassificationPerformanceEvaluator.java | 12 - .../WindowRegressionPerformanceEvaluator.java | 11 +- moa/src/main/java/moa/gui/BatchCmd.java | 5 +- .../moa/gui/ClassOptionSelectionPanel.java | 3 +- .../ClassOptionWithNamesSelectionPanel.java | 3 +- .../java/moa/gui/ConceptDriftTabPanel.java | 1 + moa/src/main/java/moa/gui/GUI.java | 6 +- moa/src/main/java/moa/gui/GUIDefaults.java | 6 +- .../java/moa/gui/MultiTargetTabPanel.java | 1 + .../moa/gui/MultiTargetTaskManagerPanel.java | 2 + .../main/java/moa/gui/RegressionTabPanel.java | 1 + .../moa/gui/RegressionTaskManagerPanel.java | 6 +- .../main/java/moa/gui/TaskManagerPanel.java | 6 +- .../java/moa/gui/TaskTextViewerPanel.java | 3 +- .../moa/gui/WEKAClassOptionEditComponent.java | 12 +- .../gui/clustertab/ClusteringAlgoPanel.java | 10 +- .../gui/clustertab/ClusteringEvalPanel.java | 3 +- .../gui/clustertab/ClusteringSetupTab.java | 2 + .../clustertab/ClusteringVisualEvalPanel.java | 4 +- .../gui/clustertab/ClusteringVisualTab.java | 2 + .../gui/conceptdrift/CDTaskManagerPanel.java | 11 +- .../moa/gui/outliertab/OutlierAlgoPanel.java | 15 +- .../moa/gui/outliertab/OutlierEvalPanel.java | 4 +- .../moa/gui/outliertab/OutlierSetupTab.java | 2 + .../outliertab/OutlierVisualEvalPanel.java | 4 +- .../moa/gui/outliertab/OutlierVisualTab.java | 2 + .../moa/gui/visualization/ClusterPanel.java | 2 + .../moa/gui/visualization/GraphCanvas.java | 2 + .../moa/gui/visualization/GraphCurve.java | 1 + .../moa/gui/visualization/OutlierPanel.java | 21 +- .../visualization/RunOutlierVisualizer.java | 10 +- .../moa/gui/visualization/RunVisualizer.java | 12 +- .../gui/visualization/StreamOutlierPanel.java | 16 +- .../moa/gui/visualization/WekaExplorer.java | 7 +- .../moa/learners/ChangeDetectorLearner.java | 3 +- moa/src/main/java/moa/learners/Learner.java | 6 +- .../java/moa/options/AbstractClassOption.java | 2 + .../moa/options/AbstractOptionHandler.java | 1 + .../main/java/moa/options/ClassOption.java | 3 +- .../moa/options/ClassOptionWithNames.java | 6 +- .../main/java/moa/options/OptionHandler.java | 1 + .../main/java/moa/options/OptionsHandler.java | 2 + .../java/moa/options/WEKAClassOption.java | 6 +- .../dataset/impl/FlixsterDataset.java | 5 +- .../dataset/impl/JesterDataset.java | 9 +- .../dataset/impl/MovielensDataset.java | 6 +- .../predictor/BRISMFPredictor.java | 6 +- .../predictor/BaselinePredictor.java | 1 + .../predictor/RatingPredictor.java | 1 + .../rc/data/AbstractRecommenderData.java | 1 + .../recommender/rc/data/RecommenderData.java | 1 + .../rc/data/impl/MemRecommenderData.java | 1 + .../rc/predictor/RatingPredictor.java | 1 + .../rc/predictor/impl/BRISMFPredictor.java | 1 + .../rc/predictor/impl/BaselinePredictor.java | 1 + .../main/java/moa/streams/ArffFileStream.java | 12 +- .../moa/streams/CachedInstancesStream.java | 5 +- .../moa/streams/ConceptDriftRealStream.java | 14 +- .../java/moa/streams/ConceptDriftStream.java | 10 +- .../main/java/moa/streams/ExampleStream.java | 5 +- .../main/java/moa/streams/InstanceStream.java | 3 +- .../java/moa/streams/MultiFilteredStream.java | 9 +- .../moa/streams/MultiLabelFilteredStream.java | 1 - .../streams/MultiTargetArffFileStream.java | 15 - .../streams/MultiTargetInstanceStream.java | 3 - .../streams/RecurrentConceptDriftStream.java | 7 +- .../streams/clustering/ClusteringStream.java | 3 +- .../moa/streams/clustering/FileStream.java | 14 +- .../clustering/RandomRBFGeneratorEvents.java | 17 +- .../streams/clustering/SimpleCSVStream.java | 1 - .../AbstractMultiLabelStreamFilter.java | 1 - .../streams/filters/AbstractStreamFilter.java | 2 +- .../moa/streams/filters/AddNoiseFilter.java | 9 +- .../java/moa/streams/filters/RBFFilter.java | 4 +- .../RemoveDiscreteAttributeFilter.java | 7 +- .../filters/ReplacingMissingValuesFilter.java | 11 +- .../filters/SelectAttributesFilter.java | 4 +- .../moa/streams/filters/StreamFilter.java | 1 + .../streams/generators/AgrawalGenerator.java | 15 +- .../generators/HyperplaneGenerator.java | 11 +- .../moa/streams/generators/LEDGenerator.java | 11 +- .../streams/generators/LEDGeneratorDrift.java | 4 +- .../generators/RandomRBFGenerator.java | 11 +- .../generators/RandomRBFGeneratorDrift.java | 6 +- .../generators/RandomTreeGenerator.java | 15 +- .../moa/streams/generators/SEAGenerator.java | 11 +- .../streams/generators/STAGGERGenerator.java | 11 +- .../streams/generators/WaveformGenerator.java | 11 +- .../generators/WaveformGeneratorDrift.java | 4 +- .../cd/AbstractConceptDriftGenerator.java | 7 +- .../generators/cd/ConceptDriftGenerator.java | 1 + .../multilabel/MetaMultilabelGenerator.java | 26 +- .../multilabel/MultilabelArffFileStream.java | 8 +- .../java/moa/tasks/CacheShuffledStream.java | 3 +- .../java/moa/tasks/ConceptDriftMainTask.java | 1 + .../java/moa/tasks/EvaluateClustering.java | 5 +- .../java/moa/tasks/EvaluateConceptDrift.java | 9 +- .../moa/tasks/EvaluateInterleavedChunks.java | 12 +- .../EvaluateInterleavedTestThenTrain.java | 7 +- .../main/java/moa/tasks/EvaluateModel.java | 4 +- .../moa/tasks/EvaluateModelMultiTarget.java | 8 +- .../moa/tasks/EvaluateModelRegression.java | 5 +- .../moa/tasks/EvaluateOnlineRecommender.java | 3 +- .../tasks/EvaluatePeriodicHeldOutTest.java | 9 +- .../java/moa/tasks/EvaluatePrequential.java | 16 +- .../java/moa/tasks/EvaluatePrequentialCV.java | 28 +- .../tasks/EvaluatePrequentialMultiTarget.java | 209 ++++++ .../tasks/EvaluatePrequentialRegression.java | 22 +- moa/src/main/java/moa/tasks/LearnModel.java | 3 +- .../java/moa/tasks/LearnModelMultiTarget.java | 1 + .../java/moa/tasks/LearnModelRegression.java | 5 +- moa/src/main/java/moa/tasks/MainTask.java | 3 +- .../java/moa/tasks/MeasureStreamSpeed.java | 4 +- .../java/moa/tasks/MultiTargetMainTask.java | 2 +- moa/src/main/java/moa/tasks/Plot.java | 3 +- .../java/moa/tasks/RegressionMainTask.java | 2 +- .../main/java/moa/tasks/RunStreamTasks.java | 1 + moa/src/main/java/moa/tasks/RunTasks.java | 5 +- .../java/moa/tasks/WriteStreamToARFFFile.java | 7 +- .../main/java/weka/classifiers/meta/MOA.java | 18 +- .../classifiers/classification/MOA.java | 19 +- .../java/weka/gui/MOAClassOptionEditor.java | 3 +- .../instances/MultiTargetArffLoaderTest.java | 12 +- .../AbstractClassifierTestCase.java | 12 +- .../AbstractMultipleClassifierTestCase.java | 1 - .../AbstractMultipleRegressorTestCase.java | 1 - .../active/ActiveClassifierTest.java | 1 - .../drift/SingleClassifierDriftTest.java | 1 - .../functions/MajorityClassTest.java | 1 - .../classifiers/functions/NoChangeTest.java | 1 - .../classifiers/functions/PerceptronTest.java | 1 - .../moa/classifiers/functions/SGDTest.java | 1 - .../classifiers/functions/SPegasosTest.java | 1 - .../meta/AccuracyUpdatedEnsembleTest.java | 1 - .../meta/AccuracyWeightedEnsembleTest.java | 1 - .../classifiers/meta/LeveragingBagTest.java | 1 - .../meta/LimAttClassifierTest.java | 1 - .../moa/classifiers/meta/OCBoostTest.java | 1 - .../OnlineAccuracyUpdatedEnsembleTest.java | 1 - .../moa/classifiers/meta/OzaBagASHTTest.java | 1 - .../moa/classifiers/meta/OzaBagAdwinTest.java | 1 - .../java/moa/classifiers/meta/OzaBagTest.java | 1 - .../classifiers/meta/OzaBoostAdwinTest.java | 1 - .../moa/classifiers/meta/OzaBoostTest.java | 1 - .../TemporallyAugmentedClassifierTest.java | 1 - .../classifiers/meta/WEKAClassifierTest.java | 1 - .../meta/WeightedMajorityAlgorithmTest.java | 1 - .../rules/AMRulesRegressorTest.java | 1 - .../rules/RuleClassifierNBayesTest.java | 1 - .../classifiers/rules/RuleClassifierTest.java | 1 - ...nverseErrorWeightedVoteMultiLabeLTest.java | 3 +- .../UniformWeightedVoteMultiLabelTest.java | 4 +- .../trees/ASHoeffdingTreeTest.java | 1 - .../trees/AdaHoeffdingOptionTreeTest.java | 1 - .../classifiers/trees/DecisionStumpTest.java | 1 - .../moa/classifiers/trees/FIMTDDTest.java | 4 +- .../trees/HoeffdingAdaptiveTreeTest.java | 1 - .../trees/HoeffdingOptionTreeTest.java | 1 - .../trees/LimAttHoeffdingTreeTest.java | 1 - .../java/moa/classifiers/trees/ORTOTest.java | 1 - .../trees/RandomHoeffdingTreeTest.java | 1 - .../moa/integration/SimpleClusterTest.java | 12 +- .../filters/SelectAttributesFilterTest.java | 5 +- .../.settings/org.eclipse.jdt.core.prefs | 9 +- 400 files changed, 2361 insertions(+), 1486 deletions(-) create mode 100644 moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTreePCT.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/PCTWeightedICVarianceReduction.java create mode 100644 moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTreeRF.java diff --git a/moa/.settings/org.eclipse.jdt.core.prefs b/moa/.settings/org.eclipse.jdt.core.prefs index 60105c1b9..672496e10 100644 --- a/moa/.settings/org.eclipse.jdt.core.prefs +++ b/moa/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,12 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java b/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java index 23522e085..68191078c 100644 --- a/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java +++ b/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java @@ -73,7 +73,6 @@ public Option[] discoverOptionsViaReflection() { Field[] fields = c.getFields(); List

diff --git a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java index 6b78777a3..ae232b9b0 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java @@ -17,7 +17,6 @@ */ package moa.classifiers.lazy; -import moa.classifiers.core.driftdetection.ADWIN; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; diff --git a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java index 65e9266ed..74670860e 100644 --- a/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java +++ b/moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java @@ -18,10 +18,12 @@ package moa.classifiers.lazy; import java.util.ArrayList; -import moa.classifiers.core.driftdetection.ADWIN; + import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.classifiers.core.driftdetection.ADWIN; + /** * k Nearest Neighbor ADAPTIVE with ADWIN+PAW.

* diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java index b3b6d7a0d..684f063d8 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java @@ -23,11 +23,13 @@ import java.util.Enumeration; import java.util.Vector; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.lazy.neighboursearch.kdtrees.KDTreeNode; import moa.classifiers.lazy.neighboursearch.kdtrees.KDTreeNodeSplitter; import moa.classifiers.lazy.neighboursearch.kdtrees.SlidingMidPointOfWidestSide; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java index ddefd58ae..541d0f527 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java @@ -21,6 +21,7 @@ package moa.classifiers.lazy.neighboursearch; import java.io.Serializable; + import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java index 7800a8576..46da24f3e 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java @@ -21,7 +21,6 @@ package moa.classifiers.lazy.neighboursearch; -import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; diff --git a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java index f69760c9f..61126b4a0 100644 --- a/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java +++ b/moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java @@ -23,10 +23,11 @@ import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; -import moa.classifiers.lazy.neighboursearch.EuclideanDistance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.classifiers.lazy.neighboursearch.EuclideanDistance; + /** * Class that splits up a KDTreeNode. * diff --git a/moa/src/main/java/moa/classifiers/meta/ADACC.java b/moa/src/main/java/moa/classifiers/meta/ADACC.java index 8aa324af8..f5dbe47c1 100644 --- a/moa/src/main/java/moa/classifiers/meta/ADACC.java +++ b/moa/src/main/java/moa/classifiers/meta/ADACC.java @@ -20,15 +20,16 @@ package moa.classifiers.meta; +import java.util.Arrays; +import java.util.Collections; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.Classifier; import moa.core.Measurement; - -import java.util.Arrays; -import java.util.Collections; import moa.core.Utils; /** diff --git a/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java index f9764fa19..7a935202d 100644 --- a/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/AccuracyUpdatedEnsemble.java @@ -19,6 +19,10 @@ */ package moa.classifiers.meta; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.classifiers.trees.HoeffdingTree; @@ -26,10 +30,7 @@ import moa.core.Measurement; import moa.core.ObjectRepository; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * The revised version of the Accuracy Updated Ensemble as proposed by diff --git a/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java index df7e6fea1..3fd651d59 100644 --- a/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java @@ -20,18 +20,20 @@ package moa.classifiers.meta; import java.util.Random; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.ObjectRepository; +import moa.core.Utils; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import moa.core.Utils; /** * The Accuracy Weighted Ensemble classifier as proposed by Wang et al. in @@ -433,9 +435,9 @@ protected Classifier addToStored(Classifier newClassifier, double newClassifiers * * @return the size of the removed classifier. */ - protected int removePoorestModelBytes() { + protected long removePoorestModelBytes() { int poorestIndex = Utils.minIndex(this.ensembleWeights); - int byteSize = this.ensemble[poorestIndex].measureByteSize(); + long byteSize = this.ensemble[poorestIndex].measureByteSize(); discardModel(poorestIndex); return byteSize; } diff --git a/moa/src/main/java/moa/classifiers/meta/DACC.java b/moa/src/main/java/moa/classifiers/meta/DACC.java index 8cb76472b..dfb470e1e 100644 --- a/moa/src/main/java/moa/classifiers/meta/DACC.java +++ b/moa/src/main/java/moa/classifiers/meta/DACC.java @@ -20,18 +20,19 @@ package moa.classifiers.meta; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.MultiChoiceOption; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import moa.options.ClassOption; /** diff --git a/moa/src/main/java/moa/classifiers/meta/LeveragingBag.java b/moa/src/main/java/moa/classifiers/meta/LeveragingBag.java index 6d6e78830..3edcf5ae1 100644 --- a/moa/src/main/java/moa/classifiers/meta/LeveragingBag.java +++ b/moa/src/main/java/moa/classifiers/meta/LeveragingBag.java @@ -19,20 +19,19 @@ */ package moa.classifiers.meta; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.FloatOption; import com.github.javacliparser.FlagOption; -import moa.options.ClassOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; -import moa.classifiers.core.driftdetection.ADWIN; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; -import moa.options.*; +import moa.options.ClassOption; /** * Leveraging Bagging for evolving data streams using ADWIN. Leveraging Bagging diff --git a/moa/src/main/java/moa/classifiers/meta/LimAttClassifier.java b/moa/src/main/java/moa/classifiers/meta/LimAttClassifier.java index 8cb281802..d223111dc 100644 --- a/moa/src/main/java/moa/classifiers/meta/LimAttClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/LimAttClassifier.java @@ -20,21 +20,21 @@ */ package moa.classifiers.meta; -import moa.classifiers.trees.LimAttHoeffdingTree; -import com.yahoo.labs.samoa.instances.Instance; -import moa.core.Utils; - import java.math.BigInteger; import java.util.Arrays; -import moa.classifiers.core.driftdetection.ADWIN; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; -import moa.core.Measurement; -import moa.options.ClassOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.core.driftdetection.ADWIN; +import moa.classifiers.trees.LimAttHoeffdingTree; +import moa.core.Measurement; +import moa.core.Utils; +import moa.options.ClassOption; /** * Ensemble Combining Restricted Hoeffding Trees using Stacking. diff --git a/moa/src/main/java/moa/classifiers/meta/OCBoost.java b/moa/src/main/java/moa/classifiers/meta/OCBoost.java index 9e796ff7b..e9c33ff73 100644 --- a/moa/src/main/java/moa/classifiers/meta/OCBoost.java +++ b/moa/src/main/java/moa/classifiers/meta/OCBoost.java @@ -19,15 +19,15 @@ */ package moa.classifiers.meta; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import moa.core.Utils; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; import moa.core.Measurement; +import moa.core.Utils; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; /** * Online Coordinate boosting for two classes evolving data streams. diff --git a/moa/src/main/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsemble.java b/moa/src/main/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsemble.java index 790599ff4..44e381d78 100644 --- a/moa/src/main/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsemble.java +++ b/moa/src/main/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsemble.java @@ -23,6 +23,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.classifiers.trees.HoeffdingTree; diff --git a/moa/src/main/java/moa/classifiers/meta/OnlineSmoothBoost.java b/moa/src/main/java/moa/classifiers/meta/OnlineSmoothBoost.java index 0810d2153..445ca1027 100644 --- a/moa/src/main/java/moa/classifiers/meta/OnlineSmoothBoost.java +++ b/moa/src/main/java/moa/classifiers/meta/OnlineSmoothBoost.java @@ -22,6 +22,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.DoubleVector; diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBag.java b/moa/src/main/java/moa/classifiers/meta/OzaBag.java index 9ca3dd639..d43f2da0b 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBag.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBag.java @@ -19,15 +19,15 @@ */ package moa.classifiers.meta; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; /** * Incremental on-line bagging of Oza and Russell. @@ -66,6 +66,14 @@ public String getPurposeString() { protected Classifier[] ensemble; + @Override + public long measureByteSize() { + long size = 0; + for (Classifier c : ensemble) + size += c.measureByteSize(); + return size; + } + @Override public void resetLearningImpl() { this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java b/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java index 09bca78da..aba193b3b 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java @@ -19,7 +19,6 @@ */ package moa.classifiers.meta; -import moa.options.ClassOption; import moa.classifiers.Classifier; import moa.classifiers.trees.ASHoeffdingTree; import moa.core.DoubleVector; @@ -27,8 +26,6 @@ import com.github.javacliparser.IntOption; import com.github.javacliparser.FlagOption; import com.yahoo.labs.samoa.instances.Instance; -import moa.classifiers.AbstractClassifier; -import moa.core.Measurement; import moa.core.Utils; /** @@ -85,7 +82,7 @@ * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) * @version $Revision: 7 $ */ -public class OzaBagASHT extends AbstractClassifier { +public class OzaBagASHT extends OzaBag { private static final long serialVersionUID = 1L; @@ -94,9 +91,6 @@ public String getPurposeString() { return "Bagging using trees of different size."; } - public IntOption ensembleSizeOption = new IntOption("ensembleSize", 's', - "The number of models in the bag.", 10, 1, Integer.MAX_VALUE); - public IntOption firstClassifierSizeOption = new IntOption("firstClassifierSize", 'f', "The size of first classifier in the bag.", 1, 1, Integer.MAX_VALUE); @@ -112,24 +106,25 @@ public String getPurposeString() { protected ASHoeffdingTree[] ensemble; protected double[] error; + protected double alpha = 0.01; @Override public void resetLearningImpl() { - this.ensemble = new ASHoeffdingTree[this.ensembleSizeOption.getValue()]; + this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; this.error = new double[this.ensembleSizeOption.getValue()]; Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); baseLearner.resetLearning(); - int pow = this.firstClassifierSizeOption.getValue(); + int pow = this.firstClassifierSizeOption.getValue(); //EXTENSION TO ASHT for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i] = (ASHoeffdingTree) baseLearner.copy(); + this.ensemble[i] = baseLearner.copy(); this.error[i] = 0.0; - ((ASHoeffdingTree) this.ensemble[i]).setMaxSize(pow); + ((ASHoeffdingTree) this.ensemble[i]).setMaxSize(pow); //EXTENSION TO ASHT if ((this.resetTreesOption != null) && this.resetTreesOption.isSet()) { ((ASHoeffdingTree) this.ensemble[i]).setResetTree(); } - pow *= 2; + pow *= 2; //EXTENSION TO ASHT } } @@ -171,20 +166,4 @@ public double[] getVotesForInstance(Instance inst) { public void getModelDescription(StringBuilder out, int indent) { // TODO Auto-generated method stub } - - @Override - public boolean isRandomizable() { - return true; - } - - @Override - protected Measurement[] getModelMeasurementsImpl() { - return new Measurement[]{new Measurement("ensemble size", - this.ensemble != null ? this.ensemble.length : 0)}; - } - - @Override - public Classifier[] getSubClassifiers() { - return this.ensemble.clone(); - } } diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java index fa688e426..8f790f339 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java @@ -19,16 +19,16 @@ */ package moa.classifiers.meta; -import moa.classifiers.core.driftdetection.ADWIN; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; /** * Bagging for evolving data streams using ADWIN. @@ -141,7 +141,7 @@ public void trainOnInstanceImpl(Instance inst) { } if (imax != -1) { this.ensemble[imax].resetLearning(); - //this.ensemble[imax].trainOnInstance(inst); + this.ensemble[imax].trainOnInstance(inst); this.ADError[imax] = new ADWIN(); } } diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBoost.java b/moa/src/main/java/moa/classifiers/meta/OzaBoost.java index 54fc8e15b..cf149c8c9 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBoost.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBoost.java @@ -19,16 +19,16 @@ */ package moa.classifiers.meta; -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; /** * Incremental on-line boosting of Oza and Russell. diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBoostAdwin.java b/moa/src/main/java/moa/classifiers/meta/OzaBoostAdwin.java index 17d370547..1e60ba154 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBoostAdwin.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBoostAdwin.java @@ -19,17 +19,18 @@ */ package moa.classifiers.meta; -import moa.classifiers.core.driftdetection.ADWIN; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; +import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Boosting for evolving data streams using ADWIN. diff --git a/moa/src/main/java/moa/classifiers/meta/PairedLearners.java b/moa/src/main/java/moa/classifiers/meta/PairedLearners.java index dc071be46..9ec64027e 100644 --- a/moa/src/main/java/moa/classifiers/meta/PairedLearners.java +++ b/moa/src/main/java/moa/classifiers/meta/PairedLearners.java @@ -18,18 +18,19 @@ */ package moa.classifiers.meta; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.Measurement; -import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; import moa.core.MiscUtils; +import moa.options.ClassOption; /** * Creates two classifiers: a stable and a reactive. The first represents the diff --git a/moa/src/main/java/moa/classifiers/meta/RandomRules.java b/moa/src/main/java/moa/classifiers/meta/RandomRules.java index e170e1ef7..143849bdb 100644 --- a/moa/src/main/java/moa/classifiers/meta/RandomRules.java +++ b/moa/src/main/java/moa/classifiers/meta/RandomRules.java @@ -19,14 +19,12 @@ */ package moa.classifiers.meta; -import moa.options.ClassOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; @@ -35,6 +33,7 @@ import moa.core.FastVector; import moa.core.Measurement; import moa.core.MiscUtils; +import moa.options.ClassOption; import moa.streams.InstanceStream; diff --git a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java index eac49168d..431348c5d 100644 --- a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java @@ -19,21 +19,23 @@ */ package moa.classifiers.meta; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.Measurement; import moa.core.Utils; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Include labels of previous instances into the training data diff --git a/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java b/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java index d9ac321c8..b2595ff28 100644 --- a/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java @@ -20,15 +20,15 @@ */ package moa.classifiers.meta; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; + import moa.classifiers.AbstractClassifier; import moa.core.Measurement; -import com.github.javacliparser.IntOption; import moa.options.WEKAClassOption; import weka.classifiers.Classifier; import weka.classifiers.UpdateableClassifier; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; /** * Class for using a classifier from WEKA. diff --git a/moa/src/main/java/moa/classifiers/meta/WeightedMajorityAlgorithm.java b/moa/src/main/java/moa/classifiers/meta/WeightedMajorityAlgorithm.java index c08bdfe6a..8ee34158b 100644 --- a/moa/src/main/java/moa/classifiers/meta/WeightedMajorityAlgorithm.java +++ b/moa/src/main/java/moa/classifiers/meta/WeightedMajorityAlgorithm.java @@ -19,19 +19,20 @@ */ package moa.classifiers.meta; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.ListOption; +import com.github.javacliparser.Option; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.ObjectRepository; +import moa.core.Utils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.ListOption; -import com.github.javacliparser.Option; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import moa.core.Utils; /** * Weighted majority algorithm for data streams. @@ -196,9 +197,9 @@ public void discardModel(int index) { this.ensembleWeights = newEnsembleWeights; } - protected int removePoorestModelBytes() { + protected long removePoorestModelBytes() { int poorestIndex = Utils.minIndex(this.ensembleWeights); - int byteSize = this.ensemble[poorestIndex].measureByteSize(); + long byteSize = this.ensemble[poorestIndex].measureByteSize(); discardModel(poorestIndex); return byteSize; } diff --git a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java index 7ac2b2825..6924b00e9 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/LocalMultiTargetClassifier.java @@ -7,9 +7,9 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.classifiers.AbstractClassifier; import moa.classifiers.AbstractMultiLabelLearner; @@ -17,6 +17,7 @@ import moa.classifiers.MultiLabelClassifier; import moa.classifiers.MultiTargetRegressor; import moa.core.Measurement; +import moa.core.SizeOf; import moa.options.ClassOption; public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner @@ -36,6 +37,17 @@ public class LocalMultiTargetClassifier extends AbstractMultiLabelLearner ArrayList classifiers = null; ArrayList headers = null; + + @Override + public long measureByteSize() { + long size = 0; + for (Classifier c : classifiers) + size += c.measureByteSize(); + for (InstancesHeader h : headers) { + size += SizeOf.sizeOf(h); + } + return size; + } @Override public boolean isRandomizable() { @@ -60,6 +72,7 @@ private void makeHeaders() { attributes.add(getModelContext().outputAttribute(target)); InstancesHeader STHeader = new InstancesHeader(); STHeader.setAttributes(attributes); + STHeader.setInstances(new ArrayList()); STHeader.setClassIndex(getModelContext().numInputAttributes()); headers.add(STHeader); } @@ -77,9 +90,7 @@ private Instance getSTInstance(StructuredInstance inst, int target) { } @Override - public void trainOnInstanceImpl(StructuredInstance instance) { - initializeClassifiers(); - + public void trainOnInstanceImpl(StructuredInstance instance) { for (int j = 0; j < instance.numberOutputTargets(); j++) { Instance STInst = getSTInstance(instance, j); @@ -89,8 +100,6 @@ public void trainOnInstanceImpl(StructuredInstance instance) { @Override public Prediction getPredictionForInstance(StructuredInstance inst) { - initializeClassifiers(); - MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); for (int j = 0; j < inst.numberOutputTargets(); j++) { Instance STInst = getSTInstance(inst, j); @@ -102,21 +111,22 @@ public Prediction getPredictionForInstance(StructuredInstance inst) { @Override public void resetLearningImpl() { classifiers = null; - + } + + public void modelContextSet() { + initializeClassifiers(); + makeHeaders(); + for (int i = 0; i < classifiers.size(); i++) + classifiers.get(i).setModelContext(getHeader(i)); } public void initializeClassifiers() { - this.classifierRandom.setSeed(1234); - if (classifiers == null) { - makeHeaders(); - classifiers = new ArrayList(); - for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { - Classifier learner = ((Classifier) getPreparedClassOption(this.classifierOption)).copy(); - classifiers.add(learner); - learner.resetLearning(); - ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; - learner.setModelContext(getHeader(i)); - } + classifiers = new ArrayList(); + for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + Classifier learner = ((Classifier) getPreparedClassOption(this.classifierOption)).copy(); + classifiers.add(learner); + learner.resetLearning(); + ((AbstractClassifier) learner).classifierRandom = this.classifierRandom; } } diff --git a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java index 0544bdfb9..c7587552f 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MEKAClassifier.java @@ -19,28 +19,20 @@ */ package moa.classifiers.multilabel; -import java.util.Arrays; import java.io.Serializable; -import moa.core.Measurement; -import weka.classifiers.UpdateableClassifier; -import moa.classifiers.AbstractClassifier; -import moa.core.Measurement; -import com.github.javacliparser.IntOption; -import moa.options.WEKAClassOption; -import weka.classifiers.Classifier; -import weka.classifiers.UpdateableClassifier; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; -import com.yahoo.labs.samoa.instances.StructuredInstance; +import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; -import moa.classifiers.MultiLabelLearner; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; -import moa.core.Example; +import moa.core.Measurement; +import moa.options.WEKAClassOption; +import weka.classifiers.Classifier; +import weka.classifiers.UpdateableClassifier; /** * Wrapper for MEKA classifiers. diff --git a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java index 135f8f88e..9ac0dd346 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MajorityLabelset.java @@ -19,16 +19,15 @@ */ package moa.classifiers.multilabel; -import java.util.Arrays; import java.util.HashMap; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; + import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; +import moa.core.Measurement; import moa.core.StringUtils; /** diff --git a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java index 9a8bf0e96..43c0deffa 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/MultilabelHoeffdingTree.java @@ -19,7 +19,6 @@ */ package moa.classifiers.multilabel; -import moa.classifiers.trees.HoeffdingTreeClassifLeaves; import java.io.StringReader; import java.util.List; import moa.classifiers.Classifier; @@ -47,7 +46,7 @@ * * */ -public class MultilabelHoeffdingTree extends HoeffdingTreeClassifLeaves implements MultiLabelLearner, MultiTargetRegressor { +public class MultilabelHoeffdingTree extends HoeffdingTreeClassifLeaves implements MultiLabelLearner, MultiTargetRegressor, Classifier { // Needs to use InfoGainSplitCriterionMultiLabel, since multilabel entropy is calculated in a different way // Trains a mlinstance adding statistics of several class values and training node classifiers // Get votes from the classifier in the learning node of the tree @@ -83,7 +82,7 @@ public MultilabelInactiveLearningNode(double[] initialClassObservations) { public void learnFromInstance(Instance inst, HoeffdingTree ht) { List labels = ((MultilabelHoeffdingTree) ht).getRelevantLabels(inst); for (int l : labels){ - this.observedClassDistribution.addToValue( l, inst.weight()); + this.observedClassDistribution.addToValue(l, inst.weight()); } } } @@ -95,7 +94,7 @@ public class MultilabelLearningNodeClassifier extends LearningNodeClassifier { public MultilabelLearningNodeClassifier(double[] initialClassObservations, Classifier cl, MultilabelHoeffdingTree ht ) { super(initialClassObservations); - + if (cl== null) { this.classifier = ((Classifier) getPreparedClassOption(ht.learnerOption)).copy(); this.classifier.resetLearning(); @@ -123,7 +122,7 @@ public Prediction getPredictionForInstance(Instance inst, HoeffdingTree ht) { public void disableAttribute(int attIndex) { // should not disable poor atts - they are used in NB calc } - + public Classifier getClassifier() { return this.classifier; } @@ -148,11 +147,9 @@ public void learnFromInstance(Instance inst, HoeffdingTree ht) { } for (int l : labels){ obs.observeAttributeClass(inst.valueInputAttribute(i), l, inst.weight()); - //obs.observeAttributeClass(inst.value(instAttIndex), 0, inst.weight()); } } } - } public void describeSubtree(HoeffdingTree ht, StringBuilder out, int indent) { @@ -186,8 +183,12 @@ public Prediction getPredictionForInstance(Example example) { return getPredictionForInstance((StructuredInstance)example.getData()); } + public Prediction getPredictionForInstance(StructuredInstance inst) { + return getPredictionForInstance((Instance) inst); + } + @Override - public Prediction getPredictionForInstance(StructuredInstance inst){ + public Prediction getPredictionForInstance(Instance inst){ if (this.treeRoot != null) { FoundNode foundNode = this.treeRoot.filterInstanceToLeaf(inst, null, -1); diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java index 58fd92faa..6a23d619d 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/core/attributeclassobservers/MultiLabelBSTree.java @@ -18,7 +18,7 @@ public class MultiLabelBSTree extends AbstractOptionHandler implements NumericSt /** * */ - public IntOption maxNodesOption = new IntOption("maxNodesOption", 'z', "Maximum number of nodes", 50, 0, Integer.MAX_VALUE); + public IntOption maxNodesOption = new IntOption("maxNodesOption", 'z', "Maximum number of nodes", 2000, 0, Integer.MAX_VALUE); protected int maxNodes; protected int numNodes; @@ -26,14 +26,25 @@ public class MultiLabelBSTree extends AbstractOptionHandler implements NumericSt protected Node root = null; - protected DoubleVector [] leftStatistics; - protected DoubleVector [] rightStatistics; + protected DoubleVector[] leftStatistics; + protected DoubleVector[] rightStatistics; + public static double roundToSignificantFigures(double num, int n) { + final double d = Math.ceil(Math.log10(num < 0 ? -num: num)); + final int power = n - (int) d; + + final double magnitude = Math.pow(10, power); + final long shifted = (long) (num*magnitude); + return shifted/magnitude; + } + @Override public void observeAttribute(double inputAttributeValue, DoubleVector[] statistics) { if (!Double.isNaN(inputAttributeValue)) { +// if ((long) inputAttributeValue != inputAttributeValue) +// inputAttributeValue = roundToSignificantFigures(inputAttributeValue, 4); if (this.root == null) { this.root = new Node(inputAttributeValue, statistics); maxNodes=maxNodesOption.getValue(); @@ -49,13 +60,13 @@ public void observeAttribute(double inputAttributeValue, public AttributeExpansionSuggestion getBestEvaluatedSplitSuggestion( MultiLabelSplitCriterion criterion, DoubleVector[] preSplitStatistics, int inputAttributeIndex) { // Initialize global variables - int numOutputs=preSplitStatistics.length; - leftStatistics=new DoubleVector[numOutputs]; - rightStatistics=new DoubleVector[numOutputs]; + int numOutputs = preSplitStatistics.length; + leftStatistics = new DoubleVector[numOutputs]; + rightStatistics = new DoubleVector[numOutputs]; for (int i=0; i< numOutputs; i++) { - leftStatistics[i]=new DoubleVector(new double [preSplitStatistics[i].numValues()]); //sets statistics to zeros - rightStatistics[i]=new DoubleVector(preSplitStatistics[i]); + leftStatistics[i] = new DoubleVector(new double [preSplitStatistics[i].numValues()]); //sets statistics to zeros + rightStatistics[i] = new DoubleVector(preSplitStatistics[i]); } return searchForBestSplitOption(this.root, null, criterion, preSplitStatistics, inputAttributeIndex); @@ -70,34 +81,36 @@ protected AttributeExpansionSuggestion searchForBestSplitOption(Node currentNode if (currentNode.left != null) { currentBestOption = searchForBestSplitOption(currentNode.left, currentBestOption, criterion, preSplitStatistics, inputAttributeIndex); } + for (int i=0; i currentBestOption.merit)) { - currentBestOption= new AttributeExpansionSuggestion(new NumericRulePredicate(inputAttributeIndex, currentNode.cutPoint, true), Utils.copy(postSplitDists), merit); + currentBestOption = new AttributeExpansionSuggestion(new NumericRulePredicate(inputAttributeIndex, currentNode.cutPoint, true), Utils.copy(postSplitDists), merit); } if (currentNode.right != null) { currentBestOption = searchForBestSplitOption(currentNode.right, currentBestOption, criterion, preSplitStatistics, inputAttributeIndex); } - for (int i=0; i currentBestOption.merit)) { + currentBestOption = new AttributeExpansionSuggestion(new NumericRulePredicate(inputAttributeIndex, currentNode.cutPoint, true), Utils.copy(postSplitTargetDists), merit); + } + + if (currentNode.right != null) { + currentBestOption = searchForBestSplitOption(currentNode.right, currentBestOption, criterion, preSplitTargetStatistics, preSplitInputStatistics, inputAttributeIndex); + } + for (int i = 0; i < leftTargetStatistics.length; i++) { + leftTargetStatistics[i].subtractValues(currentNode.targetStatistics[i]); + rightTargetStatistics[i].addValues(currentNode.targetStatistics[i]); + } + for (int i = 0; i < leftInputStatistics.length; i++) { + leftInputStatistics[i].subtractValues(currentNode.inputStatistics[i]); + rightInputStatistics[i].addValues(currentNode.inputStatistics[i]); + } + + return currentBestOption; + } + + + + + @Override + public String getPurposeString() { + return "Stores statistics for all output and input attributes for a giver input attribute."; + } + + @Override + public void getDescription(StringBuilder sb, int indent) { + } + + @Override + protected void prepareForUseImpl(TaskMonitor monitor, + ObjectRepository repository) { + + } + + + //Inner classes inspired in FIMTDDNumericalAttributeClassObserver + + protected class Node implements Serializable { + + private static final long serialVersionUID = 1L; + + // The split point to use + private double cutPoint; + + // E-BST statistics + private DoubleVector[] targetStatistics; + private DoubleVector[] inputStatistics; + + + // Child nodes + private Node left; + private Node right; + + public Node(double inputAttributeValue, DoubleVector[] targetStatistics, DoubleVector[] inputStatistics) { + cutPoint = inputAttributeValue; + int numOutputAttributes = targetStatistics.length; + int numInputAttributes = inputStatistics.length; + this.targetStatistics = new DoubleVector[numOutputAttributes]; + this.inputStatistics = new DoubleVector[numInputAttributes]; + for (int i=0; i 1) { return (squares - sum * sum / n) / (n - 1); } return 0; } - private double computeVariance(DoubleVector v) { + public double computeVariance(DoubleVector v) { return computeVariance(v.getValue(0), v.getValue(1), v.getValue(2)); } @@ -62,10 +62,10 @@ private double computeVariance(DoubleVector v) { } protected double getMeritOfSplitForOutput(DoubleVector[] preSplitDist, DoubleVector[][] postSplitDists, int outputAttributeIndex){ - return getMeritOfSplitForOutput(preSplitDist[outputAttributeIndex],postSplitDists[outputAttributeIndex]); + return getMeritOfSplitForAttribute(preSplitDist[outputAttributeIndex],postSplitDists[outputAttributeIndex]); } - protected double getMeritOfSplitForOutput(DoubleVector preSplitDist, DoubleVector[] postSplitDists) { + protected double getMeritOfSplitForAttribute(DoubleVector preSplitDist, DoubleVector[] postSplitDists) { double merit=0; //count number of branches with weightSeen higher than threshold int count = 0; diff --git a/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/PCTWeightedICVarianceReduction.java b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/PCTWeightedICVarianceReduction.java new file mode 100644 index 000000000..adb022397 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/core/splitcriteria/PCTWeightedICVarianceReduction.java @@ -0,0 +1,76 @@ +package moa.classifiers.multilabel.core.splitcriteria; + +import moa.core.DoubleVector; + +public class PCTWeightedICVarianceReduction extends WeightedICVarianceReduction { + + public DoubleVector inputWeights; + + public double targetInputTradeoff; // \in [0, 1] + + public PCTWeightedICVarianceReduction(DoubleVector targetWeights, DoubleVector inputWeights, double targetInputTradeoff) { + super(targetWeights); + this.inputWeights = inputWeights; + this.targetInputTradeoff = targetInputTradeoff; + } + + public double getMeritOfSplit(DoubleVector[] preSplitTargetDist, DoubleVector[][] postSplitTargetDists, DoubleVector[] preSplitInputDist, DoubleVector[][] postSplitInputDists) { + double targetError = 0; + double inputError = 0; + int numTargets=preSplitTargetDist.length; + int numInputs=preSplitInputDist.length; + for (int i=0; i= 0.05*preSplitDist.getValue(0)) + count = count +1; + //Consider split if all branches have required weight seen + if(count == postSplitDists.length){ + double varPreSplit=computeVariance(preSplitDist); + double sumVarPostSplit=0; + double weightTotal=0; + for (int i=0; i0) + sumVarPostSplit+=(postSplitDists[i].getValue(0)/weightTotal*variances[i]); //weight variance + merit= 1 - sumVarPostSplit / varPreSplit; + } + /*if(merit<0 || merit>1) + System.out.println("out of range");*/ + return merit; + } + + +// private double computeVariance(double n, double sum, double squares) { +// if (n > 1) { +// return (squares - sum * sum / n) / (n - 1); +// } +// return 0; +// } + +// private double computeVariance(DoubleVector v) { +// return computeVariance(v.getValue(0), v.getValue(1), v.getValue(2)); +// } + + public double getMeritOfSplit(DoubleVector[] preSplitTargetDist, DoubleVector[] preSplitInputDist, DoubleVector[][] postSplitTargetDists, DoubleVector[][] postSplitInputDists) { + double error=0; + int numOutputs=preSplitTargetDist.length; + for (int i=0; i 0) { + Instance weightedInst = (Instance) inst.copy(); + weightedInst.setWeight(inst.weight() * k); + this.ensemble[i].trainOnInstance(weightedInst); + } // get prediction - double prediction[] = this.ensemble[i].getVotesForInstance(inst); - if (prediction == null) { - prediction = new double[]{}; + Prediction P = this.ensemble[i].getPredictionForInstance(inst); + if (P == null) { + continue; // TODO what to do here? } - // get true value - double actual[] = new double[prediction.length]; - for (int j = 0; j < prediction.length; j++) { - actual[j] = (double)inst.classValue(j); + // get true value and prediction arrays + double actual[] = new double[inst.numOutputAttributes()]; + double prediction[] = new double[inst.numOutputAttributes()]; + for (int j = 0; j < inst.numOutputAttributes(); j++) { + actual[j] = (double)inst.valueOutputAttribute(j); + prediction[j] = P.getVote(j, 1); } // compute loss - double loss = Metrics.L_ZeroOne(A.toIntArray(actual,0.5), A.toIntArray(prediction,0.5)); + //double loss = Metrics.L_ZeroOne(A.toIntArray(actual,0.5), A.toIntArray(prediction,0.5)); //System.err.println("loss["+i+"] = "+loss); + int p_sum = 0, r_sum = 0; + int set_union = 0; + int set_inter = 0; + double t = 0.01; + for(int j = 0; j < prediction.length; j++) { + int p = (prediction[j] >= t) ? 1 : 0; + int R = (int) actual[j]; + if (p==1) { + p_sum++; + // predt 1, real 1 + if(R==1) { + set_inter++; + set_union++; + } + // predt 1, real 0 + else { + set_union++; + } + } + else { + // predt 0, real 1 + if(R==1) { + set_union++; + } + // predt 0, real 0 + else { + } + } + } + double accuracy = 0.0; + if(set_union > 0) //avoid NaN + accuracy = ((double)set_inter / (double)set_union); + // adwin stuff double ErrEstim = this.ADError[i].getEstimation(); - if (this.ADError[i].setInput(loss)) { + + if (this.ADError[i].setInput(1-accuracy)) { if (this.ADError[i].getEstimation() > ErrEstim) { - System.err.println("Change model "+i+"!"); - this.ensemble[i].resetLearning(); - this.ensemble[i].trainOnInstance(inst); - this.ADError[i] = new ADWIN(); + Change = true; } } } + + if (Change) { + double max=0.0; int imax=-1; + for (int i = 0; i < this.ensemble.length; i++) { + if (max(); @@ -293,24 +291,21 @@ public void processInstanceOptionNode(StructuredInstance inst, OptionNode node, // } // } + double[][] childPredictions = new double[node.numChildren()][]; for (Node child : node.children) { int i = node.getChildIndex(child); - double[] childPrediction = child.getPrediction(inst); + childPredictions[i] = child.getPrediction(inst); for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { node.optionFFSeen.get(i).setValue(j, node.optionFFSeen.get(i).getValue(j) * optionFadingFactorOption.getValue() + 1); - node.optionFFSSL.get(i).setValue(j, node.optionFFSSL.get(i).getValue(j) * optionFadingFactorOption.getValue() + Math.pow(childPrediction[j] - inst.valueOutputAttribute(j), 2)); + node.optionFFSSL.get(i).setValue(j, node.optionFFSSL.get(i).getValue(j) * optionFadingFactorOption.getValue() + (childPredictions[i][j] - inst.valueOutputAttribute(j)) * (childPredictions[i][j] - inst.valueOutputAttribute(j))); } - } - - for (Node child : node.children) { - processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); + processInstance(inst, child, childPredictions[node.getChildIndex(child)], normalError, growthAllowed && node.alternateTree == null, inAlternate); } } //endregion ================ METHODS ================ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) { - //System.out.println("Evaluating splits"); //System.out.println(examplesSeen); // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. MultiLabelSplitCriterion splitCriterion = new WeightedICVarianceReduction(targetWeights); @@ -364,28 +359,30 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) numSplits = 1; acceptedSplits.add(bestSuggestion); } - else { - // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - // TODO pruning is currently disabled - for (int i = 0; i < node.attributeObservers.size(); i++) { - AttributeStatisticsObserver obs = node.attributeObservers.get(i); - if (obs != null) { - if (getModelContext().attribute(i).isNumeric()); - //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); - if (getModelContext().attribute(i).isNominal()); - // TODO nominal class observers - } - } - } +// else { +// // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer +// // TODO pruning is currently disabled +//// for (int i = 0; i < node.attributeObservers.size(); i++) { +//// AttributeStatisticsObserver obs = node.attributeObservers.get(i); +//// if (obs != null) { +//// if (getModelContext().attribute(i).isNumeric()); +//// //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); +//// if (getModelContext().attribute(i).isNominal()); +//// // TODO nominal class observers +//// } +//// } +// } } + //System.out.println("Found " + numSplits + " candidates."); + // If the splitting criterion were met, split the current node using the chosen attribute test, and // make two new branches leading to (empty) leaves if (numSplits > 0) { double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); - if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { + if (numSplits == 1) { AttributeExpansionSuggestion splitDecision = acceptedSplits.get(0); SplitNode newSplit = newSplitNode(splitDecision.getPredicate()); newSplit.ID = node.ID; @@ -406,7 +403,7 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) parent.setChild(parentIndex, newSplit); newSplit.setParent(parent); } - } else { + } else if (optionFactor >= 2.0 || maxTreesOption.getValue() - numTrees > 1) { OptionNode optionNode = newOptionNode(); optionNode.ID = node.ID; @@ -415,7 +412,7 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) int j = 0; for (AttributeExpansionSuggestion splitDecision : acceptedSplits) { - if (j > optionFactor || maxTreesOption.getValue() - numTrees <= 0) { + if (j > optionFactor || maxTreesOption.getValue() - numTrees <= 0 || j > 4) { break; } SplitNode newSplit = newSplitNode(splitDecision.getPredicate()); @@ -447,6 +444,7 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) optionNode.resetFF(); } } + //System.out.println("Splits finished..."); } // region --- Option tree methods @@ -522,4 +520,4 @@ protected void removeExcessTrees() { } } -} +} \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java index 28b52d3b9..3829f21bb 100644 --- a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTree.java @@ -26,6 +26,11 @@ package moa.classifiers.multilabel.trees; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -36,21 +41,21 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelBSTree; +import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelBSTreePCT; import moa.classifiers.multilabel.core.attributeclassobservers.MultiLabelNominalAttributeObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; -import moa.classifiers.multilabel.core.splitcriteria.ICVarianceReduction; import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; +import moa.classifiers.multilabel.core.splitcriteria.PCTWeightedICVarianceReduction; import moa.classifiers.multilabel.core.splitcriteria.WeightedICVarianceReduction; import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.Predicate; @@ -79,7 +84,12 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR private DoubleVector sumOfAttrValues = new DoubleVector(); private DoubleVector sumOfAttrSquares = new DoubleVector(); + private int numInputAttributes; + private int numOutputAttributes; + public int maxID = 0; + + private BufferedWriter writer; public DoubleVector targetWeights; @@ -155,16 +165,17 @@ public class ISOUPTree extends AbstractMultiLabelLearner implements MultiTargetR 'o', "Keep learning rate constant instead of decaying (if kept constant learning ratio is suggested to be 0.001)."); + public FlagOption runAsPCTOption = new FlagOption( + "runAsPCT", + 'p', + "Run as a predictive clustering tree, i.e., use input attributes in heuristic calculation."); + + public FlagOption doNotNormalizeOption = new FlagOption( "doNotNormalize", 'n', "Don't normalize."); - public FlagOption randomForestBaseModelOption = new FlagOption( - "randomForestBaseModel", - 'z', - "Use the learner as a base model in a random forest."); - public FileOption weightFile = new FileOption("targetWeightFile", 'w', "File with the weights of the targets.", null, null, false); //endregion ================ OPTIONS ================ @@ -187,7 +198,6 @@ public abstract static class Node extends AbstractMOAObject { protected Node alternateTree; protected Node originalNode; - protected AutoExpandVector attributeObservers = new AutoExpandVector(); // The error values for the Page Hinckley test // PHmT = the cumulative sum of the errors @@ -202,6 +212,12 @@ public abstract static class Node extends AbstractMOAObject { // Sum of squared y values protected DoubleVector sumOfSquares = new DoubleVector(); + // Sum of y values + protected DoubleVector sumOfInputValues; + // Sum of squared y values + protected DoubleVector sumOfInputSquares; + + public Node(ISOUPTree tree) { this.tree = tree; this.ID = tree.maxID; @@ -211,10 +227,18 @@ public void copyStatistics(Node node) { examplesSeen = node.examplesSeen; sumOfValues = (DoubleVector) node.sumOfValues.copy(); sumOfSquares = (DoubleVector) node.sumOfSquares.copy(); + if (tree.runAsPCTOption.isSet()) { + sumOfInputValues = (DoubleVector) node.sumOfInputValues.copy(); + sumOfInputSquares = (DoubleVector) node.sumOfInputSquares.copy(); + } } - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); + public long calcByteSize() { + long size = SizeOf.sizeOf(this) + SizeOf.sizeOf(sumOfSquares) + SizeOf.sizeOf(sumOfValues); + if (tree.runAsPCTOption.isSet()) { + size += SizeOf.sizeOf(sumOfInputSquares) + SizeOf.sizeOf(sumOfInputValues); + } + return size; } /** @@ -244,7 +268,7 @@ public void getDescription(StringBuilder sb, int i) {} public double[] getPrediction(StructuredInstance inst) { return null; } - + public void describeSubtree(StringBuilder out, int indent) { StringUtils.appendIndented(out, indent, "Leaf"); } @@ -292,11 +316,13 @@ public static class LeafNode extends Node { public DoubleVector errorP = new DoubleVector(); public DoubleVector errorM = new DoubleVector(); - + public List inputIndexes = null; protected double examplesSeenAtLastSplitEvaluation = 0; + protected AutoExpandVector attributeObservers = new AutoExpandVector(); + /** * Create a new LeafNode */ @@ -309,28 +335,28 @@ public LeafNode(ISOUPTree tree) { examplesSeen = 0; sumOfValues = new DoubleVector(); sumOfSquares = new DoubleVector(); + if (tree.runAsPCTOption.isSet()) { + sumOfInputValues = new DoubleVector(); + sumOfInputSquares = new DoubleVector(); + } } - public void initializeInputIndexes() { - List indexes = new Vector(); - int numAttrs = tree.getModelContext().numInputAttributes(); - for (int i = 0; i < numAttrs; i++) { - indexes.add(i, i); - } - if (tree.buildingRandomForestTree()) { - // Select the first sqrt(n) attribute indexes - for (int i = 0; i < Math.ceil(Math.sqrt(numAttrs)); i++) { - int swap = i + tree.classifierRandom.nextInt(numAttrs - i); - int temp = indexes.get(i); - indexes.set(i, indexes.get(swap)); - indexes.set(swap, temp); - } - inputIndexes = indexes.subList(0, (int) Math.ceil(Math.sqrt(numAttrs))); - } else { - inputIndexes = indexes; + public long calcByteSize() { + long size = super.calcByteSize(); + if (tree.buildingModelTree()) { + size += learningModel.calcByteSize(); + size += SizeOf.sizeOf(errorP); + size += SizeOf.sizeOf(errorM); } + size += SizeOf.sizeOf(inputIndexes); + size += SizeOf.fullSizeOf(attributeObservers); + return size; + } + + public void initializeInputIndexes() { + this.inputIndexes = tree.newInputIndexes(); } - + /** * Method to learn from an instance that passes the new instance to the perceptron learner, * and also prevents the class value from being truncated to an int when it is passed to the @@ -338,28 +364,75 @@ public void initializeInputIndexes() { */ public void learnFromInstance(StructuredInstance inst, double[] prediction, boolean growthAllowed) { // Update the statistics for this node + double weight = inst.weight(); double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; double[] predictionM = getPredictionTargetMean(inst); // number of instances passing through the node - examplesSeen += inst.weight(); + examplesSeen += weight; - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { - // sum of y values - sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); + for (int i = 0; i < tree.numOutputAttributes; i++) { + if (!inst.isOutputMissing(i)) { + double outVal = inst.valueOutputAttribute(i); + // sum of y values + sumOfValues.addToValue(i, weight * outVal); - // sum of squared y values - sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); + // sum of squared y values + sumOfSquares.addToValue(i, weight * outVal * outVal); - if (tree.buildingModelTree()) { - errorP.setValue(i, errorP.getValue(i) * 0.95 + Math.abs(predictionP[i] - inst.valueOutputAttribute(i))); - errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - inst.valueOutputAttribute(i))); + if (tree.buildingModelTree()) { + errorP.setValue(i, errorP.getValue(i) * 0.95 + Math.abs(predictionP[i] - outVal)); + errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - outVal)); + } } } + if (tree.runAsPCTOption.isSet()) { + for (int i = 0; i < tree.numInputAttributes; i++) { + if (!inst.isInputMissing(i)) { + double inVal = inst.valueInputAttribute(i); + + // sum of attr values + sumOfInputValues.addToValue(i, weight * inVal); + + // sum of squared attr values + sumOfInputSquares.addToValue(i, weight * inVal * inVal); + } + } + } + + + if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); + DoubleVector[] observations = new DoubleVector[tree.numOutputAttributes]; + DoubleVector[] inputObservations = null; + + for (int j = 0; j < tree.numOutputAttributes; j++) { + observations[j] = new DoubleVector(); + if (!inst.isOutputMissing(j)) { + double outVal = inst.valueOutputAttribute(j); + observations[j].setValue(0, weight); + observations[j].setValue(1, weight * outVal); + observations[j].setValue(2, weight * outVal * outVal); + } + } + + if (tree.runAsPCTOption.isSet()) { + inputObservations = new DoubleVector[tree.numInputAttributes]; + for (int j = 0; j < tree.numInputAttributes; j++) { + + inputObservations[j] = new DoubleVector(); + if (!inst.isInputMissing(j)) { + double inVal = inst.valueInputAttribute(j); + inputObservations[j].setValue(0, weight); + inputObservations[j].setValue(1, weight * inVal); + inputObservations[j].setValue(2, weight * inVal * inVal); + } + } + } + for (int i : inputIndexes) { AttributeStatisticsObserver obs = attributeObservers.get(i); if (obs == null) { @@ -373,15 +446,12 @@ public void learnFromInstance(StructuredInstance inst, double[] prediction, bool } } - if (obs != null) { - DoubleVector[] observations = new DoubleVector[inst.numOutputAttributes()]; - for (int j = 0; j < inst.numOutputAttributes(); j++) { - observations[j] = new DoubleVector(); - observations[j].setValue(0, inst.weight()); - observations[j].setValue(1, inst.weight() * inst.valueOutputAttribute(j)); - observations[j].setValue(2, inst.weight() * inst.valueOutputAttribute(j) * inst.valueOutputAttribute(j)); + if (obs != null ) { + if (!tree.runAsPCTOption.isSet() || !inst.inputAttribute(i).isNumeric()) { + obs.observeAttribute(inst.valueInputAttribute(i), observations); + } else { + ((MultiLabelBSTreePCT) obs).observeAttribute(inst.valueInputAttribute(i), observations, inputObservations); } - obs.observeAttribute(inst.valueInputAttribute(i), observations); //obs.observeAttributeClassVector(inst.valueInputAttribute(i), getTargetVector(inst), inst.weight()); } @@ -402,16 +472,32 @@ public AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCri for (int i : inputIndexes) { AttributeStatisticsObserver obs = attributeObservers.get(i); if (obs != null) { - DoubleVector[] preSplitStatistics = new DoubleVector[tree.getModelContext().numOutputAttributes()]; - for (int j = 0; j < tree.getModelContext().numOutputAttributes(); j++) { + DoubleVector[] preSplitStatistics = new DoubleVector[tree.numOutputAttributes]; + DoubleVector[] preSplitInputStatistics = null; + for (int j = 0; j < tree.numOutputAttributes; j++) { preSplitStatistics[j] = new DoubleVector(); preSplitStatistics[j].setValue(0, examplesSeen); preSplitStatistics[j].setValue(1, sumOfValues.getValue(j)); preSplitStatistics[j].setValue(2, sumOfSquares.getValue(j)); } + + if (tree.runAsPCTOption.isSet() && tree.modelContext.inputAttribute(i).isNumeric()) { + preSplitInputStatistics = new DoubleVector[tree.numInputAttributes]; + for (int j = 0; j < tree.numInputAttributes; j++) { + preSplitInputStatistics[j] = new DoubleVector(); + preSplitInputStatistics[j].setValue(0, examplesSeen); + preSplitInputStatistics[j].setValue(1, sumOfInputValues.getValue(j)); + preSplitInputStatistics[j].setValue(2, sumOfInputSquares.getValue(j)); + } + + } AttributeExpansionSuggestion bestSuggestion = null; - bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, preSplitStatistics, i); + if (tree.runAsPCTOption.isSet() && tree.modelContext.inputAttribute(i).isNumeric()) { + bestSuggestion = ((MultiLabelBSTreePCT) obs).getBestEvaluatedSplitSuggestion(criterion, preSplitStatistics, preSplitInputStatistics, i); + } else { + bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, preSplitStatistics, i); + } if (bestSuggestion != null) { bestSuggestions.add(bestSuggestion); @@ -429,8 +515,8 @@ public double[] getPredictionModel(StructuredInstance inst) { } public double[] getPredictionTargetMean(StructuredInstance inst) { - double[] pred = new double[inst.numOutputAttributes()]; - for (int i = 0; i < inst.numOutputAttributes(); i++) { + double[] pred = new double[tree.numOutputAttributes]; + for (int i = 0; i < tree.numOutputAttributes; i++) { if (examplesSeen > 0) { pred[i] = sumOfValues.getValue(i) / examplesSeen; } else { @@ -477,7 +563,7 @@ public void checkForSplit() { public void describeSubtree(StringBuilder out, int indent) { StringUtils.appendIndented(out, indent, "Leaf"); StringUtils.appendNewline(out); - + if (tree.buildingModelTree()) { learningModel.getModelDescription(out, indent + 2); } else { @@ -513,6 +599,14 @@ public InnerNode(ISOUPTree tree) { super(tree); } + public long calcByteSize() { + long size = super.calcByteSize(); + size += SizeOf.sizeOf(PHsums) + SizeOf.sizeOf(PHmins) + SizeOf.sizeOf(sumOfAbsErrors); + for (Node child : children) + size += child.calcByteSize(); + return size; + } + public int numChildren() { return children.size(); } @@ -541,7 +635,7 @@ public void restartChangeDetection() { changeDetection = true; PHsums = new DoubleVector(); PHmins = new DoubleVector(); - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + for (int i = 0; i < tree.numOutputAttributes; i++) { PHmins.setValue(i, Double.MAX_VALUE); } for (Node child : children) @@ -607,6 +701,10 @@ public SplitNode(Predicate predicate, ISOUPTree tree) { ID = tree.maxID; } + public long calcByteSize() { + return super.calcByteSize() + SizeOf.sizeOf(predicate); + } + public int instanceChildIndex(StructuredInstance inst) { return (predicate.evaluate(inst)) ? 0 : 1; } @@ -643,10 +741,6 @@ public class MultitargetPerceptron { // The number of instances contributing to this model protected int instancesSeen = 0; - public String getPurposeString() { - return "A multi-target perceptron"; - } - public MultitargetPerceptron(ISOUPTree tree, MultitargetPerceptron original) { this.tree = tree; weights = original.weights.clone(); @@ -657,10 +751,19 @@ public MultitargetPerceptron(ISOUPTree tree) { initializeWeights(); } + public long calcByteSize() { + return SizeOf.sizeOf(this); + } + + public String getPurposeString() { + return "A multi-target perceptron"; + } + + public void initializeWeights() { instancesSeen = 0; - int numTargets = tree.getModelContext().numOutputAttributes(); - int numInputs = tree.getModelContext().numInputAttributes(); + int numTargets = tree.numOutputAttributes; + int numInputs = tree.numInputAttributes; weights = new double[numTargets][numInputs+1]; tree.classifierRandom.setSeed(1234); for (int i = 0; i < numTargets; i++) { @@ -700,10 +803,12 @@ public void updateWeights(StructuredInstance inst, double learningRatio) { double[] normalizedPrediction = prediction(normalizedInput); double[] normalizedTarget = tree.normalizedTargetVector(inst); - for (int i = 0; i < inst.numOutputAttributes(); i++){ - double delta = normalizedTarget[i] - normalizedPrediction[i]; - for (int j = 0; j < normalizedInput.length; j++) { - weights[i][j] += delta * learningRatio * normalizedInput[j]; + for (int i = 0; i < tree.numOutputAttributes; i++){ + if (normalizedTarget[i] != Double.NaN) { /* to account for missing target values */ + double delta = normalizedTarget[i] - normalizedPrediction[i]; + for (int j = 0; j < normalizedInput.length; j++) { + weights[i][j] += delta * learningRatio * normalizedInput[j]; + } } } normalizeWeights(); @@ -724,8 +829,8 @@ public void normalizeWeights() { * Output the prediction made by this perceptron on the given instance */ public double[] prediction(double[] instanceValues) { - double[] out = new double[tree.getModelContext().numOutputAttributes()]; - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + double[] out = new double[tree.numOutputAttributes]; + for (int i = 0; i < tree.numOutputAttributes; i++) { out[i] = 0; for (int j = 0; j < instanceValues.length; j++) { out[i] += weights[i][j] * instanceValues[j]; @@ -743,7 +848,7 @@ private double[] prediction(StructuredInstance inst) { private double[] denormalizePrediction(double[] normalizedPrediction) { double[] out = new double[normalizedPrediction.length]; if (tree.normalize()) { - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + for (int i = 0; i < tree.numOutputAttributes; i++) { double mean = tree.sumOfValues.getValue(i) / tree.examplesSeen; double sd = computeSD(tree.sumOfSquares.getValue(i), tree.sumOfValues.getValue(i), tree.examplesSeen); if (examplesSeen > 1) @@ -757,9 +862,9 @@ private double[] denormalizePrediction(double[] normalizedPrediction) { public void getModelDescription(StringBuilder out, int indent) { if (getModelContext() != null) { - for (int i = 0; i < tree.getModelContext().numOutputAttributes(); i++) { + for (int i = 0; i < tree.numOutputAttributes; i++) { StringUtils.appendIndented(out, indent, " [" + tree.getModelContext().outputAttribute(i).name() + "] ="); - for (int j = 0; j < getModelContext().numInputAttributes(); j++) { + for (int j = 0; j < tree.numInputAttributes; j++) { if (getModelContext().inputAttribute(j).isNumeric()) { out.append((j == 0 && weights[i][j] >= 0) ? " " : (weights[i][j] < 0) ? " - " : " + "); out.append(String.format("%.4f", Math.abs(weights[i][j]))); @@ -767,7 +872,7 @@ public void getModelDescription(StringBuilder out, int indent) { out.append(getModelContext().inputAttribute(j).name()); } } - out.append((weights[i][getModelContext().numInputAttributes()] < 0 ? " - " : " + ") + String.format("%.4f", Math.abs(weights[i][getModelContext().numInputAttributes()]))); + out.append((weights[i][tree.numInputAttributes] < 0 ? " - " : " + ") + String.format("%.4f", Math.abs(weights[i][tree.numInputAttributes]))); } StringUtils.appendNewline(out); } @@ -783,6 +888,14 @@ public ISOUPTree() { super(); } + public List newInputIndexes() { + List indexes = new Vector(); + for (int i = 0; i < this.numInputAttributes; i++) { + indexes.add(i, i); + } + return indexes; + } + public String getPurposeString() { return "Implementation of the iSOUP-Tree algorithm as described by Osojnik et al."; } @@ -795,12 +908,16 @@ public void resetLearningImpl() { sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); - + } - + @Override public void modelContextSet() { + assert getModelContext() != null; + this.numInputAttributes = getModelContext().numInputAttributes(); + this.numOutputAttributes = getModelContext().numOutputAttributes(); loadWeights(); + checkRoot(); } public void loadWeights() { @@ -809,10 +926,11 @@ public void loadWeights() { List lines = Files.readAllLines(Paths.get(weightFile.getValue()), Charset.defaultCharset()); for (int i = 0 ; i < lines.size(); i++) targetWeights.setValue(i, Double.valueOf(lines.get(i))); } catch (Exception e) { - for (int i = 0; i < getModelContext().numOutputAttributes(); i++) targetWeights.setValue(i, 1.0); + for (int i = 0; i < this.numOutputAttributes; i++) + targetWeights.setValue(i, 1.0); } } - + public boolean isRandomizable() { return true; } @@ -820,7 +938,7 @@ public boolean isRandomizable() { public void getModelDescription(StringBuilder out, int indent) { if (treeRoot != null) treeRoot.describeSubtree(out, indent); } - + protected Measurement[] getModelMeasurementsImpl() { return new Measurement[]{ //new Measurement("tree size (nodes)", this.leafNodeCount + this.splitNodeCount), @@ -828,19 +946,25 @@ protected Measurement[] getModelMeasurementsImpl() { }; } - public int calcByteSize() { - int size = (int) SizeOf.sizeOf(this); + public long measureByteSize() { + return calcByteSize(); + } + + public long calcByteSize() { + long size = SizeOf.sizeOf(this); if (this.treeRoot != null) { size += this.treeRoot.calcByteSize(); } + size += SizeOf.sizeOf(sumOfValues) + SizeOf.sizeOf(sumOfSquares); + size += SizeOf.sizeOf(sumOfAttrValues) + SizeOf.sizeOf(sumOfAttrSquares); + size += SizeOf.sizeOf(targetWeights); return size; } public Prediction getPredictionForInstance(StructuredInstance inst) { - checkRoot(); double[] predictionVector = treeRoot.getPrediction(inst); - MultiLabelPrediction prediction = new MultiLabelPrediction(getModelContext().numOutputAttributes()); - for (int i = 0; i < getModelContext().numOutputAttributes(); i++) { + MultiLabelPrediction prediction = new MultiLabelPrediction(this.numOutputAttributes); + for (int i = 0; i < this.numOutputAttributes; i++) { prediction.setVote(i, 1, predictionVector[i]); } return prediction; @@ -848,9 +972,9 @@ public Prediction getPredictionForInstance(StructuredInstance inst) { public double[] normalizedInputVector(StructuredInstance inst) { // Normalize Instance - double[] normalizedInput = new double[inst.numInputAttributes()+1]; + double[] normalizedInput = new double[this.numInputAttributes+1]; if (normalize()) { - for (int j = 0; j < inst.numInputAttributes(); j++) { + for (int j = 0; j < this.numInputAttributes; j++) { Attribute attr = inst.inputAttribute(j); double value = inst.valueInputAttribute(j); double mean = sumOfAttrValues.getValue(j) / examplesSeen; @@ -864,33 +988,35 @@ public double[] normalizedInputVector(StructuredInstance inst) { normalizedInput[j] = 0; } if (examplesSeen > 1) - normalizedInput[inst.numInputAttributes()] = 1.0; // Value to be multiplied with the constant factor + normalizedInput[this.numInputAttributes] = 1.0; // Value to be multiplied with the constant factor else - normalizedInput[inst.numInputAttributes()] = 0.0; + normalizedInput[this.numInputAttributes] = 0.0; } else { - for (int j = 0; j < inst.numInputAttributes(); j++) { + for (int j = 0; j < this.numInputAttributes; j++) { normalizedInput[j] = inst.valueInputAttribute(j); } - normalizedInput[inst.numInputAttributes()] = 1.0; + normalizedInput[this.numInputAttributes] = 1.0; } return normalizedInput; } public double[] normalizedTargetVector(StructuredInstance inst) { - double[] out = new double[getModelContext().numOutputAttributes()]; + double[] out = new double[this.numOutputAttributes]; if (normalize()) { - for (int i = 0; i < inst.numOutputAttributes(); i++) { - double value = inst.valueOutputAttribute(i); - double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); - double average = sumOfValues.getValue(i) / examplesSeen; - if (sd > 0 && examplesSeen > 1) - out[i] = (value - average) / (sd); - else - out[i] = 0; + for (int i = 0; i < this.numOutputAttributes; i++) { + double value = (inst.isOutputMissing(i)) ? Double.NaN : inst.valueOutputAttribute(i);; + if (value != Double.NaN) { + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); + double average = sumOfValues.getValue(i) / examplesSeen; + if (sd > 0 && examplesSeen > 1) + out[i] = (value - average) / (sd); + else + out[i] = 0; + } else out[i] = value; } } else { - for (int i = 0; i < inst.numOutputAttributes(); i++) { - out[i] = inst.valueOutputAttribute(i); + for (int i = 0; i < this.numOutputAttributes; i++) { + out[i] = (inst.isOutputMissing(i)) ? Double.NaN : inst.valueOutputAttribute(i); } } return out; @@ -945,8 +1071,8 @@ public double normalizeTargetValue(double value, int i) { public double[] getNormalizedError(StructuredInstance inst, double[] prediction) { double[] normalPrediction = normalizeTargetVector(prediction); double[] normalValue = normalizedTargetVector(inst); - double[] out = new double[getModelContext().numOutputAttributes()]; - for (int i = 0; i < inst.numOutputAttributes(); i++) { + double[] out = new double[this.numOutputAttributes]; + for (int i = 0; i < this.numOutputAttributes; i++) { out[i] = Math.abs(normalValue[i] - normalPrediction[i]); } return out; @@ -956,176 +1082,173 @@ public double[] getNormalizedError(StructuredInstance inst, double[] prediction) /** * Method for updating (training) the model using a new instance */ - public void trainOnInstanceImpl(StructuredInstance inst) { - if (inst.weight() > 0) { - checkRoot(); + public void trainOnInstanceImpl(StructuredInstance inst) { + if (inst.weight() > 0) { - double[] prediction = treeRoot.getPrediction(inst); - double[] normalError = getNormalizedError(inst, prediction); + double[] prediction = treeRoot.getPrediction(inst); + double[] normalError = getNormalizedError(inst, prediction); - processInstance(inst, treeRoot, prediction, normalError, true, false); + processInstance(inst, treeRoot, prediction, normalError, true, false); - examplesSeen += inst.weight(); - for (int i = 0; i < inst.numberOutputTargets(); i++) { - sumOfValues.addToValue(i, inst.weight() * inst.valueOutputAttribute(i)); - sumOfSquares.addToValue(i, inst.weight() * inst.valueOutputAttribute(i) * inst.valueOutputAttribute(i)); - } + double weight = inst.weight(); - for (int i = 0; i < inst.numInputAttributes(); i++) { - sumOfAttrValues.addToValue(i, inst.weight() * inst.valueInputAttribute(i)); - sumOfAttrSquares.addToValue(i, inst.weight() * inst.valueInputAttribute(i) * inst.valueInputAttribute(i)); - } - } - } + examplesSeen += weight; + for (int i = 0; i < this.numOutputAttributes; i++) { + double iVal = inst.valueOutputAttribute(i); + sumOfValues.addToValue(i, weight * iVal); + sumOfSquares.addToValue(i, weight * iVal * iVal); + } - public void processInstance(StructuredInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { - Node currentNode = node; - while (true) { - if (currentNode instanceof LeafNode) { - ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); - break; - } else { - currentNode.examplesSeen += inst.weight(); - //currentNode.sumOfAbsErrors.addValues(normalError); - // SplitNode iNode = (SplitNode) currentNode; - // if (!inAlternate && iNode.alternateTree != null) { - // boolean altTree = true; - // double lossO = Math.pow(inst.valueOutputAttribute() - prediction, 2); - // double lossA = Math.pow(inst.valueOutputAttribute() - iNode.alternateTree.getPrediction(inst), 2); - // - // iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; - // iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; - // iNode.lossExamplesSeen++; - // - // double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - // double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - // iNode.lossSumQi += Qi; - // iNode.lossNumQiTests += 1; - // double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - // - // if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { - // iNode.previousWeight = iNode.lossExamplesSeen; - // if (Qi > 0) { - // SplitNode parent = currentNode.getParent(); - // - // if (parent != null) { - // Node replacementTree = iNode.alternateTree; - // parent.setChild(parent.getChildIndex(currentNode), replacementTree); - // if (growthAllowed) replacementTree.restartChangeDetection(); - // } else { - // treeRoot = iNode.alternateTree; - // treeRoot.restartChangeDetection(); - // } - // - // currentNode = iNode.alternateTree; - // altTree = false; - // } else if ( - // (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) - // || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() - // ) { - // iNode.alternateTree = null; - // if (growthAllowed) iNode.restartChangeDetection(); - // altTree = false; - // } - // } - // - // if (altTree) { - // growthAllowed = false; - // processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); - // } - // } - - // if (iNode.changeDetection && !inAlternate) { - // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { - // iNode.initializeAlternateTree(this); - // } - // } - if (currentNode instanceof SplitNode) { - currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); - } else { // if the replaced alternate tree is just a leaf node - ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); - break; - } - } - } - } + for (int i = 0; i < this.numInputAttributes; i++) { + double iVal = inst.valueInputAttribute(i); + sumOfAttrValues.addToValue(i, weight * iVal); + sumOfAttrSquares.addToValue(i, weight * iVal * iVal); + } + } + } - //region --- Object instatiation methods + public void processInstance(StructuredInstance inst, Node node, double[] prediction, double[] normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + break; + } else { + currentNode.examplesSeen += inst.weight(); + //currentNode.sumOfAbsErrors.addValues(normalError); + // SplitNode iNode = (SplitNode) currentNode; + // if (!inAlternate && iNode.alternateTree != null) { + // boolean altTree = true; + // double lossO = Math.pow(inst.valueOutputAttribute() - prediction, 2); + // double lossA = Math.pow(inst.valueOutputAttribute() - iNode.alternateTree.getPrediction(inst), 2); + // + // iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + // iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + // iNode.lossExamplesSeen++; + // + // double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + // double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // iNode.lossSumQi += Qi; + // iNode.lossNumQiTests += 1; + // double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + // + // if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + // iNode.previousWeight = iNode.lossExamplesSeen; + // if (Qi > 0) { + // SplitNode parent = currentNode.getParent(); + // + // if (parent != null) { + // Node replacementTree = iNode.alternateTree; + // parent.setChild(parent.getChildIndex(currentNode), replacementTree); + // if (growthAllowed) replacementTree.restartChangeDetection(); + // } else { + // treeRoot = iNode.alternateTree; + // treeRoot.restartChangeDetection(); + // } + // + // currentNode = iNode.alternateTree; + // altTree = false; + // } else if ( + // (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * this.gracePeriodOption.getValue())) + // || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue() + // ) { + // iNode.alternateTree = null; + // if (growthAllowed) iNode.restartChangeDetection(); + // altTree = false; + // } + // } + // + // if (altTree) { + // growthAllowed = false; + // processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + // } + // } + + // if (iNode.changeDetection && !inAlternate) { + // if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + // iNode.initializeAlternateTree(this); + // } + // } + //if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).getChild(((SplitNode) currentNode).instanceChildIndex(inst)); + //} else { // if the replaced alternate tree is just a leaf node + // ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); + //break; + } + } + } - protected NumericStatisticsObserver newNumericClassObserver() { - return new MultiLabelBSTree(); - } + //region --- Object instatiation methods - public NominalStatisticsObserver newNominalClassObserver() { - return new MultiLabelNominalAttributeObserver(); - } + protected NumericStatisticsObserver newNumericClassObserver() { + try { + //NumericStatisticsObserver o = (NumericStatisticsObserver) ClassOption.cliStringToObject("MultiLabelBSTree -z 2000", MultiLabelBSTree.class, null); + //NumericStatisticsObserver o = (NumericStatisticsObserver) ClassOption.cliStringToObject("MultiLabelBSTree2 -z 2000", MultiLabelBSTree2.class, null); + if (runAsPCTOption.isSet()) { + return new MultiLabelBSTreePCT(); + } else { + return new MultiLabelBSTree(); + } - // protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { - // maxID++; - // return new SplitNode(splitTest, this); - // } + } catch (Exception e) { + return null; + } + } - protected SplitNode newSplitNode(Predicate predicate) { - maxID++; - return new SplitNode(predicate, this); - } + public NominalStatisticsObserver newNominalClassObserver() { + return new MultiLabelNominalAttributeObserver(); + } - protected LeafNode newLeafNode() { - maxID++; - return new LeafNode(this); - } + // protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + // maxID++; + // return new SplitNode(splitTest, this); + // } - public MultitargetPerceptron newLeafModel() { - return new MultitargetPerceptron(this); - } + protected SplitNode newSplitNode(Predicate predicate) { + maxID++; + return new SplitNode(predicate, this); + } - //endregion --- Object instatiation methods + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } - //region --- Processing methods - protected void checkRoot() { - if (treeRoot == null) { - treeRoot = newLeafNode(); - } - } + public MultitargetPerceptron newLeafModel() { + return new MultitargetPerceptron(this); + } - public static double computeHoeffdingBound(double range, double confidence, double n) { - return Math.sqrt(((range * range) * Math.log(1 / confidence)) / (2.0 * n)); - } + //endregion --- Object instatiation methods - public boolean buildingModelTree() { - return !regressionTreeOption.isSet(); - } - - public boolean buildingRandomForestTree() { - return randomForestBaseModelOption.isSet(); - } + //region --- Processing methods + protected void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + } + } - public boolean normalize() { - return !doNotNormalizeOption.isSet(); - } + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(((range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } - protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) { - // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. - MultiLabelSplitCriterion splitCriterion = new WeightedICVarianceReduction(targetWeights); + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } - // Using this criterion, find the best split per attribute and rank the results - AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option - Arrays.sort(bestSplitSuggestions); + public boolean normalize() { + return !doNotNormalizeOption.isSet(); + } // Declare a variable to determine if any of the splits should be performed boolean shouldSplit = false; - // If only one split was returned, use it if (bestSplitSuggestions.length < 2) { shouldSplit = bestSplitSuggestions.length > 0; } else { // Otherwise, consider which of the splits proposed may be worth trying - // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); - // Determine the top two ranked splitting suggestions - AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + // Using this criterion, find the best split per attribute and rank the results + AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option + Arrays.sort(bestSplitSuggestions); // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this @@ -1134,9 +1257,6 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - //System.out.print(hoeffdingBound); - //System.out.print(" "); - ///System.out.println(secondBestSuggestion.merit / bestSuggestion.merit); if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { shouldSplit = true; } @@ -1155,44 +1275,36 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) } } - // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (shouldSplit) { - AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; SplitNode newSplit = newSplitNode(splitDecision.predicate); newSplit.ID = node.ID; newSplit.copyStatistics(node); newSplit.changeDetection = node.changeDetection; newSplit.ID = node.ID; + log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) LeafNode newChild = newLeafNode(); if (buildingModelTree()) { // Copy the splitting node's perceptron to it's children newChild.learningModel = new MultitargetPerceptron(this, (MultitargetPerceptron) node.learningModel); - } - newChild.changeDetection = node.changeDetection; - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - } - if (parent == null && node.originalNode == null) { - treeRoot = newSplit; - } else if (parent == null && node.originalNode != null) { - node.originalNode.alternateTree = newSplit; - } else { - parent.setChild(parentIndex, newSplit); - newSplit.setParent(parent); - } - } - } + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + // try { + // Thread.sleep(20000); + // } catch (InterruptedException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } - public double computeSD(double squaredVal, double val, double size) { - if (size > 1) - return Math.sqrt((squaredVal - ((val * val) / size)) / size); - else - return 0.0; - } + if (shouldSplit) { + AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; public static double scalarProduct(DoubleVector u, DoubleVector v) { double ret = 0.0; @@ -1202,6 +1314,38 @@ public static double scalarProduct(DoubleVector u, DoubleVector v) { return ret; } //endregion --- Processing methods - + + public void initWriter(String filename) { + try { + writer = new BufferedWriter(new FileWriter(filename)); + writer.write(""); + writer.close(); + writer = new BufferedWriter(new FileWriter(filename, true)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void closeWriter() { + try { + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + writer = null; + + } + + public void log(String s) { + if (writer != null) { + try { + writer.write(s + "\n"); + writer.flush(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + //endregion ================ METHODS ================ } diff --git a/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTreeRF.java b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTreeRF.java new file mode 100644 index 000000000..ea8193d91 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/multilabel/trees/ISOUPTreeRF.java @@ -0,0 +1,46 @@ +package moa.classifiers.multilabel.trees; + +import java.util.List; +import java.util.Vector; + +import com.github.javacliparser.MultiChoiceOption; + +public class ISOUPTreeRF extends ISOUPTree { + + /** + * + */ + private static final long serialVersionUID = 3145263568676115808L; + public MultiChoiceOption radndomForestFunAttrsOption = new MultiChoiceOption( + "randomForestFunAttr", + 'z', + "The function of the number of input attribtues to use in the random forest construction.", + new String[]{"sqrt", "log", "percent"}, new String[]{"Square root", "Logarithm", "10% percent"}, 0); + + + public int numRFAttrs() { + switch (radndomForestFunAttrsOption.getChosenLabel()) { + case "sqrt": return (int) Math.ceil(Math.sqrt(this.getModelContext().numInputAttributes())); + case "log": return (int) Math.ceil(Math.log(this.getModelContext().numInputAttributes())) + 1; + case "percent": return (int) Math.ceil(0.1 * this.getModelContext().numInputAttributes()); + } + return 0; + } + + @Override + public List newInputIndexes() { + List indexes = new Vector(); + int numAttrs = this.getModelContext().numInputAttributes(); + for (int i = 0; i < numAttrs; i++) { + indexes.add(i, i); + } + for (int i = 0; i < Math.ceil(numRFAttrs()); i++) { + int swap = i + this.classifierRandom.nextInt(numAttrs - i); + int temp = indexes.get(i); + indexes.set(i, indexes.get(swap)); + indexes.set(swap, temp); + } + return indexes.subList(0, numRFAttrs()); + } + +} diff --git a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java index edad24332..a7a1a1ac1 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/multitarget/BasicMultiTargetRegressor.java @@ -1,6 +1,13 @@ package moa.classifiers.multitarget; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.Classifier; @@ -12,14 +19,6 @@ import moa.options.ClassOption; import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.MultiLabelPrediction; -import com.yahoo.labs.samoa.instances.Prediction; - public class BasicMultiTargetRegressor extends AbstractMultiLabelLearner implements MultiTargetRegressor{ diff --git a/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java b/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java index 9f08ed855..cae16376a 100644 --- a/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java +++ b/moa/src/main/java/moa/classifiers/multitarget/functions/MultiTargetNoChange.java @@ -1,14 +1,10 @@ package moa.classifiers.multitarget.functions; -import com.yahoo.labs.samoa.instances.DenseInstanceData; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; -import moa.classifiers.AbstractClassifier; import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; import moa.core.Measurement; diff --git a/moa/src/main/java/moa/classifiers/rules/AMRulesRegressorOld.java b/moa/src/main/java/moa/classifiers/rules/AMRulesRegressorOld.java index 63b1d3f9f..8a8020529 100644 --- a/moa/src/main/java/moa/classifiers/rules/AMRulesRegressorOld.java +++ b/moa/src/main/java/moa/classifiers/rules/AMRulesRegressorOld.java @@ -64,11 +64,10 @@ import com.github.javacliparser.MultiChoiceOption; import moa.classifiers.Regressor; -import moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion; import moa.classifiers.rules.core.Rule; +import moa.classifiers.rules.core.Rule.Builder; import moa.classifiers.rules.core.RuleActiveLearningNode; import moa.classifiers.rules.core.RuleActiveRegressionNode; -import moa.classifiers.rules.core.Rule.Builder; import moa.classifiers.rules.core.splitcriteria.AMRulesSplitCriterion; import moa.classifiers.rules.core.voting.ErrorWeightedVote; import moa.classifiers.rules.functions.Perceptron; diff --git a/moa/src/main/java/moa/classifiers/rules/AbstractAMRules.java b/moa/src/main/java/moa/classifiers/rules/AbstractAMRules.java index ab2555b7a..8f6911d14 100644 --- a/moa/src/main/java/moa/classifiers/rules/AbstractAMRules.java +++ b/moa/src/main/java/moa/classifiers/rules/AbstractAMRules.java @@ -31,19 +31,19 @@ * **/ +import java.util.Arrays; +import java.util.Iterator; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; -import java.util.Arrays; -import java.util.Iterator; - import moa.classifiers.AbstractClassifier; import moa.classifiers.rules.core.Rule; +import moa.classifiers.rules.core.Rule.Builder; import moa.classifiers.rules.core.RuleActiveLearningNode; import moa.classifiers.rules.core.RuleSet; -import moa.classifiers.rules.core.Rule.Builder; import moa.classifiers.rules.core.attributeclassobservers.FIMTDDNumericAttributeClassLimitObserver; import moa.classifiers.rules.core.voting.ErrorWeightedVote; import moa.classifiers.rules.core.voting.Vote; diff --git a/moa/src/main/java/moa/classifiers/rules/Predicates.java b/moa/src/main/java/moa/classifiers/rules/Predicates.java index 76b96f084..db1583359 100644 --- a/moa/src/main/java/moa/classifiers/rules/Predicates.java +++ b/moa/src/main/java/moa/classifiers/rules/Predicates.java @@ -21,6 +21,8 @@ package moa.classifiers.rules; +import com.yahoo.labs.samoa.instances.Instance; + /** * Class that creates and evaluates the predicates * @@ -32,7 +34,6 @@ */ import moa.AbstractMOAObject; -import com.yahoo.labs.samoa.instances.Instance; public class Predicates extends AbstractMOAObject{ diff --git a/moa/src/main/java/moa/classifiers/rules/RuleClassification.java b/moa/src/main/java/moa/classifiers/rules/RuleClassification.java index c7b9866e4..3d6fdcda9 100644 --- a/moa/src/main/java/moa/classifiers/rules/RuleClassification.java +++ b/moa/src/main/java/moa/classifiers/rules/RuleClassification.java @@ -33,11 +33,13 @@ */ import java.util.ArrayList; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.AbstractMOAObject; -import moa.classifiers.core.attributeclassobservers.*; +import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.core.AutoExpandVector; import moa.core.DoubleVector; -import com.yahoo.labs.samoa.instances.Instance; public class RuleClassification extends AbstractMOAObject{ diff --git a/moa/src/main/java/moa/classifiers/rules/RuleClassifier.java b/moa/src/main/java/moa/classifiers/rules/RuleClassifier.java index 0e8dbd6e3..6d4f860d6 100644 --- a/moa/src/main/java/moa/classifiers/rules/RuleClassifier.java +++ b/moa/src/main/java/moa/classifiers/rules/RuleClassifier.java @@ -25,21 +25,26 @@ import java.io.IOException; import java.io.PrintWriter; import java.math.BigDecimal; -import java.util.*; -import com.github.javacliparser.FlagOption; +import java.util.ArrayList; +import java.util.Collections; +import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; -import moa.classifiers.core.attributeclassobservers.*; +import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; +import moa.classifiers.core.attributeclassobservers.BinaryTreeNumericAttributeClassObserver; import moa.classifiers.core.attributeclassobservers.BinaryTreeNumericAttributeClassObserver.Node; +import moa.classifiers.core.attributeclassobservers.GaussianNumericAttributeClassObserver; +import moa.classifiers.core.attributeclassobservers.NominalAttributeClassObserver; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.StringUtils; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/classifiers/rules/RuleClassifierNBayes.java b/moa/src/main/java/moa/classifiers/rules/RuleClassifierNBayes.java index 6a23e9f06..d495592f3 100644 --- a/moa/src/main/java/moa/classifiers/rules/RuleClassifierNBayes.java +++ b/moa/src/main/java/moa/classifiers/rules/RuleClassifierNBayes.java @@ -22,10 +22,12 @@ import java.util.ArrayList; import java.util.Collections; + import com.github.javacliparser.IntOption; -import moa.classifiers.bayes.NaiveBayes; import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.bayes.NaiveBayes; + /** * This classifier learn ordered and unordered rule set from data stream with naive Bayes learners. *

This algorithm also does the detection of anomalies. diff --git a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java index 7e5febe56..fb5505ef7 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java @@ -2,7 +2,6 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java index a6b313c12..8387610c0 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java @@ -2,7 +2,6 @@ import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/core/Rule.java b/moa/src/main/java/moa/classifiers/rules/core/Rule.java index c12befcb2..4cea1b6dc 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/Rule.java +++ b/moa/src/main/java/moa/classifiers/rules/core/Rule.java @@ -19,6 +19,10 @@ */ package moa.classifiers.rules.core; +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; + /** * Class that stores an arrayList of predicates of a rule and the observers * (statistics). This class implements a function that evaluates a rule. @@ -36,10 +40,6 @@ import com.github.javacliparser.FloatOption; import com.yahoo.labs.samoa.instances.Instance; -import java.io.Serializable; -import java.util.LinkedList; -import java.util.List; - import moa.AbstractMOAObject; import moa.classifiers.core.conditionaltests.InstanceConditionalTest; import moa.classifiers.core.conditionaltests.NumericAttributeBinaryTest; diff --git a/moa/src/main/java/moa/classifiers/rules/core/RuleActiveLearningNode.java b/moa/src/main/java/moa/classifiers/rules/core/RuleActiveLearningNode.java index 1613a7049..1eaff66bd 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/RuleActiveLearningNode.java +++ b/moa/src/main/java/moa/classifiers/rules/core/RuleActiveLearningNode.java @@ -24,8 +24,8 @@ import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.rules.AbstractAMRules; -import moa.classifiers.rules.driftdetection.PageHinkleyTest; import moa.classifiers.rules.driftdetection.PageHinkleyFading; +import moa.classifiers.rules.driftdetection.PageHinkleyTest; import moa.classifiers.trees.HoeffdingTree; import moa.classifiers.trees.HoeffdingTree.ActiveLearningNode; import moa.core.AutoExpandVector; diff --git a/moa/src/main/java/moa/classifiers/rules/core/RuleActiveRegressionNode.java b/moa/src/main/java/moa/classifiers/rules/core/RuleActiveRegressionNode.java index 1eebdfad7..0f39b9f91 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/RuleActiveRegressionNode.java +++ b/moa/src/main/java/moa/classifiers/rules/core/RuleActiveRegressionNode.java @@ -20,28 +20,20 @@ package moa.classifiers.rules.core; -import com.yahoo.labs.samoa.instances.Instance; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.sql.PreparedStatement; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.classifiers.rules.AMRulesRegressorOld; -import moa.classifiers.rules.AbstractAMRules; import moa.classifiers.rules.core.splitcriteria.AMRulesSplitCriterion; -import moa.classifiers.rules.core.splitcriteria.SDRSplitCriterionAMRules; import moa.classifiers.rules.functions.Perceptron; import moa.classifiers.rules.functions.TargetMean; import moa.core.DoubleVector; diff --git a/moa/src/main/java/moa/classifiers/rules/core/Utils.java b/moa/src/main/java/moa/classifiers/rules/core/Utils.java index 1c60f8dfb..5340ea695 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/Utils.java +++ b/moa/src/main/java/moa/classifiers/rules/core/Utils.java @@ -14,6 +14,11 @@ public static double computeVariance(DoubleVector statistics) return computeVariance(statistics.getValue(0),statistics.getValue(1),statistics.getValue(2)); } + public static double computeVariance(double[] statistics) + { + return computeVariance(statistics[0],statistics[1],statistics[2]); + } + public static double computeSD(double squaredSum, double sum, double weightSeen) { if (weightSeen > 1) { return Math.sqrt((squaredSum - ((sum * sum) / weightSeen)) / (weightSeen - 1.0)); diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java index 13a4f85ba..5d91180e4 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AbstractAnomalyDetector.java @@ -1,8 +1,9 @@ package moa.classifiers.rules.core.anomalydetection; -import moa.options.AbstractOptionHandler; import com.yahoo.labs.samoa.instances.StructuredInstance; +import moa.options.AbstractOptionHandler; + public abstract class AbstractAnomalyDetector extends AbstractOptionHandler implements AnomalyDetector { diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java index 9297ebe1e..a6a3bdae6 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java @@ -1,18 +1,16 @@ package moa.classifiers.rules.core.anomalydetection; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.rules.core.Utils; import moa.classifiers.rules.core.anomalydetection.probabilityfunctions.ProbabilityFunction; -import moa.classifiers.rules.core.attributeclassobservers.FIMTDDNumericAttributeClassLimitObserver; import moa.core.AutoExpandVector; import moa.core.ObjectRepository; import moa.options.ClassOption; import moa.tasks.TaskMonitor; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; - public class AnomalinessRatioScore extends AbstractAnomalyDetector { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java index 722f15dfa..6ad69595a 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/NoAnomalyDetection.java @@ -1,8 +1,9 @@ package moa.classifiers.rules.core.anomalydetection; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.core.ObjectRepository; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.StructuredInstance; public class NoAnomalyDetection extends AbstractAnomalyDetector{ diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java index 53cc8556c..ee841f6f2 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java @@ -1,5 +1,10 @@ package moa.classifiers.rules.core.anomalydetection; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.rules.core.Utils; import moa.classifiers.rules.core.anomalydetection.probabilityfunctions.CantellisInequality; import moa.classifiers.rules.core.anomalydetection.probabilityfunctions.ProbabilityFunction; @@ -8,11 +13,6 @@ import moa.options.ClassOption; import moa.tasks.TaskMonitor; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; - public class OddsRatioScore extends AbstractAnomalyDetector { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/CantellisInequality.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/CantellisInequality.java index c021dad34..63aad5315 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/CantellisInequality.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/CantellisInequality.java @@ -2,11 +2,8 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import moa.options.OptionHandler; import moa.tasks.TaskMonitor; -import com.github.javacliparser.Options; - public class CantellisInequality extends AbstractOptionHandler implements ProbabilityFunction { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/ChebyshevInequality.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/ChebyshevInequality.java index 52d897aa1..f32fb6243 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/ChebyshevInequality.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/ChebyshevInequality.java @@ -2,11 +2,8 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import moa.options.OptionHandler; import moa.tasks.TaskMonitor; -import com.github.javacliparser.Options; - public class ChebyshevInequality extends AbstractOptionHandler implements ProbabilityFunction { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/GaussInequality.java b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/GaussInequality.java index aa73a67a5..ea587e6dd 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/GaussInequality.java +++ b/moa/src/main/java/moa/classifiers/rules/core/anomalydetection/probabilityfunctions/GaussInequality.java @@ -2,11 +2,8 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import moa.options.OptionHandler; import moa.tasks.TaskMonitor; -import com.github.javacliparser.Options; - public class GaussInequality extends AbstractOptionHandler implements ProbabilityFunction { /** diff --git a/moa/src/main/java/moa/classifiers/rules/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java b/moa/src/main/java/moa/classifiers/rules/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java index de93184cf..83740c403 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java +++ b/moa/src/main/java/moa/classifiers/rules/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java @@ -20,6 +20,7 @@ package moa.classifiers.rules.core.attributeclassobservers; import com.github.javacliparser.IntOption; + import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; @@ -99,9 +100,6 @@ else if (val < this.cut_point) { // right (>) distribution and send the value down to the right child node. // If no right child exists, create one else { // val > cut_point - this.rightStatistics.addToValue(0,1); - this.rightStatistics.addToValue(1,label); - this.rightStatistics.addToValue(2,label*label); if (this.right == null) { if(numNodes>{ public double getCurrentError(); diff --git a/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java b/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java index a5e48b1a8..d8d6bdd81 100644 --- a/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java +++ b/moa/src/main/java/moa/classifiers/rules/functions/Perceptron.java @@ -25,10 +25,8 @@ import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.classifiers.AbstractClassifier; -import moa.classifiers.Regressor; import moa.core.DoubleVector; import moa.core.Measurement; diff --git a/moa/src/main/java/moa/classifiers/rules/functions/TargetMean.java b/moa/src/main/java/moa/classifiers/rules/functions/TargetMean.java index 53f8c63c1..fcb7e6f8d 100644 --- a/moa/src/main/java/moa/classifiers/rules/functions/TargetMean.java +++ b/moa/src/main/java/moa/classifiers/rules/functions/TargetMean.java @@ -26,8 +26,8 @@ * */ import com.github.javacliparser.FloatOption; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; -import moa.classifiers.Regressor; import moa.core.Measurement; import moa.core.StringUtils; diff --git a/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java b/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java index 8828c1d84..5037efd76 100644 --- a/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java +++ b/moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java @@ -21,13 +21,10 @@ import java.util.Arrays; -import moa.options.ClassOption; - import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; @@ -38,11 +35,9 @@ import moa.classifiers.rules.AbstractAMRules; import moa.classifiers.rules.core.voting.ErrorWeightedVote; import moa.classifiers.rules.core.voting.Vote; -import moa.core.DoubleVector; -import moa.core.FastVector; import moa.core.Measurement; import moa.core.MiscUtils; -import moa.streams.InstanceStream; +import moa.options.ClassOption; public class RandomAMRulesOld extends AbstractClassifier implements Regressor { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java index 44a24ae5f..0ad8c1ec2 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java @@ -33,6 +33,12 @@ import java.util.Iterator; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiLabelLearner; import moa.classifiers.core.driftdetection.ChangeDetector; @@ -44,7 +50,6 @@ import moa.classifiers.rules.multilabel.core.MultiLabelRule; import moa.classifiers.rules.multilabel.core.MultiLabelRuleSet; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; -import moa.classifiers.rules.multilabel.core.voting.MultiLabelVote; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; import moa.classifiers.rules.multilabel.outputselectors.SelectAllOutputs; @@ -52,12 +57,6 @@ import moa.core.StringUtils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - public abstract class AMRulesMultiLabelLearner extends AbstractMultiLabelLearner implements MultiLabelLearner{ diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java index 146a6be85..461c63925 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java @@ -2,12 +2,10 @@ import moa.classifiers.MultiLabelLearner; import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.Regressor; import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.multilabel.core.MultiLabelRule; import moa.classifiers.rules.multilabel.core.MultiLabelRuleRegression; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; -import moa.classifiers.rules.multilabel.core.voting.InverseErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java index 9c179d2f6..a8bafb4a1 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteral.java @@ -7,15 +7,10 @@ import java.util.Random; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.classifiers.MultiLabelLearner; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.NumericAttributeClassObserver; import moa.classifiers.core.driftdetection.ChangeDetector; import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; @@ -23,13 +18,11 @@ import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; import moa.classifiers.rules.core.AttributeExpansionSuggestion; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; -import moa.classifiers.rules.multilabel.errormeasurers.AbstractMultiTargetErrorMeasurer; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.options.AbstractOptionHandler; -import moa.options.ClassOption; public abstract class LearningLiteral extends AbstractOptionHandler { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java index f9e2c5c82..282ca1dba 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java @@ -1,20 +1,14 @@ package moa.classifiers.rules.multilabel.core; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.MultiLabelLearner; -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.driftdetection.ChangeDetector; -import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.classifiers.multilabel.core.attributeclassobservers.AttributeStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; @@ -25,7 +19,6 @@ import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.ObjectRepository; -import moa.learners.Learner; import moa.tasks.TaskMonitor; public class LearningLiteralRegression extends LearningLiteral { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java index 0fb2aba8b..23e58b418 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/MultiLabelRule.java @@ -5,22 +5,16 @@ import java.util.List; import java.util.Random; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.AbstractMOAObject; import moa.classifiers.MultiLabelLearner; -import moa.classifiers.core.attributeclassobservers.NumericAttributeClassObserver; -import moa.classifiers.core.conditionaltests.InstanceConditionalTest; -import moa.classifiers.core.conditionaltests.NumericAttributeBinaryTest; import moa.classifiers.core.driftdetection.ChangeDetector; import moa.classifiers.multilabel.core.attributeclassobservers.NominalStatisticsObserver; import moa.classifiers.multilabel.core.attributeclassobservers.NumericStatisticsObserver; import moa.classifiers.multilabel.core.splitcriteria.MultiLabelSplitCriterion; -import moa.classifiers.rules.core.RuleActiveLearningNode; -import moa.classifiers.rules.core.RuleSplitNode; import moa.classifiers.rules.core.anomalydetection.AnomalyDetector; -import moa.classifiers.rules.core.conditionaltests.NumericAttributeBinaryRulePredicate; import moa.classifiers.rules.multilabel.errormeasurers.MultiLabelErrorMeasurer; import moa.classifiers.rules.multilabel.outputselectors.OutputAttributesSelector; import moa.core.StringUtils; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/AbstractErrorWeightedVoteMultiLabel.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/AbstractErrorWeightedVoteMultiLabel.java index 8572a8b5a..59cada880 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/AbstractErrorWeightedVoteMultiLabel.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/AbstractErrorWeightedVoteMultiLabel.java @@ -26,7 +26,6 @@ import com.yahoo.labs.samoa.instances.Prediction; import moa.AbstractMOAObject; -import moa.core.DoubleVector; /** * AbstractErrorWeightedVote class for weighted votes based on estimates of errors. diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/ErrorWeightedVoteMultiLabel.java b/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/ErrorWeightedVoteMultiLabel.java index 5bdb2530e..22d49cc75 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/ErrorWeightedVoteMultiLabel.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/ErrorWeightedVoteMultiLabel.java @@ -20,8 +20,6 @@ package moa.classifiers.rules.multilabel.core.voting; -import java.util.List; - import com.yahoo.labs.samoa.instances.Prediction; import moa.MOAObject; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java index b96ddd2a7..1d393bf4b 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiLabelErrorMeasurer.java @@ -1,13 +1,13 @@ package moa.classifiers.rules.multilabel.errormeasurers; +import com.github.javacliparser.FloatOption; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.tasks.TaskMonitor; -import com.github.javacliparser.FloatOption; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - public abstract class AbstractMultiLabelErrorMeasurer extends AbstractOptionHandler implements MultiTargetErrorMeasurer{ /** diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java index 5b2bc3be8..bb22ff469 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/AbstractMultiTargetErrorMeasurer.java @@ -1,8 +1,8 @@ package moa.classifiers.rules.multilabel.errormeasurers; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; public abstract class AbstractMultiTargetErrorMeasurer extends AbstractMultiLabelErrorMeasurer implements MultiLabelErrorMeasurer{ diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/MultiLabelErrorMeasurer.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/MultiLabelErrorMeasurer.java index 66259cfe6..9f280d765 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/MultiLabelErrorMeasurer.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/MultiLabelErrorMeasurer.java @@ -1,7 +1,7 @@ package moa.classifiers.rules.multilabel.errormeasurers; -import com.yahoo.labs.samoa.instances.StructuredInstance; import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; import moa.options.OptionHandler; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RootMeanSquaredErrorMT.java b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RootMeanSquaredErrorMT.java index cab1cab93..08d5d319d 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RootMeanSquaredErrorMT.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RootMeanSquaredErrorMT.java @@ -1,8 +1,5 @@ package moa.classifiers.rules.multilabel.errormeasurers; -import moa.core.ObjectRepository; -import moa.tasks.TaskMonitor; - import com.yahoo.labs.samoa.instances.Prediction; public class RootMeanSquaredErrorMT extends AbstractMultiTargetErrorMeasurer { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/functions/AdaptiveMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/rules/multilabel/functions/AdaptiveMultiTargetRegressor.java index 1f0adf4b4..7541446ac 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/functions/AdaptiveMultiTargetRegressor.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/functions/AdaptiveMultiTargetRegressor.java @@ -1,16 +1,15 @@ package moa.classifiers.rules.multilabel.functions; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; import moa.classifiers.rules.multilabel.errormeasurers.AbstractMultiTargetErrorMeasurer; import moa.classifiers.rules.multilabel.errormeasurers.MultiTargetErrorMeasurer; import moa.core.Measurement; -import moa.learners.Learner; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - public class AdaptiveMultiTargetRegressor extends AbstractMultiLabelLearner implements MultiTargetRegressor, AMRulesFunction { diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/functions/MultiLabelTargetMeanRegressor.java b/moa/src/main/java/moa/classifiers/rules/multilabel/functions/MultiLabelTargetMeanRegressor.java index ce744a59f..4a80a690d 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/functions/MultiLabelTargetMeanRegressor.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/functions/MultiLabelTargetMeanRegressor.java @@ -4,7 +4,6 @@ import moa.classifiers.MultiTargetRegressor; import moa.classifiers.multitarget.BasicMultiTargetRegressor; -import moa.classifiers.rules.functions.Perceptron; import moa.classifiers.rules.functions.TargetMean; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/classifiers/rules/multilabel/meta/MultiLabelRandomAMRules.java b/moa/src/main/java/moa/classifiers/rules/multilabel/meta/MultiLabelRandomAMRules.java index 7c08a3eed..8085c13bb 100644 --- a/moa/src/main/java/moa/classifiers/rules/multilabel/meta/MultiLabelRandomAMRules.java +++ b/moa/src/main/java/moa/classifiers/rules/multilabel/meta/MultiLabelRandomAMRules.java @@ -1,9 +1,15 @@ package moa.classifiers.rules.multilabel.meta; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.classifiers.AbstractMultiLabelLearner; import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.rules.AbstractAMRules; -import moa.classifiers.rules.core.voting.ErrorWeightedVote; import moa.classifiers.rules.multilabel.AMRulesMultiLabelLearner; import moa.classifiers.rules.multilabel.core.voting.ErrorWeightedVoteMultiLabel; import moa.classifiers.rules.multilabel.core.voting.UniformWeightedVoteMultiLabel; @@ -13,14 +19,6 @@ import moa.core.MiscUtils; import moa.options.ClassOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - public class MultiLabelRandomAMRules extends AbstractMultiLabelLearner implements MultiTargetRegressor { diff --git a/moa/src/main/java/moa/classifiers/trees/AdaHoeffdingOptionTree.java b/moa/src/main/java/moa/classifiers/trees/AdaHoeffdingOptionTree.java index 6e6db6109..2cefc4f0e 100644 --- a/moa/src/main/java/moa/classifiers/trees/AdaHoeffdingOptionTree.java +++ b/moa/src/main/java/moa/classifiers/trees/AdaHoeffdingOptionTree.java @@ -19,9 +19,10 @@ */ package moa.classifiers.trees; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.bayes.NaiveBayes; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; /** * Adaptive decision option tree for streaming data with adaptive Naive diff --git a/moa/src/main/java/moa/classifiers/trees/DecisionStump.java b/moa/src/main/java/moa/classifiers/trees/DecisionStump.java index 10f4e0fa0..705c73348 100644 --- a/moa/src/main/java/moa/classifiers/trees/DecisionStump.java +++ b/moa/src/main/java/moa/classifiers/trees/DecisionStump.java @@ -21,6 +21,8 @@ import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; @@ -31,7 +33,6 @@ import moa.core.DoubleVector; import moa.core.Measurement; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Decision trees of one level.
diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java index 5ca826b98..b41e55c5a 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java @@ -25,24 +25,24 @@ import java.util.LinkedList; import java.util.List; -import com.yahoo.labs.samoa.instances.Instance; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; -import moa.options.ClassOption; import moa.AbstractMOAObject; +import moa.classifiers.AbstractClassifier; import moa.classifiers.Regressor; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.conditionaltests.InstanceConditionalTest; import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.classifiers.AbstractClassifier; import moa.core.AutoExpandVector; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.SizeOf; import moa.core.StringUtils; +import moa.options.ClassOption; /* * Implementation of FIMTDD, regression and model trees for data streams. @@ -159,8 +159,8 @@ public void copyStatistics(Node node) { sumOfAbsErrors = node.sumOfAbsErrors; } - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); + public long calcByteSize() { + return SizeOf.sizeOf(this) + (originalNode == null && alternateTree != null ? alternateTree.calcByteSize() : 0); } /** @@ -259,6 +259,14 @@ public LeafNode(FIMTDD tree) { sumOfAbsErrors = 0; } + public long calcByteSize() { + long size = super.calcByteSize(); + if (tree.buildingModelTree()) + size += learningModel.calcByteSize(); + size += SizeOf.fullSizeOf(attributeObservers); + return size; + } + public void setChild(int parentBranch, Node node) { } @@ -416,6 +424,13 @@ public abstract static class InnerNode extends Node { public InnerNode(FIMTDD tree) { super(tree); } + + public long calcByteSize() { + long size = super.calcByteSize(); + for (Node child : children) + size += child.calcByteSize(); + return size; + } public int numChildren() { return children.size(); @@ -505,6 +520,12 @@ public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { super(tree); this.splitTest = splitTest; } + + public long calcByteSize() { + long size = super.calcByteSize(); + size += SizeOf.sizeOf(splitTest); + return size; + } public int instanceChildIndex(Instance inst) { return splitTest.branchForInstance(inst); @@ -561,6 +582,10 @@ public FIMTDDPerceptron(FIMTDD tree) { } + public long calcByteSize() { + return SizeOf.sizeOf(this); + } + public void initializeWeights() { weightAttribute = new double[tree.getModelContext().numInputAttributes()+1]; instancesSeen = 0; @@ -710,8 +735,15 @@ protected Measurement[] getModelMeasurementsImpl() { }; } - public int calcByteSize() { - return (int) SizeOf.fullSizeOf(this); + @Override + public long measureByteSize() { + return calcByteSize(); + } + + public long calcByteSize() { + long size = (long) (SizeOf.sizeOf(this)) + this.treeRoot.calcByteSize(); + size += (long) (SizeOf.sizeOf(this.sumOfAttrValues)) + (int) (SizeOf.sizeOf(this.sumOfAttrSquares)); + return size; } public double[] getVotesForInstance(Instance inst) { diff --git a/moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTree.java b/moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTree.java index dd1691fd2..c68657bc0 100644 --- a/moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTree.java +++ b/moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTree.java @@ -22,13 +22,15 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.bayes.NaiveBayes; import moa.classifiers.core.conditionaltests.InstanceConditionalTest; import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.MiscUtils; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding Adaptive Tree for evolving data streams. diff --git a/moa/src/main/java/moa/classifiers/trees/HoeffdingOptionTree.java b/moa/src/main/java/moa/classifiers/trees/HoeffdingOptionTree.java index e4dd74b0a..3ba18b87d 100644 --- a/moa/src/main/java/moa/classifiers/trees/HoeffdingOptionTree.java +++ b/moa/src/main/java/moa/classifiers/trees/HoeffdingOptionTree.java @@ -28,11 +28,14 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; + import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.AbstractMOAObject; import moa.classifiers.AbstractClassifier; import moa.classifiers.bayes.NaiveBayes; @@ -51,7 +54,6 @@ import moa.core.StringUtils; import moa.core.Utils; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding Option Tree. @@ -612,8 +614,8 @@ public void disableAttribute(int attIndex) { protected int maxPredictionPaths; - public int calcByteSize() { - int size = (int) SizeOf.sizeOf(this); + public long calcByteSize() { + long size = SizeOf.sizeOf(this); if (this.treeRoot != null) { size += this.treeRoot.calcByteSizeIncludingSubtree(); } @@ -621,7 +623,7 @@ public int calcByteSize() { } @Override - public int measureByteSize() { + public long measureByteSize() { return calcByteSize(); } @@ -1035,7 +1037,7 @@ public void estimateModelByteSizes() { this.inactiveLeafByteSizeEstimate = (double) totalInactiveSize / this.inactiveLeafNodeCount; } - int actualModelSize = this.measureByteSize(); + long actualModelSize = this.measureByteSize(); double estimatedModelSize = (this.activeLeafNodeCount * this.activeLeafByteSizeEstimate + this.inactiveLeafNodeCount * this.inactiveLeafByteSizeEstimate); diff --git a/moa/src/main/java/moa/classifiers/trees/HoeffdingTree.java b/moa/src/main/java/moa/classifiers/trees/HoeffdingTree.java index c6729b9d8..d8d64f17c 100644 --- a/moa/src/main/java/moa/classifiers/trees/HoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/trees/HoeffdingTree.java @@ -25,10 +25,13 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.AbstractMOAObject; import moa.classifiers.AbstractClassifier; import moa.classifiers.bayes.NaiveBayes; @@ -46,7 +49,6 @@ import moa.core.StringUtils; import moa.core.Utils; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding Tree or VFDT. @@ -149,7 +151,7 @@ public String getPurposeString() { 't', "Threshold below which a split will be forced to break ties.", 0.05, 0.0, 1.0); -public FlagOption binarySplitsOption = new FlagOption("binarySplits", 'b', + public FlagOption binarySplitsOption = new FlagOption("binarySplits", 'b', "Only allow binary splits."); public FlagOption stopMemManagementOption = new FlagOption( @@ -479,8 +481,8 @@ public void disableAttribute(int attIndex) { protected boolean growthAllowed; - public int calcByteSize() { - int size = (int) SizeOf.sizeOf(this); + public long calcByteSize() { + long size = SizeOf.sizeOf(this); if (this.treeRoot != null) { size += this.treeRoot.calcByteSizeIncludingSubtree(); } @@ -488,7 +490,7 @@ public int calcByteSize() { } @Override - public int measureByteSize() { + public long measureByteSize() { return calcByteSize(); } @@ -764,7 +766,7 @@ public void estimateModelByteSizes() { this.inactiveLeafByteSizeEstimate = (double) totalInactiveSize / this.inactiveLeafNodeCount; } - int actualModelSize = this.measureByteSize(); + long actualModelSize = this.measureByteSize(); double estimatedModelSize = (this.activeLeafNodeCount * this.activeLeafByteSizeEstimate + this.inactiveLeafNodeCount * this.inactiveLeafByteSizeEstimate); diff --git a/moa/src/main/java/moa/classifiers/trees/HoeffdingTreeClassifLeaves.java b/moa/src/main/java/moa/classifiers/trees/HoeffdingTreeClassifLeaves.java index 99e409f46..47587b236 100644 --- a/moa/src/main/java/moa/classifiers/trees/HoeffdingTreeClassifLeaves.java +++ b/moa/src/main/java/moa/classifiers/trees/HoeffdingTreeClassifLeaves.java @@ -22,12 +22,14 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.Classifier; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.splitcriteria.SplitCriterion; import moa.classifiers.trees.HoeffdingTree; import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding Tree that have a classifier at the leaves. diff --git a/moa/src/main/java/moa/classifiers/trees/LimAttHoeffdingTree.java b/moa/src/main/java/moa/classifiers/trees/LimAttHoeffdingTree.java index 05b02df91..6c0b669a6 100644 --- a/moa/src/main/java/moa/classifiers/trees/LimAttHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/trees/LimAttHoeffdingTree.java @@ -19,10 +19,11 @@ */ package moa.classifiers.trees; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.bayes.NaiveBayes; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; /** * Hoeffding decision trees with a restricted number of attributes for data diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO.java index 34108ef59..f31e2b480 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO.java @@ -20,22 +20,21 @@ package moa.classifiers.trees; -import java.util.Stack; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.Stack; -import com.yahoo.labs.samoa.instances.Instance; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; import moa.classifiers.Regressor; import moa.classifiers.core.AttributeSplitSuggestion; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; import moa.classifiers.core.splitcriteria.SplitCriterion; - import moa.core.AutoExpandVector; import moa.core.Measurement; import moa.core.StringUtils; @@ -100,7 +99,7 @@ public static class OptionNode extends InnerNode { public OptionNode(FIMTDD tree) { super(tree); } - + public void resetFF() { optionFFSSL = new double[children.size()]; optionFFSeen = new double[children.size()]; diff --git a/moa/src/main/java/moa/classifiers/trees/RandomHoeffdingTree.java b/moa/src/main/java/moa/classifiers/trees/RandomHoeffdingTree.java index f4b86a209..884c285b3 100644 --- a/moa/src/main/java/moa/classifiers/trees/RandomHoeffdingTree.java +++ b/moa/src/main/java/moa/classifiers/trees/RandomHoeffdingTree.java @@ -19,10 +19,11 @@ */ package moa.classifiers.trees; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.bayes.NaiveBayes; import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; import moa.core.Utils; -import com.yahoo.labs.samoa.instances.Instance; /** * Random decision trees for data streams. diff --git a/moa/src/main/java/moa/cluster/CFCluster.java b/moa/src/main/java/moa/cluster/CFCluster.java index 727b0c567..bd6e83b33 100644 --- a/moa/src/main/java/moa/cluster/CFCluster.java +++ b/moa/src/main/java/moa/cluster/CFCluster.java @@ -20,6 +20,7 @@ package moa.cluster; import java.util.Arrays; + import com.yahoo.labs.samoa.instances.Instance; /* micro cluster, as defined by Aggarwal et al, On Clustering Massive Data Streams: A Summarization Praradigm diff --git a/moa/src/main/java/moa/cluster/Cluster.java b/moa/src/main/java/moa/cluster/Cluster.java index 42c175c24..caab641ed 100644 --- a/moa/src/main/java/moa/cluster/Cluster.java +++ b/moa/src/main/java/moa/cluster/Cluster.java @@ -25,9 +25,11 @@ import java.util.Iterator; import java.util.Map; import java.util.Random; -import moa.AbstractMOAObject; + import com.yahoo.labs.samoa.instances.Instance; +import moa.AbstractMOAObject; + public abstract class Cluster extends AbstractMOAObject { private static final long serialVersionUID = 1L; diff --git a/moa/src/main/java/moa/cluster/Clustering.java b/moa/src/main/java/moa/cluster/Clustering.java index 079e1b3ef..afc47799d 100644 --- a/moa/src/main/java/moa/cluster/Clustering.java +++ b/moa/src/main/java/moa/cluster/Clustering.java @@ -28,11 +28,13 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; + +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.Instance; + import moa.AbstractMOAObject; import moa.core.AutoExpandVector; import moa.gui.visualization.DataPoint; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.Instance; public class Clustering extends AbstractMOAObject{ diff --git a/moa/src/main/java/moa/cluster/SphereCluster.java b/moa/src/main/java/moa/cluster/SphereCluster.java index 0991500dc..533ba108e 100644 --- a/moa/src/main/java/moa/cluster/SphereCluster.java +++ b/moa/src/main/java/moa/cluster/SphereCluster.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; + import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/clusterers/AbstractClusterer.java b/moa/src/main/java/moa/clusterers/AbstractClusterer.java index a8f23f48e..3e32c4d50 100644 --- a/moa/src/main/java/moa/clusterers/AbstractClusterer.java +++ b/moa/src/main/java/moa/clusterers/AbstractClusterer.java @@ -22,19 +22,19 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; -import moa.cluster.Clustering; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; + +import moa.cluster.Clustering; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.StringUtils; import moa.gui.AWTRenderer; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public abstract class AbstractClusterer extends AbstractOptionHandler implements Clusterer { diff --git a/moa/src/main/java/moa/clusterers/ClusterGenerator.java b/moa/src/main/java/moa/clusterers/ClusterGenerator.java index 2c1a5cd63..4ad2e09f8 100644 --- a/moa/src/main/java/moa/clusterers/ClusterGenerator.java +++ b/moa/src/main/java/moa/clusterers/ClusterGenerator.java @@ -23,13 +23,15 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Random; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.core.Measurement; import moa.gui.visualization.DataPoint; -import com.yahoo.labs.samoa.instances.Instance; public class ClusterGenerator extends AbstractClusterer{ diff --git a/moa/src/main/java/moa/clusterers/Clusterer.java b/moa/src/main/java/moa/clusterers/Clusterer.java index b018b421f..b7badff51 100644 --- a/moa/src/main/java/moa/clusterers/Clusterer.java +++ b/moa/src/main/java/moa/clusterers/Clusterer.java @@ -19,13 +19,14 @@ */ package moa.clusterers; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.MOAObject; import moa.cluster.Clustering; import moa.core.Measurement; import moa.gui.AWTRenderable; import moa.options.OptionHandler; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public interface Clusterer extends MOAObject, OptionHandler, AWTRenderable { diff --git a/moa/src/main/java/moa/clusterers/CobWeb.java b/moa/src/main/java/moa/clusterers/CobWeb.java index 03e34a5f9..6f315ba9e 100644 --- a/moa/src/main/java/moa/clusterers/CobWeb.java +++ b/moa/src/main/java/moa/clusterers/CobWeb.java @@ -21,16 +21,16 @@ import java.io.Serializable; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.cluster.Clustering; import moa.cluster.SphereCluster; +import moa.core.FastVector; import moa.core.Measurement; import moa.core.StringUtils; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import moa.core.FastVector; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; import weka.core.AttributeStats; import weka.experiment.Stats; import weka.filters.unsupervised.attribute.Add; diff --git a/moa/src/main/java/moa/clusterers/KMeans.java b/moa/src/main/java/moa/clusterers/KMeans.java index b7014b5f7..d509f26a7 100644 --- a/moa/src/main/java/moa/clusterers/KMeans.java +++ b/moa/src/main/java/moa/clusterers/KMeans.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; + import moa.cluster.CFCluster; import moa.cluster.Cluster; import moa.cluster.Clustering; diff --git a/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java b/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java index 978290119..ef5ddaeda 100644 --- a/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java +++ b/moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java @@ -21,21 +21,22 @@ import java.util.ArrayList; import java.util.List; -import moa.cluster.Clustering; -import moa.core.AutoClassDiscovery; -import moa.core.AutoExpandVector; -import moa.core.Measurement; -import moa.options.ClassOption; + import com.github.javacliparser.IntOption; import com.github.javacliparser.MultiChoiceOption; import com.github.javacliparser.StringOption; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; +import moa.cluster.Clustering; +import moa.core.AutoClassDiscovery; +import moa.core.AutoExpandVector; +import moa.core.FastVector; +import moa.core.Measurement; +import moa.options.ClassOption; import weka.core.Utils; public class WekaClusteringAlgorithm extends AbstractClusterer { diff --git a/moa/src/main/java/moa/clusterers/clustream/Clustream.java b/moa/src/main/java/moa/clusterers/clustream/Clustream.java index 85edb1c81..b10a2e029 100644 --- a/moa/src/main/java/moa/clusterers/clustream/Clustream.java +++ b/moa/src/main/java/moa/clusterers/clustream/Clustream.java @@ -24,14 +24,16 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; + +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.clusterers.AbstractClusterer; import moa.core.Measurement; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; /** Citation: CluStream: Charu C. Aggarwal, Jiawei Han, Jianyong Wang, Philip S. Yu: * A Framework for Clustering Evolving Data Streams. VLDB 2003: 81-92 diff --git a/moa/src/main/java/moa/clusterers/clustream/ClustreamKernel.java b/moa/src/main/java/moa/clusterers/clustream/ClustreamKernel.java index 83ae0324d..73ef8a6a7 100644 --- a/moa/src/main/java/moa/clusterers/clustream/ClustreamKernel.java +++ b/moa/src/main/java/moa/clusterers/clustream/ClustreamKernel.java @@ -20,10 +20,11 @@ package moa.clusterers.clustream; import java.util.ArrayList; -import java.util.Random; -import moa.cluster.CFCluster; + import com.yahoo.labs.samoa.instances.Instance; +import moa.cluster.CFCluster; + public class ClustreamKernel extends CFCluster { private static final long serialVersionUID = 1L; diff --git a/moa/src/main/java/moa/clusterers/clustream/WithKmeans.java b/moa/src/main/java/moa/clusterers/clustream/WithKmeans.java index 281c02813..175e1137e 100644 --- a/moa/src/main/java/moa/clusterers/clustream/WithKmeans.java +++ b/moa/src/main/java/moa/clusterers/clustream/WithKmeans.java @@ -32,15 +32,16 @@ import java.util.List; import java.util.Random; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.CFCluster; import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.clusterers.AbstractClusterer; import moa.core.Measurement; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; public class WithKmeans extends AbstractClusterer { diff --git a/moa/src/main/java/moa/clusterers/clustree/ClusKernel.java b/moa/src/main/java/moa/clusterers/clustree/ClusKernel.java index 025f86f92..fdddc6f31 100644 --- a/moa/src/main/java/moa/clusterers/clustree/ClusKernel.java +++ b/moa/src/main/java/moa/clusterers/clustree/ClusKernel.java @@ -20,11 +20,12 @@ package moa.clusterers.clustree; -import moa.clusterers.clustree.util.*; import java.util.Arrays; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.CFCluster; import moa.cluster.Cluster; -import com.yahoo.labs.samoa.instances.Instance; /** * Representation of an Entry in the tree diff --git a/moa/src/main/java/moa/clusterers/clustree/ClusTree.java b/moa/src/main/java/moa/clusterers/clustree/ClusTree.java index 1b5891461..034e182ad 100644 --- a/moa/src/main/java/moa/clusterers/clustree/ClusTree.java +++ b/moa/src/main/java/moa/clusterers/clustree/ClusTree.java @@ -21,15 +21,22 @@ package moa.clusterers.clustree; import java.util.ArrayList; - import java.util.LinkedList; -import moa.clusterers.clustree.util.*; + +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; +import moa.clusterers.clustree.util.Budget; +import moa.clusterers.clustree.util.SimpleBudget; import moa.core.Measurement; +<<<<<<< c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 import com.github.javacliparser.IntOption; import com.github.javacliparser.FlagOption; import com.yahoo.labs.samoa.instances.Instance; +======= +>>>>>>> Instances rework, new iSOUPTree models and import cleanup /** * Citation: ClusTree: Philipp Kranen, Ira Assent, Corinna Baldauf, Thomas Seidl: diff --git a/moa/src/main/java/moa/clusterers/denstream/MicroCluster.java b/moa/src/main/java/moa/clusterers/denstream/MicroCluster.java index 4b98a5606..cf6c25dba 100644 --- a/moa/src/main/java/moa/clusterers/denstream/MicroCluster.java +++ b/moa/src/main/java/moa/clusterers/denstream/MicroCluster.java @@ -19,9 +19,10 @@ */ package moa.clusterers.denstream; -import moa.cluster.CFCluster; import com.yahoo.labs.samoa.instances.Instance; +import moa.cluster.CFCluster; + public class MicroCluster extends CFCluster { private long lastEditT = -1; diff --git a/moa/src/main/java/moa/clusterers/denstream/WithDBSCAN.java b/moa/src/main/java/moa/clusterers/denstream/WithDBSCAN.java index fbc55d462..f243d664a 100644 --- a/moa/src/main/java/moa/clusterers/denstream/WithDBSCAN.java +++ b/moa/src/main/java/moa/clusterers/denstream/WithDBSCAN.java @@ -26,15 +26,16 @@ import java.util.ArrayList; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; import moa.clusterers.macro.dbscan.DBScan; import moa.core.Measurement; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; public class WithDBSCAN extends AbstractClusterer { diff --git a/moa/src/main/java/moa/clusterers/macro/NonConvexCluster.java b/moa/src/main/java/moa/clusterers/macro/NonConvexCluster.java index d264f8564..e132b69d2 100644 --- a/moa/src/main/java/moa/clusterers/macro/NonConvexCluster.java +++ b/moa/src/main/java/moa/clusterers/macro/NonConvexCluster.java @@ -26,9 +26,10 @@ import java.util.List; import java.util.Vector; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.CFCluster; import moa.cluster.Clustering; -import com.yahoo.labs.samoa.instances.Instance; public class NonConvexCluster extends CFCluster implements IDenseMacroCluster { diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractC.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractC.java index 4b67c3e78..9ac25bf0a 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractC.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractC.java @@ -21,13 +21,15 @@ package moa.clusterers.outliers.AbstractC; import java.util.Vector; -import moa.clusterers.outliers.AbstractC.ISBIndex.ISBNode; -import moa.clusterers.outliers.AbstractC.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.AbstractC.ISBIndex.ISBNode; +import moa.clusterers.outliers.AbstractC.ISBIndex.ISBSearchResult; + //The algorithm is presented in: //D. Yang, E. Rundensteiner, and M. Ward. //Neighbor-based pattern detection for windows over streaming data. diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractCBase.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractCBase.java index 6e39b8360..67150fa8b 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractCBase.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractCBase.java @@ -23,8 +23,9 @@ import java.util.ArrayList; import java.util.Vector; -import moa.clusterers.outliers.AbstractC.ISBIndex.ISBNode; + import moa.clusterers.outliers.MyBaseOutlierDetector; +import moa.clusterers.outliers.AbstractC.ISBIndex.ISBNode; public abstract class AbstractCBase extends MyBaseOutlierDetector { protected static final Long FIRST_OBJ_ID = 1L; diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/ISBIndex.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/ISBIndex.java index 9a0be6f04..26c4292ad 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/ISBIndex.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/ISBIndex.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Set; import java.util.Vector; + import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/MyMTree.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/MyMTree.java index af419a92f..5a2f5d531 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/MyMTree.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/MyMTree.java @@ -22,6 +22,7 @@ package moa.clusterers.outliers.AbstractC; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/AbstractC/Test.java b/moa/src/main/java/moa/clusterers/outliers/AbstractC/Test.java index 430a2c82f..46cc09f59 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AbstractC/Test.java +++ b/moa/src/main/java/moa/clusterers/outliers/AbstractC/Test.java @@ -21,9 +21,10 @@ package moa.clusterers.outliers.AbstractC; -import moa.streams.clustering.RandomRBFGeneratorEvents; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.clustering.RandomRBFGeneratorEvents; + public class Test { public static void main(String[] args) throws Exception { diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ApproxSTORM.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ApproxSTORM.java index 4eb279806..7b965ee9c 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ApproxSTORM.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ApproxSTORM.java @@ -26,12 +26,14 @@ import java.util.Random; import java.util.Set; import java.util.Vector; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBSearchResult; + public class ApproxSTORM extends STORMBase { public class ISBNodeAppr extends ISBNode { diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ExactSTORM.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ExactSTORM.java index 7bcd76f2f..652632ae1 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ExactSTORM.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ExactSTORM.java @@ -24,12 +24,14 @@ import java.util.Collections; import java.util.Iterator; import java.util.Vector; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBSearchResult; + // The algorithm is presented in "Distance-based outlier queries in data streams: the novel task and algorithms. //Data Mining and Knowledge Discovery, 20(2):290–324,2010. diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ISBIndex.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ISBIndex.java index c92781052..47bb87b5c 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/ISBIndex.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/ISBIndex.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Set; import java.util.Vector; + import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/MyMTree.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/MyMTree.java index e71e17623..96ba2625c 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/MyMTree.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/MyMTree.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.Angiulli; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/STORMBase.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/STORMBase.java index 7cc8b4f80..d1e2cbf28 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/STORMBase.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/STORMBase.java @@ -21,10 +21,12 @@ package moa.clusterers.outliers.Angiulli; import java.util.Vector; -import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; -import moa.clusterers.outliers.MyBaseOutlierDetector; + import com.github.javacliparser.FlagOption; +import moa.clusterers.outliers.MyBaseOutlierDetector; +import moa.clusterers.outliers.Angiulli.ISBIndex.ISBNode; + public abstract class STORMBase extends MyBaseOutlierDetector { public FlagOption waitWinFullOption = new FlagOption("waitWinFull", 'a', "Output outliers when windows is full."); diff --git a/moa/src/main/java/moa/clusterers/outliers/Angiulli/Test.java b/moa/src/main/java/moa/clusterers/outliers/Angiulli/Test.java index 4921d99f7..dc6de05d5 100644 --- a/moa/src/main/java/moa/clusterers/outliers/Angiulli/Test.java +++ b/moa/src/main/java/moa/clusterers/outliers/Angiulli/Test.java @@ -20,9 +20,10 @@ package moa.clusterers.outliers.Angiulli; -import moa.streams.clustering.RandomRBFGeneratorEvents; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.clustering.RandomRBFGeneratorEvents; + public class Test { public static void main(String[] args) throws Exception diff --git a/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOut.java b/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOut.java index 6086e6964..16e4a0f45 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOut.java +++ b/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOut.java @@ -21,9 +21,11 @@ package moa.clusterers.outliers.AnyOut; +import java.util.ArrayList; + import com.github.javacliparser.Options; import com.yahoo.labs.samoa.instances.Instance; -import java.util.ArrayList; + import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.AnyOut.util.DataObject; import moa.clusterers.outliers.AnyOut.util.DataSet; diff --git a/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOutCore.java b/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOutCore.java index a714f2d10..a56728cc8 100644 --- a/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOutCore.java +++ b/moa/src/main/java/moa/clusterers/outliers/AnyOut/AnyOutCore.java @@ -21,12 +21,14 @@ package moa.clusterers.outliers.AnyOut; +import java.util.ArrayList; +import java.util.HashMap; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; -import java.util.ArrayList; -import java.util.HashMap; + import moa.clusterers.clustree.ClusKernel; import moa.clusterers.clustree.ClusTree; import moa.clusterers.clustree.Entry; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/ISBIndex.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/ISBIndex.java index d151e92dd..047c964ff 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/ISBIndex.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/ISBIndex.java @@ -30,6 +30,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.Vector; + import com.yahoo.labs.samoa.instances.Instance; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MCOD.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MCOD.java index 60ed3df4d..0d58e7b02 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MCOD.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MCOD.java @@ -23,13 +23,15 @@ import java.util.ArrayList; import java.util.TreeSet; import java.util.Vector; -import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode; -import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode.NodeType; -import moa.clusterers.outliers.MCOD.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode; +import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode.NodeType; +import moa.clusterers.outliers.MCOD.ISBIndex.ISBSearchResult; + //The algorithm is described in // M. Kontaki, A. Gounaris, A. N. Papadopoulos, K. Tsichlas, and Y. Manolopoulos. diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MCODBase.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MCODBase.java index 66548a726..94f7ba167 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MCODBase.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MCODBase.java @@ -25,9 +25,10 @@ import java.util.Set; import java.util.TreeSet; import java.util.Vector; + +import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode; import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode.NodeType; -import moa.clusterers.outliers.MyBaseOutlierDetector; public abstract class MCODBase extends MyBaseOutlierDetector { protected static class EventItem implements Comparable { diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeMicroClusters.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeMicroClusters.java index 575b42b63..42be983f2 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeMicroClusters.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeMicroClusters.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.MCOD; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeStreamObjects.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeStreamObjects.java index 77679064b..20f44c653 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeStreamObjects.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeStreamObjects.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.MCOD; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/MicroCluster.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/MicroCluster.java index 8b8fd6a1d..40741a868 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/MicroCluster.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/MicroCluster.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.MCOD; import java.util.ArrayList; + import moa.clusterers.outliers.MCOD.ISBIndex.ISBNode; import moa.clusterers.outliers.utils.mtree.DistanceFunctions.EuclideanCoordinate; diff --git a/moa/src/main/java/moa/clusterers/outliers/MCOD/Test.java b/moa/src/main/java/moa/clusterers/outliers/MCOD/Test.java index d22e61aaf..5b8474cab 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MCOD/Test.java +++ b/moa/src/main/java/moa/clusterers/outliers/MCOD/Test.java @@ -20,9 +20,10 @@ package moa.clusterers.outliers.MCOD; -import moa.streams.clustering.RandomRBFGeneratorEvents; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.clustering.RandomRBFGeneratorEvents; + public class Test { public static void main(String[] args) throws Exception diff --git a/moa/src/main/java/moa/clusterers/outliers/MyBaseOutlierDetector.java b/moa/src/main/java/moa/clusterers/outliers/MyBaseOutlierDetector.java index a9be5efb7..1ffe3e98a 100644 --- a/moa/src/main/java/moa/clusterers/outliers/MyBaseOutlierDetector.java +++ b/moa/src/main/java/moa/clusterers/outliers/MyBaseOutlierDetector.java @@ -27,13 +27,15 @@ import java.util.Set; import java.util.TreeSet; import java.util.Vector; + +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.clusterers.AbstractClusterer; import moa.core.Measurement; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; public abstract class MyBaseOutlierDetector extends AbstractClusterer { public static class Outlier implements Comparable { diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/ISBIndex.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/ISBIndex.java index e088c2edb..4a12a6459 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/ISBIndex.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/ISBIndex.java @@ -30,6 +30,7 @@ import java.util.Map; import java.util.Set; import java.util.Vector; + import com.yahoo.labs.samoa.instances.Instance; public class ISBIndex { diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/MyMTree.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/MyMTree.java index 9cfa7e925..722ee5687 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/MyMTree.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/MyMTree.java @@ -21,6 +21,7 @@ package moa.clusterers.outliers.SimpleCOD; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.ComposedSplitFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunction; import moa.clusterers.outliers.utils.mtree.DistanceFunctions; diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCOD.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCOD.java index c7ed23161..2e8a1fb80 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCOD.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCOD.java @@ -21,12 +21,14 @@ package moa.clusterers.outliers.SimpleCOD; import java.util.Vector; -import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBNode; -import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBSearchResult; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; +import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBNode; +import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBSearchResult; + ////The algorithm is described in // M. Kontaki, A. Gounaris, A. N. Papadopoulos, K. Tsichlas, and Y. Manolopoulos. diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCODBase.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCODBase.java index b94e0992f..cd8ac90d3 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCODBase.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCODBase.java @@ -24,6 +24,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.Vector; + import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.SimpleCOD.ISBIndex.ISBNode; diff --git a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/Test.java b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/Test.java index 8039566ff..a8ed48e79 100644 --- a/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/Test.java +++ b/moa/src/main/java/moa/clusterers/outliers/SimpleCOD/Test.java @@ -20,9 +20,10 @@ package moa.clusterers.outliers.SimpleCOD; -import moa.streams.ArffFileStream; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.ArffFileStream; + public class Test { public static void main(String[] args) throws Exception diff --git a/moa/src/main/java/moa/clusterers/outliers/TestSpeed.java b/moa/src/main/java/moa/clusterers/outliers/TestSpeed.java index 019b74f91..31e903388 100644 --- a/moa/src/main/java/moa/clusterers/outliers/TestSpeed.java +++ b/moa/src/main/java/moa/clusterers/outliers/TestSpeed.java @@ -20,12 +20,13 @@ package moa.clusterers.outliers; +import com.yahoo.labs.samoa.instances.Instance; + import moa.clusterers.outliers.AbstractC.AbstractC; import moa.clusterers.outliers.Angiulli.ExactSTORM; import moa.clusterers.outliers.MCOD.MCOD; import moa.clusterers.outliers.SimpleCOD.SimpleCOD; import moa.streams.clustering.RandomRBFGeneratorEvents; -import com.yahoo.labs.samoa.instances.Instance; public class TestSpeed { public static void main(String[] args) throws Exception diff --git a/moa/src/main/java/moa/clusterers/outliers/utils/mtree/MTree.java b/moa/src/main/java/moa/clusterers/outliers/utils/mtree/MTree.java index 9c135a799..e2c8db618 100644 --- a/moa/src/main/java/moa/clusterers/outliers/utils/mtree/MTree.java +++ b/moa/src/main/java/moa/clusterers/outliers/utils/mtree/MTree.java @@ -24,6 +24,7 @@ import java.util.NoSuchElementException; import java.util.PriorityQueue; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.SplitFunction.SplitResult; diff --git a/moa/src/main/java/moa/clusterers/outliers/utils/mtree/PromotionFunctions.java b/moa/src/main/java/moa/clusterers/outliers/utils/mtree/PromotionFunctions.java index d7aa38ba4..b603935b4 100644 --- a/moa/src/main/java/moa/clusterers/outliers/utils/mtree/PromotionFunctions.java +++ b/moa/src/main/java/moa/clusterers/outliers/utils/mtree/PromotionFunctions.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Set; + import moa.clusterers.outliers.utils.mtree.utils.Pair; import moa.clusterers.outliers.utils.mtree.utils.Utils; diff --git a/moa/src/main/java/moa/clusterers/streamkm/Point.java b/moa/src/main/java/moa/clusterers/streamkm/Point.java index 28fa9d232..b272a41d6 100644 --- a/moa/src/main/java/moa/clusterers/streamkm/Point.java +++ b/moa/src/main/java/moa/clusterers/streamkm/Point.java @@ -1,10 +1,10 @@ package moa.clusterers.streamkm; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.SphereCluster; -import com.yahoo.labs.samoa.instances.Instance; - /** * * @author Marcel R. Ackermann, Christiane Lammersen, Marcus Maertens, Christoph Raupach, diff --git a/moa/src/main/java/moa/clusterers/streamkm/StreamKM.java b/moa/src/main/java/moa/clusterers/streamkm/StreamKM.java index ac66163eb..599db86f8 100644 --- a/moa/src/main/java/moa/clusterers/streamkm/StreamKM.java +++ b/moa/src/main/java/moa/clusterers/streamkm/StreamKM.java @@ -1,10 +1,11 @@ package moa.clusterers.streamkm; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.Instance; /** * diff --git a/moa/src/main/java/moa/core/AutoClassDiscovery.java b/moa/src/main/java/moa/core/AutoClassDiscovery.java index 9b085e5ca..d8e456893 100644 --- a/moa/src/main/java/moa/core/AutoClassDiscovery.java +++ b/moa/src/main/java/moa/core/AutoClassDiscovery.java @@ -21,9 +21,9 @@ import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; diff --git a/moa/src/main/java/moa/core/AutoExpandVector.java b/moa/src/main/java/moa/core/AutoExpandVector.java index 33c3ed53e..938f70a78 100644 --- a/moa/src/main/java/moa/core/AutoExpandVector.java +++ b/moa/src/main/java/moa/core/AutoExpandVector.java @@ -121,7 +121,7 @@ public MOAObject copy() { } @Override - public int measureByteSize() { + public long measureByteSize() { return AbstractMOAObject.measureByteSize(this); } diff --git a/moa/src/main/java/moa/core/MultilabelInstancesHeader.java b/moa/src/main/java/moa/core/MultilabelInstancesHeader.java index b8dc3b3c2..7ae45510a 100644 --- a/moa/src/main/java/moa/core/MultilabelInstancesHeader.java +++ b/moa/src/main/java/moa/core/MultilabelInstancesHeader.java @@ -19,7 +19,6 @@ */ package moa.core; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.InstancesHeader; /** diff --git a/moa/src/main/java/moa/core/Utils.java b/moa/src/main/java/moa/core/Utils.java index ecb4cf19d..d3ec5a4e2 100644 --- a/moa/src/main/java/moa/core/Utils.java +++ b/moa/src/main/java/moa/core/Utils.java @@ -21,17 +21,9 @@ package moa.core; -import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.FileWriter; import java.lang.reflect.Array; -import java.net.URL; import java.text.BreakIterator; -import java.util.Enumeration; -import java.util.Properties; import java.util.Random; import java.util.Vector; diff --git a/moa/src/main/java/moa/core/utils/Converter.java b/moa/src/main/java/moa/core/utils/Converter.java index a3f976c38..5a06a8490 100755 --- a/moa/src/main/java/moa/core/utils/Converter.java +++ b/moa/src/main/java/moa/core/utils/Converter.java @@ -21,10 +21,12 @@ import java.util.LinkedList; import java.util.List; -import moa.AbstractMOAObject; + import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.AbstractMOAObject; + /** * Converter. This class can be used to convert a multi-label instance into a * single-label instance. diff --git a/moa/src/main/java/moa/evaluation/Accuracy.java b/moa/src/main/java/moa/evaluation/Accuracy.java index d8925799d..049ef9913 100644 --- a/moa/src/main/java/moa/evaluation/Accuracy.java +++ b/moa/src/main/java/moa/evaluation/Accuracy.java @@ -20,6 +20,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/AdwinClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/AdwinClassificationPerformanceEvaluator.java index a0c79202c..aea7cf19e 100644 --- a/moa/src/main/java/moa/evaluation/AdwinClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/AdwinClassificationPerformanceEvaluator.java @@ -19,7 +19,6 @@ */ package moa.evaluation; -import com.github.javacliparser.IntOption; import moa.classifiers.core.driftdetection.ADWIN; /** diff --git a/moa/src/main/java/moa/evaluation/BasicClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicClassificationPerformanceEvaluator.java index f2bba1612..eeb29f978 100644 --- a/moa/src/main/java/moa/evaluation/BasicClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicClassificationPerformanceEvaluator.java @@ -20,20 +20,18 @@ */ package moa.evaluation; -import moa.AbstractMOAObject; +import java.io.Serializable; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.Utils; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; import moa.options.AbstractOptionHandler; import moa.tasks.TaskMonitor; -import java.io.Serializable; - /** * Classification evaluator that performs basic incremental evaluation. * diff --git a/moa/src/main/java/moa/evaluation/BasicConceptDriftPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicConceptDriftPerformanceEvaluator.java index d5df7cf06..40057d4cc 100644 --- a/moa/src/main/java/moa/evaluation/BasicConceptDriftPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicConceptDriftPerformanceEvaluator.java @@ -20,7 +20,6 @@ package moa.evaluation; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; import com.yahoo.labs.samoa.instances.Prediction; import moa.AbstractMOAObject; diff --git a/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java index 33e6b18d1..d18061094 100644 --- a/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java @@ -19,14 +19,14 @@ */ package moa.evaluation; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.AbstractMOAObject; import moa.core.Example; import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Multilabel Window Classification Performance Evaluator. * diff --git a/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java index 5b87a670b..0f522b1e6 100644 --- a/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java @@ -19,17 +19,14 @@ */ package moa.evaluation; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.AbstractMOAObject; import moa.core.Example; import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.DenseInstanceData; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Regression evaluator that performs basic incremental evaluation. * diff --git a/moa/src/main/java/moa/evaluation/BasicRegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/BasicRegressionPerformanceEvaluator.java index 3948cfeba..f4ca38547 100644 --- a/moa/src/main/java/moa/evaluation/BasicRegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/BasicRegressionPerformanceEvaluator.java @@ -19,14 +19,13 @@ */ package moa.evaluation; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + import moa.AbstractMOAObject; import moa.core.Example; import moa.core.Measurement; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Regression evaluator that performs basic incremental evaluation. * diff --git a/moa/src/main/java/moa/evaluation/CMM_GTAnalysis.java b/moa/src/main/java/moa/evaluation/CMM_GTAnalysis.java index 204909e2e..db4f8273b 100644 --- a/moa/src/main/java/moa/evaluation/CMM_GTAnalysis.java +++ b/moa/src/main/java/moa/evaluation/CMM_GTAnalysis.java @@ -36,10 +36,12 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.core.AutoExpandVector; import moa.gui.visualization.DataPoint; -import com.yahoo.labs.samoa.instances.Instance; public class CMM_GTAnalysis{ diff --git a/moa/src/main/java/moa/evaluation/ChangeDetectionMeasures.java b/moa/src/main/java/moa/evaluation/ChangeDetectionMeasures.java index c40dda432..faccffcc6 100644 --- a/moa/src/main/java/moa/evaluation/ChangeDetectionMeasures.java +++ b/moa/src/main/java/moa/evaluation/ChangeDetectionMeasures.java @@ -21,6 +21,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/ClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/ClassificationPerformanceEvaluator.java index 0eb9176c9..d1a6ba878 100644 --- a/moa/src/main/java/moa/evaluation/ClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/ClassificationPerformanceEvaluator.java @@ -20,9 +20,8 @@ package moa.evaluation; import com.yahoo.labs.samoa.instances.Instance; -import moa.MOAObject; + import moa.core.Example; -import moa.core.Measurement; public interface ClassificationPerformanceEvaluator extends LearningPerformanceEvaluator> { diff --git a/moa/src/main/java/moa/evaluation/EWMAClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/EWMAClassificationPerformanceEvaluator.java index 31f8ace8f..04a33adf2 100644 --- a/moa/src/main/java/moa/evaluation/EWMAClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/EWMAClassificationPerformanceEvaluator.java @@ -19,21 +19,8 @@ */ package moa.evaluation; -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; - import com.github.javacliparser.FloatOption; -import moa.options.AbstractOptionHandler; -import moa.tasks.TaskMonitor; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - -import moa.core.Utils; - /** * Classification evaluator that updates evaluation results using an Exponential Weighted Moving Average. * diff --git a/moa/src/main/java/moa/evaluation/EntropyCollection.java b/moa/src/main/java/moa/evaluation/EntropyCollection.java index 53a67226b..dcf04e018 100644 --- a/moa/src/main/java/moa/evaluation/EntropyCollection.java +++ b/moa/src/main/java/moa/evaluation/EntropyCollection.java @@ -21,6 +21,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/F1.java b/moa/src/main/java/moa/evaluation/F1.java index 36e3529ab..de214877c 100644 --- a/moa/src/main/java/moa/evaluation/F1.java +++ b/moa/src/main/java/moa/evaluation/F1.java @@ -20,6 +20,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/FadingFactorClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/FadingFactorClassificationPerformanceEvaluator.java index ed1cd700e..54bbe72e4 100644 --- a/moa/src/main/java/moa/evaluation/FadingFactorClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/FadingFactorClassificationPerformanceEvaluator.java @@ -19,20 +19,8 @@ */ package moa.evaluation; -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; - import com.github.javacliparser.FloatOption; -import moa.options.AbstractOptionHandler; -import moa.tasks.TaskMonitor; -import moa.core.Utils; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Classification evaluator that updates evaluation results using a fading factor. * diff --git a/moa/src/main/java/moa/evaluation/General.java b/moa/src/main/java/moa/evaluation/General.java index c50d1ca9f..90682d18b 100644 --- a/moa/src/main/java/moa/evaluation/General.java +++ b/moa/src/main/java/moa/evaluation/General.java @@ -22,10 +22,12 @@ import java.util.ArrayList; + +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.gui.visualization.DataPoint; -import com.yahoo.labs.samoa.instances.Instance; public class General extends MeasureCollection{ private int numPoints; diff --git a/moa/src/main/java/moa/evaluation/LearningEvaluation.java b/moa/src/main/java/moa/evaluation/LearningEvaluation.java index e03d8aaed..70bb17315 100644 --- a/moa/src/main/java/moa/evaluation/LearningEvaluation.java +++ b/moa/src/main/java/moa/evaluation/LearningEvaluation.java @@ -24,10 +24,8 @@ import java.util.List; import moa.AbstractMOAObject; -import moa.classifiers.Classifier; -import moa.clusterers.Clusterer; -import moa.learners.Learner; import moa.core.Measurement; +import moa.learners.Learner; /** * Class that stores an array of evaluation measurements. diff --git a/moa/src/main/java/moa/evaluation/LearningPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/LearningPerformanceEvaluator.java index 49b44c3c2..820886e1d 100644 --- a/moa/src/main/java/moa/evaluation/LearningPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/LearningPerformanceEvaluator.java @@ -19,7 +19,6 @@ */ package moa.evaluation; -import com.yahoo.labs.samoa.instances.InstanceData; import com.yahoo.labs.samoa.instances.Prediction; import moa.MOAObject; diff --git a/moa/src/main/java/moa/evaluation/MeasureCollection.java b/moa/src/main/java/moa/evaluation/MeasureCollection.java index 85b08ac8b..0016239e7 100644 --- a/moa/src/main/java/moa/evaluation/MeasureCollection.java +++ b/moa/src/main/java/moa/evaluation/MeasureCollection.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.HashMap; + import moa.AbstractMOAObject; import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/MembershipMatrix.java b/moa/src/main/java/moa/evaluation/MembershipMatrix.java index b139683df..d29777667 100644 --- a/moa/src/main/java/moa/evaluation/MembershipMatrix.java +++ b/moa/src/main/java/moa/evaluation/MembershipMatrix.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.HashMap; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/MultiTargetPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/MultiTargetPerformanceEvaluator.java index 38d2c10d1..166f3fe24 100644 --- a/moa/src/main/java/moa/evaluation/MultiTargetPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/MultiTargetPerformanceEvaluator.java @@ -19,9 +19,10 @@ */ package moa.evaluation; -import moa.core.Example; import com.yahoo.labs.samoa.instances.Instance; +import moa.core.Example; + /** * Interface implemented by learner evaluators to monitor diff --git a/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java index 24d45642d..0e8323c07 100644 --- a/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/MultiTargetWindowRegressionPerformanceEvaluator.java @@ -19,20 +19,17 @@ */ package moa.evaluation; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; - -import com.github.javacliparser.IntOption; - import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Multi-target regression evaluator that updates evaluation results using a sliding window. * diff --git a/moa/src/main/java/moa/evaluation/OutlierPerformance.java b/moa/src/main/java/moa/evaluation/OutlierPerformance.java index f940a631c..298472f54 100644 --- a/moa/src/main/java/moa/evaluation/OutlierPerformance.java +++ b/moa/src/main/java/moa/evaluation/OutlierPerformance.java @@ -21,7 +21,7 @@ package moa.evaluation; import java.util.ArrayList; -import java.util.Arrays; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/RegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/RegressionPerformanceEvaluator.java index 4934ab79f..78513adb7 100644 --- a/moa/src/main/java/moa/evaluation/RegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/RegressionPerformanceEvaluator.java @@ -19,9 +19,10 @@ */ package moa.evaluation; -import moa.core.Example; import com.yahoo.labs.samoa.instances.Instance; +import moa.core.Example; + /** * Interface implemented by learner evaluators to monitor diff --git a/moa/src/main/java/moa/evaluation/SSQ.java b/moa/src/main/java/moa/evaluation/SSQ.java index 34e6dc4ba..37fab259e 100644 --- a/moa/src/main/java/moa/evaluation/SSQ.java +++ b/moa/src/main/java/moa/evaluation/SSQ.java @@ -21,6 +21,7 @@ package moa.evaluation; import java.util.ArrayList; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/Separation.java b/moa/src/main/java/moa/evaluation/Separation.java index 46a151262..fd5c9fbf8 100644 --- a/moa/src/main/java/moa/evaluation/Separation.java +++ b/moa/src/main/java/moa/evaluation/Separation.java @@ -1,5 +1,8 @@ package moa.evaluation; +import java.util.ArrayList; +import java.util.List; + /* * #%L * SAMOA @@ -22,14 +25,12 @@ import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.gui.visualization.DataPoint; -import java.util.ArrayList; -import java.util.List; - public class Separation extends MeasureCollection { public Separation() { diff --git a/moa/src/main/java/moa/evaluation/SilhouetteCoefficient.java b/moa/src/main/java/moa/evaluation/SilhouetteCoefficient.java index 5f2697155..c58a7a8da 100644 --- a/moa/src/main/java/moa/evaluation/SilhouetteCoefficient.java +++ b/moa/src/main/java/moa/evaluation/SilhouetteCoefficient.java @@ -21,7 +21,7 @@ package moa.evaluation; import java.util.ArrayList; -import java.util.HashMap; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/StatisticalCollection.java b/moa/src/main/java/moa/evaluation/StatisticalCollection.java index be51d4605..74f9576d1 100644 --- a/moa/src/main/java/moa/evaluation/StatisticalCollection.java +++ b/moa/src/main/java/moa/evaluation/StatisticalCollection.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Arrays; + import moa.cluster.Clustering; import moa.gui.visualization.DataPoint; diff --git a/moa/src/main/java/moa/evaluation/WindowClassificationPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/WindowClassificationPerformanceEvaluator.java index 31b9f3ef4..c6df7de30 100644 --- a/moa/src/main/java/moa/evaluation/WindowClassificationPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/WindowClassificationPerformanceEvaluator.java @@ -19,20 +19,8 @@ */ package moa.evaluation; -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; -import moa.options.AbstractOptionHandler; - import com.github.javacliparser.IntOption; -import moa.tasks.TaskMonitor; -import moa.core.Utils; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Classification evaluator that updates evaluation results using a sliding * window. diff --git a/moa/src/main/java/moa/evaluation/WindowRegressionPerformanceEvaluator.java b/moa/src/main/java/moa/evaluation/WindowRegressionPerformanceEvaluator.java index 45d2f4e5a..280893b11 100644 --- a/moa/src/main/java/moa/evaluation/WindowRegressionPerformanceEvaluator.java +++ b/moa/src/main/java/moa/evaluation/WindowRegressionPerformanceEvaluator.java @@ -19,19 +19,16 @@ */ package moa.evaluation; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; - -import com.github.javacliparser.IntOption; - import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - /** * Regression evaluator that updates evaluation results using a sliding window. * diff --git a/moa/src/main/java/moa/gui/BatchCmd.java b/moa/src/main/java/moa/gui/BatchCmd.java index c793093c1..eacbc966f 100644 --- a/moa/src/main/java/moa/gui/BatchCmd.java +++ b/moa/src/main/java/moa/gui/BatchCmd.java @@ -32,6 +32,9 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; + import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; import moa.clusterers.ClusterGenerator; @@ -46,11 +49,9 @@ import moa.gui.visualization.DataPoint; import moa.gui.visualization.RunVisualizer; import moa.streams.clustering.ClusterEvent; -import com.yahoo.labs.samoa.instances.Instance; import moa.streams.clustering.ClusterEventListener; import moa.streams.clustering.ClusteringStream; import moa.streams.clustering.RandomRBFGeneratorEvents; -import com.yahoo.labs.samoa.instances.DenseInstance; public class BatchCmd implements ClusterEventListener{ diff --git a/moa/src/main/java/moa/gui/ClassOptionSelectionPanel.java b/moa/src/main/java/moa/gui/ClassOptionSelectionPanel.java index 16c2fbe74..239c42406 100644 --- a/moa/src/main/java/moa/gui/ClassOptionSelectionPanel.java +++ b/moa/src/main/java/moa/gui/ClassOptionSelectionPanel.java @@ -19,7 +19,6 @@ */ package moa.gui; -import com.github.javacliparser.gui.OptionsConfigurationPanel; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Window; @@ -32,6 +31,8 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; +import com.github.javacliparser.gui.OptionsConfigurationPanel; + import moa.core.AutoClassDiscovery; import moa.core.AutoExpandVector; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/gui/ClassOptionWithNamesSelectionPanel.java b/moa/src/main/java/moa/gui/ClassOptionWithNamesSelectionPanel.java index a0ba8a8c6..524199618 100644 --- a/moa/src/main/java/moa/gui/ClassOptionWithNamesSelectionPanel.java +++ b/moa/src/main/java/moa/gui/ClassOptionWithNamesSelectionPanel.java @@ -10,7 +10,6 @@ package moa.gui; -import com.github.javacliparser.gui.OptionsConfigurationPanel; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Window; @@ -23,6 +22,8 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; +import com.github.javacliparser.gui.OptionsConfigurationPanel; + import moa.core.AutoClassDiscovery; import moa.core.AutoExpandVector; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/gui/ConceptDriftTabPanel.java b/moa/src/main/java/moa/gui/ConceptDriftTabPanel.java index 5cd80e515..de248e6de 100644 --- a/moa/src/main/java/moa/gui/ConceptDriftTabPanel.java +++ b/moa/src/main/java/moa/gui/ConceptDriftTabPanel.java @@ -20,6 +20,7 @@ package moa.gui; import java.awt.BorderLayout; + import moa.gui.PreviewPanel.TypePanel; import moa.gui.conceptdrift.CDTaskManagerPanel; diff --git a/moa/src/main/java/moa/gui/GUI.java b/moa/src/main/java/moa/gui/GUI.java index 442566626..ae5be1a43 100644 --- a/moa/src/main/java/moa/gui/GUI.java +++ b/moa/src/main/java/moa/gui/GUI.java @@ -21,13 +21,11 @@ package moa.gui; import java.awt.BorderLayout; -import java.util.logging.Level; -import java.util.logging.Logger; + import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; -import javax.swing.UIManager.LookAndFeelInfo; -import javax.swing.UnsupportedLookAndFeelException; + import moa.DoTask; import moa.core.WekaUtils; diff --git a/moa/src/main/java/moa/gui/GUIDefaults.java b/moa/src/main/java/moa/gui/GUIDefaults.java index 5ff90ed57..466ff3b0c 100644 --- a/moa/src/main/java/moa/gui/GUIDefaults.java +++ b/moa/src/main/java/moa/gui/GUIDefaults.java @@ -20,15 +20,15 @@ */ package moa.gui; -import moa.core.PropertiesReader; -import moa.core.Utils; - import java.io.Serializable; import java.util.Collections; import java.util.Enumeration; import java.util.Properties; import java.util.Vector; +import moa.core.PropertiesReader; +import moa.core.Utils; + /** * This class offers get methods for the default GUI settings in * the props file moa/gui/GUI.props. diff --git a/moa/src/main/java/moa/gui/MultiTargetTabPanel.java b/moa/src/main/java/moa/gui/MultiTargetTabPanel.java index 955cad212..63ef5f263 100644 --- a/moa/src/main/java/moa/gui/MultiTargetTabPanel.java +++ b/moa/src/main/java/moa/gui/MultiTargetTabPanel.java @@ -20,6 +20,7 @@ package moa.gui; import java.awt.BorderLayout; + import moa.gui.PreviewPanel.TypePanel; /** diff --git a/moa/src/main/java/moa/gui/MultiTargetTaskManagerPanel.java b/moa/src/main/java/moa/gui/MultiTargetTaskManagerPanel.java index 01a9ea4cf..0d5745bd0 100644 --- a/moa/src/main/java/moa/gui/MultiTargetTaskManagerPanel.java +++ b/moa/src/main/java/moa/gui/MultiTargetTaskManagerPanel.java @@ -38,6 +38,7 @@ import java.util.ArrayList; import java.util.List; import java.util.prefs.Preferences; + import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; @@ -56,6 +57,7 @@ import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; + import moa.core.StringUtils; import moa.options.ClassOption; import moa.options.OptionHandler; diff --git a/moa/src/main/java/moa/gui/RegressionTabPanel.java b/moa/src/main/java/moa/gui/RegressionTabPanel.java index 372157ad8..ae99d364c 100644 --- a/moa/src/main/java/moa/gui/RegressionTabPanel.java +++ b/moa/src/main/java/moa/gui/RegressionTabPanel.java @@ -20,6 +20,7 @@ package moa.gui; import java.awt.BorderLayout; + import moa.gui.PreviewPanel.TypePanel; /** diff --git a/moa/src/main/java/moa/gui/RegressionTaskManagerPanel.java b/moa/src/main/java/moa/gui/RegressionTaskManagerPanel.java index 226421523..4d7fb91ab 100644 --- a/moa/src/main/java/moa/gui/RegressionTaskManagerPanel.java +++ b/moa/src/main/java/moa/gui/RegressionTaskManagerPanel.java @@ -23,13 +23,13 @@ import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; diff --git a/moa/src/main/java/moa/gui/TaskManagerPanel.java b/moa/src/main/java/moa/gui/TaskManagerPanel.java index 7ab117cf1..1eb3b29df 100644 --- a/moa/src/main/java/moa/gui/TaskManagerPanel.java +++ b/moa/src/main/java/moa/gui/TaskManagerPanel.java @@ -23,13 +23,13 @@ import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; diff --git a/moa/src/main/java/moa/gui/TaskTextViewerPanel.java b/moa/src/main/java/moa/gui/TaskTextViewerPanel.java index 6f250579c..195098150 100644 --- a/moa/src/main/java/moa/gui/TaskTextViewerPanel.java +++ b/moa/src/main/java/moa/gui/TaskTextViewerPanel.java @@ -40,9 +40,8 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; -import moa.evaluation.Accuracy; + import moa.evaluation.MeasureCollection; -import moa.evaluation.RegressionAccuracy; import moa.gui.PreviewPanel.TypePanel; import moa.gui.conceptdrift.CDTaskManagerPanel; import moa.streams.clustering.ClusterEvent; diff --git a/moa/src/main/java/moa/gui/WEKAClassOptionEditComponent.java b/moa/src/main/java/moa/gui/WEKAClassOptionEditComponent.java index 5288a0ce5..755326f70 100644 --- a/moa/src/main/java/moa/gui/WEKAClassOptionEditComponent.java +++ b/moa/src/main/java/moa/gui/WEKAClassOptionEditComponent.java @@ -20,12 +20,6 @@ */ package moa.gui; -import com.github.javacliparser.gui.OptionEditComponent; -import moa.core.Utils; -import weka.gui.GenericObjectEditor; -import weka.gui.PropertyDialog; -import weka.gui.GenericObjectEditor.GOEPanel; - import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -35,7 +29,13 @@ import javax.swing.JTextField; import com.github.javacliparser.Option; +import com.github.javacliparser.gui.OptionEditComponent; + +import moa.core.Utils; import moa.options.WEKAClassOption; +import weka.gui.GenericObjectEditor; +import weka.gui.GenericObjectEditor.GOEPanel; +import weka.gui.PropertyDialog; /** * An OptionEditComponent that lets the user edit a WEKA class option. diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringAlgoPanel.java b/moa/src/main/java/moa/gui/clustertab/ClusteringAlgoPanel.java index 0a04c98f9..61385baf7 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringAlgoPanel.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringAlgoPanel.java @@ -21,7 +21,6 @@ package moa.gui.clustertab; import java.awt.BorderLayout; - import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -32,20 +31,21 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; + import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; +import com.github.javacliparser.Option; +import com.github.javacliparser.gui.OptionEditComponent; +import com.github.javacliparser.gui.OptionsConfigurationPanel; + import moa.clusterers.AbstractClusterer; import moa.clusterers.Clusterer; import moa.gui.GUIUtils; -import com.github.javacliparser.gui.OptionEditComponent; -import com.github.javacliparser.gui.OptionsConfigurationPanel; import moa.options.ClassOption; -import com.github.javacliparser.Option; import moa.streams.clustering.ClusteringStream; -import moa.streams.generators.RandomRBFGenerator; public class ClusteringAlgoPanel extends javax.swing.JPanel implements ActionListener{ diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringEvalPanel.java b/moa/src/main/java/moa/gui/clustertab/ClusteringEvalPanel.java index eb9a57d81..9d94481db 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringEvalPanel.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringEvalPanel.java @@ -22,11 +22,12 @@ import java.awt.GridBagConstraints; import java.util.ArrayList; import java.util.logging.Logger; + import javax.swing.JCheckBox; import javax.swing.JLabel; + import moa.core.AutoClassDiscovery; import moa.core.AutoExpandVector; -import moa.evaluation.ClassificationMeasureCollection; import moa.evaluation.MeasureCollection; public class ClusteringEvalPanel extends javax.swing.JPanel { diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringSetupTab.java b/moa/src/main/java/moa/gui/clustertab/ClusteringSetupTab.java index beffc7e52..f27f5eece 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringSetupTab.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringSetupTab.java @@ -24,7 +24,9 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; + import javax.swing.JFileChooser; + import moa.clusterers.AbstractClusterer; import moa.evaluation.MeasureCollection; import moa.gui.FileExtensionFilter; diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringVisualEvalPanel.java b/moa/src/main/java/moa/gui/clustertab/ClusteringVisualEvalPanel.java index 626bed80a..574a78b96 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringVisualEvalPanel.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringVisualEvalPanel.java @@ -25,13 +25,13 @@ import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.event.ActionListener; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; import java.text.DecimalFormat; import java.util.ArrayList; + import javax.swing.ButtonGroup; import javax.swing.JLabel; import javax.swing.JRadioButton; + import moa.evaluation.MeasureCollection; public class ClusteringVisualEvalPanel extends javax.swing.JPanel{ diff --git a/moa/src/main/java/moa/gui/clustertab/ClusteringVisualTab.java b/moa/src/main/java/moa/gui/clustertab/ClusteringVisualTab.java index ba2f22c94..02fe10e7b 100644 --- a/moa/src/main/java/moa/gui/clustertab/ClusteringVisualTab.java +++ b/moa/src/main/java/moa/gui/clustertab/ClusteringVisualTab.java @@ -24,10 +24,12 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; + import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.ToolTipManager; + import moa.gui.FileExtensionFilter; import moa.gui.visualization.GraphCanvas; import moa.gui.visualization.RunVisualizer; diff --git a/moa/src/main/java/moa/gui/conceptdrift/CDTaskManagerPanel.java b/moa/src/main/java/moa/gui/conceptdrift/CDTaskManagerPanel.java index 2b8ad6651..3794d6667 100644 --- a/moa/src/main/java/moa/gui/conceptdrift/CDTaskManagerPanel.java +++ b/moa/src/main/java/moa/gui/conceptdrift/CDTaskManagerPanel.java @@ -20,17 +20,16 @@ */ package moa.gui.conceptdrift; -import moa.gui.*; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; @@ -60,6 +59,10 @@ import javax.swing.table.TableCellRenderer; import moa.core.StringUtils; +import moa.gui.ClassOptionSelectionPanel; +import moa.gui.FileExtensionFilter; +import moa.gui.GUIUtils; +import moa.gui.PreviewPanel; import moa.options.ClassOption; import moa.options.OptionHandler; import moa.tasks.ConceptDriftMainTask; diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierAlgoPanel.java b/moa/src/main/java/moa/gui/outliertab/OutlierAlgoPanel.java index d7fd2acd8..9951c4aa7 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierAlgoPanel.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierAlgoPanel.java @@ -20,7 +20,11 @@ package moa.gui.outliertab; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; @@ -28,16 +32,19 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; + import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; -import moa.clusterers.outliers.MyBaseOutlierDetector; -import moa.gui.GUIUtils; -import moa.options.ClassOption; + import com.github.javacliparser.Option; import com.github.javacliparser.gui.OptionEditComponent; import com.github.javacliparser.gui.OptionsConfigurationPanel; + +import moa.clusterers.outliers.MyBaseOutlierDetector; +import moa.gui.GUIUtils; +import moa.options.ClassOption; import moa.streams.clustering.ClusteringStream; public class OutlierAlgoPanel extends javax.swing.JPanel implements ActionListener{ diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierEvalPanel.java b/moa/src/main/java/moa/gui/outliertab/OutlierEvalPanel.java index 84500eb92..0883b9034 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierEvalPanel.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierEvalPanel.java @@ -22,12 +22,12 @@ import java.awt.GridBagConstraints; import java.util.ArrayList; -import java.util.logging.Logger; + import javax.swing.JCheckBox; import javax.swing.JLabel; + import moa.core.AutoClassDiscovery; import moa.core.AutoExpandVector; -import moa.evaluation.ClassificationMeasureCollection; import moa.evaluation.MeasureCollection; import moa.evaluation.OutlierPerformance; diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierSetupTab.java b/moa/src/main/java/moa/gui/outliertab/OutlierSetupTab.java index 70b2dd742..56c6889d4 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierSetupTab.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierSetupTab.java @@ -24,7 +24,9 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; + import javax.swing.JFileChooser; + import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.evaluation.MeasureCollection; import moa.gui.FileExtensionFilter; diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierVisualEvalPanel.java b/moa/src/main/java/moa/gui/outliertab/OutlierVisualEvalPanel.java index 7c5307f1d..24c410add 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierVisualEvalPanel.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierVisualEvalPanel.java @@ -25,13 +25,13 @@ import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.event.ActionListener; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; import java.text.DecimalFormat; import java.util.ArrayList; + import javax.swing.ButtonGroup; import javax.swing.JLabel; import javax.swing.JRadioButton; + import moa.evaluation.MeasureCollection; public class OutlierVisualEvalPanel extends javax.swing.JPanel{ diff --git a/moa/src/main/java/moa/gui/outliertab/OutlierVisualTab.java b/moa/src/main/java/moa/gui/outliertab/OutlierVisualTab.java index 2322a01f6..9923bfeed 100644 --- a/moa/src/main/java/moa/gui/outliertab/OutlierVisualTab.java +++ b/moa/src/main/java/moa/gui/outliertab/OutlierVisualTab.java @@ -28,10 +28,12 @@ import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.io.File; + import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.ToolTipManager; + import moa.gui.FileExtensionFilter; import moa.gui.visualization.GraphCanvas; import moa.gui.visualization.RunOutlierVisualizer; diff --git a/moa/src/main/java/moa/gui/visualization/ClusterPanel.java b/moa/src/main/java/moa/gui/visualization/ClusterPanel.java index 3db527710..352100b4d 100644 --- a/moa/src/main/java/moa/gui/visualization/ClusterPanel.java +++ b/moa/src/main/java/moa/gui/visualization/ClusterPanel.java @@ -24,7 +24,9 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; + import javax.swing.JPanel; + import moa.cluster.SphereCluster; public class ClusterPanel extends JPanel { diff --git a/moa/src/main/java/moa/gui/visualization/GraphCanvas.java b/moa/src/main/java/moa/gui/visualization/GraphCanvas.java index 6aecc5a32..fe857f285 100644 --- a/moa/src/main/java/moa/gui/visualization/GraphCanvas.java +++ b/moa/src/main/java/moa/gui/visualization/GraphCanvas.java @@ -22,9 +22,11 @@ import java.awt.Dimension; import java.awt.Graphics; import java.util.ArrayList; + import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JViewport; + import moa.evaluation.MeasureCollection; import moa.streams.clustering.ClusterEvent; diff --git a/moa/src/main/java/moa/gui/visualization/GraphCurve.java b/moa/src/main/java/moa/gui/visualization/GraphCurve.java index a791cafb3..46518e7a1 100644 --- a/moa/src/main/java/moa/gui/visualization/GraphCurve.java +++ b/moa/src/main/java/moa/gui/visualization/GraphCurve.java @@ -23,6 +23,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.util.ArrayList; + import moa.evaluation.MeasureCollection; import moa.streams.clustering.ClusterEvent; diff --git a/moa/src/main/java/moa/gui/visualization/OutlierPanel.java b/moa/src/main/java/moa/gui/visualization/OutlierPanel.java index 68c5c1a48..f917a0ad9 100644 --- a/moa/src/main/java/moa/gui/visualization/OutlierPanel.java +++ b/moa/src/main/java/moa/gui/visualization/OutlierPanel.java @@ -21,13 +21,20 @@ package moa.gui.visualization; -import java.awt.*; -import java.awt.event.WindowEvent; -import java.awt.event.WindowFocusListener; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; -import javax.swing.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.PointerInfo; +import java.awt.RenderingHints; + +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + import moa.cluster.SphereCluster; import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.MyBaseOutlierDetector.Outlier; diff --git a/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java b/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java index ce611e1ba..5dd794716 100644 --- a/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java +++ b/moa/src/main/java/moa/gui/visualization/RunOutlierVisualizer.java @@ -39,6 +39,12 @@ import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; + +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.clusterers.outliers.MyBaseOutlierDetector; @@ -56,10 +62,6 @@ import moa.streams.clustering.ClusterEventListener; import moa.streams.clustering.ClusteringStream; import moa.streams.clustering.RandomRBFGeneratorEvents; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class RunOutlierVisualizer implements Runnable, ActionListener, ClusterEventListener{ /** the pause interval, being read from the gui at startup */ diff --git a/moa/src/main/java/moa/gui/visualization/RunVisualizer.java b/moa/src/main/java/moa/gui/visualization/RunVisualizer.java index 1e08cab18..0e33cbebb 100644 --- a/moa/src/main/java/moa/gui/visualization/RunVisualizer.java +++ b/moa/src/main/java/moa/gui/visualization/RunVisualizer.java @@ -34,25 +34,25 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.cluster.Cluster; import moa.cluster.Clustering; import moa.clusterers.AbstractClusterer; import moa.clusterers.ClusterGenerator; +import moa.core.FastVector; import moa.evaluation.MeasureCollection; import moa.gui.TextViewerPanel; import moa.gui.clustertab.ClusteringSetupTab; import moa.gui.clustertab.ClusteringVisualEvalPanel; import moa.gui.clustertab.ClusteringVisualTab; import moa.streams.clustering.ClusterEvent; -import com.yahoo.labs.samoa.instances.Instance; -import moa.gui.clustertab.ClusteringSetupTab; import moa.streams.clustering.ClusterEventListener; import moa.streams.clustering.ClusteringStream; import moa.streams.clustering.RandomRBFGeneratorEvents; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class RunVisualizer implements Runnable, ActionListener, ClusterEventListener{ diff --git a/moa/src/main/java/moa/gui/visualization/StreamOutlierPanel.java b/moa/src/main/java/moa/gui/visualization/StreamOutlierPanel.java index 039619ad8..58f95e1a7 100644 --- a/moa/src/main/java/moa/gui/visualization/StreamOutlierPanel.java +++ b/moa/src/main/java/moa/gui/visualization/StreamOutlierPanel.java @@ -20,19 +20,31 @@ package moa.gui.visualization; -import java.awt.*; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.RenderingHints; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.RescaleOp; -import java.io.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; + import javax.imageio.ImageIO; import javax.swing.JPanel; import javax.swing.JScrollPane; + import moa.cluster.SphereCluster; import moa.clusterers.outliers.MyBaseOutlierDetector; import moa.clusterers.outliers.MyBaseOutlierDetector.Outlier; diff --git a/moa/src/main/java/moa/gui/visualization/WekaExplorer.java b/moa/src/main/java/moa/gui/visualization/WekaExplorer.java index cfc1d5254..6ed93c826 100644 --- a/moa/src/main/java/moa/gui/visualization/WekaExplorer.java +++ b/moa/src/main/java/moa/gui/visualization/WekaExplorer.java @@ -27,18 +27,21 @@ package moa.gui.visualization; -import weka.gui.explorer.Explorer; -import weka.core.Memory; //import weka.gui.LookAndFeel; import java.awt.BorderLayout; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; + import javax.swing.JFrame; + import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; +import weka.core.Memory; +import weka.gui.explorer.Explorer; + public class WekaExplorer { diff --git a/moa/src/main/java/moa/learners/ChangeDetectorLearner.java b/moa/src/main/java/moa/learners/ChangeDetectorLearner.java index db3abce46..d13d93025 100644 --- a/moa/src/main/java/moa/learners/ChangeDetectorLearner.java +++ b/moa/src/main/java/moa/learners/ChangeDetectorLearner.java @@ -19,9 +19,10 @@ package moa.learners; import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.AbstractClassifier; -import moa.core.Measurement; import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.core.Measurement; import moa.options.ClassOption; /** diff --git a/moa/src/main/java/moa/learners/Learner.java b/moa/src/main/java/moa/learners/Learner.java index 5d700571e..823e8797f 100644 --- a/moa/src/main/java/moa/learners/Learner.java +++ b/moa/src/main/java/moa/learners/Learner.java @@ -19,13 +19,11 @@ */ package moa.learners; -import moa.MOAObject; -import moa.core.Example; - -import com.yahoo.labs.samoa.instances.InstanceData; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.Prediction; +import moa.MOAObject; +import moa.core.Example; import moa.core.Measurement; import moa.gui.AWTRenderable; import moa.options.OptionHandler; diff --git a/moa/src/main/java/moa/options/AbstractClassOption.java b/moa/src/main/java/moa/options/AbstractClassOption.java index 00b0a10c0..70e1af183 100644 --- a/moa/src/main/java/moa/options/AbstractClassOption.java +++ b/moa/src/main/java/moa/options/AbstractClassOption.java @@ -20,8 +20,10 @@ package moa.options; import java.io.File; + import com.github.javacliparser.AbstractOption; import com.github.javacliparser.SerializeUtils; + import moa.core.ObjectRepository; import moa.tasks.Task; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/options/AbstractOptionHandler.java b/moa/src/main/java/moa/options/AbstractOptionHandler.java index 622f969a4..a26009fc4 100644 --- a/moa/src/main/java/moa/options/AbstractOptionHandler.java +++ b/moa/src/main/java/moa/options/AbstractOptionHandler.java @@ -20,6 +20,7 @@ package moa.options; import com.github.javacliparser.Options; + import moa.AbstractMOAObject; import moa.core.ObjectRepository; import moa.tasks.NullMonitor; diff --git a/moa/src/main/java/moa/options/ClassOption.java b/moa/src/main/java/moa/options/ClassOption.java index 56eaf8d19..8a94d3c78 100644 --- a/moa/src/main/java/moa/options/ClassOption.java +++ b/moa/src/main/java/moa/options/ClassOption.java @@ -20,9 +20,10 @@ package moa.options; import java.io.File; + import com.github.javacliparser.Option; import com.github.javacliparser.Options; -import moa.options.OptionHandler; + import moa.tasks.Task; /** diff --git a/moa/src/main/java/moa/options/ClassOptionWithNames.java b/moa/src/main/java/moa/options/ClassOptionWithNames.java index 256dfdfc2..59959d90c 100644 --- a/moa/src/main/java/moa/options/ClassOptionWithNames.java +++ b/moa/src/main/java/moa/options/ClassOptionWithNames.java @@ -11,13 +11,11 @@ package moa.options; -import com.github.javacliparser.Options; -import com.github.javacliparser.Option; import java.io.File; -import javax.swing.JComponent; +import com.github.javacliparser.Option; +import com.github.javacliparser.Options; -import com.github.javacliparser.gui.ClassOptionWithNamesEditComponent; import moa.tasks.Task; public class ClassOptionWithNames extends AbstractClassOption { diff --git a/moa/src/main/java/moa/options/OptionHandler.java b/moa/src/main/java/moa/options/OptionHandler.java index 6faba81ad..1fac302da 100644 --- a/moa/src/main/java/moa/options/OptionHandler.java +++ b/moa/src/main/java/moa/options/OptionHandler.java @@ -21,6 +21,7 @@ import com.github.javacliparser.Configurable; import com.github.javacliparser.Options; + import moa.MOAObject; import moa.core.ObjectRepository; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/options/OptionsHandler.java b/moa/src/main/java/moa/options/OptionsHandler.java index fac313a80..42e0b54f2 100644 --- a/moa/src/main/java/moa/options/OptionsHandler.java +++ b/moa/src/main/java/moa/options/OptionsHandler.java @@ -2,8 +2,10 @@ import java.util.HashMap; + import com.github.javacliparser.JavaCLIParser; import com.github.javacliparser.Option; + import moa.core.ObjectRepository; import moa.tasks.NullMonitor; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/options/WEKAClassOption.java b/moa/src/main/java/moa/options/WEKAClassOption.java index f117dbbf9..c46d75476 100644 --- a/moa/src/main/java/moa/options/WEKAClassOption.java +++ b/moa/src/main/java/moa/options/WEKAClassOption.java @@ -20,17 +20,17 @@ */ package moa.options; -import com.github.javacliparser.Option; -import weka.core.Utils; - import java.io.File; import java.util.Enumeration; import java.util.Vector; +import com.github.javacliparser.Option; + //import javax.swing.JComponent; //import moa.gui.WEKAClassOptionEditComponent; import moa.tasks.Task; +import weka.core.Utils; /** * WEKA class option. This option is used to access options in WEKA. diff --git a/moa/src/main/java/moa/recommender/dataset/impl/FlixsterDataset.java b/moa/src/main/java/moa/recommender/dataset/impl/FlixsterDataset.java index 0f1844d5e..19841cc24 100644 --- a/moa/src/main/java/moa/recommender/dataset/impl/FlixsterDataset.java +++ b/moa/src/main/java/moa/recommender/dataset/impl/FlixsterDataset.java @@ -28,10 +28,11 @@ import java.io.InputStreamReader; import java.util.logging.Level; import java.util.logging.Logger; -import moa.core.ObjectRepository; -import moa.options.AbstractOptionHandler; + import com.github.javacliparser.FileOption; +import moa.core.ObjectRepository; +import moa.options.AbstractOptionHandler; import moa.recommender.dataset.Dataset; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/recommender/dataset/impl/JesterDataset.java b/moa/src/main/java/moa/recommender/dataset/impl/JesterDataset.java index 7ff32b3c0..13716c156 100644 --- a/moa/src/main/java/moa/recommender/dataset/impl/JesterDataset.java +++ b/moa/src/main/java/moa/recommender/dataset/impl/JesterDataset.java @@ -23,16 +23,17 @@ import java.io.BufferedReader; import java.io.DataInputStream; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; - -import moa.recommender.dataset.Dataset; -import java.io.FileNotFoundException; import java.util.logging.Level; import java.util.logging.Logger; + +import com.github.javacliparser.FileOption; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FileOption; +import moa.recommender.dataset.Dataset; import moa.tasks.TaskMonitor; public class JesterDataset extends AbstractOptionHandler implements Dataset { diff --git a/moa/src/main/java/moa/recommender/dataset/impl/MovielensDataset.java b/moa/src/main/java/moa/recommender/dataset/impl/MovielensDataset.java index 8d42e2221..66c86baa6 100644 --- a/moa/src/main/java/moa/recommender/dataset/impl/MovielensDataset.java +++ b/moa/src/main/java/moa/recommender/dataset/impl/MovielensDataset.java @@ -20,7 +20,6 @@ package moa.recommender.dataset.impl; -import moa.recommender.dataset.Dataset; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.FileInputStream; @@ -29,9 +28,12 @@ import java.io.InputStreamReader; import java.util.logging.Level; import java.util.logging.Logger; + +import com.github.javacliparser.FileOption; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FileOption; +import moa.recommender.dataset.Dataset; import moa.tasks.TaskMonitor; public class MovielensDataset extends AbstractOptionHandler implements Dataset { diff --git a/moa/src/main/java/moa/recommender/predictor/BRISMFPredictor.java b/moa/src/main/java/moa/recommender/predictor/BRISMFPredictor.java index 69932b399..8d69c8450 100644 --- a/moa/src/main/java/moa/recommender/predictor/BRISMFPredictor.java +++ b/moa/src/main/java/moa/recommender/predictor/BRISMFPredictor.java @@ -21,11 +21,13 @@ package moa.recommender.predictor; import java.util.List; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.recommender.data.RecommenderData; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/recommender/predictor/BaselinePredictor.java b/moa/src/main/java/moa/recommender/predictor/BaselinePredictor.java index 3433ff24b..1ca885c1e 100644 --- a/moa/src/main/java/moa/recommender/predictor/BaselinePredictor.java +++ b/moa/src/main/java/moa/recommender/predictor/BaselinePredictor.java @@ -21,6 +21,7 @@ package moa.recommender.predictor; import java.util.List; + import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/recommender/predictor/RatingPredictor.java b/moa/src/main/java/moa/recommender/predictor/RatingPredictor.java index 911864980..839821251 100644 --- a/moa/src/main/java/moa/recommender/predictor/RatingPredictor.java +++ b/moa/src/main/java/moa/recommender/predictor/RatingPredictor.java @@ -22,6 +22,7 @@ import java.io.Serializable; import java.util.List; + import moa.recommender.rc.data.RecommenderData; /** diff --git a/moa/src/main/java/moa/recommender/rc/data/AbstractRecommenderData.java b/moa/src/main/java/moa/recommender/rc/data/AbstractRecommenderData.java index b3d6cab0b..8c755448f 100644 --- a/moa/src/main/java/moa/recommender/rc/data/AbstractRecommenderData.java +++ b/moa/src/main/java/moa/recommender/rc/data/AbstractRecommenderData.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; + import moa.recommender.rc.utils.Updatable; diff --git a/moa/src/main/java/moa/recommender/rc/data/RecommenderData.java b/moa/src/main/java/moa/recommender/rc/data/RecommenderData.java index 455f29f5c..d986dcee2 100644 --- a/moa/src/main/java/moa/recommender/rc/data/RecommenderData.java +++ b/moa/src/main/java/moa/recommender/rc/data/RecommenderData.java @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; + import moa.recommender.rc.utils.Rating; import moa.recommender.rc.utils.SparseVector; import moa.recommender.rc.utils.Updatable; diff --git a/moa/src/main/java/moa/recommender/rc/data/impl/MemRecommenderData.java b/moa/src/main/java/moa/recommender/rc/data/impl/MemRecommenderData.java index 9e61cbe83..af9b55f9c 100644 --- a/moa/src/main/java/moa/recommender/rc/data/impl/MemRecommenderData.java +++ b/moa/src/main/java/moa/recommender/rc/data/impl/MemRecommenderData.java @@ -27,6 +27,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; + import moa.recommender.rc.data.AbstractRecommenderData; import moa.recommender.rc.utils.Rating; import moa.recommender.rc.utils.SparseVector; diff --git a/moa/src/main/java/moa/recommender/rc/predictor/RatingPredictor.java b/moa/src/main/java/moa/recommender/rc/predictor/RatingPredictor.java index d160de6f2..9033917f9 100644 --- a/moa/src/main/java/moa/recommender/rc/predictor/RatingPredictor.java +++ b/moa/src/main/java/moa/recommender/rc/predictor/RatingPredictor.java @@ -22,6 +22,7 @@ import java.io.Serializable; import java.util.List; + import moa.recommender.rc.data.RecommenderData; public interface RatingPredictor extends Serializable { diff --git a/moa/src/main/java/moa/recommender/rc/predictor/impl/BRISMFPredictor.java b/moa/src/main/java/moa/recommender/rc/predictor/impl/BRISMFPredictor.java index ccc6e1e25..936496e73 100644 --- a/moa/src/main/java/moa/recommender/rc/predictor/impl/BRISMFPredictor.java +++ b/moa/src/main/java/moa/recommender/rc/predictor/impl/BRISMFPredictor.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.List; import java.util.Random; + import moa.recommender.rc.data.RecommenderData; import moa.recommender.rc.utils.Pair; import moa.recommender.rc.utils.Rating; diff --git a/moa/src/main/java/moa/recommender/rc/predictor/impl/BaselinePredictor.java b/moa/src/main/java/moa/recommender/rc/predictor/impl/BaselinePredictor.java index cfc22b2e2..6411ce6e9 100644 --- a/moa/src/main/java/moa/recommender/rc/predictor/impl/BaselinePredictor.java +++ b/moa/src/main/java/moa/recommender/rc/predictor/impl/BaselinePredictor.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; + import moa.recommender.rc.data.RecommenderData; import moa.recommender.rc.predictor.RatingPredictor; diff --git a/moa/src/main/java/moa/streams/ArffFileStream.java b/moa/src/main/java/moa/streams/ArffFileStream.java index 81d639198..3161ac6ba 100644 --- a/moa/src/main/java/moa/streams/ArffFileStream.java +++ b/moa/src/main/java/moa/streams/ArffFileStream.java @@ -19,17 +19,17 @@ */ package moa.streams; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.StringOption; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.Reader; +import java.io.Reader; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.StringOption; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.InputStreamProgressMonitor; import moa.core.InstanceExample; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/streams/CachedInstancesStream.java b/moa/src/main/java/moa/streams/CachedInstancesStream.java index bb618fac8..bd260db04 100644 --- a/moa/src/main/java/moa/streams/CachedInstancesStream.java +++ b/moa/src/main/java/moa/streams/CachedInstancesStream.java @@ -19,11 +19,10 @@ */ package moa.streams; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.AbstractMOAObject; import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator for representing a stream that is cached in memory. diff --git a/moa/src/main/java/moa/streams/ConceptDriftRealStream.java b/moa/src/main/java/moa/streams/ConceptDriftRealStream.java index 46c30398a..b0bd8b18e 100644 --- a/moa/src/main/java/moa/streams/ConceptDriftRealStream.java +++ b/moa/src/main/java/moa/streams/ConceptDriftRealStream.java @@ -19,24 +19,20 @@ */ package moa.streams; +import java.util.Random; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; -import moa.core.utils.AttributeDefinitionUtil; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/ConceptDriftStream.java b/moa/src/main/java/moa/streams/ConceptDriftStream.java index 19ff13c49..50de9fa90 100644 --- a/moa/src/main/java/moa/streams/ConceptDriftStream.java +++ b/moa/src/main/java/moa/streams/ConceptDriftStream.java @@ -20,16 +20,16 @@ package moa.streams; import java.util.Random; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; -import moa.core.InstanceExample; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator that adds concept drift to examples in a stream. diff --git a/moa/src/main/java/moa/streams/ExampleStream.java b/moa/src/main/java/moa/streams/ExampleStream.java index 20877597a..d06f4d915 100644 --- a/moa/src/main/java/moa/streams/ExampleStream.java +++ b/moa/src/main/java/moa/streams/ExampleStream.java @@ -19,12 +19,11 @@ */ package moa.streams; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.MOAObject; import moa.core.Example; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; - /** * Interface representing a data stream of examples. * diff --git a/moa/src/main/java/moa/streams/InstanceStream.java b/moa/src/main/java/moa/streams/InstanceStream.java index 83e246300..530201337 100644 --- a/moa/src/main/java/moa/streams/InstanceStream.java +++ b/moa/src/main/java/moa/streams/InstanceStream.java @@ -19,9 +19,10 @@ */ package moa.streams; -import moa.core.Example; import com.yahoo.labs.samoa.instances.Instance; +import moa.core.Example; + /** * Interface representing a data stream of instances. * diff --git a/moa/src/main/java/moa/streams/MultiFilteredStream.java b/moa/src/main/java/moa/streams/MultiFilteredStream.java index befa684b6..b4247be27 100644 --- a/moa/src/main/java/moa/streams/MultiFilteredStream.java +++ b/moa/src/main/java/moa/streams/MultiFilteredStream.java @@ -19,18 +19,17 @@ */ package moa.streams; +import com.github.javacliparser.ListOption; +import com.github.javacliparser.Option; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; -import moa.core.InstanceExample; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.options.ClassOption; -import com.github.javacliparser.ListOption; -import com.github.javacliparser.Option; import moa.options.OptionHandler; import moa.streams.filters.StreamFilter; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Class for representing a stream that is filtered. diff --git a/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java b/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java index f7c8bdf79..dd722fc2b 100644 --- a/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java +++ b/moa/src/main/java/moa/streams/MultiLabelFilteredStream.java @@ -28,7 +28,6 @@ import moa.options.OptionHandler; import moa.streams.filters.MultiLabelStreamFilter; import moa.streams.filters.SelectAttributesFilter; -import moa.streams.filters.StreamFilter; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java index 9ade14c76..54fe69cee 100644 --- a/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java +++ b/moa/src/main/java/moa/streams/MultiTargetArffFileStream.java @@ -19,21 +19,6 @@ */ package moa.streams; -import com.github.javacliparser.FileOption; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import moa.core.InputStreamProgressMonitor; -import moa.core.InstanceExample; -import moa.core.ObjectRepository; -import moa.options.AbstractOptionHandler; -import moa.tasks.TaskMonitor; - /** * Stream reader of ARFF files. * diff --git a/moa/src/main/java/moa/streams/MultiTargetInstanceStream.java b/moa/src/main/java/moa/streams/MultiTargetInstanceStream.java index 6e706a8e1..6b5432c90 100644 --- a/moa/src/main/java/moa/streams/MultiTargetInstanceStream.java +++ b/moa/src/main/java/moa/streams/MultiTargetInstanceStream.java @@ -19,9 +19,6 @@ */ package moa.streams; -import moa.core.Example; -import com.yahoo.labs.samoa.instances.Instance; - /** * Interface representing a data stream of instances. * diff --git a/moa/src/main/java/moa/streams/RecurrentConceptDriftStream.java b/moa/src/main/java/moa/streams/RecurrentConceptDriftStream.java index 54476e78a..1082192f9 100644 --- a/moa/src/main/java/moa/streams/RecurrentConceptDriftStream.java +++ b/moa/src/main/java/moa/streams/RecurrentConceptDriftStream.java @@ -20,12 +20,13 @@ */ package moa.streams; -import moa.core.Example; import java.util.Random; + +import com.github.javacliparser.IntOption; + +import moa.core.Example; import moa.core.ObjectRepository; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; -import com.github.javacliparser.IntOption; diff --git a/moa/src/main/java/moa/streams/clustering/ClusteringStream.java b/moa/src/main/java/moa/streams/clustering/ClusteringStream.java index e7c2b4bf8..c40660b02 100644 --- a/moa/src/main/java/moa/streams/clustering/ClusteringStream.java +++ b/moa/src/main/java/moa/streams/clustering/ClusteringStream.java @@ -20,9 +20,10 @@ package moa.streams.clustering; -import moa.options.AbstractOptionHandler; import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; + +import moa.options.AbstractOptionHandler; import moa.streams.InstanceStream; public abstract class ClusteringStream extends AbstractOptionHandler implements InstanceStream{ diff --git a/moa/src/main/java/moa/streams/clustering/FileStream.java b/moa/src/main/java/moa/streams/clustering/FileStream.java index bd8458fff..422fc23a1 100644 --- a/moa/src/main/java/moa/streams/clustering/FileStream.java +++ b/moa/src/main/java/moa/streams/clustering/FileStream.java @@ -34,23 +34,21 @@ import java.util.Arrays; import java.util.HashSet; -import moa.core.InputStreamProgressMonitor; -import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import moa.core.ObjectRepository; -import moa.core.utils.AttributeDefinitionUtil; - import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; import com.github.javacliparser.ListOption; import com.github.javacliparser.Option; import com.github.javacliparser.StringOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InputStreamProgressMonitor; +import moa.core.InstanceExample; +import moa.core.ObjectRepository; +import moa.core.utils.AttributeDefinitionUtil; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Instance; - public class FileStream extends ClusteringStream{ @Override diff --git a/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java b/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java index 84b15eebc..f26ca664e 100644 --- a/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java +++ b/moa/src/main/java/moa/streams/clustering/RandomRBFGeneratorEvents.java @@ -31,23 +31,22 @@ import java.util.Random; import java.util.Vector; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.cluster.Clustering; import moa.cluster.SphereCluster; import moa.core.AutoExpandVector; import moa.core.InstanceExample; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.gui.visualization.DataPoint; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class RandomRBFGeneratorEvents extends ClusteringStream { diff --git a/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java b/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java index fe46621be..946b5d728 100644 --- a/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java +++ b/moa/src/main/java/moa/streams/clustering/SimpleCSVStream.java @@ -34,7 +34,6 @@ import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.InputStreamProgressMonitor; import moa.core.InstanceExample; diff --git a/moa/src/main/java/moa/streams/filters/AbstractMultiLabelStreamFilter.java b/moa/src/main/java/moa/streams/filters/AbstractMultiLabelStreamFilter.java index e099e7ba3..4206ba4ca 100644 --- a/moa/src/main/java/moa/streams/filters/AbstractMultiLabelStreamFilter.java +++ b/moa/src/main/java/moa/streams/filters/AbstractMultiLabelStreamFilter.java @@ -25,7 +25,6 @@ import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/filters/AbstractStreamFilter.java b/moa/src/main/java/moa/streams/filters/AbstractStreamFilter.java index dd6d3ffbb..29b691cc1 100644 --- a/moa/src/main/java/moa/streams/filters/AbstractStreamFilter.java +++ b/moa/src/main/java/moa/streams/filters/AbstractStreamFilter.java @@ -20,11 +20,11 @@ package moa.streams.filters; import com.yahoo.labs.samoa.instances.Instance; + import moa.core.InstanceExample; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java b/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java index c7968e479..7787ae0b1 100644 --- a/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java +++ b/moa/src/main/java/moa/streams/filters/AddNoiseFilter.java @@ -21,16 +21,15 @@ import java.util.Random; -import moa.core.AutoExpandVector; -import moa.core.DoubleVector; -import moa.core.GaussianEstimator; -import moa.core.InstanceExample; - import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.GaussianEstimator; + /** * Filter for adding random noise to examples in a stream. * Noise can be added to attribute values or to class labels. diff --git a/moa/src/main/java/moa/streams/filters/RBFFilter.java b/moa/src/main/java/moa/streams/filters/RBFFilter.java index df300eb65..3a7e787a8 100644 --- a/moa/src/main/java/moa/streams/filters/RBFFilter.java +++ b/moa/src/main/java/moa/streams/filters/RBFFilter.java @@ -4,14 +4,14 @@ import java.util.List; import java.util.Random; -import moa.core.InstanceExample; - import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InstanceExample; + public class RBFFilter extends AbstractStreamFilter { /** diff --git a/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java b/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java index f2143f080..d5e49c595 100644 --- a/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java +++ b/moa/src/main/java/moa/streams/filters/RemoveDiscreteAttributeFilter.java @@ -21,14 +21,15 @@ import java.util.ArrayList; import java.util.List; -import moa.core.InstanceExample; -import moa.streams.InstanceStream; + import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SparseInstance; + import moa.core.FastVector; +import moa.core.InstanceExample; +import moa.streams.InstanceStream; /** * Filter for removing discrete attributes in instances of a stream. diff --git a/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java b/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java index fefe7f955..718de5a27 100644 --- a/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java +++ b/moa/src/main/java/moa/streams/filters/ReplacingMissingValuesFilter.java @@ -19,11 +19,6 @@ */ package moa.streams.filters; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; - import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -31,6 +26,12 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.InstanceExample; diff --git a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java index 5270011e2..3847bb637 100644 --- a/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java +++ b/moa/src/main/java/moa/streams/filters/SelectAttributesFilter.java @@ -3,14 +3,14 @@ import java.util.ArrayList; import java.util.List; -import moa.core.InstanceExample; - import com.github.javacliparser.StringOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstanceImpl; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InstanceExample; + public class SelectAttributesFilter extends AbstractMultiLabelStreamFilter implements MultiLabelStreamFilter{ /** diff --git a/moa/src/main/java/moa/streams/filters/StreamFilter.java b/moa/src/main/java/moa/streams/filters/StreamFilter.java index 2f866dc64..9b864d63a 100644 --- a/moa/src/main/java/moa/streams/filters/StreamFilter.java +++ b/moa/src/main/java/moa/streams/filters/StreamFilter.java @@ -20,6 +20,7 @@ package moa.streams.filters; import com.yahoo.labs.samoa.instances.Instance; + import moa.streams.ExampleStream; /** diff --git a/moa/src/main/java/moa/streams/generators/AgrawalGenerator.java b/moa/src/main/java/moa/streams/generators/AgrawalGenerator.java index b6fd685eb..9af709ce6 100644 --- a/moa/src/main/java/moa/streams/generators/AgrawalGenerator.java +++ b/moa/src/main/java/moa/streams/generators/AgrawalGenerator.java @@ -19,23 +19,20 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; -import moa.core.Example; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import moa.streams.ExampleStream; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/HyperplaneGenerator.java b/moa/src/main/java/moa/streams/generators/HyperplaneGenerator.java index be6e6aa71..cfaac82ee 100644 --- a/moa/src/main/java/moa/streams/generators/HyperplaneGenerator.java +++ b/moa/src/main/java/moa/streams/generators/HyperplaneGenerator.java @@ -20,19 +20,20 @@ package moa.streams.generators; import java.util.Random; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.FastVector; import moa.core.InstanceExample; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Stream generator for Hyperplane data stream. diff --git a/moa/src/main/java/moa/streams/generators/LEDGenerator.java b/moa/src/main/java/moa/streams/generators/LEDGenerator.java index a57fb1dc1..8479c9479 100644 --- a/moa/src/main/java/moa/streams/generators/LEDGenerator.java +++ b/moa/src/main/java/moa/streams/generators/LEDGenerator.java @@ -19,20 +19,19 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/LEDGeneratorDrift.java b/moa/src/main/java/moa/streams/generators/LEDGeneratorDrift.java index 26ee76a89..01ab912ce 100644 --- a/moa/src/main/java/moa/streams/generators/LEDGeneratorDrift.java +++ b/moa/src/main/java/moa/streams/generators/LEDGeneratorDrift.java @@ -19,13 +19,13 @@ */ package moa.streams.generators; -import moa.core.InstanceExample; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InstanceExample; import moa.core.ObjectRepository; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/generators/RandomRBFGenerator.java b/moa/src/main/java/moa/streams/generators/RandomRBFGenerator.java index cbbe0202c..fc67d6ab9 100644 --- a/moa/src/main/java/moa/streams/generators/RandomRBFGenerator.java +++ b/moa/src/main/java/moa/streams/generators/RandomRBFGenerator.java @@ -19,21 +19,20 @@ */ package moa.streams.generators; +import java.io.Serializable; +import java.util.Random; + +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.io.Serializable; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.MiscUtils; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/RandomRBFGeneratorDrift.java b/moa/src/main/java/moa/streams/generators/RandomRBFGeneratorDrift.java index c437a4a95..abcb14e32 100644 --- a/moa/src/main/java/moa/streams/generators/RandomRBFGeneratorDrift.java +++ b/moa/src/main/java/moa/streams/generators/RandomRBFGeneratorDrift.java @@ -20,11 +20,11 @@ package moa.streams.generators; import java.util.Random; -import moa.core.InstanceExample; -import com.github.javacliparser.IntOption; import com.github.javacliparser.FloatOption; -import com.yahoo.labs.samoa.instances.Instance; +import com.github.javacliparser.IntOption; + +import moa.core.InstanceExample; /** * Stream generator for a random radial basis function stream with drift. diff --git a/moa/src/main/java/moa/streams/generators/RandomTreeGenerator.java b/moa/src/main/java/moa/streams/generators/RandomTreeGenerator.java index 282618a02..157ce8adb 100644 --- a/moa/src/main/java/moa/streams/generators/RandomTreeGenerator.java +++ b/moa/src/main/java/moa/streams/generators/RandomTreeGenerator.java @@ -19,22 +19,21 @@ */ package moa.streams.generators; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Random; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/SEAGenerator.java b/moa/src/main/java/moa/streams/generators/SEAGenerator.java index 06da33f07..e4ede9220 100644 --- a/moa/src/main/java/moa/streams/generators/SEAGenerator.java +++ b/moa/src/main/java/moa/streams/generators/SEAGenerator.java @@ -19,20 +19,19 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/STAGGERGenerator.java b/moa/src/main/java/moa/streams/generators/STAGGERGenerator.java index a92118e17..def9e5ee4 100644 --- a/moa/src/main/java/moa/streams/generators/STAGGERGenerator.java +++ b/moa/src/main/java/moa/streams/generators/STAGGERGenerator.java @@ -19,20 +19,19 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/WaveformGenerator.java b/moa/src/main/java/moa/streams/generators/WaveformGenerator.java index f66e5b0ff..06cc45350 100644 --- a/moa/src/main/java/moa/streams/generators/WaveformGenerator.java +++ b/moa/src/main/java/moa/streams/generators/WaveformGenerator.java @@ -19,20 +19,19 @@ */ package moa.streams.generators; +import java.util.Random; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; -import moa.core.FastVector; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.Random; +import moa.core.FastVector; import moa.core.InstanceExample; - -import com.yahoo.labs.samoa.instances.InstancesHeader; import moa.core.ObjectRepository; import moa.options.AbstractOptionHandler; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; import moa.streams.InstanceStream; import moa.tasks.TaskMonitor; diff --git a/moa/src/main/java/moa/streams/generators/WaveformGeneratorDrift.java b/moa/src/main/java/moa/streams/generators/WaveformGeneratorDrift.java index c918ad8b3..e5b17cfdb 100644 --- a/moa/src/main/java/moa/streams/generators/WaveformGeneratorDrift.java +++ b/moa/src/main/java/moa/streams/generators/WaveformGeneratorDrift.java @@ -20,13 +20,13 @@ */ package moa.streams.generators; -import moa.core.InstanceExample; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.InstanceExample; import moa.core.ObjectRepository; -import com.github.javacliparser.IntOption; import moa.tasks.TaskMonitor; /** diff --git a/moa/src/main/java/moa/streams/generators/cd/AbstractConceptDriftGenerator.java b/moa/src/main/java/moa/streams/generators/cd/AbstractConceptDriftGenerator.java index 7dd440d98..6a1ae7979 100644 --- a/moa/src/main/java/moa/streams/generators/cd/AbstractConceptDriftGenerator.java +++ b/moa/src/main/java/moa/streams/generators/cd/AbstractConceptDriftGenerator.java @@ -19,15 +19,16 @@ */ package moa.streams.generators.cd; +import java.util.ArrayList; +import java.util.Random; + import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.DenseInstance; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import java.util.ArrayList; -import java.util.Random; + import moa.core.FastVector; import moa.core.InstanceExample; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/streams/generators/cd/ConceptDriftGenerator.java b/moa/src/main/java/moa/streams/generators/cd/ConceptDriftGenerator.java index 02ed7c229..732885aa7 100644 --- a/moa/src/main/java/moa/streams/generators/cd/ConceptDriftGenerator.java +++ b/moa/src/main/java/moa/streams/generators/cd/ConceptDriftGenerator.java @@ -20,6 +20,7 @@ package moa.streams.generators.cd; import java.util.ArrayList; + import moa.streams.InstanceStream; import moa.streams.clustering.ClusterEvent; diff --git a/moa/src/main/java/moa/streams/generators/multilabel/MetaMultilabelGenerator.java b/moa/src/main/java/moa/streams/generators/multilabel/MetaMultilabelGenerator.java index 62536ddc5..f2ac3625e 100644 --- a/moa/src/main/java/moa/streams/generators/multilabel/MetaMultilabelGenerator.java +++ b/moa/src/main/java/moa/streams/generators/multilabel/MetaMultilabelGenerator.java @@ -19,22 +19,32 @@ */ package moa.streams.generators.multilabel; -import java.util.*; -import moa.core.InstanceExample; -import moa.core.MultilabelInstancesHeader; -import moa.core.ObjectRepository; -import moa.options.AbstractOptionHandler; -import moa.options.ClassOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + import com.github.javacliparser.FloatOption; import com.github.javacliparser.IntOption; -import moa.streams.InstanceStream; -import moa.tasks.TaskMonitor; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; import com.yahoo.labs.samoa.instances.InstancesHeader; import com.yahoo.labs.samoa.instances.SparseInstance; + import moa.core.FastVector; +import moa.core.InstanceExample; +import moa.core.MultilabelInstancesHeader; +import moa.core.ObjectRepository; import moa.core.Utils; +import moa.options.AbstractOptionHandler; +import moa.options.ClassOption; +import moa.streams.InstanceStream; +import moa.tasks.TaskMonitor; /** * Stream generator for multilabel data. diff --git a/moa/src/main/java/moa/streams/generators/multilabel/MultilabelArffFileStream.java b/moa/src/main/java/moa/streams/generators/multilabel/MultilabelArffFileStream.java index cec7e0aa4..064d4fae0 100644 --- a/moa/src/main/java/moa/streams/generators/multilabel/MultilabelArffFileStream.java +++ b/moa/src/main/java/moa/streams/generators/multilabel/MultilabelArffFileStream.java @@ -19,13 +19,13 @@ */ package moa.streams.generators.multilabel; -import moa.streams.ArffFileStream; -import moa.streams.MultiTargetInstanceStream; -import moa.core.MultilabelInstancesHeader; - import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.InstancesHeader; +import moa.core.MultilabelInstancesHeader; +import moa.streams.ArffFileStream; +import moa.streams.MultiTargetInstanceStream; + /** * Stream reader for ARFF files of multilabel data. * diff --git a/moa/src/main/java/moa/tasks/CacheShuffledStream.java b/moa/src/main/java/moa/tasks/CacheShuffledStream.java index ae50c8c53..91cf2194f 100644 --- a/moa/src/main/java/moa/tasks/CacheShuffledStream.java +++ b/moa/src/main/java/moa/tasks/CacheShuffledStream.java @@ -21,10 +21,11 @@ import java.util.Random; +import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.ObjectRepository; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.streams.CachedInstancesStream; import moa.streams.InstanceStream; diff --git a/moa/src/main/java/moa/tasks/ConceptDriftMainTask.java b/moa/src/main/java/moa/tasks/ConceptDriftMainTask.java index a5841fc12..1cdfcf560 100644 --- a/moa/src/main/java/moa/tasks/ConceptDriftMainTask.java +++ b/moa/src/main/java/moa/tasks/ConceptDriftMainTask.java @@ -20,6 +20,7 @@ package moa.tasks; import java.util.ArrayList; + import moa.streams.clustering.ClusterEvent; public abstract class ConceptDriftMainTask extends MainTask { diff --git a/moa/src/main/java/moa/tasks/EvaluateClustering.java b/moa/src/main/java/moa/tasks/EvaluateClustering.java index 0fc7f4f62..df03b8498 100644 --- a/moa/src/main/java/moa/tasks/EvaluateClustering.java +++ b/moa/src/main/java/moa/tasks/EvaluateClustering.java @@ -8,13 +8,14 @@ */ package moa.tasks; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; + import moa.clusterers.AbstractClusterer; import moa.core.ObjectRepository; import moa.evaluation.LearningCurve; import moa.gui.BatchCmd; import moa.options.ClassOption; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; import moa.streams.clustering.ClusteringStream; /** diff --git a/moa/src/main/java/moa/tasks/EvaluateConceptDrift.java b/moa/src/main/java/moa/tasks/EvaluateConceptDrift.java index 5f268ebb4..c59a965f9 100644 --- a/moa/src/main/java/moa/tasks/EvaluateConceptDrift.java +++ b/moa/src/main/java/moa/tasks/EvaluateConceptDrift.java @@ -20,12 +20,14 @@ */ package moa.tasks; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; @@ -35,7 +37,6 @@ import moa.evaluation.LearningPerformanceEvaluator; import moa.learners.ChangeDetectorLearner; import moa.options.ClassOption; - import moa.streams.clustering.ClusterEvent; import moa.streams.generators.cd.ConceptDriftGenerator; diff --git a/moa/src/main/java/moa/tasks/EvaluateInterleavedChunks.java b/moa/src/main/java/moa/tasks/EvaluateInterleavedChunks.java index f8c78b6bb..5ce5a1ec2 100644 --- a/moa/src/main/java/moa/tasks/EvaluateInterleavedChunks.java +++ b/moa/src/main/java/moa/tasks/EvaluateInterleavedChunks.java @@ -22,7 +22,12 @@ import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; -import moa.classifiers.Classifier; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; import moa.core.InstanceExample; import moa.core.Measurement; @@ -33,12 +38,7 @@ import moa.evaluation.LearningPerformanceEvaluator; import moa.learners.Learner; import moa.options.ClassOption; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; public class EvaluateInterleavedChunks extends MainTask { diff --git a/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java b/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java index 36791f102..46f6ca2c2 100644 --- a/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java +++ b/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java @@ -23,7 +23,9 @@ import java.io.FileOutputStream; import java.io.PrintStream; -import moa.classifiers.Classifier; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; @@ -33,11 +35,8 @@ import moa.evaluation.LearningPerformanceEvaluator; import moa.learners.Learner; import moa.options.ClassOption; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; /** * Task for evaluating a classifier on a stream by testing then training with each example in sequence. diff --git a/moa/src/main/java/moa/tasks/EvaluateModel.java b/moa/src/main/java/moa/tasks/EvaluateModel.java index a9fe3f056..04dbd4aab 100644 --- a/moa/src/main/java/moa/tasks/EvaluateModel.java +++ b/moa/src/main/java/moa/tasks/EvaluateModel.java @@ -22,8 +22,11 @@ import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; + import com.github.javacliparser.FileOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.Classifier; import moa.core.Example; import moa.core.ObjectRepository; @@ -34,7 +37,6 @@ import moa.options.ClassOption; import moa.streams.ExampleStream; import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; /** * Task for evaluating a static model on a stream. diff --git a/moa/src/main/java/moa/tasks/EvaluateModelMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluateModelMultiTarget.java index df5d18631..0ef68f18f 100644 --- a/moa/src/main/java/moa/tasks/EvaluateModelMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluateModelMultiTarget.java @@ -19,12 +19,14 @@ */ package moa.tasks; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.Classifier; import moa.classifiers.MultiTargetRegressor; import moa.core.Example; diff --git a/moa/src/main/java/moa/tasks/EvaluateModelRegression.java b/moa/src/main/java/moa/tasks/EvaluateModelRegression.java index 34b57232c..3e7318e1a 100644 --- a/moa/src/main/java/moa/tasks/EvaluateModelRegression.java +++ b/moa/src/main/java/moa/tasks/EvaluateModelRegression.java @@ -22,13 +22,15 @@ import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; + import com.github.javacliparser.FileOption; import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.classifiers.Classifier; import moa.classifiers.Regressor; import moa.core.Example; import moa.core.ObjectRepository; -import moa.core.Utils; import moa.evaluation.LearningEvaluation; import moa.evaluation.LearningPerformanceEvaluator; import moa.evaluation.RegressionPerformanceEvaluator; @@ -36,7 +38,6 @@ import moa.options.ClassOption; import moa.streams.ExampleStream; import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; /** * Task for evaluating a static model on a stream. diff --git a/moa/src/main/java/moa/tasks/EvaluateOnlineRecommender.java b/moa/src/main/java/moa/tasks/EvaluateOnlineRecommender.java index 0fbc8cb32..470382d9c 100644 --- a/moa/src/main/java/moa/tasks/EvaluateOnlineRecommender.java +++ b/moa/src/main/java/moa/tasks/EvaluateOnlineRecommender.java @@ -19,12 +19,13 @@ */ package moa.tasks; +import com.github.javacliparser.IntOption; + import moa.core.Measurement; import moa.core.ObjectRepository; import moa.evaluation.LearningCurve; import moa.evaluation.LearningEvaluation; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.recommender.dataset.Dataset; import moa.recommender.predictor.RatingPredictor; import moa.recommender.rc.data.RecommenderData; diff --git a/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java b/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java index 22e8975e6..b79a1cb03 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java +++ b/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java @@ -25,10 +25,17 @@ import java.io.PrintStream; import java.util.ArrayList; import java.util.List; + import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; +<<<<<<< c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 import moa.classifiers.Classifier; +======= +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + +>>>>>>> Instances rework, new iSOUPTree models and import cleanup import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; @@ -41,8 +48,6 @@ import moa.options.ClassOption; import moa.streams.CachedInstancesStream; import moa.streams.ExampleStream; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; /** * Task for evaluating a classifier on a stream by periodically testing on a heldout set. diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequential.java b/moa/src/main/java/moa/tasks/EvaluatePrequential.java index 51a4019b5..22adf218e 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequential.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequential.java @@ -24,27 +24,25 @@ import java.io.FileOutputStream; import java.io.PrintStream; -import moa.classifiers.Classifier; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.TimingUtils; -import moa.evaluation.WindowClassificationPerformanceEvaluator; +import moa.core.Utils; import moa.evaluation.EWMAClassificationPerformanceEvaluator; import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; import moa.evaluation.LearningCurve; import moa.evaluation.LearningEvaluation; import moa.evaluation.LearningPerformanceEvaluator; +import moa.evaluation.WindowClassificationPerformanceEvaluator; import moa.learners.Learner; import moa.options.ClassOption; - -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; -import com.yahoo.labs.samoa.instances.Instance; -import moa.core.Utils; /** * Task for evaluating a classifier on a stream by testing then training with each example in sequence. diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialCV.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialCV.java index f68d5036a..68b5b2545 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialCV.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialCV.java @@ -20,18 +20,6 @@ */ package moa.tasks; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; -import moa.classifiers.Classifier; -import moa.core.*; -import moa.evaluation.*; -import moa.learners.Learner; -import moa.options.ClassOption; -import moa.streams.ExampleStream; - import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; @@ -40,6 +28,22 @@ import java.util.List; import java.util.Random; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; + +import moa.core.Example; +import moa.core.Measurement; +import moa.core.MiscUtils; +import moa.core.ObjectRepository; +import moa.core.TimingUtils; +import moa.evaluation.LearningCurve; +import moa.evaluation.LearningEvaluation; +import moa.evaluation.LearningPerformanceEvaluator; +import moa.learners.Learner; +import moa.options.ClassOption; +import moa.streams.ExampleStream; + /** * Task for prequential cross-validation evaluation of a classifier on a stream by testing then training with each * example in sequence and doing cross-validation at the same time. diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java index 9b3a1920b..ec057e886 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java @@ -1,3 +1,4 @@ +<<<<<<< c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 /* * EvaluatePrequentialMultiTarget.java * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand @@ -129,6 +130,214 @@ protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { if (widthOption.getValue() != 1000) { System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); return learningCurve; +======= +/* + * EvaluatePrequentialMultiTarget.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.tasks; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + +import moa.classifiers.MultiTargetRegressor; +import moa.core.Example; +import moa.core.Measurement; +import moa.core.ObjectRepository; +import moa.core.TimingUtils; +import moa.evaluation.EWMAClassificationPerformanceEvaluator; +import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; +import moa.evaluation.LearningCurve; +import moa.evaluation.LearningEvaluation; +import moa.evaluation.LearningPerformanceEvaluator; +import moa.evaluation.MultiTargetPerformanceEvaluator; +import moa.evaluation.WindowClassificationPerformanceEvaluator; +import moa.learners.Learner; +import moa.options.ClassOption; +import moa.streams.ExampleStream; +import moa.streams.MultiTargetInstanceStream; + +/** + * Task for evaluating a classifier on a stream by testing then training with each example in sequence. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * @version $Revision: 7 $ + */ +public class EvaluatePrequentialMultiTarget extends MultiTargetMainTask { + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } + + private static final long serialVersionUID = 1L; + + public ClassOption learnerOption = new ClassOption("learner", 'l', + "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); + + public ClassOption streamOption = new ClassOption("stream", 's', + "Stream to learn from.", MultiTargetInstanceStream.class, + "MultiTargetArffFileStream"); + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + MultiTargetPerformanceEvaluator.class, + "BasicMultiTargetPerformanceEvaluator"); + + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); + + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); + + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); + + public FileOption dumpFileOption = new FileOption("dumpFile", 'd', + "File to append intermediate csv results to.", null, "csv", true); + + public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', + "File to append output predictions to.", null, "pred", true); + + //New for prequential method DEPRECATED + public IntOption widthOption = new IntOption("width", + 'w', "Size of Window", 1000); + + public FloatOption alphaOption = new FloatOption("alpha", + 'a', "Fading factor or exponential smoothing factor", .01); + //End New for prequential methods + + @Override + public Class getTaskResultType() { + return LearningCurve.class; + } + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + Learner learner = (Learner) getPreparedClassOption(this.learnerOption); + ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); + LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); + LearningCurve learningCurve = new LearningCurve( + "learning evaluation instances"); + + //New for prequential methods + if (evaluator instanceof WindowClassificationPerformanceEvaluator) { + //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); + if (widthOption.getValue() != 1000) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { + //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { + //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + //End New for prequential methods + + learner.setModelContext(stream.getHeader()); + int maxInstances = this.instanceLimitOption.getValue(); + long instancesProcessed = 0; + int maxSeconds = this.timeLimitOption.getValue(); + int secondsElapsed = 0; + monitor.setCurrentActivity("Evaluating learner...", -1.0); + + File dumpFile = this.dumpFileOption.getFile(); + PrintStream immediateResultStream = null; + if (dumpFile != null) { + try { + if (dumpFile.exists()) { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile, true), true); + } else { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open immediate result file: " + dumpFile, ex); + } + } + //File for output predictions + File outputPredictionFile = this.outputPredictionFileOption.getFile(); + PrintStream outputPredictionResultStream = null; + if (outputPredictionFile != null) { + try { + if (outputPredictionFile.exists()) { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile, true), true); + } else { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open prediction result file: " + outputPredictionFile, ex); + } + } + boolean firstDump = true; + boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); + long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + long lastEvaluateStartTime = evaluateStartTime; + double RAMHours = 0.0; + while (stream.hasMoreInstances() + && ((maxInstances < 0) || (instancesProcessed < maxInstances)) + && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { + Example trainInst = stream.nextInstance(); + Example testInst = (Example) trainInst; //.copy(); + //testInst.setClassMissing(); + //double[] prediction = learner.getVotesForInstance(testInst); + Prediction prediction = learner.getPredictionForInstance(testInst); + // Output prediction + if (outputPredictionFile != null) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); +>>>>>>> Instances rework, new iSOUPTree models and import cleanup } } if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java index 7a3d8b059..56996cb47 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java @@ -24,32 +24,28 @@ import java.io.FileOutputStream; import java.io.PrintStream; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + +import moa.classifiers.Regressor; import moa.core.Example; import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.TimingUtils; -import moa.evaluation.WindowClassificationPerformanceEvaluator; import moa.evaluation.EWMAClassificationPerformanceEvaluator; import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; import moa.evaluation.LearningCurve; import moa.evaluation.LearningEvaluation; import moa.evaluation.LearningPerformanceEvaluator; +import moa.evaluation.RegressionPerformanceEvaluator; +import moa.evaluation.WindowClassificationPerformanceEvaluator; import moa.learners.Learner; import moa.options.ClassOption; - -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; - -import moa.classifiers.Regressor; import moa.streams.ExampleStream; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - -import moa.evaluation.RegressionPerformanceEvaluator; - /** * Task for evaluating a classifier on a stream by testing then training with each example in sequence. * diff --git a/moa/src/main/java/moa/tasks/LearnModel.java b/moa/src/main/java/moa/tasks/LearnModel.java index f9fa58608..cb5362421 100644 --- a/moa/src/main/java/moa/tasks/LearnModel.java +++ b/moa/src/main/java/moa/tasks/LearnModel.java @@ -19,11 +19,12 @@ */ package moa.tasks; +import com.github.javacliparser.IntOption; + import moa.classifiers.Classifier; import moa.core.ObjectRepository; import moa.learners.Learner; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; import moa.streams.InstanceStream; diff --git a/moa/src/main/java/moa/tasks/LearnModelMultiTarget.java b/moa/src/main/java/moa/tasks/LearnModelMultiTarget.java index e1ce7f43f..14f30af31 100644 --- a/moa/src/main/java/moa/tasks/LearnModelMultiTarget.java +++ b/moa/src/main/java/moa/tasks/LearnModelMultiTarget.java @@ -20,6 +20,7 @@ package moa.tasks; import com.github.javacliparser.IntOption; + import moa.classifiers.Classifier; import moa.classifiers.MultiTargetRegressor; import moa.core.ObjectRepository; diff --git a/moa/src/main/java/moa/tasks/LearnModelRegression.java b/moa/src/main/java/moa/tasks/LearnModelRegression.java index 84e1cca2e..4869602e3 100644 --- a/moa/src/main/java/moa/tasks/LearnModelRegression.java +++ b/moa/src/main/java/moa/tasks/LearnModelRegression.java @@ -19,12 +19,13 @@ */ package moa.tasks; +import com.github.javacliparser.IntOption; + import moa.classifiers.Classifier; +import moa.classifiers.Regressor; import moa.core.ObjectRepository; import moa.learners.Learner; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; -import moa.classifiers.Regressor; import moa.streams.ExampleStream; import moa.streams.InstanceStream; diff --git a/moa/src/main/java/moa/tasks/MainTask.java b/moa/src/main/java/moa/tasks/MainTask.java index cc5498311..4a62e816f 100644 --- a/moa/src/main/java/moa/tasks/MainTask.java +++ b/moa/src/main/java/moa/tasks/MainTask.java @@ -23,9 +23,10 @@ import java.io.IOException; import java.io.Serializable; +import com.github.javacliparser.FileOption; + import moa.core.ObjectRepository; import moa.core.SerializeUtils; -import com.github.javacliparser.FileOption; /** * Abstract Main Task. All tasks that want to write their result diff --git a/moa/src/main/java/moa/tasks/MeasureStreamSpeed.java b/moa/src/main/java/moa/tasks/MeasureStreamSpeed.java index 49d05a34e..2651db95c 100644 --- a/moa/src/main/java/moa/tasks/MeasureStreamSpeed.java +++ b/moa/src/main/java/moa/tasks/MeasureStreamSpeed.java @@ -19,14 +19,14 @@ */ package moa.tasks; +import com.github.javacliparser.IntOption; + import moa.core.Measurement; import moa.core.ObjectRepository; import moa.core.TimingUtils; import moa.evaluation.LearningEvaluation; import moa.options.ClassOption; -import com.github.javacliparser.IntOption; import moa.streams.ExampleStream; -import moa.streams.InstanceStream; /** * Task for measuring the speed of the stream. diff --git a/moa/src/main/java/moa/tasks/MultiTargetMainTask.java b/moa/src/main/java/moa/tasks/MultiTargetMainTask.java index 0d0797078..1b5ce701e 100644 --- a/moa/src/main/java/moa/tasks/MultiTargetMainTask.java +++ b/moa/src/main/java/moa/tasks/MultiTargetMainTask.java @@ -5,7 +5,7 @@ package moa.tasks; import java.util.ArrayList; -import moa.streams.InstanceStream; + import moa.streams.clustering.ClusterEvent; /** diff --git a/moa/src/main/java/moa/tasks/Plot.java b/moa/src/main/java/moa/tasks/Plot.java index 8ea104707..328625433 100644 --- a/moa/src/main/java/moa/tasks/Plot.java +++ b/moa/src/main/java/moa/tasks/Plot.java @@ -26,7 +26,6 @@ import java.io.IOException; import java.io.InputStreamReader; -import moa.core.ObjectRepository; import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; @@ -34,6 +33,8 @@ import com.github.javacliparser.MultiChoiceOption; import com.github.javacliparser.StringOption; +import moa.core.ObjectRepository; + /** * A task allowing to create and plot gnuplot scripts. * diff --git a/moa/src/main/java/moa/tasks/RegressionMainTask.java b/moa/src/main/java/moa/tasks/RegressionMainTask.java index e6eeffa1f..fc45af42d 100644 --- a/moa/src/main/java/moa/tasks/RegressionMainTask.java +++ b/moa/src/main/java/moa/tasks/RegressionMainTask.java @@ -5,7 +5,7 @@ package moa.tasks; import java.util.ArrayList; -import moa.streams.InstanceStream; + import moa.streams.clustering.ClusterEvent; /** diff --git a/moa/src/main/java/moa/tasks/RunStreamTasks.java b/moa/src/main/java/moa/tasks/RunStreamTasks.java index ded79182a..43d5621ee 100644 --- a/moa/src/main/java/moa/tasks/RunStreamTasks.java +++ b/moa/src/main/java/moa/tasks/RunStreamTasks.java @@ -22,6 +22,7 @@ import com.github.javacliparser.FloatOption; import com.github.javacliparser.StringOption; + import moa.MOAObject; import moa.core.ObjectRepository; import moa.options.ClassOption; diff --git a/moa/src/main/java/moa/tasks/RunTasks.java b/moa/src/main/java/moa/tasks/RunTasks.java index 47314962b..4e79f573e 100644 --- a/moa/src/main/java/moa/tasks/RunTasks.java +++ b/moa/src/main/java/moa/tasks/RunTasks.java @@ -20,11 +20,12 @@ */ package moa.tasks; -import moa.core.ObjectRepository; -import moa.options.ClassOption; import com.github.javacliparser.FloatOption; import com.github.javacliparser.StringOption; +import moa.core.ObjectRepository; +import moa.options.ClassOption; + /** * Task for running several experiments modifying values of parameters. * diff --git a/moa/src/main/java/moa/tasks/WriteStreamToARFFFile.java b/moa/src/main/java/moa/tasks/WriteStreamToARFFFile.java index d0f252703..314dde2ad 100644 --- a/moa/src/main/java/moa/tasks/WriteStreamToARFFFile.java +++ b/moa/src/main/java/moa/tasks/WriteStreamToARFFFile.java @@ -24,13 +24,12 @@ import java.io.FileWriter; import java.io.Writer; -import moa.core.ObjectRepository; -import moa.options.ClassOption; import com.github.javacliparser.FileOption; import com.github.javacliparser.FlagOption; import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.InstanceImpl; -import com.yahoo.labs.samoa.instances.InstancesHeader; + +import moa.core.ObjectRepository; +import moa.options.ClassOption; import moa.streams.InstanceStream; /** diff --git a/moa/src/main/java/weka/classifiers/meta/MOA.java b/moa/src/main/java/weka/classifiers/meta/MOA.java index e736f1495..753969d2a 100644 --- a/moa/src/main/java/weka/classifiers/meta/MOA.java +++ b/moa/src/main/java/weka/classifiers/meta/MOA.java @@ -21,23 +21,23 @@ package weka.classifiers.meta; +import java.util.Enumeration; +import java.util.Vector; + +import com.yahoo.labs.samoa.instances.WekaToSamoaInstanceConverter; + +import moa.classifiers.Classifier; +import moa.classifiers.trees.DecisionStump; +import moa.options.ClassOption; import weka.classifiers.UpdateableClassifier; import weka.core.Capabilities; +import weka.core.Capabilities.Capability; import weka.core.Instance; import weka.core.Instances; import weka.core.MOAUtils; import weka.core.Option; import weka.core.RevisionUtils; import weka.core.Utils; -import weka.core.Capabilities.Capability; - -import java.util.Enumeration; -import java.util.Vector; - -import moa.classifiers.Classifier; -import moa.classifiers.trees.DecisionStump; -import moa.options.ClassOption; -import com.yahoo.labs.samoa.instances.WekaToSamoaInstanceConverter; /** diff --git a/moa/src/main/java/weka/datagenerators/classifiers/classification/MOA.java b/moa/src/main/java/weka/datagenerators/classifiers/classification/MOA.java index 50537008e..76257e8e6 100644 --- a/moa/src/main/java/weka/datagenerators/classifiers/classification/MOA.java +++ b/moa/src/main/java/weka/datagenerators/classifiers/classification/MOA.java @@ -22,24 +22,23 @@ package weka.datagenerators.classifiers.classification; -import weka.core.Instance; -import weka.core.Instances; -import weka.core.MOAUtils; -import weka.core.Option; -import weka.core.RevisionUtils; -import weka.core.Utils; -import weka.datagenerators.ClassificationGenerator; - import java.util.Enumeration; import java.util.Random; import java.util.Vector; +import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; + import moa.options.AbstractOptionHandler; import moa.options.ClassOption; import moa.streams.InstanceStream; import moa.streams.generators.LEDGenerator; -import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter; -import com.yahoo.labs.samoa.instances.WekaToSamoaInstanceConverter; +import weka.core.Instance; +import weka.core.Instances; +import weka.core.MOAUtils; +import weka.core.Option; +import weka.core.RevisionUtils; +import weka.core.Utils; +import weka.datagenerators.ClassificationGenerator; /** diff --git a/moa/src/main/java/weka/gui/MOAClassOptionEditor.java b/moa/src/main/java/weka/gui/MOAClassOptionEditor.java index 5604cf644..029f0f025 100644 --- a/moa/src/main/java/weka/gui/MOAClassOptionEditor.java +++ b/moa/src/main/java/weka/gui/MOAClassOptionEditor.java @@ -20,10 +20,11 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import com.github.javacliparser.Option; import com.github.javacliparser.gui.ClassOptionEditComponent; import com.github.javacliparser.gui.OptionsConfigurationPanel; + import moa.options.ClassOption; -import com.github.javacliparser.Option; /** * An editor for MOA ClassOption objects. diff --git a/moa/src/test/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoaderTest.java b/moa/src/test/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoaderTest.java index 1171e785b..adf24d539 100644 --- a/moa/src/test/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoaderTest.java +++ b/moa/src/test/java/com/yahoo/labs/samoa/instances/MultiTargetArffLoaderTest.java @@ -1,6 +1,7 @@ package com.yahoo.labs.samoa.instances; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.io.BufferedReader; import java.io.FileInputStream; @@ -9,15 +10,6 @@ import java.io.InputStreamReader; import java.io.Reader; -import moa.core.InputStreamProgressMonitor; -import moa.streams.ArffFileStream; -import moa.streams.MultiTargetArffFileStream; -import moa.test.MoaTestCase; -import moa.test.TmpFile; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; diff --git a/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java b/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java index 4987e2718..7cccd9e5a 100644 --- a/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java +++ b/moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java @@ -24,6 +24,9 @@ import java.io.InputStreamReader; import java.io.Reader; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + import moa.core.Example; import moa.core.InstanceExample; import moa.core.Measurement; @@ -34,9 +37,6 @@ import moa.test.TmpFile; import weka.core.MOAUtils; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; - /** * Ancestor for all classifier test cases. * @@ -130,14 +130,8 @@ protected AbstractTestHelper newTestHelper() { */ protected InstancesHeader load(String filename, int classIndex) { InstancesHeader result = null; - //ArffLoader loader; - - //result = null; try { - /*loader = new ArffLoader(); - loader.setFile(new TmpFile(filename)); - result = loader.getDataSet();*/ // JD: weka's ARffLoader TmpFile tmp=new TmpFile(filename); FileInputStream fileStream = new FileInputStream(tmp.getAbsolutePath()); Reader reader=new BufferedReader(new InputStreamReader(fileStream)); diff --git a/moa/src/test/java/moa/classifiers/AbstractMultipleClassifierTestCase.java b/moa/src/test/java/moa/classifiers/AbstractMultipleClassifierTestCase.java index bbb6a231f..1c59250f4 100644 --- a/moa/src/test/java/moa/classifiers/AbstractMultipleClassifierTestCase.java +++ b/moa/src/test/java/moa/classifiers/AbstractMultipleClassifierTestCase.java @@ -22,7 +22,6 @@ import moa.core.Example; import moa.evaluation.BasicClassificationPerformanceEvaluator; -import moa.evaluation.BasicRegressionPerformanceEvaluator; import moa.evaluation.LearningPerformanceEvaluator; /** diff --git a/moa/src/test/java/moa/classifiers/AbstractMultipleRegressorTestCase.java b/moa/src/test/java/moa/classifiers/AbstractMultipleRegressorTestCase.java index 657782eed..1cfab00ef 100644 --- a/moa/src/test/java/moa/classifiers/AbstractMultipleRegressorTestCase.java +++ b/moa/src/test/java/moa/classifiers/AbstractMultipleRegressorTestCase.java @@ -22,7 +22,6 @@ import moa.core.Example; import moa.evaluation.BasicRegressionPerformanceEvaluator; -import moa.evaluation.ClassificationPerformanceEvaluator; import moa.evaluation.LearningPerformanceEvaluator; /** diff --git a/moa/src/test/java/moa/classifiers/active/ActiveClassifierTest.java b/moa/src/test/java/moa/classifiers/active/ActiveClassifierTest.java index 51cce2895..4ccc930ce 100644 --- a/moa/src/test/java/moa/classifiers/active/ActiveClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/active/ActiveClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the ActiveClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/drift/SingleClassifierDriftTest.java b/moa/src/test/java/moa/classifiers/drift/SingleClassifierDriftTest.java index 3fe81a73c..959679e80 100644 --- a/moa/src/test/java/moa/classifiers/drift/SingleClassifierDriftTest.java +++ b/moa/src/test/java/moa/classifiers/drift/SingleClassifierDriftTest.java @@ -24,7 +24,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the SingleClassifierDrift classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/MajorityClassTest.java b/moa/src/test/java/moa/classifiers/functions/MajorityClassTest.java index c74a92408..05cd19aaa 100644 --- a/moa/src/test/java/moa/classifiers/functions/MajorityClassTest.java +++ b/moa/src/test/java/moa/classifiers/functions/MajorityClassTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the MajorityClass classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/NoChangeTest.java b/moa/src/test/java/moa/classifiers/functions/NoChangeTest.java index 9bb60fb75..f2a16a5ae 100644 --- a/moa/src/test/java/moa/classifiers/functions/NoChangeTest.java +++ b/moa/src/test/java/moa/classifiers/functions/NoChangeTest.java @@ -24,7 +24,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the NoChange classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/PerceptronTest.java b/moa/src/test/java/moa/classifiers/functions/PerceptronTest.java index b7bf710dc..7019b4a25 100644 --- a/moa/src/test/java/moa/classifiers/functions/PerceptronTest.java +++ b/moa/src/test/java/moa/classifiers/functions/PerceptronTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the Perceptron classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/SGDTest.java b/moa/src/test/java/moa/classifiers/functions/SGDTest.java index 7319242a9..34f6c6783 100644 --- a/moa/src/test/java/moa/classifiers/functions/SGDTest.java +++ b/moa/src/test/java/moa/classifiers/functions/SGDTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the SGD classifier. diff --git a/moa/src/test/java/moa/classifiers/functions/SPegasosTest.java b/moa/src/test/java/moa/classifiers/functions/SPegasosTest.java index 5f6d7c5d7..6586cb408 100644 --- a/moa/src/test/java/moa/classifiers/functions/SPegasosTest.java +++ b/moa/src/test/java/moa/classifiers/functions/SPegasosTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the SPegasos classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/AccuracyUpdatedEnsembleTest.java b/moa/src/test/java/moa/classifiers/meta/AccuracyUpdatedEnsembleTest.java index 404dbd614..54044879c 100644 --- a/moa/src/test/java/moa/classifiers/meta/AccuracyUpdatedEnsembleTest.java +++ b/moa/src/test/java/moa/classifiers/meta/AccuracyUpdatedEnsembleTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the AccuracyUpdatedEnsemble classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/AccuracyWeightedEnsembleTest.java b/moa/src/test/java/moa/classifiers/meta/AccuracyWeightedEnsembleTest.java index 9a1be3d65..62aa6ff98 100644 --- a/moa/src/test/java/moa/classifiers/meta/AccuracyWeightedEnsembleTest.java +++ b/moa/src/test/java/moa/classifiers/meta/AccuracyWeightedEnsembleTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the AccuracyWeightedEnsemble classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/LeveragingBagTest.java b/moa/src/test/java/moa/classifiers/meta/LeveragingBagTest.java index 901b86331..015aa68a4 100644 --- a/moa/src/test/java/moa/classifiers/meta/LeveragingBagTest.java +++ b/moa/src/test/java/moa/classifiers/meta/LeveragingBagTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the LeveragingBag classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/LimAttClassifierTest.java b/moa/src/test/java/moa/classifiers/meta/LimAttClassifierTest.java index 17eaf73e3..0daec8b4b 100644 --- a/moa/src/test/java/moa/classifiers/meta/LimAttClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/meta/LimAttClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the LimAttClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OCBoostTest.java b/moa/src/test/java/moa/classifiers/meta/OCBoostTest.java index 4954c654a..e536ff91c 100644 --- a/moa/src/test/java/moa/classifiers/meta/OCBoostTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OCBoostTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OCBoost classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsembleTest.java b/moa/src/test/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsembleTest.java index 984aa61fa..3b5070ad3 100644 --- a/moa/src/test/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsembleTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsembleTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OnlineAccuracyUpdatedEnsemble classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBagASHTTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBagASHTTest.java index 2a3e0ef96..5c77a5fea 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBagASHTTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBagASHTTest.java @@ -24,7 +24,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBagASHT classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBagAdwinTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBagAdwinTest.java index 653d4ba08..5b63754e8 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBagAdwinTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBagAdwinTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBagAdwin classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBagTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBagTest.java index a70e900d9..8b9975880 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBagTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBagTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBag classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBoostAdwinTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBoostAdwinTest.java index ae14a1fcb..edd191889 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBoostAdwinTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBoostAdwinTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBoostAdwin classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/OzaBoostTest.java b/moa/src/test/java/moa/classifiers/meta/OzaBoostTest.java index 313694835..679bb2fbe 100644 --- a/moa/src/test/java/moa/classifiers/meta/OzaBoostTest.java +++ b/moa/src/test/java/moa/classifiers/meta/OzaBoostTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the OzaBoost classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/TemporallyAugmentedClassifierTest.java b/moa/src/test/java/moa/classifiers/meta/TemporallyAugmentedClassifierTest.java index 8f4b711ac..e38df4f74 100644 --- a/moa/src/test/java/moa/classifiers/meta/TemporallyAugmentedClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/meta/TemporallyAugmentedClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the TemporallyAugmentedClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/WEKAClassifierTest.java b/moa/src/test/java/moa/classifiers/meta/WEKAClassifierTest.java index edfb78792..cbed95b51 100644 --- a/moa/src/test/java/moa/classifiers/meta/WEKAClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/meta/WEKAClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the WEKAClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/meta/WeightedMajorityAlgorithmTest.java b/moa/src/test/java/moa/classifiers/meta/WeightedMajorityAlgorithmTest.java index bbef3c0e7..16061d035 100644 --- a/moa/src/test/java/moa/classifiers/meta/WeightedMajorityAlgorithmTest.java +++ b/moa/src/test/java/moa/classifiers/meta/WeightedMajorityAlgorithmTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the WeightedMajorityAlgorithm classifier. diff --git a/moa/src/test/java/moa/classifiers/rules/AMRulesRegressorTest.java b/moa/src/test/java/moa/classifiers/rules/AMRulesRegressorTest.java index a66b6717d..b07a43514 100644 --- a/moa/src/test/java/moa/classifiers/rules/AMRulesRegressorTest.java +++ b/moa/src/test/java/moa/classifiers/rules/AMRulesRegressorTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleRegressorTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the AMRulesRegressor classifier. diff --git a/moa/src/test/java/moa/classifiers/rules/RuleClassifierNBayesTest.java b/moa/src/test/java/moa/classifiers/rules/RuleClassifierNBayesTest.java index c78ed0149..ba1ac994d 100644 --- a/moa/src/test/java/moa/classifiers/rules/RuleClassifierNBayesTest.java +++ b/moa/src/test/java/moa/classifiers/rules/RuleClassifierNBayesTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the RuleClassifierNBayes classifier. diff --git a/moa/src/test/java/moa/classifiers/rules/RuleClassifierTest.java b/moa/src/test/java/moa/classifiers/rules/RuleClassifierTest.java index 4660bde9b..4d5562a3e 100644 --- a/moa/src/test/java/moa/classifiers/rules/RuleClassifierTest.java +++ b/moa/src/test/java/moa/classifiers/rules/RuleClassifierTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the RuleClassifier classifier. diff --git a/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabeLTest.java b/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabeLTest.java index b34e58063..bc3da45c5 100644 --- a/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabeLTest.java +++ b/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabeLTest.java @@ -1,7 +1,6 @@ package moa.classifiers.rules.multilabel.core.voting; -import static org.junit.Assert.*; -import moa.classifiers.rules.core.voting.InverseErrorWeightedVote; +import static org.junit.Assert.assertEquals; import org.junit.BeforeClass; import org.junit.Test; diff --git a/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java b/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java index e9f91997a..92ff6bdcb 100644 --- a/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java +++ b/moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java @@ -1,10 +1,10 @@ package moa.classifiers.rules.multilabel.core.voting; +import static org.junit.Assert.assertEquals; + import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assert.*; - import com.yahoo.labs.samoa.instances.MultiLabelPrediction; import com.yahoo.labs.samoa.instances.Prediction; diff --git a/moa/src/test/java/moa/classifiers/trees/ASHoeffdingTreeTest.java b/moa/src/test/java/moa/classifiers/trees/ASHoeffdingTreeTest.java index 1614cb051..4012c9652 100644 --- a/moa/src/test/java/moa/classifiers/trees/ASHoeffdingTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/ASHoeffdingTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the ASHoeffdingTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/AdaHoeffdingOptionTreeTest.java b/moa/src/test/java/moa/classifiers/trees/AdaHoeffdingOptionTreeTest.java index 3960e6d97..fd343eaea 100644 --- a/moa/src/test/java/moa/classifiers/trees/AdaHoeffdingOptionTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/AdaHoeffdingOptionTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the AdaHoeffdingOptionTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/DecisionStumpTest.java b/moa/src/test/java/moa/classifiers/trees/DecisionStumpTest.java index 1e4b3297a..407365442 100644 --- a/moa/src/test/java/moa/classifiers/trees/DecisionStumpTest.java +++ b/moa/src/test/java/moa/classifiers/trees/DecisionStumpTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the DecisionStump classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java b/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java index eb863020e..fa2876054 100644 --- a/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java +++ b/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleRegressorTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the FIMTDD classifier. @@ -31,8 +30,7 @@ * @author fracpete (fracpete at waikato dot ac dot nz) * @version $Revision$ */ -public class FIMTDDTest - extends AbstractMultipleRegressorTestCase { +public class FIMTDDTest extends AbstractMultipleRegressorTestCase { /** * Constructs the test case. Called by subclasses. diff --git a/moa/src/test/java/moa/classifiers/trees/HoeffdingAdaptiveTreeTest.java b/moa/src/test/java/moa/classifiers/trees/HoeffdingAdaptiveTreeTest.java index 8729f2fe2..20312bb02 100644 --- a/moa/src/test/java/moa/classifiers/trees/HoeffdingAdaptiveTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/HoeffdingAdaptiveTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the HoeffdingAdaptiveTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/HoeffdingOptionTreeTest.java b/moa/src/test/java/moa/classifiers/trees/HoeffdingOptionTreeTest.java index 1af0b309d..b0ab7fe1c 100644 --- a/moa/src/test/java/moa/classifiers/trees/HoeffdingOptionTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/HoeffdingOptionTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the HoeffdingOptionTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/LimAttHoeffdingTreeTest.java b/moa/src/test/java/moa/classifiers/trees/LimAttHoeffdingTreeTest.java index 8f59fae43..e19351825 100644 --- a/moa/src/test/java/moa/classifiers/trees/LimAttHoeffdingTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/LimAttHoeffdingTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the LimAttHoeffdingTree classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/ORTOTest.java b/moa/src/test/java/moa/classifiers/trees/ORTOTest.java index fd83e41f0..d9ff53950 100644 --- a/moa/src/test/java/moa/classifiers/trees/ORTOTest.java +++ b/moa/src/test/java/moa/classifiers/trees/ORTOTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleRegressorTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the ORTO classifier. diff --git a/moa/src/test/java/moa/classifiers/trees/RandomHoeffdingTreeTest.java b/moa/src/test/java/moa/classifiers/trees/RandomHoeffdingTreeTest.java index 3e804b065..a08f2e4ec 100644 --- a/moa/src/test/java/moa/classifiers/trees/RandomHoeffdingTreeTest.java +++ b/moa/src/test/java/moa/classifiers/trees/RandomHoeffdingTreeTest.java @@ -23,7 +23,6 @@ import junit.framework.TestSuite; import moa.classifiers.AbstractMultipleClassifierTestCase; import moa.classifiers.Classifier; -import static moa.test.MoaTestCase.runTest; /** * Tests the RandomHoeffdingTree classifier. diff --git a/moa/src/test/java/moa/integration/SimpleClusterTest.java b/moa/src/test/java/moa/integration/SimpleClusterTest.java index 678627b38..4ac287d82 100644 --- a/moa/src/test/java/moa/integration/SimpleClusterTest.java +++ b/moa/src/test/java/moa/integration/SimpleClusterTest.java @@ -1,5 +1,11 @@ package moa.integration; +import org.junit.Test; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.Option; + import junit.framework.TestCase; import moa.core.Globals; import moa.core.Measurement; @@ -10,12 +16,6 @@ import moa.tasks.Task; import moa.tasks.TaskThread; -import org.junit.Test; - -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.Option; - /* test that all clusterers run, i.e., do not die on simpe input **/ public class SimpleClusterTest extends TestCase { diff --git a/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java b/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java index 02ee87bf6..86cf29292 100644 --- a/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java +++ b/moa/src/test/java/moa/streams/filters/SelectAttributesFilterTest.java @@ -2,14 +2,13 @@ import static org.junit.Assert.assertEquals; -import moa.streams.ArffFileStream; -import moa.streams.MultiTargetArffFileStream; - import org.junit.BeforeClass; import org.junit.Test; import com.yahoo.labs.samoa.instances.Instance; +import moa.streams.ArffFileStream; + public class SelectAttributesFilterTest { private static double EPS=0.00000001; private static SelectAttributesFilter filter; diff --git a/weka-package/.settings/org.eclipse.jdt.core.prefs b/weka-package/.settings/org.eclipse.jdt.core.prefs index 60105c1b9..6e80039d3 100644 --- a/weka-package/.settings/org.eclipse.jdt.core.prefs +++ b/weka-package/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,8 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.8 From 32d534d2e43c28db1711ab2fe7ff580d214e22fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Tue, 13 Jun 2017 11:58:39 +0200 Subject: [PATCH 29/33] Commit before cleanup --- moa/.classpath | 2 +- .../instances/FeatureRelevanceResult.java | 14 +++++++ .../java/moa/classifiers/meta/OzaBag.java | 3 +- .../moa/classifiers/meta/OzaBagAdwin.java | 3 +- .../trees/{FIMTDD.java => FIMTDD2.java} | 40 ++++++++++++++----- .../trees/{ORTO.java => ORTO2.java} | 8 ++-- .../tasks/EvaluatePrequentialRegression.java | 2 +- .../java/moa/tasks/LearnModelRegression.java | 2 +- .../moa/classifiers/trees/FIMTDDTest.java | 2 +- .../java/moa/classifiers/trees/ORTOTest.java | 2 +- weka-package/.classpath | 2 +- 11 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/FeatureRelevanceResult.java rename moa/src/main/java/moa/classifiers/trees/{FIMTDD.java => FIMTDD2.java} (98%) rename moa/src/main/java/moa/classifiers/trees/{ORTO.java => ORTO2.java} (98%) diff --git a/moa/.classpath b/moa/.classpath index 534b5e52f..fae1a2b37 100644 --- a/moa/.classpath +++ b/moa/.classpath @@ -22,7 +22,7 @@ - + diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/FeatureRelevanceResult.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/FeatureRelevanceResult.java new file mode 100644 index 000000000..cc29c97d4 --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/FeatureRelevanceResult.java @@ -0,0 +1,14 @@ +package com.yahoo.labs.samoa.instances; + +import java.util.List; + +public interface FeatureRelevanceResult { + public void addFeature(Attribute attr); + + public void setFeatureRelevance(Attribute attr, double relevance); + + public double getFeatureRelevance(Attribute attr); + + public List getFeatures(); + +} diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBag.java b/moa/src/main/java/moa/classifiers/meta/OzaBag.java index d43f2da0b..2cc5000cc 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBag.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBag.java @@ -24,6 +24,7 @@ import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; +import moa.classifiers.Regressor; import moa.core.DoubleVector; import moa.core.Measurement; import moa.core.MiscUtils; @@ -49,7 +50,7 @@ * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) * @version $Revision: 7 $ */ -public class OzaBag extends AbstractClassifier { +public class OzaBag extends AbstractClassifier implements Regressor, Classifier { @Override public String getPurposeString() { diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java index 8f790f339..f88027cfe 100644 --- a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwin.java @@ -24,6 +24,7 @@ import moa.classifiers.AbstractClassifier; import moa.classifiers.Classifier; +import moa.classifiers.Regressor; import moa.classifiers.core.driftdetection.ADWIN; import moa.core.DoubleVector; import moa.core.Measurement; @@ -79,7 +80,7 @@ * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) * @version $Revision: 7 $ */ -public class OzaBagAdwin extends AbstractClassifier { +public class OzaBagAdwin extends AbstractClassifier implements Classifier, Regressor { private static final long serialVersionUID = 1L; diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD2.java similarity index 98% rename from moa/src/main/java/moa/classifiers/trees/FIMTDD.java rename to moa/src/main/java/moa/classifiers/trees/FIMTDD2.java index b41e55c5a..6c24de38a 100644 --- a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD2.java @@ -48,14 +48,14 @@ * Implementation of FIMTDD, regression and model trees for data streams. */ -public class FIMTDD extends AbstractClassifier implements Regressor { +public class FIMTDD2 extends AbstractClassifier implements Regressor { private static final long serialVersionUID = 1L; public Node treeRoot; - protected int leafNodeCount = 0; - protected int splitNodeCount = 0; + public int leafNodeCount = 0; + public int splitNodeCount = 0; protected double examplesSeen = 0.0; protected double sumOfValues = 0.0; @@ -117,6 +117,10 @@ public class FIMTDD extends AbstractClassifier implements Regressor { public FlagOption learningRatioConstOption = new FlagOption( "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); + + public IntOption maxDepthOption = new IntOption( + "maxDepthFactor", 'b', "The maximum depth of the tree.", + Integer.MAX_VALUE, 0, Integer.MAX_VALUE); //endregion ================ OPTIONS ================ @@ -128,7 +132,7 @@ public abstract static class Node extends AbstractMOAObject { public int ID; - protected FIMTDD tree; + protected FIMTDD2 tree; protected boolean changeDetection = true; @@ -147,7 +151,7 @@ public abstract static class Node extends AbstractMOAObject { // Sum of absolute errors protected double sumOfAbsErrors; // Needed for PH tracking of mean error - public Node(FIMTDD tree) { + public Node(FIMTDD2 tree) { this.tree = tree; ID = tree.maxID; } @@ -226,6 +230,10 @@ public int getNumSubtrees() { return 1; } + public int numLeaves() { + return 1; + } + protected boolean skipInLevelCount() { return false; } @@ -248,7 +256,7 @@ public static class LeafNode extends Node { /** * Create a new LeafNode */ - public LeafNode(FIMTDD tree) { + public LeafNode(FIMTDD2 tree) { super(tree); if (tree.buildingModelTree()) { learningModel = tree.newLeafModel(); @@ -381,7 +389,7 @@ public double getPrediction(Instance inst) { public void checkForSplit(Instance inst, double prediction) { // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node - if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { + if (this.getLevel() < tree.maxDepthOption.getValue() && examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { int index = (parent != null) ? parent.getChildIndex(this) : 0; tree.attemptToSplit(this, parent, index, inst, prediction); @@ -421,7 +429,7 @@ public abstract static class InnerNode extends Node { protected double lossSumQi; protected double previousWeight = 0; - public InnerNode(FIMTDD tree) { + public InnerNode(FIMTDD2 tree) { super(tree); } @@ -436,6 +444,12 @@ public int numChildren() { return children.size(); } + public int numLeaves() { + int leaves = 0; + for (Node child : children) leaves += child.numLeaves(); + return leaves; + } + public Node getChild(int index) { return children.get(index); } @@ -516,7 +530,7 @@ public static class SplitNode extends InnerNode { * Create a new SplitNode * @param tree */ - public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { + public SplitNode(InstanceConditionalTest splitTest, FIMTDD2 tree) { super(tree); this.splitTest = splitTest; } @@ -558,7 +572,7 @@ public class FIMTDDPerceptron implements Serializable { private static final long serialVersionUID = 1L; - protected FIMTDD tree; + protected FIMTDD2 tree; // The Perception weights protected double[] weightAttribute; @@ -576,7 +590,7 @@ public FIMTDDPerceptron(FIMTDDPerceptron original) { instancesSeen = original.instancesSeen / 2; } - public FIMTDDPerceptron(FIMTDD tree) { + public FIMTDDPerceptron(FIMTDD2 tree) { this.tree = tree; initializeWeights(); @@ -837,6 +851,7 @@ public void processInstance(Instance inst, Node node, double prediction, double // Switch the subtrees Node parent = iNode.getParent(); + System.out.println("Switching trees!"); if (parent != null) { Node replacementTree = iNode.alternateTree; parent.setChild(parent.getChildIndex(iNode), replacementTree); @@ -845,6 +860,8 @@ public void processInstance(Instance inst, Node node, double prediction, double treeRoot = iNode.alternateTree; treeRoot.restartChangeDetection(); } + leafNodeCount += iNode.alternateTree.numLeaves() - iNode.numLeaves(); + currentNode = iNode.alternateTree; currentNode.originalNode = null; @@ -865,6 +882,7 @@ public void processInstance(Instance inst, Node node, double prediction, double if (iNode.changeDetection && !inAlternate) { if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + System.out.println("CD triggered!"); iNode.initializeAlternateTree(); growthAllowed = false; } diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO.java b/moa/src/main/java/moa/classifiers/trees/ORTO2.java similarity index 98% rename from moa/src/main/java/moa/classifiers/trees/ORTO.java rename to moa/src/main/java/moa/classifiers/trees/ORTO2.java index f31e2b480..05e41a208 100644 --- a/moa/src/main/java/moa/classifiers/trees/ORTO.java +++ b/moa/src/main/java/moa/classifiers/trees/ORTO2.java @@ -43,7 +43,7 @@ * Implementation of ORTO, option trees for data streams. */ -public class ORTO extends FIMTDD implements Regressor { +public class ORTO2 extends FIMTDD2 implements Regressor { private static final long serialVersionUID = 1L; @@ -96,7 +96,7 @@ public static class OptionNode extends InnerNode { protected double[] optionFFSSL; protected double[] optionFFSeen; - public OptionNode(FIMTDD tree) { + public OptionNode(FIMTDD2 tree) { super(tree); } @@ -140,13 +140,13 @@ public double getPrediction(Instance inst) { } private double aggregate(double[] predictions) { - if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average + if (((ORTO2) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average double sum = 0.0; for (int i = 0; i < predictions.length; i++) { sum += predictions[i]; } return sum / predictions.length; - } else if (((ORTO) tree).optionNodeAggregationOption.getChosenIndex() == 1) { + } else if (((ORTO2) tree).optionNodeAggregationOption.getChosenIndex() == 1) { int d = directionForBestTree(); return predictions[d]; } else { diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java index 56996cb47..8f0d2839a 100644 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialRegression.java @@ -63,7 +63,7 @@ public String getPurposeString() { private static final long serialVersionUID = 1L; public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", Regressor.class, "moa.classifiers.trees.FIMTDD"); + "Learner to train.", Regressor.class, "moa.classifiers.trees.ORTO"); public ClassOption streamOption = new ClassOption("stream", 's', "Stream to learn from.", ExampleStream.class, diff --git a/moa/src/main/java/moa/tasks/LearnModelRegression.java b/moa/src/main/java/moa/tasks/LearnModelRegression.java index 4869602e3..fd92e8453 100644 --- a/moa/src/main/java/moa/tasks/LearnModelRegression.java +++ b/moa/src/main/java/moa/tasks/LearnModelRegression.java @@ -45,7 +45,7 @@ public String getPurposeString() { private static final long serialVersionUID = 1L; public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", Regressor.class, "moa.classifiers.trees.FIMTDD"); + "Learner to train.", Regressor.class, "moa.classifiers.trees.HoeffdingTree"); public ClassOption streamOption = new ClassOption("stream", 's', "Stream to learn from.", ExampleStream.class, diff --git a/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java b/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java index fa2876054..dc931074a 100644 --- a/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java +++ b/moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java @@ -50,7 +50,7 @@ public FIMTDDTest(String name) { @Override protected Classifier[] getRegressionClassifierSetups() { return new Classifier[]{ - new FIMTDD(), + new FIMTDD2(), }; } diff --git a/moa/src/test/java/moa/classifiers/trees/ORTOTest.java b/moa/src/test/java/moa/classifiers/trees/ORTOTest.java index d9ff53950..4a86c0099 100644 --- a/moa/src/test/java/moa/classifiers/trees/ORTOTest.java +++ b/moa/src/test/java/moa/classifiers/trees/ORTOTest.java @@ -51,7 +51,7 @@ public ORTOTest(String name) { @Override protected Classifier[] getRegressionClassifierSetups() { return new Classifier[]{ - new ORTO(), + new ORTO2(), }; } diff --git a/weka-package/.classpath b/weka-package/.classpath index fd7ad7fbd..af1430be1 100644 --- a/weka-package/.classpath +++ b/weka-package/.classpath @@ -12,7 +12,7 @@ - + From 5c0c858ce4883b6cbe3b73563540aa08d9be8f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Sun, 2 Jul 2017 23:49:22 +0200 Subject: [PATCH 30/33] Learner, Prediction rework --- README.md | 0 moa/pom.xml.orig | 156 +++ .../predictions/ClassificationPrediction.java | 132 +++ .../MultiTargetRegressionPrediction.java | 134 +++ .../predictions/RegressionPrediction.java | 119 ++ .../moa/classifiers/AbstractClassifier.java | 7 + .../classifiers/AbstractEnsembleLearner.java | 77 ++ .../AbstractMultiLabelClassifier.java | 20 + .../AbstractMultiLabelLearner.java | 46 - .../AbstractMultiTargetRegressor.java | 22 + .../moa/classifiers/AbstractRegressor.java | 9 + .../moa/classifiers/MultiLabelLearner.java | 12 - .../moa/classifiers/meta/OzaBagASHT.java.orig | 200 ++++ .../meta/OzaBagAdwinClassification.java | 31 + .../meta/OzaBagAdwinRegression.java | 28 + .../meta/OzaBagClassification.java | 33 + .../classifiers/meta/OzaBagRegression.java | 24 + .../meta/OzaBoostClassification.java | 46 + .../classifiers/meta/RegressionViaMTR.java | 54 + .../TemporallyAugmentedClassifier.java.orig | 190 +++ .../mlc/MultilabelHoeffdingTree.java.orig | 237 ++++ .../moa/classifiers/mlc/meta/MLOzaBag.java | 126 -- .../java/moa/classifiers/trees/FIMTDD.java | 1031 +++++++++++++++++ .../moa/classifiers/trees/ORTO2.java.orig | 543 +++++++++ .../clusterers/clustree/ClusTree.java.orig | 891 ++++++++++++++ .../java/moa/learners/InstanceLearner.java | 56 + .../moa/tasks/ClassificationMainTask.java | 5 + .../EvaluateInterleavedTestThenTrain.java | 218 ---- .../EvaluatePeriodicHeldOutTest.java.orig | 308 +++++ .../EvaluatePrequentialClassification.java | 30 + ...tePrequentialMultiLabelClassification.java | 27 + .../EvaluatePrequentialMultiTarget.java.orig | 713 ++++++++++++ .../moa/tasks/LearnModelClassification.java | 19 + .../LearnModelMultiLabelClassification.java | 20 + .../java/moa/tasks/MainTaskInterface.java | 10 + .../MultiLabelClassificatioMainTask.java | 5 + weka-package/.classpath | 2 +- .../.settings/org.eclipse.jdt.core.prefs | 6 +- weka-package/pom.xml.orig | 57 + 39 files changed, 5238 insertions(+), 406 deletions(-) mode change 100755 => 100644 README.md create mode 100644 moa/pom.xml.orig create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/ClassificationPrediction.java create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/MultiTargetRegressionPrediction.java create mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/RegressionPrediction.java create mode 100644 moa/src/main/java/moa/classifiers/AbstractClassifier.java create mode 100644 moa/src/main/java/moa/classifiers/AbstractEnsembleLearner.java create mode 100644 moa/src/main/java/moa/classifiers/AbstractMultiLabelClassifier.java delete mode 100644 moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java create mode 100644 moa/src/main/java/moa/classifiers/AbstractMultiTargetRegressor.java create mode 100644 moa/src/main/java/moa/classifiers/AbstractRegressor.java delete mode 100644 moa/src/main/java/moa/classifiers/MultiLabelLearner.java create mode 100644 moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java.orig create mode 100644 moa/src/main/java/moa/classifiers/meta/OzaBagAdwinClassification.java create mode 100644 moa/src/main/java/moa/classifiers/meta/OzaBagAdwinRegression.java create mode 100644 moa/src/main/java/moa/classifiers/meta/OzaBagClassification.java create mode 100644 moa/src/main/java/moa/classifiers/meta/OzaBagRegression.java create mode 100644 moa/src/main/java/moa/classifiers/meta/OzaBoostClassification.java create mode 100644 moa/src/main/java/moa/classifiers/meta/RegressionViaMTR.java create mode 100644 moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java.orig create mode 100644 moa/src/main/java/moa/classifiers/mlc/MultilabelHoeffdingTree.java.orig delete mode 100644 moa/src/main/java/moa/classifiers/mlc/meta/MLOzaBag.java create mode 100644 moa/src/main/java/moa/classifiers/trees/FIMTDD.java create mode 100644 moa/src/main/java/moa/classifiers/trees/ORTO2.java.orig create mode 100644 moa/src/main/java/moa/clusterers/clustree/ClusTree.java.orig create mode 100644 moa/src/main/java/moa/learners/InstanceLearner.java create mode 100644 moa/src/main/java/moa/tasks/ClassificationMainTask.java delete mode 100644 moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java create mode 100644 moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java.orig create mode 100644 moa/src/main/java/moa/tasks/EvaluatePrequentialClassification.java create mode 100644 moa/src/main/java/moa/tasks/EvaluatePrequentialMultiLabelClassification.java create mode 100644 moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java.orig create mode 100644 moa/src/main/java/moa/tasks/LearnModelClassification.java create mode 100644 moa/src/main/java/moa/tasks/LearnModelMultiLabelClassification.java create mode 100644 moa/src/main/java/moa/tasks/MainTaskInterface.java create mode 100644 moa/src/main/java/moa/tasks/MultiLabelClassificatioMainTask.java create mode 100644 weka-package/pom.xml.orig diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/moa/pom.xml.orig b/moa/pom.xml.orig new file mode 100644 index 000000000..8edfa56e1 --- /dev/null +++ b/moa/pom.xml.orig @@ -0,0 +1,156 @@ + + 4.0.0 + + + nz.ac.waikato.cms.moa + moa-pom +<<<<<<< Updated upstream + 2014.04 +======= + 2017.10-SNAPSHOT +>>>>>>> Stashed changes + + + moa + jar + + MOA: Massive Online Analysis + + Massive On-line Analysis is an environment for massive data mining. MOA + provides a framework for data stream mining and includes tools for evaluation + and a collection of machine learning algorithms. Related to the WEKA project, + also written in Java, while scaling to more demanding problems. + + http://moa.cms.waikato.ac.nz/ + + University of Waikato, Hamilton, NZ + http://www.waikato.ac.nz/ + + + + GNU General Public License 3.0 + http://www.gnu.org/licenses/gpl-3.0.txt + repo + + + + + + abifet + Albert Bifet + abifet@waikato.ac.nz + + + rkirkby + Richard Kirkby + + + + + + nz.ac.waikato.cms.weka + weka-dev + + + + com.googlecode.sizeofag + sizeofag + + +<<<<<<< Updated upstream +======= + + net.sf.meka + meka + + +>>>>>>> Stashed changes + + junit + junit + test + + + + org.apache.commons + commons-math3 + 3.6.1 + + + + com.googlecode.java-diff-utils + diffutils + 1.2.1 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.7 + 1.7 + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + org.codehaus.mojo + license-maven-plugin + + + + org.codehaus.mojo + latex-maven-plugin + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + + license-maven-plugin + + [1.1,) + + add-third-party + + + + + + + + + + + + + + diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/ClassificationPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/ClassificationPrediction.java new file mode 100644 index 000000000..9e311f188 --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/ClassificationPrediction.java @@ -0,0 +1,132 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package com.yahoo.labs.samoa.instances.predictions; + +import java.io.Serializable; + +import com.yahoo.labs.samoa.instances.Attribute; + +import moa.core.DoubleVector; + +public class ClassificationPrediction implements Prediction, Serializable { + + private static final long serialVersionUID = 1L; + + protected double[] prediction; + + protected Attribute classAttribute; + + public ClassificationPrediction() { + } + + public ClassificationPrediction(double[] prediction) { + this.prediction = prediction; + } + + public void setClassAttribute(Attribute a) { + this.classAttribute = a; + } + + @Override + public int numOutputAttributes() { + return 1; + } + + @Override + public int numClasses(int outputAttributeIndex) { + throw new UnsupportedOperationException("This is a single-target classification prediction."); + } + + @Override + public double[] getVotes(int outputAttributeIndex) { + throw new UnsupportedOperationException("This is a single-target classification prediction."); + } + + @Override + public double[] getVotes() { + return prediction; + } + + @Override + public double getVote(int outputAttributeIndex, int classIndex) { + throw new UnsupportedOperationException("This is a single-target classification prediction."); + } + + @Override + public void setVotes(int outputAttributeIndex, double[] votes) { + throw new UnsupportedOperationException("This is a single-target classification prediction."); + } + + @Override + public void setVotes(double[] votes) { + this.prediction = votes; + } + + @Override + public void setVote(int outputAttributeIndex, int classIndex, double vote) { + throw new UnsupportedOperationException("This is a single-target classification prediction."); + } + + @Override + public String toString() { + StringBuffer sb= new StringBuffer(); + sb.append("Out: "); + int id = 0; + double max = Double.NEGATIVE_INFINITY; + for (int i = 0; i < prediction.length; i++) { + if (prediction[i] > max) { + id = i; + max = prediction[i]; + } + } + if (classAttribute != null) { + sb.append(classAttribute.value(id)); + } else + sb.append(id); + return sb.toString(); + } + + @Override + public boolean hasVotesForAttribute(int outputAttributeIndex) { + throw new UnsupportedOperationException("This is a single-target classification prediction."); + } + + @Override + public int size() { + return 1; + } + + public double asDouble() { + throw new UnsupportedOperationException("This is a classification prediction."); + } + + public DoubleVector asDoubleVector() { + return new DoubleVector(prediction); + } + + public double[] asDoubleArray() { + return prediction; + } + + public String asPredictionString() { + return String.valueOf(prediction.toString()); + } + + @Override + public double getPrediction(int outputAttributeIndex) { + throw new UnsupportedOperationException("This is a single-target classification prediction."); + } + +} diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/MultiTargetRegressionPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/MultiTargetRegressionPrediction.java new file mode 100644 index 000000000..7023a1316 --- /dev/null +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/MultiTargetRegressionPrediction.java @@ -0,0 +1,134 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package com.yahoo.labs.samoa.instances.predictions; + +import java.io.Serializable; + +import moa.core.DoubleVector; + +public class MultiTargetRegressionPrediction implements Prediction, Serializable { + /** + * + */ + private static final long serialVersionUID = 1L; + + protected DoubleVector prediction; + + public MultiTargetRegressionPrediction() { + this(0); + } + + public MultiTargetRegressionPrediction(int numOutputAttributes) { + prediction=new DoubleVector(); + for (int i=0; i < numOutputAttributes;i++) + prediction.setValue(i, 0.0);; + } + + public MultiTargetRegressionPrediction(DoubleVector prediction) { + this.prediction = prediction; + } + + public MultiTargetRegressionPrediction(double[] prediction) { + this.prediction = new DoubleVector(prediction); + } + + + @Override + public int numOutputAttributes() { + return prediction.numValues(); + } + + @Override + public int numClasses(int outputAttributeIndex) { + throw new UnsupportedOperationException("This is a multi-target regression prediction. Each output attribute corresponds to a continuouos variable."); + } + + @Override + public double[] getVotes(int outputAttributeIndex) { + throw new UnsupportedOperationException("This is a multi-target regression prediction. Each output attribute corresponds to a continuouos variable."); + } + + @Override + public double[] getVotes() { + return this.asDoubleArray(); + } + + @Override + public double getVote(int outputAttributeIndex, int classIndex) { + throw new UnsupportedOperationException("This is a multi-target regression prediction. Each output attribute corresponds to a continuouos variable."); + } + + @Override + public void setVotes(int outputAttributeIndex, double[] votes) { + throw new UnsupportedOperationException("This is a multi-target regression prediction. Each output attribute corresponds to a continuouos variable."); + } + + @Override + public void setVotes(double[] votes) { + setVotes(0, votes); + } + + @Override + public void setVote(int outputAttributeIndex, int classIndex, double vote) { + throw new UnsupportedOperationException("This is a multi-target regression prediction. Each output attribute corresponds to a continuouos variable."); + } + + @Override + public String toString() { + StringBuffer sb= new StringBuffer(); + // TODO +// for (int i=0; i implements Classifier { + +} diff --git a/moa/src/main/java/moa/classifiers/AbstractEnsembleLearner.java b/moa/src/main/java/moa/classifiers/AbstractEnsembleLearner.java new file mode 100644 index 000000000..67984cfa3 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/AbstractEnsembleLearner.java @@ -0,0 +1,77 @@ +package moa.classifiers; + +import java.util.ArrayList; + +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.predictions.Prediction; + +import moa.core.Measurement; +import moa.learners.InstanceLearner; +import moa.options.ClassOption; + +public abstract class AbstractEnsembleLearner extends AbstractInstanceLearner { + + private static final long serialVersionUID = 1L; + + public ClassOption baseLearnerOption; + + public IntOption ensembleSizeOption = new IntOption("ensembleSize", 's', + "The number of models in the ensemble.", 10, 1, Integer.MAX_VALUE); + + public ArrayList ensemble; + + public long measureByteSize() { + long size = 0; + for (MLTask c : ensemble) + size += c.measureByteSize(); + return size; + } + + @SuppressWarnings("unchecked") + @Override + public void resetLearningImpl() { + this.ensemble = new ArrayList(this.ensembleSizeOption.getValue()); + MLTask baseLearner = (MLTask) getPreparedClassOption(this.baseLearnerOption); + for (int i = 0; i < this.ensemble.size(); i++) { + this.ensemble.set(i, (MLTask) baseLearner.copy()); + this.ensemble.get(i).setRandomSeed(this.randomSeed + i * 100); + } + } + + public abstract Prediction combinePredictions(Prediction[] predictions); + + public Prediction getPredictionForInstance(Instance inst) { + Prediction[] predictions = new Prediction[this.ensemble.size()]; + for (int i = 0; i < this.ensemble.size(); i++) { + predictions[i] = this.ensemble.get(i).getPredictionForInstance(inst); + } + return combinePredictions(predictions); + } + + public Prediction getPredictionForInstanceUsingN(Instance inst, int n) { + Prediction[] predictions = new Prediction[this.ensemble.size()]; + for (int i = 0; i < n; i++) { + predictions[i] = this.ensemble.get(i).getPredictionForInstance(inst); + } + return combinePredictions(predictions); + } + + @Override + public void modelContextSet() { + for (int i = 0; i < this.ensemble.size(); i++) { + this.ensemble.get(i).setModelContext(this.getModelContext());; + } + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{new Measurement("ensemble size", + this.ensemble != null ? this.ensemble.size() : 0)}; + } + + @SuppressWarnings("unchecked") + public MLTask[] getSubClassifiers() { + return (MLTask[]) this.ensemble.clone(); + } +} diff --git a/moa/src/main/java/moa/classifiers/AbstractMultiLabelClassifier.java b/moa/src/main/java/moa/classifiers/AbstractMultiLabelClassifier.java new file mode 100644 index 000000000..a220d147a --- /dev/null +++ b/moa/src/main/java/moa/classifiers/AbstractMultiLabelClassifier.java @@ -0,0 +1,20 @@ +package moa.classifiers; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.MultiLabelInstance; +import com.yahoo.labs.samoa.instances.predictions.Prediction; + +import moa.learners.MultiLabelClassifier; + +public abstract class AbstractMultiLabelClassifier extends AbstractInstanceLearner { + + private static final long serialVersionUID = 1L; + + public Prediction getPredictionForInstance(MultiLabelInstance inst) { + return this.getPredictionForInstance((Instance) inst); + } + + public void trainOnInstanceImpl(MultiLabelInstance inst) { + this.trainOnInstanceImpl((Instance) inst); + } +} diff --git a/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java b/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java deleted file mode 100644 index c4ea71475..000000000 --- a/moa/src/main/java/moa/classifiers/AbstractMultiLabelLearner.java +++ /dev/null @@ -1,46 +0,0 @@ -package moa.classifiers; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Prediction; -import com.yahoo.labs.samoa.instances.StructuredInstance; - -import moa.core.Example; - -public abstract class AbstractMultiLabelLearner extends AbstractClassifier implements MultiLabelLearner { - - /** - * - */ - private static final long serialVersionUID = 1L; - - @Override - abstract public void trainOnInstanceImpl(StructuredInstance instance); - - @Override - public void trainOnInstanceImpl(Instance instance) { - trainOnInstanceImpl((StructuredInstance) instance); - } - - @Override - public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance(example.getData()); - } - - @Override - public Prediction getPredictionForInstance(Instance inst) { - return getPredictionForInstance((StructuredInstance) inst); - } - - abstract public Prediction getPredictionForInstance(StructuredInstance inst); - - @Override - public double[] getVotesForInstance(Instance inst) { - Prediction pred = getPredictionForInstance(inst); - if (pred != null) { - return pred.getVotes(); - } else { - return new double[]{0}; //for compatibility with single target code - } - } - -} diff --git a/moa/src/main/java/moa/classifiers/AbstractMultiTargetRegressor.java b/moa/src/main/java/moa/classifiers/AbstractMultiTargetRegressor.java new file mode 100644 index 000000000..54ee2a713 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/AbstractMultiTargetRegressor.java @@ -0,0 +1,22 @@ +package moa.classifiers; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.StructuredInstance; +import com.yahoo.labs.samoa.instances.predictions.Prediction; + +import moa.learners.MultiTargetRegressor; + +public abstract class AbstractMultiTargetRegressor extends AbstractInstanceLearner implements MultiTargetRegressor { + + private static final long serialVersionUID = 1L; + + public Prediction getPredictionForInstance(StructuredInstance instance) { + return this.getPredictionForInstance((Instance) instance); + } + + @Override + public void trainOnInstanceImpl(StructuredInstance inst) { + this.trainOnInstanceImpl((Instance) inst); + } + +} diff --git a/moa/src/main/java/moa/classifiers/AbstractRegressor.java b/moa/src/main/java/moa/classifiers/AbstractRegressor.java new file mode 100644 index 000000000..9e8bfc3b4 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/AbstractRegressor.java @@ -0,0 +1,9 @@ +package moa.classifiers; + +import moa.learners.Regressor; + +public abstract class AbstractRegressor extends AbstractInstanceLearner implements Regressor { + + private static final long serialVersionUID = 1L; + +} diff --git a/moa/src/main/java/moa/classifiers/MultiLabelLearner.java b/moa/src/main/java/moa/classifiers/MultiLabelLearner.java deleted file mode 100644 index 97e995a1c..000000000 --- a/moa/src/main/java/moa/classifiers/MultiLabelLearner.java +++ /dev/null @@ -1,12 +0,0 @@ -package moa.classifiers; - -import com.yahoo.labs.samoa.instances.Prediction; -import com.yahoo.labs.samoa.instances.StructuredInstance; - -public interface MultiLabelLearner extends Classifier{ - - public void trainOnInstanceImpl(StructuredInstance instance); - - public Prediction getPredictionForInstance(StructuredInstance instance); - -} diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java.orig b/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java.orig new file mode 100644 index 000000000..6b78f94de --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java.orig @@ -0,0 +1,200 @@ +/* + * OzaBagASHT.java + * Copyright (C) 2008 University of Waikato, Hamilton, New Zealand + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.classifiers.meta; + +<<<<<<< HEAD +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; + +======= +import moa.options.ClassOption; +>>>>>>> 3d07f07a8e1662963b332241c1fcfe85cebe0609 +import moa.classifiers.Classifier; +import moa.classifiers.trees.ASHoeffdingTree; +import moa.core.DoubleVector; +import moa.core.MiscUtils; +<<<<<<< HEAD +======= +import com.github.javacliparser.IntOption; +import com.github.javacliparser.FlagOption; +import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.core.Measurement; +>>>>>>> 3d07f07a8e1662963b332241c1fcfe85cebe0609 +import moa.core.Utils; + +/** + * Bagging using trees of different size. + * The Adaptive-Size Hoeffding Tree (ASHT) is derived from the Hoeffding Tree + * algorithm with the following differences: + *

    + *
  • it has a maximum number of split nodes, or size + *
  • after one node splits, if the number of split nodes of the ASHT tree + * is higher than the maximum value, then it deletes some nodes to reduce its size + *
+ * The intuition behind this method is as follows: smaller trees adapt + * more quickly to changes, and larger trees do better during periods with + * no or little change, simply because they were built on more data. Trees + * limited to size s will be reset about twice as often as trees with a size + * limit of 2s. This creates a set of different reset-speeds for an ensemble of such + * trees, and therefore a subset of trees that are a good approximation for the + * current rate of change. It is important to note that resets will happen all + * the time, even for stationary datasets, but this behaviour should not have + * a negative impact on the ensemble’s predictive performance. + * When the tree size exceeds the maximun size value, there are two different + * delete options:
    + *
  • delete the oldest node, the root, and all of its children except the one + * where the split has been made. After that, the root of the child not + * deleted becomes the new root + *
  • delete all the nodes of the tree, i.e., restart from a new root. + *
+ * The maximum allowed size for the n-th ASHT tree is twice the maximum + * allowed size for the (n-1)-th tree. Moreover, each tree has a weight + * proportional to the inverse of the square of its error, and it monitors its + * error with an exponential weighted moving average (EWMA) with alpha = .01. + * The size of the first tree is 2. + *

+ * With this new method, it is attempted to improve bagging performance + * by increasing tree diversity. It has been observed that boosting tends to + * produce a more diverse set of classifiers than bagging, and this has been + * cited as a factor in increased performance.
+ * See more details in:

+ * Albert Bifet, Geoff Holmes, Bernhard Pfahringer, Richard Kirkby, + * and Ricard Gavaldà. New ensemble methods for evolving data + * streams. In 15th ACM SIGKDD International Conference on Knowledge + * Discovery and Data Mining, 2009.

+ * The learner must be ASHoeffdingTree, a Hoeffding Tree with a maximum + * size value.

+ * Example:

+ * OzaBagASHT -l ASHoeffdingTree -s 10 -u -r + * Parameters:
    + *
  • Same parameters as OzaBag + *
  • -f : the size of first classifier in the bag. + *
  • -u : Enable weight classifiers + *
  • -e : Reset trees when size is higher than the max + *
+ * + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * @version $Revision: 7 $ + */ +public class OzaBagASHT extends AbstractClassifier { + + private static final long serialVersionUID = 1L; + + @Override + public String getPurposeString() { + return "Bagging using trees of different size."; + } + + public IntOption ensembleSizeOption = new IntOption("ensembleSize", 's', + "The number of models in the bag.", 10, 1, Integer.MAX_VALUE); + + public IntOption firstClassifierSizeOption = new IntOption("firstClassifierSize", 'f', + "The size of first classifier in the bag.", 1, 1, Integer.MAX_VALUE); + + public FlagOption useWeightOption = new FlagOption("useWeight", + 'u', "Enable weight classifiers."); + + public FlagOption resetTreesOption = new FlagOption("resetTrees", + 'e', "Reset trees when size is higher than the max."); + + public ClassOption baseLearnerOption = new ClassOption("baseLearner", 'l', + "ASHoeffdingTree to train.", ASHoeffdingTree.class, + "moa.classifiers.trees.ASHoeffdingTree"); + + protected ASHoeffdingTree[] ensemble; + protected double[] error; + protected double alpha = 0.01; + + @Override + public void resetLearningImpl() { + this.ensemble = new ASHoeffdingTree[this.ensembleSizeOption.getValue()]; + this.error = new double[this.ensembleSizeOption.getValue()]; + Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); + baseLearner.resetLearning(); + int pow = this.firstClassifierSizeOption.getValue(); + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i] = (ASHoeffdingTree) baseLearner.copy(); + this.error[i] = 0.0; + ((ASHoeffdingTree) this.ensemble[i]).setMaxSize(pow); + if ((this.resetTreesOption != null) + && this.resetTreesOption.isSet()) { + ((ASHoeffdingTree) this.ensemble[i]).setResetTree(); + } + pow *= 2; + } + } + + @Override + public void trainOnInstanceImpl(Instance inst) { + int trueClass = (int) inst.classValue(); + for (int i = 0; i < this.ensemble.length; i++) { + int k = MiscUtils.poisson(1.0, this.classifierRandom); + if (k > 0) { + Instance weightedInst = (Instance) inst.copy(); + weightedInst.setWeight(inst.weight() * k); + if (Utils.maxIndex(this.ensemble[i].getPredictionForInstance(inst)) == trueClass) { + this.error[i] += alpha * (0.0 - this.error[i]); //EWMA + } else { + this.error[i] += alpha * (1.0 - this.error[i]); //EWMA + } + this.ensemble[i].trainOnInstance(weightedInst); + } + } + } + + public Prediction getPredictionForInstance(Instance inst) { + DoubleVector combinedVote = new DoubleVector(); + for (int i = 0; i < this.ensemble.length; i++) { + DoubleVector vote = new DoubleVector(this.ensemble[i].getPredictionForInstance(inst)); + if (vote.sumOfValues() > 0.0) { + vote.normalize(); + if ((this.useWeightOption != null) + && this.useWeightOption.isSet()) { + vote.scaleValues(1.0 / (this.error[i] * this.error[i])); + } + combinedVote.addValues(vote); + } + } + return combinedVote.getArrayRef(); + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + // TODO Auto-generated method stub + } + + @Override + public boolean isRandomizable() { + return true; + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{new Measurement("ensemble size", + this.ensemble != null ? this.ensemble.length : 0)}; + } + + @Override + public Classifier[] getSubClassifiers() { + return this.ensemble.clone(); + } +} diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwinClassification.java b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwinClassification.java new file mode 100644 index 000000000..ae568d20e --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwinClassification.java @@ -0,0 +1,31 @@ +package moa.classifiers.meta; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.predictions.MultiTargetRegressionPrediction; +import com.yahoo.labs.samoa.instances.predictions.Prediction; + +import moa.core.DoubleVector; +import moa.learners.Classifier; + +public class OzaBagAdwinClassification extends AbstractOzaBagAdwin implements Classifier{ + + private static final long serialVersionUID = 1L; + + public OzaBagAdwinClassification() { + super(Classifier.class, "moa.classifiers.trees.HoeffdingTree"); + } + + public double getAdwinError(Instance inst, int i) { + return this.ensemble.get(i).correctlyClassifies(inst) ? 0 : 1; + } + + public Prediction combinePredictions(Prediction[] predictions) { + DoubleVector sums = new DoubleVector(); + for (Prediction p : predictions) { + sums.addValues(p.asDoubleVector()); + } + sums.scaleValues(1 / sums.numValues()); + return new MultiTargetRegressionPrediction(sums); + } + +} diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagAdwinRegression.java b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwinRegression.java new file mode 100644 index 000000000..868594834 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagAdwinRegression.java @@ -0,0 +1,28 @@ +package moa.classifiers.meta; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.predictions.Prediction; +import com.yahoo.labs.samoa.instances.predictions.RegressionPrediction; + +import moa.learners.Regressor; + +public class OzaBagAdwinRegression extends AbstractOzaBagAdwin { + + private static final long serialVersionUID = 1L; + + public OzaBagAdwinRegression() { + super(Regressor.class, "classifiers.trees.FIMTD"); + } + + public double getAdwinError(Instance inst, int i) { + return Math.abs(this.ensemble.get(i).getPredictionForInstance(inst).asDouble() - inst.classValue()); + } + + public Prediction combinePredictions(Prediction[] predictions) { + double sum = 0; + for (Prediction p : predictions) { + sum += p.asDouble(); + } + return new RegressionPrediction(sum / predictions.length); + } +} diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagClassification.java b/moa/src/main/java/moa/classifiers/meta/OzaBagClassification.java new file mode 100644 index 000000000..41acd896a --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagClassification.java @@ -0,0 +1,33 @@ +package moa.classifiers.meta; + +import com.yahoo.labs.samoa.instances.predictions.MultiTargetRegressionPrediction; +import com.yahoo.labs.samoa.instances.predictions.Prediction; + +import moa.core.DoubleVector; +import moa.learners.Classifier; + +public class OzaBagClassification extends AbstractOzaBag implements Classifier { + + + private static final long serialVersionUID = 1L; + + public OzaBagClassification() { + super(Classifier.class, "moa.classifiers.trees.HoeffdingTree"); + } + + public Prediction combinePredictions(Prediction[] predictions) { + DoubleVector sums = new DoubleVector(); + for (Prediction p : predictions) { + sums.addValues(p.asDoubleVector()); + } + sums.scaleValues(1 / sums.numValues()); + return new MultiTargetRegressionPrediction(sums); + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + // TODO Auto-generated method stub + + } + +} diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagRegression.java b/moa/src/main/java/moa/classifiers/meta/OzaBagRegression.java new file mode 100644 index 000000000..4f715b8c1 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/OzaBagRegression.java @@ -0,0 +1,24 @@ +package moa.classifiers.meta; + +import com.yahoo.labs.samoa.instances.predictions.Prediction; +import com.yahoo.labs.samoa.instances.predictions.RegressionPrediction; + +import moa.learners.Regressor; + +public class OzaBagRegression extends AbstractOzaBag implements Regressor { + + private static final long serialVersionUID = 1L; + + public OzaBagRegression() { + super(Regressor.class, "moa.classifiers.trees.FIMTDD"); + } + + public Prediction combinePredictions(Prediction[] predictions) { + double sum = 0; + for (Prediction p : predictions) { + sum += p.asDouble(); + } + return new RegressionPrediction(sum / predictions.length); + } + +} diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBoostClassification.java b/moa/src/main/java/moa/classifiers/meta/OzaBoostClassification.java new file mode 100644 index 000000000..9ed60eaee --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/OzaBoostClassification.java @@ -0,0 +1,46 @@ +package moa.classifiers.meta; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.predictions.ClassificationPrediction; +import com.yahoo.labs.samoa.instances.predictions.Prediction; + +import moa.core.DoubleVector; +import moa.learners.Classifier; + +public class OzaBoostClassification extends AbstractOzaBoost implements Classifier { + + private static final long serialVersionUID = 1L; + + public OzaBoostClassification() { + super(Classifier.class, "moa.classifiers.trees.HoeffdingTree"); + } + + @Override + public void updateWeight(int i, Instance inst) { + double lambda_d = 1.0; + if (this.ensemble.get(i).correctlyClassifies(inst)) { + this.scms[i] += lambda_d; + lambda_d *= this.trainingWeightSeenByModel / (2 * this.scms[i]); + } else { + this.swms[i] += lambda_d; + lambda_d *= this.trainingWeightSeenByModel / (2 * this.swms[i]); + } + } + + @Override + public Prediction combinePredictions(Prediction[] predictions, double[] weights) { + DoubleVector combinedVote = new DoubleVector(); + for (int i = 0; i < predictions.length; i++) { + if (weights[i] > 0.0) { + DoubleVector vote = predictions[i].asDoubleVector(); + if (vote.sumOfValues() > 0.0) { + vote.normalize(); + vote.scaleValues(weights[i]); + combinedVote.addValues(vote); + } + } + } + return new ClassificationPrediction(combinedVote.getArrayRef()); + } + +} diff --git a/moa/src/main/java/moa/classifiers/meta/RegressionViaMTR.java b/moa/src/main/java/moa/classifiers/meta/RegressionViaMTR.java new file mode 100644 index 000000000..578286f9f --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/RegressionViaMTR.java @@ -0,0 +1,54 @@ +package moa.classifiers.meta; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.predictions.Prediction; +import com.yahoo.labs.samoa.instances.predictions.RegressionPrediction; + +import moa.classifiers.AbstractRegressor; +import moa.core.Measurement; +import moa.learners.MultiTargetRegressor; +import moa.learners.Regressor; +import moa.options.ClassOption; + +public class RegressionViaMTR extends AbstractRegressor implements Regressor { + + public MultiTargetRegressor mtr; + + public ClassOption regressorOption = new ClassOption("MTregessor", 'c', "Multi-target regressor to be used as a single target regressor.", MultiTargetRegressor.class, "moa.classifiers.mtr.ISOUPTree"); + + @Override + public boolean isRandomizable() { + return true; + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + out.append("Meta single-target regressor which uses a multi-target regressor with a single target."); + } + + @Override + public Prediction getPredictionForInstance(Instance instance) { + Prediction p = mtr.getPredictionForInstance(instance); + return new RegressionPrediction(p.getPrediction(0)); + } + + @Override + public void trainOnInstanceImpl(Instance inst) { + mtr.trainOnInstance(inst); + } + + @Override + public void resetLearningImpl() { + if (this.mtr == null) + this.mtr = (MultiTargetRegressor) getPreparedClassOption(this.regressorOption); + this.mtr.resetLearning(); + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + return this.mtr.getModelMeasurements(); + } + + + +} diff --git a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java.orig b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java.orig new file mode 100644 index 000000000..15378090c --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java.orig @@ -0,0 +1,190 @@ +/* + * TemporallyAugmentedClassifier.java + * Copyright (C) 2013 University of Waikato, Hamilton, New Zealand + * @author Bernhard Pfahringer (bernhard@cs.waikato.ac.nz) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.classifiers.meta; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +<<<<<<< HEAD +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Attribute; +import com.yahoo.labs.samoa.instances.DenseInstance; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + +======= +import com.yahoo.labs.samoa.instances.*; +>>>>>>> 3d07f07a8e1662963b332241c1fcfe85cebe0609 +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.core.Measurement; +import moa.core.Utils; +import moa.options.ClassOption; + +/** + * Include labels of previous instances into the training data + * + *

This enables a classifier to exploit potentially present auto-correlation + *

+ * + *

Parameters:

  • -l : Classifier to train
  • -n : The number + * of old labels to include
+ * + * @author Bernhard Pfahringer (bernhard@cs.waikato.ac.nz) + * @version $Revision: 1 $ + */ +public class TemporallyAugmentedClassifier extends AbstractClassifier { + + @Override + public String getPurposeString() { + return "Add some old labels to every instance"; + } + private static final long serialVersionUID = 1L; + + public ClassOption baseLearnerOption = new ClassOption("baseLearner", 'l', + "Classifier to train.", Classifier.class, "trees.HoeffdingTree"); + + public IntOption numOldLabelsOption = new IntOption("numOldLabels", 'n', + "The number of old labels to add to each example.", 1, 0, Integer.MAX_VALUE); + + protected Classifier baseLearner; + + protected double[] oldLabels; + + protected InstancesHeader header; + + public FlagOption labelDelayOption = new FlagOption("labelDelay", 'd', + "Labels arrive with Delay. Use predictions instead of true Labels."); + + @Override + public void resetLearningImpl() { + this.baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); + this.oldLabels = new double[this.numOldLabelsOption.getValue()]; + this.header = null; + baseLearner.resetLearning(); + } + + @Override + public void trainOnInstanceImpl(Instance instance) { + this.baseLearner.trainOnInstance(extendWithOldLabels(instance)); + if (this.labelDelayOption.isSet() == false) { + // Use true old Labels to add attributes to instances + addOldLabel(instance.classValue()); + } + } + + public void addOldLabel(double newPrediction) { + int numLabels = this.oldLabels.length; + if (numLabels > 0) { + for (int i = 1; i < numLabels; i++) { + this.oldLabels[i - 1] = this.oldLabels[i]; + } + this.oldLabels[ numLabels - 1] = newPrediction; + } + } + + public void initHeader(InstancesHeader dataset) { + int numLabels = this.numOldLabelsOption.getValue(); + Attribute target = dataset.classAttribute(); + + List possibleValues = new ArrayList(); + int n = target.numValues(); + for (int i = 0; i < n; i++) { + possibleValues.add(target.value(i)); + } + + ArrayList attrs = new ArrayList(numLabels + dataset.numAttributes()); + for (int i = 0; i < numLabels; i++) { + attrs.add(new Attribute(target.name() + "_" + i, possibleValues)); + } + for (int i = 0; i < dataset.numAttributes(); i++) { + Attribute attr = dataset.attribute(i); + Attribute newAttribute = null; + if (attr.isNominal() == true) { + newAttribute = new Attribute(attr.name(), attr.getAttributeValues()); + } + if (attr.isNumeric() == true) { + newAttribute = new Attribute(attr.name()); + } + if (newAttribute != null) { + attrs.add(newAttribute); + } + } + this.header = new InstancesHeader("extended_" + dataset.getRelationName(), attrs, 0); + this.header.setClassIndex(numLabels + dataset.classIndex()); + } + + public Instance extendWithOldLabels(Instance instance) { + if (this.header == null) { + initHeader(instance.dataset()); + this.baseLearner.setModelContext(new InstancesHeader(this.header)); + } + int numLabels = this.oldLabels.length; + if (numLabels == 0) { + return instance; + } + double[] x = instance.toDoubleArray(); + double[] x2 = Arrays.copyOfRange(this.oldLabels, 0, numLabels + x.length); + System.arraycopy(x, 0, x2, numLabels, x.length); + Instance extendedInstance = new DenseInstance(instance.weight(), x2); + extendedInstance.setDataset(this.header); + //System.out.println( extendedInstance); + return extendedInstance; + } + + @Override + public Prediction getPredictionForInstance(Instance instance) { + double[] prediction = this.baseLearner.getPredictionForInstance(extendWithOldLabels(instance)); + if (this.labelDelayOption.isSet() == true) { + // Use predicted Labels to add attributes to instances + addOldLabel(Utils.maxIndex(prediction)); + } + return prediction; + } + + @Override + public boolean isRandomizable() { + return false; // ??? this.baseLearner.isRandomizable; + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + List measurementList = new LinkedList(); + Measurement[] modelMeasurements = ((AbstractClassifier) this.baseLearner).getModelMeasurements(); + if (modelMeasurements != null) { + for (Measurement measurement : modelMeasurements) { + measurementList.add(measurement); + } + } + return measurementList.toArray(new Measurement[measurementList.size()]); + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + // TODO Auto-generated method stub + } + + public String toString() { + return "TemporallyAugmentedClassifier using " + this.numOldLabelsOption.getValue() + " labels\n" + this.baseLearner; + } +} diff --git a/moa/src/main/java/moa/classifiers/mlc/MultilabelHoeffdingTree.java.orig b/moa/src/main/java/moa/classifiers/mlc/MultilabelHoeffdingTree.java.orig new file mode 100644 index 000000000..e0a4c43a7 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/mlc/MultilabelHoeffdingTree.java.orig @@ -0,0 +1,237 @@ +/* + * MultilabelHoeffdingTree.java + * Copyright (C) 2012 University of Waikato, Hamilton, New Zealand + * @author Jesse Read (jesse@tsc.uc3m.es) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.classifiers.multilabel; + +import java.util.LinkedList; +import java.util.List; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; +<<<<<<< HEAD +======= +import com.yahoo.labs.samoa.instances.StructuredInstance; +import com.yahoo.labs.samoa.instances.MultiLabelPrediction; +>>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe +import com.yahoo.labs.samoa.instances.Prediction; +import com.yahoo.labs.samoa.instances.StructuredInstance; + +import moa.classifiers.Classifier; +import moa.classifiers.MultiLabelClassifier; +import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; +import moa.classifiers.trees.HoeffdingTree; +import moa.core.Example; +import moa.core.StringUtils; + +/** + * Hoeffding Tree for classifying multi-label data. + * + * A Hoeffding tree is an incremental, anytime decision tree induction algorithm + * that is capable of learning from massive data streams, assuming that the + * distribution generating examples does not change over time. + * + * + */ +public class MultilabelHoeffdingTree extends HoeffdingTreeClassifLeaves implements MultiLabelClassifier, MultiTargetRegressor, Classifier { +// Needs to use InfoGainSplitCriterionMultiLabel, since multilabel entropy is calculated in a different way +// Trains a mlinstance adding statistics of several class values and training node classifiers +// Get votes from the classifier in the learning node of the tree + + private static final long serialVersionUID = 1L; + + + /*public MultilabelHoeffdingTree() { + this.removePoorAttsOption = null; + }*/ + + @Override + protected LearningNode newLearningNode(double[] initialClassObservations) { + // Create new Learning Node with a null classifier + return new MultilabelLearningNodeClassifier(initialClassObservations,null,this); + } + + //@Override + protected LearningNode newLearningNode(double[] initialClassObservations, Classifier cl) { + // Create new Learning Node + return new MultilabelLearningNodeClassifier(initialClassObservations,cl,this); + } + + public static class MultilabelInactiveLearningNode extends InactiveLearningNode { + + private static final long serialVersionUID = 1L; + + public MultilabelInactiveLearningNode(double[] initialClassObservations) { + super(initialClassObservations); + } + + @Override + public void learnFromInstance(Instance inst, HoeffdingTree ht) { + List labels = ((MultilabelHoeffdingTree) ht).getRelevantLabels(inst); + for (int l : labels){ + this.observedClassDistribution.addToValue(l, inst.weight()); + } + } + } + + public class MultilabelLearningNodeClassifier extends LearningNodeClassifier { + // It uses classifier at nodes, and to be able to train with several class values + + private static final long serialVersionUID = 1L; + + public MultilabelLearningNodeClassifier(double[] initialClassObservations, Classifier cl, MultilabelHoeffdingTree ht ) { + super(initialClassObservations); + + if (cl== null) { + this.classifier = ((Classifier) getPreparedClassOption(ht.learnerOption)).copy(); + this.classifier.resetLearning(); + + InstancesHeader raw_header = ht.getModelContext(); + this.classifier.setModelContext(raw_header); + } + else{ + this.classifier = cl.copy(); + } + } + + @Override + public double[] getClassVotes(Instance inst, HoeffdingTree ht) { + + return this.classifier.getPredictionForInstance(inst); + } + + public Prediction getPredictionForInstance(Instance inst, HoeffdingTree ht) { + + return this.classifier.getPredictionForInstance(inst); + } + + @Override + public void disableAttribute(int attIndex) { + // should not disable poor atts - they are used in NB calc + } + + public Classifier getClassifier() { + return this.classifier; + } + + @Override + public void learnFromInstance(Instance inst, HoeffdingTree ht) { + + //It uses different class values, not only one + this.classifier.trainOnInstance(inst); + MultilabelHoeffdingTree mht = ((MultilabelHoeffdingTree) ht); + List labels = mht.getRelevantLabels(inst); + for (int l : labels){ + this.observedClassDistribution.addToValue( l, inst.weight()); + } + + for (int i = 0; i < inst.numInputAttributes(); i++) { + int instAttIndex = i; + AttributeClassObserver obs = this.attributeObservers.get(instAttIndex); //i + if (obs == null) { + obs = inst.inputAttribute(i).isNominal() ? mht.newNominalClassObserver() : mht.newNumericClassObserver(); + this.attributeObservers.set(i, obs); + } + for (int l : labels){ + obs.observeAttributeClass(inst.valueInputAttribute(i), l, inst.weight()); + } + } + } + + public void describeSubtree(HoeffdingTree ht, StringBuilder out, + int indent) { + StringUtils.appendIndented(out, indent, "Leaf "); + out.append(" = "); + out.append(" weights: "); + this.observedClassDistribution.getSingleLineDescription(out, + this.observedClassDistribution.numValues()); + StringUtils.appendNewline(out); + } + } + + @Override + protected void deactivateLearningNode(ActiveLearningNode toDeactivate, + SplitNode parent, int parentBranch) { + //It uses MultilabelInactiveLearningNode since there are several class values + Node newLeaf = new MultilabelInactiveLearningNode(toDeactivate + .getObservedClassDistribution()); + if (parent == null) { + this.treeRoot = newLeaf; + } else { + parent.setChild(parentBranch, newLeaf); + } + this.activeLeafNodeCount--; + this.inactiveLeafNodeCount++; + } + + + @Override + public Prediction getPredictionForInstance(Example example) { + return getPredictionForInstance((StructuredInstance)example.getData()); + } + + public Prediction getPredictionForInstance(StructuredInstance inst) { + return getPredictionForInstance((Instance) inst); + } + + @Override + public Prediction getPredictionForInstance(Instance inst){ + + if (this.treeRoot != null) { + FoundNode foundNode = this.treeRoot.filterInstanceToLeaf(inst, null, -1); + Node leafNode = (MultilabelLearningNodeClassifier) foundNode.node; + MultilabelLearningNodeClassifier multilabelLeafNode = (MultilabelLearningNodeClassifier) leafNode; + if (leafNode == null) { + leafNode = foundNode.parent; + } + return multilabelLeafNode.getPredictionForInstance(inst, this); + } + else { + System.err.println("[WARNING] Root Node == Null !!!!!!"); + } + + // Return empty array (this should only happen once! -- before we build the root node). + return null; + } + + @Override + public void trainOnInstance(Instance inst) { + boolean isTraining = (inst.weight() > 0.0); + if (isTraining) { + this.trainingWeightSeenByModel += inst.weight(); + trainOnInstanceImpl((StructuredInstance) inst); + } + } + + @Override + public void trainOnInstanceImpl(StructuredInstance instance) { + trainOnInstanceImpl((Instance) instance); + } + + public static List getRelevantLabels(Instance x) { + List classValues = new LinkedList(); + //get all class attributes + for (int j = 0; j < x.numberOutputTargets(); j++) { + if (x.classValue(j) > 0.0) { + classValues.add(j); + } + } + return classValues; + } +} diff --git a/moa/src/main/java/moa/classifiers/mlc/meta/MLOzaBag.java b/moa/src/main/java/moa/classifiers/mlc/meta/MLOzaBag.java deleted file mode 100644 index f5d1dff78..000000000 --- a/moa/src/main/java/moa/classifiers/mlc/meta/MLOzaBag.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * MLOzaBag.java - * Copyright (C) 2012 University of Waikato, Hamilton, New Zealand - * @author Jesse Read (jesse@tsc.uc3m.es) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package moa.classifiers.multilabel.meta; - -import moa.classifiers.Classifier; -import moa.classifiers.meta.OzaBag; -import com.yahoo.labs.samoa.instances.InstancesHeader; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.MultiLabelPrediction; -import com.yahoo.labs.samoa.instances.Prediction; -import moa.classifiers.MultiLabelLearner; -import moa.classifiers.MultiTargetRegressor; -import moa.core.Example; - -/** - * OzaBag for Multi-label data. - * - * @author Jesse Read (jesse@tsc.uc3m.es) - * @version $Revision: 1 $ - */ -public class MLOzaBag extends OzaBag implements MultiLabelLearner, MultiTargetRegressor{ - - protected int m_L = -1; - - //protected Random random = null; - - /* - * @Override public void resetLearningImpl() { super.resetLearningImpl(); - * //this.random = new Random(randomSeedOption.getValue()); } - */ - @Override - public void resetLearningImpl() { - this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; - Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); - baseLearner.resetLearning(); - for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i] = baseLearner.copy(); - } - } - - @Override - public void setModelContext(InstancesHeader raw_header) { - - //set the multilabel model context - this.modelContext = raw_header; - - m_L = raw_header.classIndex() + 1; - - // reset ensemble - this.resetLearningImpl(); - - for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i].setModelContext(raw_header); - this.ensemble[i].resetLearning(); - } - } - - @Override // @note don't need this here - public boolean isRandomizable() { - return true; - } - - @Override - public double[] getVotesForInstance(Instance x) { - - int L = x.classIndex() + 1; - if (m_L != L) { - m_L = L; - } - - double y[] = new double[m_L]; - - for (int i = 0; i < this.ensemble.length; i++) { - double w[] = this.ensemble[i].getVotesForInstance(x); - for (int j = 0; j < w.length; j++) { - y[j] += w[j]; - } - } - - return y; - } - - @Override - public void trainOnInstanceImpl(StructuredInstance instance) { - trainOnInstanceImpl((Instance) instance); - } - - @Override - public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance((StructuredInstance)example.getData()); - } - - @Override - public Prediction getPredictionForInstance(StructuredInstance instance) { - - double[] predictionArray = this.getVotesForInstance(instance); - - //System.out.println("y = "+Arrays.toString(predictionArray)); - - Prediction prediction = new MultiLabelPrediction(predictionArray.length); - for (int j = 0; j < predictionArray.length; j++){ - prediction.setVote(j, 1, predictionArray[j]); - //prediction.setVote(j, 0, 1. - predictionArray[j]); - } - return prediction; - } - -} diff --git a/moa/src/main/java/moa/classifiers/trees/FIMTDD.java b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java new file mode 100644 index 000000000..e4cc9792d --- /dev/null +++ b/moa/src/main/java/moa/classifiers/trees/FIMTDD.java @@ -0,0 +1,1031 @@ +/* + * FIMTDD.java + * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia + * @author Aljaž Osojnik + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package moa.classifiers.trees; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.predictions.Prediction; +import com.yahoo.labs.samoa.instances.predictions.RegressionPrediction; + +import moa.AbstractMOAObject; +import moa.classifiers.AbstractRegressor; +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; +import moa.classifiers.core.conditionaltests.InstanceConditionalTest; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.core.AutoExpandVector; +import moa.core.DoubleVector; +import moa.core.Measurement; +import moa.core.SizeOf; +import moa.core.StringUtils; +import moa.learners.Regressor; +import moa.options.ClassOption; + +/* + * Implementation of FIMTDD, regression and model trees for data streams. + */ + +public class FIMTDD extends AbstractRegressor implements Regressor { + + private static final long serialVersionUID = 1L; + + public Node treeRoot; + + public int leafNodeCount = 0; + public int splitNodeCount = 0; + + protected double examplesSeen = 0.0; + protected double sumOfValues = 0.0; + protected double sumOfSquares = 0.0; + + protected DoubleVector sumOfAttrValues = new DoubleVector(); + protected DoubleVector sumOfAttrSquares = new DoubleVector(); + + public int maxID = 0; + + //region ================ OPTIONS ================ + + public ClassOption splitCriterionOption = new ClassOption( + "splitCriterion", 's', "Split criterion to use.", + SplitCriterion.class, "moa.classifiers.core.splitcriteria.VarianceReductionSplitCriterion"); + + public IntOption gracePeriodOption = new IntOption( + "gracePeriod", 'g', "Number of instances a leaf should observe between split attempts.", + 200, 0, Integer.MAX_VALUE); + + public FloatOption splitConfidenceOption = new FloatOption( + "splitConfidence", 'c', "Allowed error in split decision, values close to 0 will take long to decide.", + 0.0000001, 0.0, 1.0); + + public FloatOption tieThresholdOption = new FloatOption( + "tieThreshold", 't', "Threshold below which a split will be forced to break ties.", + 0.05, 0.0, 1.0); + + public FloatOption PageHinckleyAlphaOption = new FloatOption( + "PageHinckleyAlpha", 'a', "Alpha value to use in the Page Hinckley change detection tests.", + 0.005, 0.0, 1.0); + + public IntOption PageHinckleyThresholdOption = new IntOption( + "PageHinckleyThreshold", 'h', "Threshold value used in the Page Hinckley change detection tests.", + 50, 0, Integer.MAX_VALUE); + + public FloatOption alternateTreeFadingFactorOption = new FloatOption( + "alternateTreeFadingFactor", 'f', "Fading factor used to decide if an alternate tree should replace an original.", + 0.995, 0.0, 1.0); + + public IntOption alternateTreeTMinOption = new IntOption( + "alternateTreeTMin", 'y', "Tmin value used to decide if an alternate tree should replace an original.", + 150, 0, Integer.MAX_VALUE); + + public IntOption alternateTreeTimeOption = new IntOption( + "alternateTreeTime", 'u', "The number of instances used to decide if an alternate tree should be discarded.", + 1500, 0, Integer.MAX_VALUE); + + public FlagOption regressionTreeOption = new FlagOption( + "regressionTree", 'e', "Build a regression tree instead of a model tree."); + + public FloatOption learningRatioOption = new FloatOption( + "learningRatio", 'l', "Learning ratio to used for training the Perceptrons in the leaves.", + 0.003, 0, 1.00); + + public FloatOption learningRateDecayFactorOption = new FloatOption( + "learningRatioDecayFactor", 'd', "Learning rate decay factor (not used when learning rate is constant).", + 0.001, 0, 1.00); + + public FlagOption learningRatioConstOption = new FlagOption( + "learningRatioConst", 'p', "Keep learning rate constant instead of decaying."); + + public IntOption maxDepthOption = new IntOption( + "maxDepthFactor", 'b', "The maximum depth of the tree.", + Integer.MAX_VALUE, 0, Integer.MAX_VALUE); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public abstract static class Node extends AbstractMOAObject { + + private static final long serialVersionUID = 1L; + + public int ID; + + protected FIMTDD tree; + + protected boolean changeDetection = true; + + protected Node parent; + + protected Node alternateTree; + protected Node originalNode; + + // The statistics for this node: + // Number of instances that have reached it + protected double examplesSeen; + // Sum of y values + protected double sumOfValues; + // Sum of squared y values + protected double sumOfSquares; + // Sum of absolute errors + protected double sumOfAbsErrors; // Needed for PH tracking of mean error + + public Node(FIMTDD tree) { + this.tree = tree; + ID = tree.maxID; + } + + public void copyStatistics(Node node) { + examplesSeen = node.examplesSeen; + sumOfValues = node.sumOfValues; + sumOfSquares = node.sumOfSquares; + sumOfAbsErrors = node.sumOfAbsErrors; + } + + public long calcByteSize() { + return SizeOf.sizeOf(this) + (originalNode == null && alternateTree != null ? alternateTree.calcByteSize() : 0); + } + + /** + * Set the parent node + */ + public void setParent(Node parent) { + this.parent = parent; + } + + /** + * Return the parent node + */ + public Node getParent() { + return parent; + } + + public void disableChangeDetection() { + changeDetection = false; + } + + public void restartChangeDetection() { + changeDetection = true; + } + + public void getDescription(StringBuilder sb, int indent) { + + } + + public double getPrediction(Instance inst) { + return 0; + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf"); + } + + public int getLevel() { + Node target = this; + int level = 0; + while (target.getParent() != null) { + if (target.skipInLevelCount()) { + target = target.getParent(); + continue; + } + level = level + 1; + target = target.getParent(); + } + if (target.originalNode == null) { + return level; + } else { + return level + originalNode.getLevel(); + } + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + public int numLeaves() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + } + + public static class LeafNode extends Node { + + private static final long serialVersionUID = 1L; + + public double errorModel = 0.0; + public double errorTargetMean = 0.0; + + // Perceptron model that carries out the actual learning in each node + public FIMTDDPerceptron learningModel; + + protected AutoExpandVector attributeObservers = new AutoExpandVector(); + + protected double examplesSeenAtLastSplitEvaluation = 0; + + /** + * Create a new LeafNode + */ + public LeafNode(FIMTDD tree) { + super(tree); + if (tree.buildingModelTree()) { + learningModel = tree.newLeafModel(); + } + examplesSeen = 0; + sumOfValues = 0; + sumOfSquares = 0; + sumOfAbsErrors = 0; + } + + public long calcByteSize() { + long size = super.calcByteSize(); + if (tree.buildingModelTree()) + size += learningModel.calcByteSize(); + size += SizeOf.fullSizeOf(attributeObservers); + return size; + } + + public void setChild(int parentBranch, Node node) { + } + + public int getChildIndex(Node child) { + return -1; + } + + public int getNumSubtrees() { + return 1; + } + + protected boolean skipInLevelCount() { + return false; + } + + /** + * Method to learn from an instance that passes the new instance to the perceptron learner, + * and also prevents the class value from being truncated to an int when it is passed to the + * attribute observer + */ + public void learnFromInstance(Instance inst, boolean growthAllowed, double prediction) { + //The prediction must be calculated here -- it may be different from the tree's prediction due to alternate trees + + // Update the statistics for this node + // number of instances passing through the node + examplesSeen += inst.weight(); + + // sum of y values + sumOfValues += inst.weight() * inst.classValue(); + + // sum of squared y values + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + // sum of absolute errors + sumOfAbsErrors += inst.weight() * Math.abs(tree.normalizeTargetValue(Math.abs(inst.classValue() - prediction))); + + if (tree.buildingModelTree()) { + double predictionModel = getPredictionModel(inst); + double predictionTargetMean = getPredictionTargetMean(inst); + + errorModel = errorModel * 0.95 + Math.abs(predictionModel - inst.classValue()); + errorTargetMean = errorTargetMean * 0.95 + Math.abs(predictionTargetMean - inst.classValue()); + + learningModel.updatePerceptron(inst); + } + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int instAttIndex = modelAttIndexToInstanceAttIndex(i, inst); + FIMTDDNumericAttributeClassObserver obs = attributeObservers.get(i); + if (obs == null) { + // At this stage all nominal attributes are ignored + if (inst.attribute(instAttIndex).isNumeric()) { + obs = tree.newNumericClassObserver(); + this.attributeObservers.set(i, obs); + } + } + if (obs != null) { + obs.observeAttributeClass(inst.value(instAttIndex), inst.classValue(), inst.weight()); + } + } + + if (growthAllowed) { + checkForSplit(inst, prediction); + } + } + + /** + * Return the best split suggestions for this node using the given split criteria + */ + public AttributeSplitSuggestion[] getBestSplitSuggestions(SplitCriterion criterion) { + + List bestSuggestions = new LinkedList(); + + // Set the nodeStatistics up as the preSplitDistribution, rather than the observedClassDistribution + double[] nodeSplitDist = new double[] {examplesSeen, sumOfValues, sumOfSquares}; + + for (int i = 0; i < this.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = this.attributeObservers.get(i); + if (obs != null) { + + // AT THIS STAGE NON-NUMERIC ATTRIBUTES ARE IGNORED + AttributeSplitSuggestion bestSuggestion = null; + if (obs instanceof FIMTDDNumericAttributeClassObserver) { + bestSuggestion = obs.getBestEvaluatedSplitSuggestion(criterion, nodeSplitDist, i, true); + } + + if (bestSuggestion != null) { + bestSuggestions.add(bestSuggestion); + } + } + } + return bestSuggestions.toArray(new AttributeSplitSuggestion[bestSuggestions.size()]); + } + + /** + * Retrieve the class votes using the perceptron learner + */ + public double getPredictionModel(Instance inst) { + return learningModel.prediction(inst); + } + + public double getPredictionTargetMean(Instance inst) { + return (examplesSeen > 0.0) ? sumOfValues / examplesSeen : 0.0; + } + + public double getPrediction(Instance inst) { + if (tree.buildingModelTree()) { + return (errorModel < errorTargetMean) ? getPredictionModel(inst) : getPredictionTargetMean(inst); + } else + return getPredictionTargetMean(inst); + } + + public void checkForSplit(Instance inst, double prediction) { + // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node + if (this.getLevel() < tree.maxDepthOption.getValue() && examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { + int index = (parent != null) ? parent.getChildIndex(this) : 0; + tree.attemptToSplit(this, parent, index, inst, prediction); + + // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation + examplesSeenAtLastSplitEvaluation = examplesSeen; + } + } + + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "Leaf "); + if (tree.buildingModelTree()) { + learningModel.getModelDescription(out, 0); + } else { + out.append(tree.getClassNameString() + " = " + String.format("%.4f", sumOfValues / examplesSeen)); + StringUtils.appendNewline(out); + } + } + } + + public abstract static class InnerNode extends Node { + // The InnerNode and SplitNode design is used for easy extension in ORTO + private static final long serialVersionUID = 1L; + + protected AutoExpandVector children = new AutoExpandVector(); + + // The error values for the Page Hinckley test + // PHmT = the cumulative sum of the errors + // PHMT = the minimum error value seen so far + protected double PHsum = 0; + protected double PHmin = Double.MAX_VALUE; + + // Keep track of the statistics for loss error calculations + protected double lossExamplesSeen; + protected double lossFadedSumOriginal; + protected double lossFadedSumAlternate; + protected double lossNumQiTests; + protected double lossSumQi; + protected double previousWeight = 0; + + public InnerNode(FIMTDD tree) { + super(tree); + } + + public long calcByteSize() { + long size = super.calcByteSize(); + for (Node child : children) + size += child.calcByteSize(); + return size; + } + + public int numChildren() { + return children.size(); + } + + public int numLeaves() { + int leaves = 0; + for (Node child : children) leaves += child.numLeaves(); + return leaves; + } + + public Node getChild(int index) { + return children.get(index); + } + + public int getChildIndex(Node child) { + return children.indexOf(child); + } + + public void setChild(int index, Node child) { + children.set(index, child); + } + + public void disableChangeDetection() { + changeDetection = false; + for (Node child : children) { + child.disableChangeDetection(); + } + } + + public void restartChangeDetection() { + if (alternateTree == null) { + changeDetection = true; + PHsum = 0; + PHmin = Integer.MAX_VALUE; + for (Node child : children) + child.restartChangeDetection(); + } + } + + /** + * Check to see if the tree needs updating + */ + public boolean PageHinckleyTest(double error, double threshold) { + // Update the cumulative mT sum + PHsum += error; + + // Update the minimum mT value if the new mT is + // smaller than the current minimum + if(PHsum < PHmin) { + PHmin = PHsum; + } + // Return true if the cumulative value - the current minimum is + // greater than the current threshold (in which case we should adapt) + return PHsum - PHmin > threshold; + } + + public void initializeAlternateTree() { + // Start a new alternate tree, beginning with a learning node + alternateTree = tree.newLeafNode(); + alternateTree.originalNode = this; + + // Set up the blank statistics + // Number of instances reaching this node since the alternate tree was started + lossExamplesSeen = 0; + // Faded squared error (original tree) + lossFadedSumOriginal = 0; + // Faded squared error (alternate tree) + lossFadedSumAlternate = 0; + // Number of evaluations of alternate tree + lossNumQiTests = 0; + // Sum of Qi values + lossSumQi = 0; + // Number of examples at last test + previousWeight = 0; + + // Disable the change detection mechanism bellow this node + disableChangeDetection(); + } + } + + public static class SplitNode extends InnerNode { + + private static final long serialVersionUID = 1L; + + protected InstanceConditionalTest splitTest; + + /** + * Create a new SplitNode + * @param tree + */ + public SplitNode(InstanceConditionalTest splitTest, FIMTDD tree) { + super(tree); + this.splitTest = splitTest; + } + + public long calcByteSize() { + long size = super.calcByteSize(); + size += SizeOf.sizeOf(splitTest); + return size; + } + + public int instanceChildIndex(Instance inst) { + return splitTest.branchForInstance(inst); + } + + public Node descendOneStep(Instance inst) { + return children.get(splitTest.branchForInstance(inst)); + } + + public void describeSubtree(StringBuilder out, int indent) { + for (int branch = 0; branch < children.size(); branch++) { + Node child = getChild(branch); + if (child != null) { + StringUtils.appendIndented(out, indent, "if "); + out.append(this.splitTest.describeConditionForBranch(branch, + tree.getModelContext())); + out.append(": "); + StringUtils.appendNewline(out); + child.describeSubtree(out, indent + 2); + } + } + } + + public double getPrediction(Instance inst) { + return children.get(splitTest.branchForInstance(inst)).getPrediction(inst); + } + } + + public class FIMTDDPerceptron implements Serializable { + + private static final long serialVersionUID = 1L; + + protected FIMTDD tree; + + // The Perception weights + protected double[] weightAttribute; + + // The number of instances contributing to this model + protected double instancesSeen = 0; + + public String getPurposeString() { + return "A perceptron regressor as specified by Ikonomovska et al. used for FIMTDD"; + } + + public FIMTDDPerceptron(FIMTDDPerceptron original) { + this.tree = original.tree; + weightAttribute = original.weightAttribute.clone(); + instancesSeen = original.instancesSeen / 2; + } + + public FIMTDDPerceptron(FIMTDD tree) { + this.tree = tree; + initializeWeights(); + + } + + public long calcByteSize() { + return SizeOf.sizeOf(this); + } + + public void initializeWeights() { + weightAttribute = new double[tree.getModelContext().numInputAttributes()+1]; + instancesSeen = 0; + for (int j = 0; j < tree.getModelContext().numInputAttributes()+1; j++) { + // The last index corresponds to the constant b + weightAttribute[j] = 2 * tree.classifierRandom.nextDouble() - 1; + } + normalizeWeights(); + } + + /** + * Update the model using the provided instance + */ + public void updatePerceptron(Instance inst) { + + // Update attribute statistics + instancesSeen += inst.weight(); + + // Update weights + double learningRatio = 0.0; + if (tree.learningRatioConstOption.isSet()) { + learningRatio = learningRatioOption.getValue(); + } else { + learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); + } + + // Loop for compatibility with bagging methods + for (int i = 0; i < (int) inst.weight(); i++) { + updateWeights(inst, learningRatio); + } + + } + + public void updateWeights(Instance inst, double learningRatio) { + // Compute the normalized instance and the delta + double[] normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + double normalizedValue = tree.normalizeTargetValue(inst.classValue()); + double delta = normalizedValue - normalizedPrediction; + for (int i = 0; i < weightAttribute.length; i++) { + weightAttribute[i] += delta * learningRatio * normalizedInstance[i]; + } + + normalizeWeights(); + } + + public void normalizeWeights() { + double sum = 0; + for (int i = 0; i < this.weightAttribute.length; i++) + sum += Math.abs(weightAttribute[i]); + for (int i = 0; i < this.weightAttribute.length; i++) + weightAttribute[i] /= sum; + } + + public double[] normalizedInstance(Instance inst) { + // Normalize Instance + double[] normalizedInstance = new double[inst.numInputAttributes()+1]; + for (int j = 0; j < inst.numInputAttributes(); j++) { + double mean = tree.sumOfAttrValues.getValue(j) / tree.examplesSeen; + double sd = computeSD(tree.sumOfAttrSquares.getValue(j), tree.sumOfAttrValues.getValue(j), tree.examplesSeen); + if (inst.inputAttribute(j).isNumeric() && tree.examplesSeen > 1 && sd > 0.0000001) + normalizedInstance[j] = (inst.valueInputAttribute(j) - mean) / (sd); + else + normalizedInstance[j] = 0; + } + normalizedInstance[inst.numInputAttributes()] = tree.examplesSeen > 1 ? 1 : 0; // Value to be multiplied with the constant factor + return normalizedInstance; + } + + /** + * Output the prediction made by this perceptron on the given instance + */ + public double prediction(double[] instanceValues) { + double ret = 0; + for (int i = 0; i < instanceValues.length; i++) + ret += instanceValues[i] * weightAttribute[i]; + return ret; + } + + protected double prediction(Instance inst) { + double[] normalizedInstance = normalizedInstance(inst); + double normalizedPrediction = prediction(normalizedInstance); + return denormalizePrediction(normalizedPrediction); + } + + private double denormalizePrediction(double normalizedPrediction) { + double mean = tree.sumOfValues / tree.examplesSeen; + double sd = computeSD(tree.sumOfSquares, tree.sumOfValues, tree.examplesSeen); + if (examplesSeen > 1) + return normalizedPrediction * sd + mean; + else + return 0.0; + } + + public void getModelDescription(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, getClassNameString() + " ="); + if (getModelContext() != null) { + for (int j = 0; j < getModelContext().numAttributes() - 1; j++) { + if (getModelContext().attribute(j).isNumeric()) { + out.append((j == 0 || weightAttribute[j] < 0) ? " " : " + "); + out.append(String.format("%.4f", weightAttribute[j])); + out.append(" * "); + out.append(getAttributeNameString(j)); + } + } + out.append(" + " + weightAttribute[getModelContext().numInputAttributes()]); + } + StringUtils.appendNewline(out); + } + } + + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + // region --- Regressor methods + + public String getPurposeString() { + return "Implementation of the FIMT-DD tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + this.treeRoot = null; + this.leafNodeCount = 0; + this.splitNodeCount = 0; + this.maxID = 0; + this.examplesSeen = 0; + this.sumOfValues = 0.0; + this.sumOfSquares = 0.0; + + this.sumOfAttrValues = new DoubleVector(); + this.sumOfAttrSquares = new DoubleVector(); + } + + public boolean isRandomizable() { + return true; + } + + public void getModelDescription(StringBuilder out, int indent) { + if (treeRoot != null) treeRoot.describeSubtree(out, indent); + } + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("tree size (leaves)", this.leafNodeCount) + }; + } + + @Override + public long measureByteSize() { + return calcByteSize(); + } + + public long calcByteSize() { + long size = (long) (SizeOf.sizeOf(this)) + this.treeRoot.calcByteSize(); + size += (long) (SizeOf.sizeOf(this.sumOfAttrValues)) + (int) (SizeOf.sizeOf(this.sumOfAttrSquares)); + return size; + } + + public Prediction getPredictionForInstance(Instance inst) { + return new RegressionPrediction((treeRoot == null) ? 0 : treeRoot.getPrediction(inst)); + } + + public double normalizeTargetValue(double value) { + if (examplesSeen > 1) { + double sd = Math.sqrt((sumOfSquares - ((sumOfValues * sumOfValues)/examplesSeen))/examplesSeen); + double average = sumOfValues / examplesSeen; + if (sd > 0 && examplesSeen > 1) + return (value - average) / sd; + else + return 0.0; + } + return 0.0; + } + + public double getNormalizedError(Instance inst, double prediction) { + double normalPrediction = normalizeTargetValue(prediction); + double normalValue = normalizeTargetValue(inst.classValue()); + return Math.abs(normalValue - normalPrediction); + } + + + public void updateStatistics(Instance inst) { + examplesSeen += inst.weight(); + sumOfValues += inst.weight() * inst.classValue(); + sumOfSquares += inst.weight() * inst.classValue() * inst.classValue(); + + for (int i = 0; i < inst.numAttributes() - 1; i++) { + int aIndex = modelAttIndexToInstanceAttIndex(i, inst); + sumOfAttrValues.addToValue(i, inst.weight() * inst.value(aIndex)); + sumOfAttrSquares.addToValue(i, inst.weight() * inst.value(aIndex) * inst.value(aIndex)); + } + } + + /** + * Method for updating (training) the model using a new instance + */ + public void trainOnInstanceImpl(Instance inst) { + checkRoot(); + + double prediction = treeRoot.getPrediction(inst); + double normalError = getNormalizedError(inst, prediction); + + processInstance(inst, treeRoot, prediction, normalError, true, false); + + updateStatistics(inst); + + } + + public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); + break; + } else { + currentNode.examplesSeen += inst.weight(); + currentNode.sumOfAbsErrors += inst.weight() * normalError; + InnerNode iNode = (InnerNode) currentNode; + if (!inAlternate && iNode.alternateTree != null) { + boolean altTree = true; + double lossO = Math.pow(inst.classValue() - prediction, 2); + double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); + + // Loop for compatibility with bagging methods + for (int i = 0; i < inst.weight(); i++) { + iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + iNode.lossExamplesSeen++; + + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + iNode.lossSumQi += Qi; + iNode.lossNumQiTests += 1; + } + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + + if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + iNode.previousWeight = iNode.lossExamplesSeen; + if (Qi > 0) { + // Switch the subtrees + Node parent = iNode.getParent(); + + System.out.println("Switching trees!"); + if (parent != null) { + Node replacementTree = iNode.alternateTree; + parent.setChild(parent.getChildIndex(iNode), replacementTree); + if (growthAllowed) replacementTree.restartChangeDetection(); + } else { + treeRoot = iNode.alternateTree; + treeRoot.restartChangeDetection(); + } + leafNodeCount += iNode.alternateTree.numLeaves() - iNode.numLeaves(); + + + currentNode = iNode.alternateTree; + currentNode.originalNode = null; + altTree = false; + } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { + // Remove the alternate tree + iNode.alternateTree = null; + if (growthAllowed) iNode.restartChangeDetection(); + altTree = false; + } + } + + if (altTree) { + growthAllowed = false; + processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); + } + } + + if (iNode.changeDetection && !inAlternate) { + if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + System.out.println("CD triggered!"); + iNode.initializeAlternateTree(); + growthAllowed = false; + } + } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).descendOneStep(inst); + } + } + } + } + + // endregion --- Regressor methods + + // region --- Object instatiation methods + + protected FIMTDDNumericAttributeClassObserver newNumericClassObserver() { + return new FIMTDDNumericAttributeClassObserver(); + } + + protected SplitNode newSplitNode(InstanceConditionalTest splitTest) { + maxID++; + return new SplitNode(splitTest, this); + } + + protected LeafNode newLeafNode() { + maxID++; + return new LeafNode(this); + } + + protected FIMTDDPerceptron newLeafModel() { + return new FIMTDDPerceptron(this); + } + + //endregion --- Object instatiation methods + + // region --- Processing methods + + public void checkRoot() { + if (treeRoot == null) { + treeRoot = newLeafNode(); + leafNodeCount = 1; + } + } + + public static double computeHoeffdingBound(double range, double confidence, double n) { + return Math.sqrt(( (range * range) * Math.log(1 / confidence)) / (2.0 * n)); + } + + public boolean buildingModelTree() { + return !regressionTreeOption.isSet(); + } + + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex, Instance inst, double prediction) { + + // Set the split criterion to use to the SDR split criterion as described by Ikonomovska et al. + SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(this.splitCriterionOption); + + // Using this criterion, find the best split per attribute and rank the results + AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine if any of the splits should be performed + boolean shouldSplit = false; + + // If only one split was returned, use it + if (bestSplitSuggestions.length < 2) { + shouldSplit = bestSplitSuggestions.length > 0; + } else { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, this.splitConfidenceOption.getValue(), node.examplesSeen); + // Determine the top two ranked splitting suggestions + AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { + shouldSplit = true; + } + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + else { + for (int i = 0; i < node.attributeObservers.size(); i++) { + FIMTDDNumericAttributeClassObserver obs = node.attributeObservers.get(i); + if (obs != null) { + obs.removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); + } + } + } + } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (shouldSplit) { + AttributeSplitSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + + SplitNode newSplit = newSplitNode(splitDecision.splitTest); + newSplit.copyStatistics(node); + newSplit.changeDetection = node.changeDetection; + newSplit.ID = node.ID; + leafNodeCount--; + for (int i = 0; i < splitDecision.numSplits(); i++) { + LeafNode newChild = newLeafNode(); + if (buildingModelTree()) { + // Copy the splitting node's perceptron to it's children + newChild.learningModel = new FIMTDDPerceptron((FIMTDDPerceptron) node.learningModel); + + } + newChild.changeDetection = node.changeDetection; + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + leafNodeCount++; + } + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + ((SplitNode) parent).setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + + splitNodeCount++; + } + } + + public double computeSD(double squaredVal, double val, double size) { + if (size > 1) + return Math.sqrt((squaredVal - ((val * val) / size)) / size); + else + return 0.0; + } + + public double scalarProduct(DoubleVector u, DoubleVector v) { + double ret = 0.0; + for (int i = 0; i < Math.max(u.numValues(), v.numValues()); i++) { + ret += u.getValue(i) * v.getValue(i); + } + return ret; + } + //endregion --- Processing methods + + //endregion ================ METHODS ================ +} \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO2.java.orig b/moa/src/main/java/moa/classifiers/trees/ORTO2.java.orig new file mode 100644 index 000000000..99b0cc910 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/trees/ORTO2.java.orig @@ -0,0 +1,543 @@ +/* + * ORTO.java + * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia + * @author Aljaž Osojnik + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package moa.classifiers.trees; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Stack; + +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; + +import moa.classifiers.Regressor; +import moa.classifiers.core.AttributeSplitSuggestion; +import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; +import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; +import moa.classifiers.core.splitcriteria.SplitCriterion; +import moa.core.AutoExpandVector; +import moa.core.Measurement; +import moa.core.StringUtils; +<<<<<<< HEAD:moa/src/main/java/moa/classifiers/trees/ORTO2.java + +======= +>>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe:moa/src/main/java/moa/classifiers/trees/ORTO2.java + +/* + * Implementation of ORTO, option trees for data streams. + */ + +public class ORTO2 extends FIMTDD2 implements Regressor { + + private static final long serialVersionUID = 1L; + + private int innerNodeCount = 0; + private int optionNodeCount = 0; + + private int numTrees = 1; + + + //region ================ OPTIONS ================ + + public IntOption maxTreesOption = new IntOption( + "maxTrees", + 'm', + "The maximum number of trees contained in the option tree.", + 10, 1, Integer.MAX_VALUE); + + public IntOption maxOptionLevelOption = new IntOption( + "maxOptionLevel", + 'x', + "The maximal depth at which option nodes can be created.", + 10, 0, Integer.MAX_VALUE); + + public FloatOption optionDecayFactorOption = new FloatOption( + "optionDecayFactor", + 'z', + "The option decay factor that determines how many options can be selected at a given level.", + 0.9, 0.0, 1.0); + + public MultiChoiceOption optionNodeAggregationOption = new MultiChoiceOption( + "optionNodeAggregation", + 'o', + "The aggregation method used to combine predictions in option nodes.", + new String[]{"average", "bestTree"}, new String[]{"Average", "Best tree"}, 0); + + public FloatOption optionFadingFactorOption = new FloatOption( + "optionFadingFactor", + 'q', + "The fading factor used for comparing subtrees of an option node.", + 0.9995, 0.0, 1.0); + + //endregion ================ OPTIONS ================ + + //region ================ CLASSES ================ + + public static class OptionNode extends InnerNode { + + private static final long serialVersionUID = 1L; + + protected double[] optionFFSSL; + protected double[] optionFFSeen; + + public OptionNode(FIMTDD2 tree) { + super(tree); + } + + public void resetFF() { + optionFFSSL = new double[children.size()]; + optionFFSeen = new double[children.size()]; + + for (int i = 0; i < children.size(); i++) { + optionFFSSL[i] = 0.0; + optionFFSeen[i] = 0.0; + } + } + + public int getNumSubtrees() { + int num = 0; + for (Node child : children) { + num += child.getNumSubtrees(); + } + return num; + } + + public int directionForBestTree() { + int d = 0; + double tmp = 0.0, min = Double.MAX_VALUE; + for (int i = 0; i < children.size(); i++) { + tmp = getFFRatio(i); + if (tmp < min) { + min = tmp; + d = i; + } + } + return d; + } + + public double getPrediction(Instance inst) { + double[] predictions = new double[numChildren()]; + for (int i = 0; i < numChildren(); i++) { + predictions[i] = getChild(i).getPrediction(inst); + } + return aggregate(predictions); + } + + private double aggregate(double[] predictions) { + if (((ORTO2) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average + double sum = 0.0; + for (int i = 0; i < predictions.length; i++) { + sum += predictions[i]; + } + return sum / predictions.length; + } else if (((ORTO2) tree).optionNodeAggregationOption.getChosenIndex() == 1) { + int d = directionForBestTree(); + return predictions[d]; + } else { + return 0.0; + } + } + + public double getFFRatio(int childIndex) { + return optionFFSSL[childIndex] / optionFFSeen[childIndex]; + } + + protected boolean skipInLevelCount() { + return true; + } + + @Override + public void describeSubtree(StringBuilder out, int indent) { + StringUtils.appendIndented(out, indent, "[option node]"); + StringUtils.appendNewline(out); + for (int childIndex = 0; childIndex < children.size(); childIndex++) { + Node split = getChild(childIndex); + StringUtils.appendIndented(out, indent, "[" + childIndex + "]"); + StringUtils.appendNewline(out); + split.describeSubtree(out, indent + 2); + } + } +<<<<<<< HEAD:moa/src/main/java/moa/classifiers/trees/ORTO2.java + +======= +>>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe:moa/src/main/java/moa/classifiers/trees/ORTO2.java + } + + //endregion ================ CLASSES ================ + + //region ================ METHODS ================ + + // region --- Regressor methods + + public String getPurposeString() { + return "Implementation of the ORTO tree as described by Ikonomovska et al."; + } + + public void resetLearningImpl() { + super.resetLearningImpl(); + this.innerNodeCount = 0; + this.optionNodeCount = 0; + } + + + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{ + new Measurement("number of subtrees", this.numTrees), + new Measurement("tree size (nodes)", this.leafNodeCount + this.innerNodeCount), + new Measurement("tree size (leaves)", this.leafNodeCount), + new Measurement("number of option nodes", this.optionNodeCount),}; + } + + public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { + if (node instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) node, prediction, normalError, growthAllowed, inAlternate); + } else { + Node currentNode = node; + while (true) { + if (currentNode instanceof LeafNode) { + ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); + break; + } else { + currentNode.examplesSeen += inst.weight(); + currentNode.sumOfAbsErrors += inst.weight() * normalError; + InnerNode iNode = (InnerNode) currentNode; + if (!inAlternate && iNode.alternateTree != null) { + boolean altTree = true; + double lossO = Math.pow(inst.classValue() - prediction, 2); + double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); + + // Loop for compatibility with bagging methods + for (int i = 0; i < inst.weight(); i++) { + iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; + iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; + iNode.lossExamplesSeen++; + + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + iNode.lossSumQi += Qi; + iNode.lossNumQiTests += 1; + } + double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); + double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; + + if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { + iNode.previousWeight = iNode.lossExamplesSeen; + if (Qi > 0) { + // Switch the subtrees + Node parent = iNode.getParent(); + + if (parent != null) { + Node replacementTree = iNode.alternateTree; + parent.setChild(parent.getChildIndex(iNode), replacementTree); + if (growthAllowed) replacementTree.restartChangeDetection(); + } else { + treeRoot = iNode.alternateTree; + treeRoot.restartChangeDetection(); + } + optionNodeCount += iNode.alternateTree.getNumSubtrees() - iNode.getNumSubtrees(); + removeExcessTrees(); + + currentNode = iNode.alternateTree; + currentNode.originalNode = null; + altTree = false; + } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { + // Remove the alternate tree + iNode.alternateTree = null; + if (growthAllowed) iNode.restartChangeDetection(); + altTree = false; + } + } + if (altTree) { + growthAllowed = false; // this is the growth of the original tree + processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree + } else if (currentNode instanceof OptionNode) { + // this happens when an option node is switched into the tree + for (Node child : ((OptionNode) currentNode).children) { + processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); + } + break; + } + } + + if (iNode.changeDetection && !inAlternate) { + if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + iNode.initializeAlternateTree(); + } + } + if (currentNode instanceof SplitNode) { + currentNode = ((SplitNode) currentNode).descendOneStep(inst); + } else if (currentNode instanceof OptionNode) { + processInstanceOptionNode(inst, (OptionNode) currentNode, prediction, normalError, growthAllowed, inAlternate); + break; + } + } + } + } + + } + + public void processInstanceOptionNode(Instance inst, OptionNode node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { + node.examplesSeen += inst.weight(); + node.sumOfAbsErrors += inst.weight() * normalError; +<<<<<<< HEAD:moa/src/main/java/moa/classifiers/trees/ORTO2.java + +======= +>>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe:moa/src/main/java/moa/classifiers/trees/ORTO2.java + if (node.changeDetection) { + double error = Math.abs(prediction - inst.classValue()); + node.sumOfAbsErrors += error; + + if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { + node.initializeAlternateTree(); + growthAllowed = false; + } + } + + for (Node child : node.children) { + int index = node.getChildIndex(child); + double childPrediction = child.getPrediction(inst); + + // Loop for compatibility with bagging methods + for (int i = 0; i < inst.weight(); i++) { + node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; + node.optionFFSSL[index] = node.optionFFSSL[index] * optionFadingFactorOption.getValue() + Math.pow(childPrediction - inst.classValue(), 2); + } + } + + for (Node child : node.children) { + processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); + } + } + + // endregion --- Regressor methods + + // region --- Object instantiation methods + + protected OptionNode newOptionNode() { + maxID++; + return new OptionNode(this); + } + + // endregion --- Object instantiation methods + + // region --- Processing methods + + protected void attemptToSplit(LeafNode node, Node parent, int parentIndex, Instance inst, double prediction) { + // Initialize the split criterion + SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); + + // Using this criterion, find the best split per attribute and rank the results + AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); + List acceptedSplits = new LinkedList(); + Arrays.sort(bestSplitSuggestions); + + // Declare a variable to determine the number of splits to be performed + int numSplits = 0; + + // If only one split was returned, use it (this generally shouldn't happen) + if (bestSplitSuggestions.length == 1) { + numSplits = 1; + acceptedSplits.add(bestSplitSuggestions[0]); + } else if (bestSplitSuggestions.length > 1) { // Otherwise, consider which of the splits proposed may be worth trying + + // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision + // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + + // Determine the top two ranked splitting suggestions + AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; + AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; + + + // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), + // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this + // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and + // splitting should occur. + // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit + // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two + // competing attributes are equally good, and the split will be made on the one with the higher SDR value. + if (secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) { + numSplits = 1; + acceptedSplits.add(bestSuggestion); + } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { + for (int i = 0; i < bestSplitSuggestions.length; i++) { + AttributeSplitSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; + if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { + numSplits++; + acceptedSplits.add(suggestion); + } else { + break; + } + } + } else if (hoeffdingBound < tieThresholdOption.getValue()) { + numSplits = 1; + acceptedSplits.add(bestSuggestion); + } else { // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer + for (int i = 0; i < node.attributeObservers.size(); i++) { + AttributeClassObserver obs = node.attributeObservers.get(i); + if (obs != null) { + ((FIMTDDNumericAttributeClassObserver) obs).removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); + } + } + } + } + + // If the splitting criterion was met, split the current node using the chosen attribute test, and + // make two new branches leading to (empty) leaves + if (numSplits > 0) { + double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); + + if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { + AttributeSplitSuggestion splitDecision = acceptedSplits.get(0); + SplitNode newSplit = newSplitNode(splitDecision.splitTest); + for (int i = 0; i < splitDecision.numSplits(); i++) { + LeafNode newChild = newLeafNode(); + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + leafNodeCount--; + innerNodeCount++; + leafNodeCount += splitDecision.numSplits(); + if (parent == null && node.originalNode == null) { + treeRoot = newSplit; + } else if (parent == null && node.originalNode != null) { + node.originalNode.alternateTree = newSplit; + } else { + parent.setChild(parentIndex, newSplit); + newSplit.setParent(parent); + } + } else { + OptionNode optionNode = newOptionNode(); + leafNodeCount--; + int j = 0; + + for (AttributeSplitSuggestion splitDecision : acceptedSplits) { + if (j > optionFactor || maxTreesOption.getValue() - numTrees <= 0) { + break; + } + SplitNode newSplit = newSplitNode(splitDecision.splitTest); + for (int i = 0; i < splitDecision.numSplits(); i++) { + LeafNode newChild = newLeafNode(); + newChild.setParent(newSplit); + newSplit.setChild(i, newChild); + } + + leafNodeCount += splitDecision.numSplits(); + innerNodeCount++; + numTrees++; + + newSplit.setParent(optionNode); + optionNode.setChild(j, newSplit); + j++; + } + + innerNodeCount++; + optionNodeCount++; + + if (parent == null) { + treeRoot = optionNode; + } else { + parent.setChild(parentIndex, optionNode); + optionNode.setParent(parent); + } + + optionNode.resetFF(); + } + } + } + + // endregion --- Processing methods + + // region --- Option tree methods + protected Node findWorstOption() { + Stack stack = new Stack(); + stack.add(treeRoot); + + double ratio = Double.MIN_VALUE; + Node out = null; + + while (!stack.empty()) { + Node node = stack.pop(); + if (node.getParent() instanceof OptionNode) { + OptionNode myParent = (OptionNode) node.getParent(); + int nodeIndex = myParent.getChildIndex(node); + double nodeRatio = myParent.getFFRatio(nodeIndex); + + if (nodeRatio > ratio) { + ratio = nodeRatio; + out = node; + } + } + if (node instanceof InnerNode) { + for (Node child : ((InnerNode) node).children) { + stack.add(child); + } + } + } + + return out; + } + + protected void removeExcessTrees() { + while (numTrees > maxTreesOption.getValue()) { + Node option = findWorstOption(); + OptionNode parent = (OptionNode) option.parent; + int index = parent.getChildIndex(option); + + if (parent.children.size() == 2) { + parent.children.remove(index); + for (Node chld : parent.children) { + chld.parent = parent.parent; + parent.parent.setChild(parent.parent.getChildIndex(parent), chld); + } + } else { + AutoExpandVector children = new AutoExpandVector(); + double[] optionFFSSL = new double[parent.children.size() - 1]; + double[] optionFFSeen = new double[parent.children.size() - 1]; + + int seen = 0; + + for (int i = 0; i < parent.children.size() - 1; i++) { + if (parent.getChild(i) != option) { + children.add(parent.getChild(i)); + optionFFSSL[i] = parent.optionFFSSL[i + seen]; + optionFFSeen[i] = parent.optionFFSeen[i + seen]; + } else { + seen = 1; + } + } + + parent.children = children; + parent.optionFFSSL = optionFFSSL; + parent.optionFFSeen = optionFFSeen; + + assert parent.children.size() == parent.optionFFSSL.length; + } + numTrees--; + } + } + + // endregion --- Option tree methods + + //endregion ================ METHODS ================ +} diff --git a/moa/src/main/java/moa/clusterers/clustree/ClusTree.java.orig b/moa/src/main/java/moa/clusterers/clustree/ClusTree.java.orig new file mode 100644 index 000000000..ed142e454 --- /dev/null +++ b/moa/src/main/java/moa/clusterers/clustree/ClusTree.java.orig @@ -0,0 +1,891 @@ +/* + * ClusTree.java + * Copyright (C) 2010 RWTH Aachen University, Germany + * @author Sanchez Villaamil (moa@cs.rwth-aachen.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package moa.clusterers.clustree; + +import java.util.ArrayList; + +import java.util.LinkedList; +import moa.clusterers.clustree.util.*; +import moa.cluster.Clustering; +import moa.clusterers.AbstractClusterer; +import moa.core.Measurement; +<<<<<<< Updated upstream +<<<<<<< HEAD +======= +<<<<<<< c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 +import com.github.javacliparser.IntOption; +import com.github.javacliparser.FlagOption; +import com.yahoo.labs.samoa.instances.Instance; +======= +>>>>>>> Instances rework, new iSOUPTree models and import cleanup +>>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe +======= +import com.github.javacliparser.IntOption; +import com.github.javacliparser.FlagOption; +import com.yahoo.labs.samoa.instances.Instance; +>>>>>>> Stashed changes + +/** + * Citation: ClusTree: Philipp Kranen, Ira Assent, Corinna Baldauf, Thomas Seidl: + * The ClusTree: indexing micro-clusters for anytime stream mining. + * Knowl. Inf. Syst. 29(2): 249-272 (2011) +*/ +public class ClusTree extends AbstractClusterer{ + private static final long serialVersionUID = 1L; + + public IntOption horizonOption = new IntOption("horizon", + 'h', "Range of the window.", 1000); + + public IntOption maxHeightOption = new IntOption( + "maxHeight", 'H', + "The maximal height of the tree", getDefaultHeight()); + + public FlagOption breadthFirstStrategyOption = new FlagOption( + "breadthFirstStrategy", 'B', + "Use breadth first strategy"); + + public FlagOption breadthFirstStrategyOption = new FlagOption( + "breadthFirstStrategy", 'B', + "Use breadth first strategy"); + + protected int getDefaultHeight() { + return 8; + } + + private static int INSERTIONS_BETWEEN_CLEANUPS = 10000; + /** + * The root node of the tree. + */ + protected Node root; + // Information about the data represented in this tree. + /** + * Dimensionality of the data points managed by this tree. + */ + private int numberDimensions; + /** + * Parameter for the weighting function use to weight the entries. + */ + protected double negLambda; + /** + * The current height of the tree. Should always be smaller than maxHeight. + */ + private int height; + /** + * The maximal height of the tree. + */ + protected int maxHeight; + /** + * This variable is used to keep the inverse height that is stored in every + * node correct. + */ + private int numRootSplits; + /** + * The threshold for the weighting of an Entry. An Entry is irrelevant, if + * it is in a leaf and the weightedN of the data Cluster is smaller than + * this threshold. + * @see Entry#data + */ + private double weightThreshold = 0.05; + /** + * Number of points inserted into the tree. + */ + private int numberInsertions; + private long timestamp; + + /** + * Parameter to determine wich strategy to use + */ + protected boolean breadthFirstStrat = false; + + //TODO: cleanup + private Entry alsoUpdate; + + @Override + public void resetLearningImpl() { + breadthFirstStrat = breadthFirstStrategyOption.isSet(); + negLambda = (1.0 / (double) horizonOption.getValue()) + * (Math.log(weightThreshold) / Math.log(2)); + maxHeight = maxHeightOption.getValue(); + numberDimensions = -1; + root = null; + timestamp = 0; + height = 0; + numRootSplits = 0; + numberInsertions = 0; + } + + + @Override + protected Measurement[] getModelMeasurementsImpl() { + return null; + } + + public boolean isRandomizable() { + return false; + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + } + + public Prediction getPredictionForInstance(Instance inst) { + return null; + } + + @Override + public boolean implementsMicroClusterer() { + return true; + } + + + + @Override + public void trainOnInstanceImpl(Instance instance) { + timestamp++; + + //TODO check if instance contains label + if(root == null){ + numberDimensions = instance.numAttributes(); + root = new Node(numberDimensions, 0); + } + else{ + if(numberDimensions!=instance.numAttributes()) + System.out.println("Wrong dimensionality, expected:"+numberDimensions+ "found:"+instance.numAttributes()); + } + + ClusKernel newPointAsKernel = new ClusKernel(instance.toDoubleArray(), numberDimensions); + insert(newPointAsKernel, new SimpleBudget(1000),timestamp); + } + + + /** + * Insert a new point in the Tree. The point should be + * represented as a cluster with a single data point(i.e. N = 1). A + * Budget class is also given, which is informed of the number + * of operation the tree does, and informs the tree when it does not have + * time left and should stop the insertion. + * @param newPoint The point to be inserted. + * @param budget The budget and statistics recollector for the insertion. + * @param timestamp The moment at which this point is inserted. + * @see Kernel + * @see Budget + */ + public void insert(ClusKernel newPoint, Budget budget, long timestamp) { + if (breadthFirstStrat){ + insertBreadthFirst(newPoint, budget, timestamp); + } + else{ + Entry rootEntry = new Entry(this.numberDimensions, + root, timestamp, null, null); + ClusKernel carriedBuffer = new ClusKernel(this.numberDimensions); + Entry toInsertHere = insert(newPoint, carriedBuffer, root, rootEntry, + budget, timestamp); + + if (toInsertHere != null) { + this.numRootSplits++; + this.height += this.height < this.maxHeight ? 1 : 0; + + Node newRoot = new Node(this.numberDimensions, + toInsertHere.getChild().getRawLevel() + 1); + newRoot.addEntry(rootEntry, timestamp); + newRoot.addEntry(toInsertHere, timestamp); + rootEntry.setNode(newRoot); + toInsertHere.setNode(newRoot); + this.root = newRoot; + } + } + + this.numberInsertions++; + if (this.numberInsertions % INSERTIONS_BETWEEN_CLEANUPS == 0) { + cleanUp(this.root, 0); + } + } + + /** + * insert newPoint into the tree using the BreadthFirst strategy, i.e.: insert into + * the closest entry in a leaf node. + * @param newPoint + * @param budget + * @param timestamp + * @return + */ + private Entry insertBreadthFirst(ClusKernel newPoint, Budget budget, long timestamp) { + //check all leaf nodes and get the one with the closest entry to newPoint + Node bestFit = findBestLeafNode(newPoint); + bestFit.makeOlder(timestamp, negLambda); + Entry parent = bestFit.getEntries()[0].getParentEntry(); + // Search for an Entry with a weight under the threshold. + Entry irrelevantEntry = bestFit.getIrrelevantEntry(this.weightThreshold); + int numFreeEntries = bestFit.numFreeEntries(); + Entry newEntry = new Entry(newPoint.getCenter().length, + newPoint, timestamp, parent, bestFit); + //if there is space, add it to the node ( doesn't ever occur, since nodes are created with 3 entries) + if (numFreeEntries>0){ + bestFit.addEntry(newEntry, timestamp); + } + //if outdated cluster in this best fitting node, replace it + else if (irrelevantEntry != null) { + irrelevantEntry.overwriteOldEntry(newEntry); + } + //if there is space/outdated cluster on path to top, split. Else merge without split + else { + if (existsOutdatedEntryOnPath(bestFit)||!this.hasMaximalSize()){ + // We have to split. + insertHereWithSplit(newEntry, bestFit, timestamp); + } + else { + mergeEntryWithoutSplit(bestFit, newEntry, + timestamp); + } + } + //update all nodes on path to top. + if (bestFit.getEntries()[0].getParentEntry()!=null) + updateToTop(bestFit.getEntries()[0].getParentEntry().getNode()); + return null; + } + /** + * This method checks if there is an outdated (or empty) entry on the path from node to root. + * It updates the weights of nodes on path and then checks if it is outdated. + * @param node + * @return true if an outdated/empty entry exists on the path + */ + private boolean existsOutdatedEntryOnPath(Node node) { + if (node == root){ + node.makeOlder(timestamp, negLambda); + return node.getIrrelevantEntry(this.weightThreshold)!=null; + } + do{ + node = node.getEntries()[0].getParentEntry().getNode(); + node.makeOlder(timestamp, negLambda); + for (Entry e : node.getEntries()){ + e.recalculateData(); + } + if (node.numFreeEntries()>0) + return true; + if (node.getIrrelevantEntry(this.weightThreshold)!=null) + return true; + }while(node.getEntries()[0].getParentEntry()!=null); + return false; + } + + /** + * recalculates data for all entries, that lie on the path from the root to the + * Entry toUpdate. + */ + private void updateToTop(Node toUpdate) { + while(toUpdate!=null){ + for (Entry e: toUpdate.getEntries()) + e.recalculateData(); + if (toUpdate.getEntries()[0].getParentEntry()==null) + break; + toUpdate=toUpdate.getEntries()[0].getParentEntry().getNode(); + } + } + + /** + * Method called by insertBreadthFirst. + * @param toInsert + * @param insertNode + * @param timestamp + * @return + */ + private Entry insertHereWithSplit(Entry toInsert, Node insertNode, + long timestamp) { + //Handle root split + if (insertNode.getEntries()[0].getParentEntry()==null){ + root.makeOlder(timestamp, negLambda); + Entry irrelevantEntry = insertNode.getIrrelevantEntry(this.weightThreshold); + int numFreeEntries = insertNode.numFreeEntries(); + if (irrelevantEntry != null) { + irrelevantEntry.overwriteOldEntry(toInsert); + } + else if (numFreeEntries>0){ + insertNode.addEntry(toInsert, timestamp); + } + else{ + this.numRootSplits++; + this.height += this.height < this.maxHeight ? 1 : 0; + Entry oldRootEntry = new Entry(this.numberDimensions, + root, timestamp, null, null); + Node newRoot = new Node(this.numberDimensions, + this.height); + Entry newRootEntry = split(toInsert, root, oldRootEntry, timestamp); + newRoot.addEntry(oldRootEntry, timestamp); + newRoot.addEntry(newRootEntry, timestamp); + this.root = newRoot; + for (Entry c : oldRootEntry.getChild().getEntries()) + c.setParentEntry(root.getEntries()[0]); + for (Entry c : newRootEntry.getChild().getEntries()) + c.setParentEntry(root.getEntries()[1]); + } + return null; + } + insertNode.makeOlder(timestamp, negLambda); + Entry irrelevantEntry = insertNode.getIrrelevantEntry(this.weightThreshold); + int numFreeEntries = insertNode.numFreeEntries(); + if (irrelevantEntry != null) { + irrelevantEntry.overwriteOldEntry(toInsert); + } + else if (numFreeEntries>0){ + insertNode.addEntry(toInsert, timestamp); + } + else { + // We have to split. + Entry parentEntry = insertNode.getEntries()[0].getParentEntry(); + Entry residualEntry = split(toInsert, insertNode, parentEntry, timestamp); + if (alsoUpdate!=null){ + alsoUpdate = residualEntry; + } + Node nodeForResidualEntry = insertNode.getEntries()[0].getParentEntry().getNode(); + //recursive call + return insertHereWithSplit(residualEntry, nodeForResidualEntry, timestamp); + } + + //no Split + return null; + } + + + // XXX: Document the insertion when the final implementation is done. + private Entry insertHere(Entry newEntry, Node currentNode, + Entry parentEntry, ClusKernel carriedBuffer, Budget budget, + long timestamp) { + + int numFreeEntries = currentNode.numFreeEntries(); + + // Insert the buffer that we carry. + if (!carriedBuffer.isEmpty()) { + Entry bufferEntry = new Entry(this.numberDimensions, + carriedBuffer, timestamp, parentEntry, currentNode); + + if (numFreeEntries <= 1) { + // Distance from buffer to entries. + Entry nearestEntryToCarriedBuffer = + currentNode.nearestEntry(newEntry); + double distanceNearestEntryToBuffer = + nearestEntryToCarriedBuffer.calcDistance(newEntry); + + // Distance between buffer and point to insert. + double distanceBufferNewEntry = + newEntry.calcDistance(carriedBuffer); + + // Best distance between Entrys in the Node. + BestMergeInNode bestMergeInNode = + calculateBestMergeInNode(currentNode); + + // See what the minimal distance is and do the correspoding + // action. + if (distanceNearestEntryToBuffer <= distanceBufferNewEntry + && distanceNearestEntryToBuffer <= bestMergeInNode.distance) { + // Aggregate buffer entry to nearest entry in node. + nearestEntryToCarriedBuffer.aggregateEntry(bufferEntry, + timestamp, this.negLambda); + } else if (distanceBufferNewEntry <= distanceNearestEntryToBuffer + && distanceBufferNewEntry <= bestMergeInNode.distance) { + newEntry.mergeWith(bufferEntry); + } else { + currentNode.mergeEntries(bestMergeInNode.entryPos1, + bestMergeInNode.entryPos2); + currentNode.addEntry(bufferEntry, timestamp); + } + + } else { + assert (currentNode.isLeaf()); + currentNode.addEntry(bufferEntry, timestamp); + } + } + + // Normally the insertion of the carries buffer does not change the + // number of free entries, but in case of future changes we calculate + // the number again. + numFreeEntries = currentNode.numFreeEntries(); + + // Search for an Entry with a weight under the threshold. + Entry irrelevantEntry = currentNode.getIrrelevantEntry(this.weightThreshold); + if (currentNode.isLeaf() && irrelevantEntry != null) { + irrelevantEntry.overwriteOldEntry(newEntry); + } else if (numFreeEntries >= 1) { + currentNode.addEntry(newEntry, timestamp); + } else { + if (currentNode.isLeaf() && (this.hasMaximalSize() + || !budget.hasMoreTime())) { + mergeEntryWithoutSplit(currentNode, newEntry, + timestamp); + } else { + // We have to split. + return split(newEntry, currentNode, parentEntry, timestamp); + } + } + + return null; + } + + /** + * This method calculates the distances between the new point and each Entry in a leaf node. + * It returns the node that contains the entry with the smallest distance + * to the new point. + * @param newPoint + * @return best fitting node + */ + private Node findBestLeafNode(ClusKernel newPoint) { + double minDist = Double.MAX_VALUE; + Node bestFit = null; + for (Node e: collectLeafNodes(root)){ + if (newPoint.calcDistance(e.nearestEntry(newPoint).getData()) collectLeafNodes(Node curr){ + ArrayList toReturn = new ArrayList(); + if (curr==null) + return toReturn; + if (curr.isLeaf()){ + toReturn.add(curr); + return toReturn; + } + else{ + for (Entry e : curr.getEntries()) + toReturn.addAll(collectLeafNodes(e.getChild())); + return toReturn; + } + } + + // TODO: Expand all function that work on entries to work with the Budget. + private Entry insert(ClusKernel pointToInsert, ClusKernel carriedBuffer, + Node currentNode, Entry parentEntry, Budget budget, long timestamp) { + assert (currentNode != null); + assert (currentNode.isLeaf() + || currentNode.getEntries()[0].getChild() != null); + + currentNode.makeOlder(timestamp, this.negLambda); + + // This variable will be changed from to null to an actual reference + // in the following if-else block if we have to insert something here, + // either because this is a leaf, or because of split propagation. + Entry toInsertHere = null; + + if (currentNode.isLeaf()) { + // At the end of the function the entry will be inserted. + toInsertHere = new Entry(this.numberDimensions, + pointToInsert, timestamp, parentEntry, currentNode); + } else { + + Entry bestEntry = currentNode.nearestEntry(pointToInsert); + bestEntry.aggregateCluster(pointToInsert, timestamp, + this.negLambda); + + boolean isCarriedBufferEmpty = carriedBuffer.isEmpty(); + + Entry bestBufferEntry = null; + if (!isCarriedBufferEmpty) { + bestBufferEntry = currentNode.nearestEntry(carriedBuffer); + bestBufferEntry.aggregateCluster(carriedBuffer, timestamp, + this.negLambda); + } + + if (!budget.hasMoreTime()) { + bestEntry.aggregateToBuffer(pointToInsert, timestamp, + this.negLambda); + if (!isCarriedBufferEmpty) { + bestBufferEntry.aggregateToBuffer(carriedBuffer, + timestamp, this.negLambda); + } + return null; + } + + // If the way of the buffer differs from the way of the point to + // be inserted, leave the buffer here. + if (!isCarriedBufferEmpty && (bestEntry != bestBufferEntry)) { + bestBufferEntry.aggregateToBuffer(carriedBuffer, timestamp, + this.negLambda); + carriedBuffer.clear(); + } + // Take the buffer of the best entry for the point to be inserted + // along. + ClusKernel takeAlongBuffer = bestEntry.emptyBuffer(timestamp, + this.negLambda); + carriedBuffer.add(takeAlongBuffer); + + // Recursive call. + toInsertHere = insert(pointToInsert, carriedBuffer, + bestEntry.getChild(), bestEntry, budget, timestamp); + } + + // If the above block has a new Entry for this place insert it. + if (toInsertHere != null) { + return this.insertHere(toInsertHere, currentNode, parentEntry, + carriedBuffer, budget, timestamp); + } + + // If nothing else needs to be done in all the above levels + // return null to signalize it. + return null; + } + + /** + * Inserts an Entry into a Node without inducing + * a split. + * @param node The node at which the entry is to be inserted. + * @param newEntry The entry to be inserted. + * @param timestamp The moment at which this occurs. + */ + private void mergeEntryWithoutSplit(Node node, + Entry newEntry, long timestamp) { + + Entry nearestEntryToCarriedBuffer = + node.nearestEntry(newEntry); + double distanceNearestEntryToBuffer = + nearestEntryToCarriedBuffer.calcDistance(newEntry); + + BestMergeInNode bestMergeInNode = + calculateBestMergeInNode(node); + + if (distanceNearestEntryToBuffer < bestMergeInNode.distance) { + nearestEntryToCarriedBuffer.aggregateEntry(newEntry, timestamp, + this.negLambda); + } else { + node.mergeEntries(bestMergeInNode.entryPos1, + bestMergeInNode.entryPos2); + node.addEntry(newEntry, timestamp); + } + } + + /** + * Calculates the best merge possible between two nodes in a node. This + * means that the pair with the smallest distance is found. + * @param node The node in which these two entries have to be found. + * @return An object which encodes the two position of the entries with the + * smallest distance in the node and the distance between them. + * @see BestMergeInNode + * @see Entry#calcDistance(tree.Entry) + */ + private BestMergeInNode calculateBestMergeInNode(Node node) { + assert (node.numFreeEntries() == 0); + + Entry[] entries = node.getEntries(); + + int toMerge1 = -1; + int toMerge2 = -1; + double distanceBetweenMergeEntries = Double.NaN; + + double minDistance = Double.MAX_VALUE; + for (int i = 0; i < entries.length; i++) { + Entry e1 = entries[i]; + for (int j = i + 1; j < entries.length; j++) { + Entry e2 = entries[j]; + double distance = e1.calcDistance(e2); + if (distance < minDistance) { + toMerge1 = i; + toMerge2 = j; + distanceBetweenMergeEntries = distance; + } + } + } + + assert (toMerge1 != -1 && toMerge2 != -1); + if (Double.isNaN(distanceBetweenMergeEntries)) { + throw new RuntimeException("The minimal distance between two " + + "Entrys in a Node was Double.MAX_VAUE. That can hardly " + + "be right."); + } + + return new BestMergeInNode(toMerge1, toMerge2, + distanceBetweenMergeEntries); + } + + private boolean hasMaximalSize() { + // TODO: Improve hasMaximalSize(). For now it just works somehow for testing. + return this.height == this.maxHeight; + } + + /** + * Performs a (2,2) split on the given node with the given entry. This + * implementation only works if the nodes have three entries each. The split + * will generate two new nodes. One of them will be put where the old node + * was, and for the other a new Entry will be generated and + * returned. + * @param newEntry The entry to be added to the node. + * @param node The node that is going to be splitted. + * @param parentEntry The entry in the tree that points at the node that + * is going to be splitted. + * @param timestamp The moment at which this split occurs. + * @return An entry which points at the second node created in the split. + * This entry has to be introduced later in the tree. + */ + private Entry split(Entry newEntry, Node node, Entry parentEntry, + long timestamp) { + // The implemented split function only works in trees where node + // have three entries. + // Splitting only makes sense on full nodes. + assert (node.numFreeEntries() == 0); + assert (parentEntry.getChild() == node); + + // All the entries we have to separate in two nodes. + Entry[] allEntries = new Entry[4]; + Entry[] nodeEntries = node.getEntries(); + for (int i = 0; i < nodeEntries.length; i++) { + allEntries[i] = new Entry(nodeEntries[i]); + } + allEntries[3] = newEntry; + + // Clear the given node, since we are going to refill it later. + node = new Node(this.numberDimensions, node.getRawLevel()); + + // Calculate the distance of all the possible pairings, since we want + // to do a (2,2) split. + double select01 = allEntries[0].calcDistance(allEntries[1]) + + allEntries[2].calcDistance(allEntries[3]); + + double select02 = allEntries[0].calcDistance(allEntries[2]) + + allEntries[1].calcDistance(allEntries[3]); + + double select03 = allEntries[0].calcDistance(allEntries[3]) + + allEntries[1].calcDistance(allEntries[2]); + + // See which of the pairings is minimal and distribute the entries + // accordingly. + Node residualNode = new Node(this.numberDimensions, + node.getRawLevel()); + if (select01 < select02) { + if (select01 < select03) {//select01 smallest + node.addEntry(allEntries[0], timestamp); + node.addEntry(allEntries[1], timestamp); + residualNode.addEntry(allEntries[2], timestamp); + residualNode.addEntry(allEntries[3], timestamp); + } else {//select03 smallest + node.addEntry(allEntries[0], timestamp); + node.addEntry(allEntries[3], timestamp); + residualNode.addEntry(allEntries[1], timestamp); + residualNode.addEntry(allEntries[2], timestamp); + } + } else { + if (select02 < select03) {//select02 smallest + node.addEntry(allEntries[0], timestamp); + node.addEntry(allEntries[2], timestamp); + residualNode.addEntry(allEntries[1], timestamp); + residualNode.addEntry(allEntries[3], timestamp); + } else {//select03 smallest + node.addEntry(allEntries[0], timestamp); + node.addEntry(allEntries[3], timestamp); + residualNode.addEntry(allEntries[1], timestamp); + residualNode.addEntry(allEntries[2], timestamp); + } + } + + // Set the other node into the tree. + parentEntry.setChild(node); + parentEntry.recalculateData(); + int count = 0; + for (Entry e : node.getEntries()){ + e.setParentEntry(parentEntry); + if (e.getData().getN() != 0) + count++; + } + //System.out.println(count); + // Generate a new entry for the residual node. + Entry residualEntry = new Entry(this.numberDimensions, + residualNode, timestamp, parentEntry, node); + count=0; + for (Entry e: residualNode.getEntries()){ + e.setParentEntry(residualEntry); + if (e.getData().getN() != 0) + count++; + } + //System.out.println(count); + return residualEntry; + } + + /** + * Return the number of time the tree has grown in size. If the tree grows + * and is then cutted from a certain depth, it also counts. + * @return The number of times the root node was splitted. + */ + public int getNumRootSplits() { + return numRootSplits; + } + + /** + * Return the current height of the tree. This should never be greater than + * maxHeight. + * @return The height of the tree. + * @see #maxHeight + */ + public int getHeight() { + assert (height <= maxHeight); + return height; + } + + private void cleanUp(Node currentNode, int level) { + if (currentNode == null) { + return; + } + + Entry[] entries = currentNode.getEntries(); + if (level == this.maxHeight) { + for (int i = 0; i < entries.length; i++) { + Entry e = entries[i]; + e.setChild(null); + } + } else { + for (int i = 0; i < entries.length; i++) { + Entry e = entries[i]; + cleanUp(e.getChild(), level + 1); + } + } + } + + /** + * @param currentTime The current time + * @return The kernels at the leaf level as a clustering + */ + //TODO: Microcluster unter dem Threshhold nich zur�ckgeben (WIe bei outdated entries) + @Override + public Clustering getMicroClusteringResult() { + return getClustering(timestamp, -1); + } + + @Override + public Clustering getClusteringResult() { + return null; + } + + + /** + * @param currentTime The current time + * @return The kernels at the given level as a clustering. + */ + public Clustering getClustering(long currentTime, int targetLevel) { + if (root == null) { + return null; + } + + Clustering clusters = new Clustering(); + LinkedList queue = new LinkedList(); + queue.add(root); + + while (!queue.isEmpty()) { + Node current = queue.remove(); + // if (current == null) + // continue; + int currentLevel = current.getLevel(this); + boolean isLeaf = (current.isLeaf() && currentLevel <= maxHeight) + || currentLevel == maxHeight; + + if (currentLevel == targetLevel + || (targetLevel == - 1 && isLeaf)) { + assert (currentLevel <= maxHeight); + + Entry[] entries = current.getEntries(); + for (int i = 0; i < entries.length; i++) { + Entry entry = entries[i]; + if (entry == null || entry.isEmpty()) { + continue; + } + // XXX + entry.makeOlder(currentTime, this.negLambda); + if (entry.isIrrelevant(this.weightThreshold)) + continue; + + ClusKernel gaussKernel = new ClusKernel(entry.getData()); + +// long diff = currentTime - entry.getTimestamp(); +// if (diff > 0) { +// gaussKernel.makeOlder(diff, negLambda); +// } + + clusters.add(gaussKernel); + } + } else if (!current.isLeaf()) { + Entry[] entries = current.getEntries(); + for (int i = 0; i < entries.length; i++) { + Entry entry = entries[i]; + + if (entry.isEmpty()) { + continue; + } + + if (entry.isIrrelevant(weightThreshold)) { + continue; + } + + queue.add(entry.getChild()); + } + } + } + + return clusters; + } + + + + /************************************************************************** + * LOCAL CLASSES + **************************************************************************/ + /** + * A class to code the return value of searching the smallest merge in a + * node. + */ + class BestMergeInNode { + + /** + * The position of the first entry in the array of the node. + */ + public int entryPos1; + /** + * The position of the second entry in the array of the node. + */ + public int entryPos2; + /** + * The distance between the two entries. + */ + public double distance; + + /** + * The constructor of this return value. It will automatically make + * sure that the first position is the smaller one of the two. + * @param pos1 One of the position. + * @param pos2 One of the position. + * @param distance The distance between the entries at these positions. + */ + public BestMergeInNode(int pos1, int pos2, + double distance) { + assert (pos1 != pos2); + + this.distance = distance; + + if (pos1 < pos2) { + this.entryPos1 = pos1; + this.entryPos2 = pos2; + } else { + this.entryPos1 = pos2; + this.entryPos2 = pos1; + } + } + } + +} diff --git a/moa/src/main/java/moa/learners/InstanceLearner.java b/moa/src/main/java/moa/learners/InstanceLearner.java new file mode 100644 index 000000000..5a57e8163 --- /dev/null +++ b/moa/src/main/java/moa/learners/InstanceLearner.java @@ -0,0 +1,56 @@ +/* + * Learner.java + * Copyright (C) 2011 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +package moa.learners; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.predictions.Prediction; + +import moa.core.Example; + +/** + * Learner interface for incremental learning models. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @version $Revision: 7 $ + */ +public interface InstanceLearner extends Learner> { + + + /** + * Trains this learner incrementally using the given example. + * + * @param inst the instance to be used for training + */ + public void trainOnInstance(Instance example); + + /** + * Predicts the class memberships for a given instance. If + * an instance is unclassified, the returned array elements + * must be all zero. + * + * @param inst the instance to be classified + * @return an array containing the estimated membership + * probabilities of the test instance in each class + */ + public Prediction getPredictionForInstance(Instance testInst); +} + + + diff --git a/moa/src/main/java/moa/tasks/ClassificationMainTask.java b/moa/src/main/java/moa/tasks/ClassificationMainTask.java new file mode 100644 index 000000000..86339d21f --- /dev/null +++ b/moa/src/main/java/moa/tasks/ClassificationMainTask.java @@ -0,0 +1,5 @@ +package moa.tasks; + +public interface ClassificationMainTask extends MainTaskInterface { + +} diff --git a/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java b/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java deleted file mode 100644 index 46f6ca2c2..000000000 --- a/moa/src/main/java/moa/tasks/EvaluateInterleavedTestThenTrain.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * EvaluateInterleavedTestThenTrain.java - * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package moa.tasks; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.PrintStream; - -import com.github.javacliparser.FileOption; -import com.github.javacliparser.IntOption; - -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; -import moa.core.TimingUtils; -import moa.evaluation.LearningCurve; -import moa.evaluation.LearningEvaluation; -import moa.evaluation.LearningPerformanceEvaluator; -import moa.learners.Learner; -import moa.options.ClassOption; -import moa.streams.ExampleStream; -import moa.streams.InstanceStream; - -/** - * Task for evaluating a classifier on a stream by testing then training with each example in sequence. - * - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * @version $Revision: 7 $ - */ -public class EvaluateInterleavedTestThenTrain extends MainTask { - - @Override - public String getPurposeString() { - return "Evaluates a classifier on a stream by testing then training with each example in sequence."; - } - - private static final long serialVersionUID = 1L; - - public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", Learner.class, "moa.classifiers.bayes.NaiveBayes"); - - public ClassOption streamOption = new ClassOption("stream", 's', - "Stream to learn from.", ExampleStream.class, - "generators.RandomTreeGenerator"); - - public IntOption randomSeedOption = new IntOption( - "instanceRandomSeed", 'r', - "Seed for random generation of instances.", 1); - - public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', - "Classification performance evaluation method.", - LearningPerformanceEvaluator.class, - "BasicClassificationPerformanceEvaluator"); - - public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', - "Maximum number of instances to test/train on (-1 = no limit).", - 100000000, -1, Integer.MAX_VALUE); - - public IntOption timeLimitOption = new IntOption("timeLimit", 't', - "Maximum number of seconds to test/train for (-1 = no limit).", -1, - -1, Integer.MAX_VALUE); - - public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", - 'f', - "How many instances between samples of the learning performance.", - 100000, 0, Integer.MAX_VALUE); - - public IntOption memCheckFrequencyOption = new IntOption( - "memCheckFrequency", 'q', - "How many instances between memory bound checks.", 100000, 0, - Integer.MAX_VALUE); - - public FileOption dumpFileOption = new FileOption("dumpFile", 'd', - "File to append intermediate csv reslts to.", null, "csv", true); - - @Override - public Class getTaskResultType() { - return LearningCurve.class; - } - - @Override - protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { - - String learnerString = this.learnerOption.getValueAsCLIString(); - String streamString = this.streamOption.getValueAsCLIString(); - //this.learnerOption.setValueViaCLIString(this.learnerOption.getValueAsCLIString() + " -r " +this.randomSeedOption); - // this.streamOption.setValueViaCLIString(streamString + " -i " + this.randomSeedOption.getValueAsCLIString()); - - Learner learner = (Learner) getPreparedClassOption(this.learnerOption); - if (learner.isRandomizable()) { - learner.setRandomSeed(this.randomSeedOption.getValue()); - learner.resetLearning(); - } - ExampleStream stream = (InstanceStream) getPreparedClassOption(this.streamOption); - - LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); - learner.setModelContext(stream.getHeader()); - int maxInstances = this.instanceLimitOption.getValue(); - long instancesProcessed = 0; - int maxSeconds = this.timeLimitOption.getValue(); - int secondsElapsed = 0; - monitor.setCurrentActivity("Evaluating learner...", -1.0); - LearningCurve learningCurve = new LearningCurve( - "learning evaluation instances"); - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - boolean firstDump = true; - boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); - long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - long lastEvaluateStartTime = evaluateStartTime; - double RAMHours = 0.0; - while (stream.hasMoreInstances() - && ((maxInstances < 0) || (instancesProcessed < maxInstances)) - && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { - Example trainInst = stream.nextInstance(); - Example testInst = trainInst; //.copy(); - //int trueClass = (int) trainInst.classValue(); - //testInst.setClassMissing(); - double[] prediction = learner.getVotesForInstance(testInst); - //evaluator.addClassificationAttempt(trueClass, prediction, testInst - // .weight()); - evaluator.addResult(testInst, prediction); - learner.trainOnInstance(trainInst); - instancesProcessed++; - if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 - || stream.hasMoreInstances() == false) { - long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); - double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); - double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs - RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours - RAMHours += RAMHoursIncrement; - lastEvaluateStartTime = evaluateTime; - learningCurve.insertEntry(new LearningEvaluation( - new Measurement[]{ - new Measurement( - "learning evaluation instances", - instancesProcessed), - new Measurement( - "evaluation time (" - + (preciseCPUTiming ? "cpu " - : "") + "seconds)", - time), - new Measurement( - "model cost (RAM-Hours)", - RAMHours) - }, - evaluator, learner)); - if (immediateResultStream != null) { - if (firstDump) { - immediateResultStream.print("Learner,stream,randomSeed,"); - immediateResultStream.println(learningCurve.headerToString()); - firstDump = false; - } - immediateResultStream.print(learnerString + "," + streamString + "," + this.randomSeedOption.getValueAsCLIString() + ","); - immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); - immediateResultStream.flush(); - } - } - if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { - if (monitor.taskShouldAbort()) { - return null; - } - long estimatedRemainingInstances = stream.estimatedRemainingInstances(); - if (maxInstances > 0) { - long maxRemaining = maxInstances - instancesProcessed; - if ((estimatedRemainingInstances < 0) - || (maxRemaining < estimatedRemainingInstances)) { - estimatedRemainingInstances = maxRemaining; - } - } - monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 - : (double) instancesProcessed - / (double) (instancesProcessed + estimatedRemainingInstances)); - if (monitor.resultPreviewRequested()) { - monitor.setLatestResultPreview(learningCurve.copy()); - } - secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() - - evaluateStartTime); - } - } - if (immediateResultStream != null) { - immediateResultStream.close(); - } - return learningCurve; - } -} diff --git a/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java.orig b/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java.orig new file mode 100644 index 000000000..a9f314477 --- /dev/null +++ b/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java.orig @@ -0,0 +1,308 @@ +/* + * EvaluatePeriodicHeldOutTest.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Ammar Shaker (shaker@mathematik.uni-marburg.de) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.tasks; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +<<<<<<< Updated upstream +<<<<<<< HEAD +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + +======= +<<<<<<< c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 +import moa.classifiers.Classifier; +======= +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstancesHeader; + +>>>>>>> Instances rework, new iSOUPTree models and import cleanup +>>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe +======= +import moa.classifiers.Classifier; +>>>>>>> Stashed changes +import moa.core.Example; +import moa.core.Measurement; +import moa.core.ObjectRepository; +import moa.core.StringUtils; +import moa.core.TimingUtils; +import moa.evaluation.LearningCurve; +import moa.evaluation.LearningEvaluation; +import moa.evaluation.LearningPerformanceEvaluator; +import moa.learners.Learner; +import moa.options.ClassOption; +import moa.streams.CachedInstancesStream; +import moa.streams.ExampleStream; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstanceHeader; + +/** + * Task for evaluating a classifier on a stream by periodically testing on a heldout set. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @version $Revision: 7 $ + */ +public class EvaluatePeriodicHeldOutTest extends MainTask { + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by periodically testing on a heldout set."; + } + + private static final long serialVersionUID = 1L; + + public ClassOption learnerOption = new ClassOption("learner", 'l', + "Classifier to train.", Classifier.class, "moa.classifiers.trees.HoeffdingTree"); + + public ClassOption streamOption = new ClassOption("stream", 's', + "Stream to learn from.", ExampleStream.class, + "generators.RandomTreeGenerator"); + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Learning performance evaluation method.", + LearningPerformanceEvaluator.class, + "BasicClassificationPerformanceEvaluator"); + + public IntOption testSizeOption = new IntOption("testSize", 'n', + "Number of testing examples.", 1000000, 0, Integer.MAX_VALUE); + + public IntOption trainSizeOption = new IntOption("trainSize", 'i', + "Number of training examples, <1 = unlimited.", 0, 0, + Integer.MAX_VALUE); + + public IntOption trainTimeOption = new IntOption("trainTime", 't', + "Number of training seconds.", 10 * 60 * 60, 0, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption( + "sampleFrequency", + 'f', + "Number of training examples between samples of learning performance.", + 100000, 0, Integer.MAX_VALUE); + + public FileOption dumpFileOption = new FileOption("dumpFile", 'd', + "File to append intermediate csv results to.", null, "csv", true); + + public FlagOption cacheTestOption = new FlagOption("cacheTest", 'c', + "Cache test instances in memory."); + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + Learner learner = (Learner) getPreparedClassOption(this.learnerOption); + ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); + LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); + learner.setModelContext(stream.getHeader()); + long instancesProcessed = 0; + LearningCurve learningCurve = new LearningCurve("evaluation instances"); + File dumpFile = this.dumpFileOption.getFile(); + PrintStream immediateResultStream = null; + if (dumpFile != null) { + try { + if (dumpFile.exists()) { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile, true), true); + } else { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open immediate result file: " + dumpFile, ex); + } + } + boolean firstDump = true; + ExampleStream testStream = null; + int testSize = this.testSizeOption.getValue(); + if (this.cacheTestOption.isSet()) { + monitor.setCurrentActivity("Caching test examples...", -1.0); + InstancesHeader testInstances = new InstancesHeader(stream.getHeader(), + this.testSizeOption.getValue()); + while (testInstances.numInstances() < testSize) { + testInstances.add((Instance) stream.nextInstance().getData()); + if (testInstances.numInstances() + % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { + if (monitor.taskShouldAbort()) { + return null; + } + monitor.setCurrentActivityFractionComplete((double) testInstances.numInstances() + / (double) (this.testSizeOption.getValue())); + } + } + testStream = new CachedInstancesStream(testInstances); + } else { + //testStream = (InstanceStream) stream.copy(); + testStream = stream; + /*monitor.setCurrentActivity("Skipping test examples...", -1.0); + for (int i = 0; i < testSize; i++) { + stream.nextInstance(); + }*/ + } + instancesProcessed = 0; + TimingUtils.enablePreciseTiming(); + double totalTrainTime = 0.0; + while ((this.trainSizeOption.getValue() < 1 + || instancesProcessed < this.trainSizeOption.getValue()) + && stream.hasMoreInstances() == true) { + monitor.setCurrentActivityDescription("Training..."); + long instancesTarget = instancesProcessed + + this.sampleFrequencyOption.getValue(); + long trainStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + while (instancesProcessed < instancesTarget && stream.hasMoreInstances() == true) { + learner.trainOnInstance(stream.nextInstance()); + instancesProcessed++; + if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { + if (monitor.taskShouldAbort()) { + return null; + } + monitor.setCurrentActivityFractionComplete((double) (instancesProcessed) + / (double) (this.trainSizeOption.getValue())); + } + } + double lastTrainTime = TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() + - trainStartTime); + totalTrainTime += lastTrainTime; + if (totalTrainTime > this.trainTimeOption.getValue()) { + break; + } + if (this.cacheTestOption.isSet()) { + testStream.restart(); + } + evaluator.reset(); + long testInstancesProcessed = 0; + monitor.setCurrentActivityDescription("Testing (after " + + StringUtils.doubleToString( + ((double) (instancesProcessed) + / (double) (this.trainSizeOption.getValue()) * 100.0), 2) + + "% training)..."); + long testStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + int instCount = 0 ; + for (instCount = 0; instCount < testSize; instCount++) { + if (stream.hasMoreInstances() == false) { + break; + } + Example testInst = (Example) testStream.nextInstance(); //.copy(); + double trueClass = ((Instance) testInst.getData()).classValue(); + //testInst.setClassMissing(); + double[] prediction = learner.getPredictionForInstance(testInst); + //testInst.setClassValue(trueClass); + evaluator.addResult(testInst, prediction); + testInstancesProcessed++; + if (testInstancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { + if (monitor.taskShouldAbort()) { + return null; + } + monitor.setCurrentActivityFractionComplete((double) testInstancesProcessed + / (double) (testSize)); + } + } + if ( instCount != testSize) { + break; + } + double testTime = TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() + - testStartTime); + List measurements = new ArrayList(); + measurements.add(new Measurement("evaluation instances", + instancesProcessed)); + measurements.add(new Measurement("total train time", totalTrainTime)); + measurements.add(new Measurement("total train speed", + instancesProcessed / totalTrainTime)); + measurements.add(new Measurement("last train time", lastTrainTime)); + measurements.add(new Measurement("last train speed", + this.sampleFrequencyOption.getValue() / lastTrainTime)); + measurements.add(new Measurement("test time", testTime)); + measurements.add(new Measurement("test speed", this.testSizeOption.getValue() + / testTime)); + Measurement[] performanceMeasurements = evaluator.getPerformanceMeasurements(); + for (Measurement measurement : performanceMeasurements) { + measurements.add(measurement); + } + Measurement[] modelMeasurements = learner.getModelMeasurements(); + for (Measurement measurement : modelMeasurements) { + measurements.add(measurement); + } + learningCurve.insertEntry(new LearningEvaluation(measurements.toArray(new Measurement[measurements.size()]))); + if (immediateResultStream != null) { + if (firstDump) { + immediateResultStream.println(learningCurve.headerToString()); + firstDump = false; + } + immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); + immediateResultStream.flush(); + } + if (monitor.resultPreviewRequested()) { + monitor.setLatestResultPreview(learningCurve.copy()); + } + // if (learner instanceof HoeffdingTree + // || learner instanceof HoeffdingOptionTree) { + // int numActiveNodes = (int) Measurement.getMeasurementNamed( + // "active learning leaves", + // modelMeasurements).getValue(); + // // exit if tree frozen + // if (numActiveNodes < 1) { + // break; + // } + // int numNodes = (int) Measurement.getMeasurementNamed( + // "tree size (nodes)", modelMeasurements) + // .getValue(); + // if (numNodes == lastNumNodes) { + // noGrowthCount++; + // } else { + // noGrowthCount = 0; + // } + // lastNumNodes = numNodes; + // } else if (learner instanceof OzaBoost || learner instanceof + // OzaBag) { + // double numActiveNodes = Measurement.getMeasurementNamed( + // "[avg] active learning leaves", + // modelMeasurements).getValue(); + // // exit if all trees frozen + // if (numActiveNodes == 0.0) { + // break; + // } + // int numNodes = (int) (Measurement.getMeasurementNamed( + // "[avg] tree size (nodes)", + // learner.getModelMeasurements()).getValue() * Measurement + // .getMeasurementNamed("ensemble size", + // modelMeasurements).getValue()); + // if (numNodes == lastNumNodes) { + // noGrowthCount++; + // } else { + // noGrowthCount = 0; + // } + // lastNumNodes = numNodes; + // } + } + if (immediateResultStream != null) { + immediateResultStream.close(); + } + return learningCurve; + } + + @Override + public Class getTaskResultType() { + return LearningCurve.class; + } +} diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialClassification.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialClassification.java new file mode 100644 index 000000000..287bb51d2 --- /dev/null +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialClassification.java @@ -0,0 +1,30 @@ +package moa.tasks; + +import java.io.PrintStream; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.predictions.Prediction; + +import moa.core.Utils; +import moa.learners.Classifier; + +public class EvaluatePrequentialClassification extends AbstractEvaluatePrequential implements ClassificationMainTask { + + private static final long serialVersionUID = 1L; + + public EvaluatePrequentialClassification() { + super(Classifier.class, "moa.classifiers.trees.HoeffdingTree"); + } + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } + @Override + public void printPrediction(PrintStream print, Instance inst, Prediction prediction) { + int trueClass = (int) inst.classValue(); + print.println(Utils.maxIndex(prediction.asDoubleArray()) + "," + (inst.classIsMissing() ? " ? " : trueClass)); + + } + +} diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiLabelClassification.java b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiLabelClassification.java new file mode 100644 index 000000000..26108f057 --- /dev/null +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiLabelClassification.java @@ -0,0 +1,27 @@ +package moa.tasks; + +import java.io.PrintStream; + +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.predictions.Prediction; + +import moa.learners.MultiLabelClassifier; + +public class EvaluatePrequentialMultiLabelClassification extends AbstractEvaluatePrequential { + + private static final long serialVersionUID = 1L; + + public EvaluatePrequentialMultiLabelClassification() { + super(MultiLabelClassifier.class, "moa.classifiers.mlc.trees.MultilabelHoeffdingTree"); + } + + @Override + public String getPurposeString() { + return "Evaluates a multi-label classifier on a stream by testing then training with each example in sequence."; + } + + @Override + public void printPrediction(PrintStream print, Instance inst, Prediction prediction) { + print.println(prediction.asPredictionString() + "," + inst.outputAttributesToString()); + } +} diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java.orig b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java.orig new file mode 100644 index 000000000..55b4ceade --- /dev/null +++ b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java.orig @@ -0,0 +1,713 @@ +<<<<<<< c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 +/* + * EvaluatePrequentialMultiTarget.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.tasks; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.InstanceData; +import com.yahoo.labs.samoa.instances.Prediction; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; + +import moa.classifiers.MultiTargetRegressor; +import moa.classifiers.Regressor; +import moa.core.Example; +import moa.core.Measurement; +import moa.core.ObjectRepository; +import moa.core.TimingUtils; +import moa.evaluation.EWMAClassificationPerformanceEvaluator; +import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; +import moa.evaluation.LearningCurve; +import moa.evaluation.LearningEvaluation; +import moa.evaluation.LearningPerformanceEvaluator; +import moa.evaluation.MultiTargetPerformanceEvaluator; +import moa.evaluation.RegressionPerformanceEvaluator; +import moa.evaluation.WindowClassificationPerformanceEvaluator; +import moa.learners.Learner; +import moa.options.ClassOption; +import moa.streams.ExampleStream; +import moa.streams.MultiTargetInstanceStream; + +/** + * Task for evaluating a classifier on a stream by testing then training with each example in sequence. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * @version $Revision: 7 $ + */ +public class EvaluatePrequentialMultiTarget extends MultiTargetMainTask { + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } + + private static final long serialVersionUID = 1L; + + public ClassOption learnerOption = new ClassOption("learner", 'l', + "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); + + public ClassOption streamOption = new ClassOption("stream", 's', + "Stream to learn from.", MultiTargetInstanceStream.class, + "MultiTargetArffFileStream"); + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + MultiTargetPerformanceEvaluator.class, + "BasicMultiTargetPerformanceEvaluator"); + + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); + + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); + + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); + + public FileOption dumpFileOption = new FileOption("dumpFile", 'd', + "File to append intermediate csv results to.", null, "csv", true); + + public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', + "File to append output predictions to.", null, "pred", true); + + //New for prequential method DEPRECATED + public IntOption widthOption = new IntOption("width", + 'w', "Size of Window", 1000); + + public FloatOption alphaOption = new FloatOption("alpha", + 'a', "Fading factor or exponential smoothing factor", .01); + //End New for prequential methods + + @Override + public Class getTaskResultType() { + return LearningCurve.class; + } + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + Learner learner = (Learner) getPreparedClassOption(this.learnerOption); + ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); + LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); + LearningCurve learningCurve = new LearningCurve( + "learning evaluation instances"); + + //New for prequential methods + if (evaluator instanceof WindowClassificationPerformanceEvaluator) { + //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); + if (widthOption.getValue() != 1000) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); + return learningCurve; +======= +/* + * EvaluatePrequentialMultiTarget.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package moa.tasks; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; + +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import com.yahoo.labs.samoa.instances.Prediction; + +import moa.classifiers.MultiTargetRegressor; +import moa.core.Example; +import moa.core.Measurement; +import moa.core.ObjectRepository; +import moa.core.TimingUtils; +import moa.evaluation.EWMAClassificationPerformanceEvaluator; +import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; +import moa.evaluation.LearningCurve; +import moa.evaluation.LearningEvaluation; +import moa.evaluation.LearningPerformanceEvaluator; +import moa.evaluation.MultiTargetPerformanceEvaluator; +import moa.evaluation.WindowClassificationPerformanceEvaluator; +import moa.learners.Learner; +import moa.options.ClassOption; +import moa.streams.ExampleStream; +import moa.streams.MultiTargetInstanceStream; + +/** + * Task for evaluating a classifier on a stream by testing then training with each example in sequence. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * @version $Revision: 7 $ + */ +public class EvaluatePrequentialMultiTarget extends MultiTargetMainTask { + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } +<<<<<<< HEAD + + private static final long serialVersionUID = 1L; + + public ClassOption learnerOption = new ClassOption("learner", 'l', + "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); + + public ClassOption streamOption = new ClassOption("stream", 's', + "Stream to learn from.", MultiTargetInstanceStream.class, + "MultiTargetArffFileStream"); + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + MultiTargetPerformanceEvaluator.class, + "BasicMultiTargetPerformanceEvaluator"); + + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); + + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); + + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); + + public FileOption dumpFileOption = new FileOption("dumpFile", 'd', + "File to append intermediate csv results to.", null, "csv", true); + + public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', + "File to append output predictions to.", null, "pred", true); + + //New for prequential method DEPRECATED + public IntOption widthOption = new IntOption("width", + 'w', "Size of Window", 1000); + + public FloatOption alphaOption = new FloatOption("alpha", + 'a', "Fading factor or exponential smoothing factor", .01); + //End New for prequential methods + + @Override + public Class getTaskResultType() { + return LearningCurve.class; + } + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + Learner learner = (Learner) getPreparedClassOption(this.learnerOption); + ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); + LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); + LearningCurve learningCurve = new LearningCurve( + "learning evaluation instances"); + + //New for prequential methods + if (evaluator instanceof WindowClassificationPerformanceEvaluator) { + //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); + if (widthOption.getValue() != 1000) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { + //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { + //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + //End New for prequential methods + + learner.setModelContext(stream.getHeader()); + int maxInstances = this.instanceLimitOption.getValue(); + long instancesProcessed = 0; + int maxSeconds = this.timeLimitOption.getValue(); + int secondsElapsed = 0; + monitor.setCurrentActivity("Evaluating learner...", -1.0); + + File dumpFile = this.dumpFileOption.getFile(); + PrintStream immediateResultStream = null; + if (dumpFile != null) { + try { + if (dumpFile.exists()) { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile, true), true); + } else { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open immediate result file: " + dumpFile, ex); + } + } + //File for output predictions + File outputPredictionFile = this.outputPredictionFileOption.getFile(); + PrintStream outputPredictionResultStream = null; + if (outputPredictionFile != null) { + try { + if (outputPredictionFile.exists()) { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile, true), true); + } else { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open prediction result file: " + outputPredictionFile, ex); + } + } + boolean firstDump = true; + boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); + long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + long lastEvaluateStartTime = evaluateStartTime; + double RAMHours = 0.0; + while (stream.hasMoreInstances() + && ((maxInstances < 0) || (instancesProcessed < maxInstances)) + && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { + Example trainInst = stream.nextInstance(); + Example testInst = (Example) trainInst; //.copy(); + //testInst.setClassMissing(); + //double[] prediction = learner.getPredictionForInstance(testInst); + Prediction prediction = learner.getPredictionForInstance(testInst); + // Output prediction + if (outputPredictionFile != null) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); + } + + //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); + evaluator.addResult(testInst, prediction); + learner.trainOnInstance(trainInst); + instancesProcessed++; + if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 + || stream.hasMoreInstances() == false) { + long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); + double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); + double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs + RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours + RAMHours += RAMHoursIncrement; + lastEvaluateStartTime = evaluateTime; + learningCurve.insertEntry(new LearningEvaluation( + new Measurement[]{ + new Measurement( + "learning evaluation instances", + instancesProcessed), + new Measurement( + "evaluation time (" + + (preciseCPUTiming ? "cpu " + : "") + "seconds)", + time), + new Measurement( + "model cost (RAM-Hours)", + RAMHours) + }, + evaluator, learner)); + + if (immediateResultStream != null) { + if (firstDump) { + immediateResultStream.println(learningCurve.headerToString()); + firstDump = false; + } + immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); + immediateResultStream.flush(); + } + } + if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { + if (monitor.taskShouldAbort()) { + return null; + } + long estimatedRemainingInstances = stream.estimatedRemainingInstances(); + if (maxInstances > 0) { + long maxRemaining = maxInstances - instancesProcessed; + if ((estimatedRemainingInstances < 0) + || (maxRemaining < estimatedRemainingInstances)) { + estimatedRemainingInstances = maxRemaining; + } + } + monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 + : (double) instancesProcessed + / (double) (instancesProcessed + estimatedRemainingInstances)); + if (monitor.resultPreviewRequested()) { + monitor.setLatestResultPreview(learningCurve.copy()); + } + secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() + - evaluateStartTime); + } + } + StringBuilder sb= new StringBuilder(); + learner.getDescription(sb, 0); + System.out.println(sb.toString()); + if (immediateResultStream != null) { + immediateResultStream.close(); + } + if (outputPredictionResultStream != null) { + outputPredictionResultStream.close(); + } + return learningCurve; + } +} +======= + + private static final long serialVersionUID = 1L; + + public ClassOption learnerOption = new ClassOption("learner", 'l', + "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); + + public ClassOption streamOption = new ClassOption("stream", 's', + "Stream to learn from.", MultiTargetInstanceStream.class, + "MultiTargetArffFileStream"); + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + MultiTargetPerformanceEvaluator.class, + "BasicMultiTargetPerformanceEvaluator"); + + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); + + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); + + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); + + public FileOption dumpFileOption = new FileOption("dumpFile", 'd', + "File to append intermediate csv results to.", null, "csv", true); + + public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', + "File to append output predictions to.", null, "pred", true); + + //New for prequential method DEPRECATED + public IntOption widthOption = new IntOption("width", + 'w', "Size of Window", 1000); + + public FloatOption alphaOption = new FloatOption("alpha", + 'a', "Fading factor or exponential smoothing factor", .01); + //End New for prequential methods + + @Override + public Class getTaskResultType() { + return LearningCurve.class; + } + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + Learner learner = (Learner) getPreparedClassOption(this.learnerOption); + ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); + LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); + LearningCurve learningCurve = new LearningCurve( + "learning evaluation instances"); + + //New for prequential methods + if (evaluator instanceof WindowClassificationPerformanceEvaluator) { + //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); + if (widthOption.getValue() != 1000) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { + //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { + //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + //End New for prequential methods + + learner.setModelContext(stream.getHeader()); + int maxInstances = this.instanceLimitOption.getValue(); + long instancesProcessed = 0; + int maxSeconds = this.timeLimitOption.getValue(); + int secondsElapsed = 0; + monitor.setCurrentActivity("Evaluating learner...", -1.0); + + File dumpFile = this.dumpFileOption.getFile(); + PrintStream immediateResultStream = null; + if (dumpFile != null) { + try { + if (dumpFile.exists()) { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile, true), true); + } else { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open immediate result file: " + dumpFile, ex); + } + } + //File for output predictions + File outputPredictionFile = this.outputPredictionFileOption.getFile(); + PrintStream outputPredictionResultStream = null; + if (outputPredictionFile != null) { + try { + if (outputPredictionFile.exists()) { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile, true), true); + } else { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open prediction result file: " + outputPredictionFile, ex); + } + } + boolean firstDump = true; + boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); + long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + long lastEvaluateStartTime = evaluateStartTime; + double RAMHours = 0.0; + while (stream.hasMoreInstances() + && ((maxInstances < 0) || (instancesProcessed < maxInstances)) + && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { + Example trainInst = stream.nextInstance(); + Example testInst = (Example) trainInst; //.copy(); + //testInst.setClassMissing(); + //double[] prediction = learner.getPredictionForInstance(testInst); + Prediction prediction = learner.getPredictionForInstance(testInst); + // Output prediction + if (outputPredictionFile != null) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); +>>>>>>> Instances rework, new iSOUPTree models and import cleanup + } + } + if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { + //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { + //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); + if (alphaOption.getValue() != .01) { + System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); + return learningCurve; + } + } + //End New for prequential methods + + learner.setModelContext(stream.getHeader()); + int maxInstances = this.instanceLimitOption.getValue(); + long instancesProcessed = 0; + int maxSeconds = this.timeLimitOption.getValue(); + int secondsElapsed = 0; + monitor.setCurrentActivity("Evaluating learner...", -1.0); + + File dumpFile = this.dumpFileOption.getFile(); + PrintStream immediateResultStream = null; + if (dumpFile != null) { + try { + if (dumpFile.exists()) { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile, true), true); + } else { + immediateResultStream = new PrintStream( + new FileOutputStream(dumpFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open immediate result file: " + dumpFile, ex); + } + } + //File for output predictions + File outputPredictionFile = this.outputPredictionFileOption.getFile(); + PrintStream outputPredictionResultStream = null; + if (outputPredictionFile != null) { + try { + if (outputPredictionFile.exists()) { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile, true), true); + } else { + outputPredictionResultStream = new PrintStream( + new FileOutputStream(outputPredictionFile), true); + } + } catch (Exception ex) { + throw new RuntimeException( + "Unable to open prediction result file: " + outputPredictionFile, ex); + } + } + boolean firstDump = true; + boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); + long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + long lastEvaluateStartTime = evaluateStartTime; + double RAMHours = 0.0; + while (stream.hasMoreInstances() + && ((maxInstances < 0) || (instancesProcessed < maxInstances)) + && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { + Example trainInst = stream.nextInstance(); + Example testInst = (Example) trainInst; //.copy(); + //testInst.setClassMissing(); + //double[] prediction = learner.getPredictionForInstance(testInst); + Prediction prediction = learner.getPredictionForInstance(testInst); + // Output prediction + if (outputPredictionFile != null) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { + sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); + } + outputPredictionResultStream.println(prediction + "," + sb.toString()); + } + + //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); + evaluator.addResult(testInst, prediction); + learner.trainOnInstance(trainInst); + instancesProcessed++; + if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 + || stream.hasMoreInstances() == false) { + long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); + double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); + double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); + double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs + RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours + RAMHours += RAMHoursIncrement; + lastEvaluateStartTime = evaluateTime; + learningCurve.insertEntry(new LearningEvaluation( + new Measurement[]{ + new Measurement( + "learning evaluation instances", + instancesProcessed), + new Measurement( + "evaluation time (" + + (preciseCPUTiming ? "cpu " + : "") + "seconds)", + time), + new Measurement( + "model cost (RAM-Hours)", + RAMHours) + }, + evaluator, learner)); + + if (immediateResultStream != null) { + if (firstDump) { + immediateResultStream.println(learningCurve.headerToString()); + firstDump = false; + } + immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); + immediateResultStream.flush(); + } + } + if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { + if (monitor.taskShouldAbort()) { + return null; + } + long estimatedRemainingInstances = stream.estimatedRemainingInstances(); + if (maxInstances > 0) { + long maxRemaining = maxInstances - instancesProcessed; + if ((estimatedRemainingInstances < 0) + || (maxRemaining < estimatedRemainingInstances)) { + estimatedRemainingInstances = maxRemaining; + } + } + monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 + : (double) instancesProcessed + / (double) (instancesProcessed + estimatedRemainingInstances)); + if (monitor.resultPreviewRequested()) { + monitor.setLatestResultPreview(learningCurve.copy()); + } + secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() + - evaluateStartTime); + } + } + StringBuilder sb= new StringBuilder(); + learner.getDescription(sb, 0); + System.out.println(sb.toString()); + if (immediateResultStream != null) { + immediateResultStream.close(); + } + if (outputPredictionResultStream != null) { + outputPredictionResultStream.close(); + } + return learningCurve; + } +} +>>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe diff --git a/moa/src/main/java/moa/tasks/LearnModelClassification.java b/moa/src/main/java/moa/tasks/LearnModelClassification.java new file mode 100644 index 000000000..751337858 --- /dev/null +++ b/moa/src/main/java/moa/tasks/LearnModelClassification.java @@ -0,0 +1,19 @@ +package moa.tasks; + +import moa.learners.Classifier; +import moa.options.ClassOption; + +public class LearnModelClassification extends AbstractLearnModel implements ClassificationMainTask { + + @Override + public String getPurposeString() { + return "Learns a Classification model from a stream."; + } + + private static final long serialVersionUID = 1L; + + public LearnModelClassification() { + this.learnerOption = new ClassOption("learner", 'l', "Learner to train.", Classifier.class, "moa.classifiers.trees.HoeffdingTree"); + } + +} diff --git a/moa/src/main/java/moa/tasks/LearnModelMultiLabelClassification.java b/moa/src/main/java/moa/tasks/LearnModelMultiLabelClassification.java new file mode 100644 index 000000000..51f85e8da --- /dev/null +++ b/moa/src/main/java/moa/tasks/LearnModelMultiLabelClassification.java @@ -0,0 +1,20 @@ +package moa.tasks; + +import moa.learners.MultiLabelClassifier; +import moa.options.ClassOption; + +public class LearnModelMultiLabelClassification extends AbstractLearnModel { + + @Override + public String getPurposeString() { + return "Learns a multi-label classification model from a stream."; + } + + private static final long serialVersionUID = 1L; + + public LearnModelMultiLabelClassification() { + this.learnerOption = new ClassOption("learner", 'l', "Learner to train.", MultiLabelClassifier.class, "moa.classifiers.mlc.trees.MultiLabelHoeffdingTree"); + } + + +} diff --git a/moa/src/main/java/moa/tasks/MainTaskInterface.java b/moa/src/main/java/moa/tasks/MainTaskInterface.java new file mode 100644 index 000000000..10eaf61c4 --- /dev/null +++ b/moa/src/main/java/moa/tasks/MainTaskInterface.java @@ -0,0 +1,10 @@ +package moa.tasks; + +public interface MainTaskInterface { + + public Object doTask(); + + public String getCLICreationString(Class c); + + public Object copy(); +} diff --git a/moa/src/main/java/moa/tasks/MultiLabelClassificatioMainTask.java b/moa/src/main/java/moa/tasks/MultiLabelClassificatioMainTask.java new file mode 100644 index 000000000..bdb4f6b40 --- /dev/null +++ b/moa/src/main/java/moa/tasks/MultiLabelClassificatioMainTask.java @@ -0,0 +1,5 @@ +package moa.tasks; + +public interface MultiLabelClassificatioMainTask extends MainTaskInterface { + +} diff --git a/weka-package/.classpath b/weka-package/.classpath index af1430be1..f619a5369 100644 --- a/weka-package/.classpath +++ b/weka-package/.classpath @@ -12,7 +12,7 @@
- + diff --git a/weka-package/.settings/org.eclipse.jdt.core.prefs b/weka-package/.settings/org.eclipse.jdt.core.prefs index 6e80039d3..443e08599 100644 --- a/weka-package/.settings/org.eclipse.jdt.core.prefs +++ b/weka-package/.settings/org.eclipse.jdt.core.prefs @@ -1,8 +1,8 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.8 +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/weka-package/pom.xml.orig b/weka-package/pom.xml.orig new file mode 100644 index 000000000..8068f153f --- /dev/null +++ b/weka-package/pom.xml.orig @@ -0,0 +1,57 @@ + + + + 4.0.0 + + + nz.ac.waikato.cms.moa + moa-pom +<<<<<<< Updated upstream + 2014.04 +======= + 2017.10-SNAPSHOT +>>>>>>> Stashed changes + + + weka-package + jar + + MOA: WEKA Package + + Massive On-line Analysis is an environment for massive data mining. MOA provides a framework for data stream mining and includes tools for evaluation and a collection of machine learning algorithms. Related to the WEKA project, also written in Java, while scaling to more demanding problems. + This artifact enables you to use MOA from within WEKA. + + http://moa.cms.waikato.ac.nz/ + + University of Waikato, Hamilton, NZ + http://www.waikato.ac.nz/ + + + + GNU General Public License 3 + http://www.gnu.org/licenses/gpl-3.0.txt + repo + + + + + + abifet + Albert Bifet + abifet@waikato.ac.nz + + + fracpete + Peter Reutemann + fracpete@waikato.ac.nz + + + + + + nz.ac.waikato.cms.moa + moa + [${project.version},) + + + From 374ba36441bc65c9167c0581b346c451f670594c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 3 Jul 2017 10:11:16 +0200 Subject: [PATCH 31/33] Removed merging artifacts --- moa/pom.xml.orig | 156 --- .../moa/classifiers/meta/OzaBagASHT.java.orig | 200 ---- .../TemporallyAugmentedClassifier.java.orig | 190 ---- .../mlc/MultilabelHoeffdingTree.java.orig | 237 ----- .../moa/classifiers/trees/ORTO2.java.orig | 543 ----------- .../clusterers/clustree/ClusTree.java.orig | 891 ------------------ .../EvaluatePeriodicHeldOutTest.java.orig | 308 ------ .../EvaluatePrequentialMultiTarget.java.orig | 713 -------------- 8 files changed, 3238 deletions(-) delete mode 100644 moa/pom.xml.orig delete mode 100644 moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java.orig delete mode 100644 moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java.orig delete mode 100644 moa/src/main/java/moa/classifiers/mlc/MultilabelHoeffdingTree.java.orig delete mode 100644 moa/src/main/java/moa/classifiers/trees/ORTO2.java.orig delete mode 100644 moa/src/main/java/moa/clusterers/clustree/ClusTree.java.orig delete mode 100644 moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java.orig delete mode 100644 moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java.orig diff --git a/moa/pom.xml.orig b/moa/pom.xml.orig deleted file mode 100644 index 8edfa56e1..000000000 --- a/moa/pom.xml.orig +++ /dev/null @@ -1,156 +0,0 @@ - - 4.0.0 - - - nz.ac.waikato.cms.moa - moa-pom -<<<<<<< Updated upstream - 2014.04 -======= - 2017.10-SNAPSHOT ->>>>>>> Stashed changes - - - moa - jar - - MOA: Massive Online Analysis - - Massive On-line Analysis is an environment for massive data mining. MOA - provides a framework for data stream mining and includes tools for evaluation - and a collection of machine learning algorithms. Related to the WEKA project, - also written in Java, while scaling to more demanding problems. - - http://moa.cms.waikato.ac.nz/ - - University of Waikato, Hamilton, NZ - http://www.waikato.ac.nz/ - - - - GNU General Public License 3.0 - http://www.gnu.org/licenses/gpl-3.0.txt - repo - - - - - - abifet - Albert Bifet - abifet@waikato.ac.nz - - - rkirkby - Richard Kirkby - - - - - - nz.ac.waikato.cms.weka - weka-dev - - - - com.googlecode.sizeofag - sizeofag - - -<<<<<<< Updated upstream -======= - - net.sf.meka - meka - - ->>>>>>> Stashed changes - - junit - junit - test - - - - org.apache.commons - commons-math3 - 3.6.1 - - - - com.googlecode.java-diff-utils - diffutils - 1.2.1 - test - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.7 - 1.7 - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - - org.codehaus.mojo - license-maven-plugin - - - - org.codehaus.mojo - latex-maven-plugin - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - - license-maven-plugin - - [1.1,) - - add-third-party - - - - - - - - - - - - - - diff --git a/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java.orig b/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java.orig deleted file mode 100644 index 6b78f94de..000000000 --- a/moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java.orig +++ /dev/null @@ -1,200 +0,0 @@ -/* - * OzaBagASHT.java - * Copyright (C) 2008 University of Waikato, Hamilton, New Zealand - * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package moa.classifiers.meta; - -<<<<<<< HEAD -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; - -======= -import moa.options.ClassOption; ->>>>>>> 3d07f07a8e1662963b332241c1fcfe85cebe0609 -import moa.classifiers.Classifier; -import moa.classifiers.trees.ASHoeffdingTree; -import moa.core.DoubleVector; -import moa.core.MiscUtils; -<<<<<<< HEAD -======= -import com.github.javacliparser.IntOption; -import com.github.javacliparser.FlagOption; -import com.yahoo.labs.samoa.instances.Instance; -import moa.classifiers.AbstractClassifier; -import moa.core.Measurement; ->>>>>>> 3d07f07a8e1662963b332241c1fcfe85cebe0609 -import moa.core.Utils; - -/** - * Bagging using trees of different size. - * The Adaptive-Size Hoeffding Tree (ASHT) is derived from the Hoeffding Tree - * algorithm with the following differences: - *
    - *
  • it has a maximum number of split nodes, or size - *
  • after one node splits, if the number of split nodes of the ASHT tree - * is higher than the maximum value, then it deletes some nodes to reduce its size - *
- * The intuition behind this method is as follows: smaller trees adapt - * more quickly to changes, and larger trees do better during periods with - * no or little change, simply because they were built on more data. Trees - * limited to size s will be reset about twice as often as trees with a size - * limit of 2s. This creates a set of different reset-speeds for an ensemble of such - * trees, and therefore a subset of trees that are a good approximation for the - * current rate of change. It is important to note that resets will happen all - * the time, even for stationary datasets, but this behaviour should not have - * a negative impact on the ensemble’s predictive performance. - * When the tree size exceeds the maximun size value, there are two different - * delete options:
    - *
  • delete the oldest node, the root, and all of its children except the one - * where the split has been made. After that, the root of the child not - * deleted becomes the new root - *
  • delete all the nodes of the tree, i.e., restart from a new root. - *
- * The maximum allowed size for the n-th ASHT tree is twice the maximum - * allowed size for the (n-1)-th tree. Moreover, each tree has a weight - * proportional to the inverse of the square of its error, and it monitors its - * error with an exponential weighted moving average (EWMA) with alpha = .01. - * The size of the first tree is 2. - *

- * With this new method, it is attempted to improve bagging performance - * by increasing tree diversity. It has been observed that boosting tends to - * produce a more diverse set of classifiers than bagging, and this has been - * cited as a factor in increased performance.
- * See more details in:

- * Albert Bifet, Geoff Holmes, Bernhard Pfahringer, Richard Kirkby, - * and Ricard Gavaldà. New ensemble methods for evolving data - * streams. In 15th ACM SIGKDD International Conference on Knowledge - * Discovery and Data Mining, 2009.

- * The learner must be ASHoeffdingTree, a Hoeffding Tree with a maximum - * size value.

- * Example:

- * OzaBagASHT -l ASHoeffdingTree -s 10 -u -r - * Parameters:
    - *
  • Same parameters as OzaBag - *
  • -f : the size of first classifier in the bag. - *
  • -u : Enable weight classifiers - *
  • -e : Reset trees when size is higher than the max - *
- * - * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) - * @version $Revision: 7 $ - */ -public class OzaBagASHT extends AbstractClassifier { - - private static final long serialVersionUID = 1L; - - @Override - public String getPurposeString() { - return "Bagging using trees of different size."; - } - - public IntOption ensembleSizeOption = new IntOption("ensembleSize", 's', - "The number of models in the bag.", 10, 1, Integer.MAX_VALUE); - - public IntOption firstClassifierSizeOption = new IntOption("firstClassifierSize", 'f', - "The size of first classifier in the bag.", 1, 1, Integer.MAX_VALUE); - - public FlagOption useWeightOption = new FlagOption("useWeight", - 'u', "Enable weight classifiers."); - - public FlagOption resetTreesOption = new FlagOption("resetTrees", - 'e', "Reset trees when size is higher than the max."); - - public ClassOption baseLearnerOption = new ClassOption("baseLearner", 'l', - "ASHoeffdingTree to train.", ASHoeffdingTree.class, - "moa.classifiers.trees.ASHoeffdingTree"); - - protected ASHoeffdingTree[] ensemble; - protected double[] error; - protected double alpha = 0.01; - - @Override - public void resetLearningImpl() { - this.ensemble = new ASHoeffdingTree[this.ensembleSizeOption.getValue()]; - this.error = new double[this.ensembleSizeOption.getValue()]; - Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); - baseLearner.resetLearning(); - int pow = this.firstClassifierSizeOption.getValue(); - for (int i = 0; i < this.ensemble.length; i++) { - this.ensemble[i] = (ASHoeffdingTree) baseLearner.copy(); - this.error[i] = 0.0; - ((ASHoeffdingTree) this.ensemble[i]).setMaxSize(pow); - if ((this.resetTreesOption != null) - && this.resetTreesOption.isSet()) { - ((ASHoeffdingTree) this.ensemble[i]).setResetTree(); - } - pow *= 2; - } - } - - @Override - public void trainOnInstanceImpl(Instance inst) { - int trueClass = (int) inst.classValue(); - for (int i = 0; i < this.ensemble.length; i++) { - int k = MiscUtils.poisson(1.0, this.classifierRandom); - if (k > 0) { - Instance weightedInst = (Instance) inst.copy(); - weightedInst.setWeight(inst.weight() * k); - if (Utils.maxIndex(this.ensemble[i].getPredictionForInstance(inst)) == trueClass) { - this.error[i] += alpha * (0.0 - this.error[i]); //EWMA - } else { - this.error[i] += alpha * (1.0 - this.error[i]); //EWMA - } - this.ensemble[i].trainOnInstance(weightedInst); - } - } - } - - public Prediction getPredictionForInstance(Instance inst) { - DoubleVector combinedVote = new DoubleVector(); - for (int i = 0; i < this.ensemble.length; i++) { - DoubleVector vote = new DoubleVector(this.ensemble[i].getPredictionForInstance(inst)); - if (vote.sumOfValues() > 0.0) { - vote.normalize(); - if ((this.useWeightOption != null) - && this.useWeightOption.isSet()) { - vote.scaleValues(1.0 / (this.error[i] * this.error[i])); - } - combinedVote.addValues(vote); - } - } - return combinedVote.getArrayRef(); - } - - @Override - public void getModelDescription(StringBuilder out, int indent) { - // TODO Auto-generated method stub - } - - @Override - public boolean isRandomizable() { - return true; - } - - @Override - protected Measurement[] getModelMeasurementsImpl() { - return new Measurement[]{new Measurement("ensemble size", - this.ensemble != null ? this.ensemble.length : 0)}; - } - - @Override - public Classifier[] getSubClassifiers() { - return this.ensemble.clone(); - } -} diff --git a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java.orig b/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java.orig deleted file mode 100644 index 15378090c..000000000 --- a/moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java.orig +++ /dev/null @@ -1,190 +0,0 @@ -/* - * TemporallyAugmentedClassifier.java - * Copyright (C) 2013 University of Waikato, Hamilton, New Zealand - * @author Bernhard Pfahringer (bernhard@cs.waikato.ac.nz) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package moa.classifiers.meta; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -<<<<<<< HEAD -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Attribute; -import com.yahoo.labs.samoa.instances.DenseInstance; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; - -======= -import com.yahoo.labs.samoa.instances.*; ->>>>>>> 3d07f07a8e1662963b332241c1fcfe85cebe0609 -import moa.classifiers.AbstractClassifier; -import moa.classifiers.Classifier; -import moa.core.Measurement; -import moa.core.Utils; -import moa.options.ClassOption; - -/** - * Include labels of previous instances into the training data - * - *

This enables a classifier to exploit potentially present auto-correlation - *

- * - *

Parameters:

  • -l : Classifier to train
  • -n : The number - * of old labels to include
- * - * @author Bernhard Pfahringer (bernhard@cs.waikato.ac.nz) - * @version $Revision: 1 $ - */ -public class TemporallyAugmentedClassifier extends AbstractClassifier { - - @Override - public String getPurposeString() { - return "Add some old labels to every instance"; - } - private static final long serialVersionUID = 1L; - - public ClassOption baseLearnerOption = new ClassOption("baseLearner", 'l', - "Classifier to train.", Classifier.class, "trees.HoeffdingTree"); - - public IntOption numOldLabelsOption = new IntOption("numOldLabels", 'n', - "The number of old labels to add to each example.", 1, 0, Integer.MAX_VALUE); - - protected Classifier baseLearner; - - protected double[] oldLabels; - - protected InstancesHeader header; - - public FlagOption labelDelayOption = new FlagOption("labelDelay", 'd', - "Labels arrive with Delay. Use predictions instead of true Labels."); - - @Override - public void resetLearningImpl() { - this.baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); - this.oldLabels = new double[this.numOldLabelsOption.getValue()]; - this.header = null; - baseLearner.resetLearning(); - } - - @Override - public void trainOnInstanceImpl(Instance instance) { - this.baseLearner.trainOnInstance(extendWithOldLabels(instance)); - if (this.labelDelayOption.isSet() == false) { - // Use true old Labels to add attributes to instances - addOldLabel(instance.classValue()); - } - } - - public void addOldLabel(double newPrediction) { - int numLabels = this.oldLabels.length; - if (numLabels > 0) { - for (int i = 1; i < numLabels; i++) { - this.oldLabels[i - 1] = this.oldLabels[i]; - } - this.oldLabels[ numLabels - 1] = newPrediction; - } - } - - public void initHeader(InstancesHeader dataset) { - int numLabels = this.numOldLabelsOption.getValue(); - Attribute target = dataset.classAttribute(); - - List possibleValues = new ArrayList(); - int n = target.numValues(); - for (int i = 0; i < n; i++) { - possibleValues.add(target.value(i)); - } - - ArrayList attrs = new ArrayList(numLabels + dataset.numAttributes()); - for (int i = 0; i < numLabels; i++) { - attrs.add(new Attribute(target.name() + "_" + i, possibleValues)); - } - for (int i = 0; i < dataset.numAttributes(); i++) { - Attribute attr = dataset.attribute(i); - Attribute newAttribute = null; - if (attr.isNominal() == true) { - newAttribute = new Attribute(attr.name(), attr.getAttributeValues()); - } - if (attr.isNumeric() == true) { - newAttribute = new Attribute(attr.name()); - } - if (newAttribute != null) { - attrs.add(newAttribute); - } - } - this.header = new InstancesHeader("extended_" + dataset.getRelationName(), attrs, 0); - this.header.setClassIndex(numLabels + dataset.classIndex()); - } - - public Instance extendWithOldLabels(Instance instance) { - if (this.header == null) { - initHeader(instance.dataset()); - this.baseLearner.setModelContext(new InstancesHeader(this.header)); - } - int numLabels = this.oldLabels.length; - if (numLabels == 0) { - return instance; - } - double[] x = instance.toDoubleArray(); - double[] x2 = Arrays.copyOfRange(this.oldLabels, 0, numLabels + x.length); - System.arraycopy(x, 0, x2, numLabels, x.length); - Instance extendedInstance = new DenseInstance(instance.weight(), x2); - extendedInstance.setDataset(this.header); - //System.out.println( extendedInstance); - return extendedInstance; - } - - @Override - public Prediction getPredictionForInstance(Instance instance) { - double[] prediction = this.baseLearner.getPredictionForInstance(extendWithOldLabels(instance)); - if (this.labelDelayOption.isSet() == true) { - // Use predicted Labels to add attributes to instances - addOldLabel(Utils.maxIndex(prediction)); - } - return prediction; - } - - @Override - public boolean isRandomizable() { - return false; // ??? this.baseLearner.isRandomizable; - } - - @Override - protected Measurement[] getModelMeasurementsImpl() { - List measurementList = new LinkedList(); - Measurement[] modelMeasurements = ((AbstractClassifier) this.baseLearner).getModelMeasurements(); - if (modelMeasurements != null) { - for (Measurement measurement : modelMeasurements) { - measurementList.add(measurement); - } - } - return measurementList.toArray(new Measurement[measurementList.size()]); - } - - @Override - public void getModelDescription(StringBuilder out, int indent) { - // TODO Auto-generated method stub - } - - public String toString() { - return "TemporallyAugmentedClassifier using " + this.numOldLabelsOption.getValue() + " labels\n" + this.baseLearner; - } -} diff --git a/moa/src/main/java/moa/classifiers/mlc/MultilabelHoeffdingTree.java.orig b/moa/src/main/java/moa/classifiers/mlc/MultilabelHoeffdingTree.java.orig deleted file mode 100644 index e0a4c43a7..000000000 --- a/moa/src/main/java/moa/classifiers/mlc/MultilabelHoeffdingTree.java.orig +++ /dev/null @@ -1,237 +0,0 @@ -/* - * MultilabelHoeffdingTree.java - * Copyright (C) 2012 University of Waikato, Hamilton, New Zealand - * @author Jesse Read (jesse@tsc.uc3m.es) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package moa.classifiers.multilabel; - -import java.util.LinkedList; -import java.util.List; - -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; -<<<<<<< HEAD -======= -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.MultiLabelPrediction; ->>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe -import com.yahoo.labs.samoa.instances.Prediction; -import com.yahoo.labs.samoa.instances.StructuredInstance; - -import moa.classifiers.Classifier; -import moa.classifiers.MultiLabelClassifier; -import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.trees.HoeffdingTree; -import moa.core.Example; -import moa.core.StringUtils; - -/** - * Hoeffding Tree for classifying multi-label data. - * - * A Hoeffding tree is an incremental, anytime decision tree induction algorithm - * that is capable of learning from massive data streams, assuming that the - * distribution generating examples does not change over time. - * - * - */ -public class MultilabelHoeffdingTree extends HoeffdingTreeClassifLeaves implements MultiLabelClassifier, MultiTargetRegressor, Classifier { -// Needs to use InfoGainSplitCriterionMultiLabel, since multilabel entropy is calculated in a different way -// Trains a mlinstance adding statistics of several class values and training node classifiers -// Get votes from the classifier in the learning node of the tree - - private static final long serialVersionUID = 1L; - - - /*public MultilabelHoeffdingTree() { - this.removePoorAttsOption = null; - }*/ - - @Override - protected LearningNode newLearningNode(double[] initialClassObservations) { - // Create new Learning Node with a null classifier - return new MultilabelLearningNodeClassifier(initialClassObservations,null,this); - } - - //@Override - protected LearningNode newLearningNode(double[] initialClassObservations, Classifier cl) { - // Create new Learning Node - return new MultilabelLearningNodeClassifier(initialClassObservations,cl,this); - } - - public static class MultilabelInactiveLearningNode extends InactiveLearningNode { - - private static final long serialVersionUID = 1L; - - public MultilabelInactiveLearningNode(double[] initialClassObservations) { - super(initialClassObservations); - } - - @Override - public void learnFromInstance(Instance inst, HoeffdingTree ht) { - List labels = ((MultilabelHoeffdingTree) ht).getRelevantLabels(inst); - for (int l : labels){ - this.observedClassDistribution.addToValue(l, inst.weight()); - } - } - } - - public class MultilabelLearningNodeClassifier extends LearningNodeClassifier { - // It uses classifier at nodes, and to be able to train with several class values - - private static final long serialVersionUID = 1L; - - public MultilabelLearningNodeClassifier(double[] initialClassObservations, Classifier cl, MultilabelHoeffdingTree ht ) { - super(initialClassObservations); - - if (cl== null) { - this.classifier = ((Classifier) getPreparedClassOption(ht.learnerOption)).copy(); - this.classifier.resetLearning(); - - InstancesHeader raw_header = ht.getModelContext(); - this.classifier.setModelContext(raw_header); - } - else{ - this.classifier = cl.copy(); - } - } - - @Override - public double[] getClassVotes(Instance inst, HoeffdingTree ht) { - - return this.classifier.getPredictionForInstance(inst); - } - - public Prediction getPredictionForInstance(Instance inst, HoeffdingTree ht) { - - return this.classifier.getPredictionForInstance(inst); - } - - @Override - public void disableAttribute(int attIndex) { - // should not disable poor atts - they are used in NB calc - } - - public Classifier getClassifier() { - return this.classifier; - } - - @Override - public void learnFromInstance(Instance inst, HoeffdingTree ht) { - - //It uses different class values, not only one - this.classifier.trainOnInstance(inst); - MultilabelHoeffdingTree mht = ((MultilabelHoeffdingTree) ht); - List labels = mht.getRelevantLabels(inst); - for (int l : labels){ - this.observedClassDistribution.addToValue( l, inst.weight()); - } - - for (int i = 0; i < inst.numInputAttributes(); i++) { - int instAttIndex = i; - AttributeClassObserver obs = this.attributeObservers.get(instAttIndex); //i - if (obs == null) { - obs = inst.inputAttribute(i).isNominal() ? mht.newNominalClassObserver() : mht.newNumericClassObserver(); - this.attributeObservers.set(i, obs); - } - for (int l : labels){ - obs.observeAttributeClass(inst.valueInputAttribute(i), l, inst.weight()); - } - } - } - - public void describeSubtree(HoeffdingTree ht, StringBuilder out, - int indent) { - StringUtils.appendIndented(out, indent, "Leaf "); - out.append(" = "); - out.append(" weights: "); - this.observedClassDistribution.getSingleLineDescription(out, - this.observedClassDistribution.numValues()); - StringUtils.appendNewline(out); - } - } - - @Override - protected void deactivateLearningNode(ActiveLearningNode toDeactivate, - SplitNode parent, int parentBranch) { - //It uses MultilabelInactiveLearningNode since there are several class values - Node newLeaf = new MultilabelInactiveLearningNode(toDeactivate - .getObservedClassDistribution()); - if (parent == null) { - this.treeRoot = newLeaf; - } else { - parent.setChild(parentBranch, newLeaf); - } - this.activeLeafNodeCount--; - this.inactiveLeafNodeCount++; - } - - - @Override - public Prediction getPredictionForInstance(Example example) { - return getPredictionForInstance((StructuredInstance)example.getData()); - } - - public Prediction getPredictionForInstance(StructuredInstance inst) { - return getPredictionForInstance((Instance) inst); - } - - @Override - public Prediction getPredictionForInstance(Instance inst){ - - if (this.treeRoot != null) { - FoundNode foundNode = this.treeRoot.filterInstanceToLeaf(inst, null, -1); - Node leafNode = (MultilabelLearningNodeClassifier) foundNode.node; - MultilabelLearningNodeClassifier multilabelLeafNode = (MultilabelLearningNodeClassifier) leafNode; - if (leafNode == null) { - leafNode = foundNode.parent; - } - return multilabelLeafNode.getPredictionForInstance(inst, this); - } - else { - System.err.println("[WARNING] Root Node == Null !!!!!!"); - } - - // Return empty array (this should only happen once! -- before we build the root node). - return null; - } - - @Override - public void trainOnInstance(Instance inst) { - boolean isTraining = (inst.weight() > 0.0); - if (isTraining) { - this.trainingWeightSeenByModel += inst.weight(); - trainOnInstanceImpl((StructuredInstance) inst); - } - } - - @Override - public void trainOnInstanceImpl(StructuredInstance instance) { - trainOnInstanceImpl((Instance) instance); - } - - public static List getRelevantLabels(Instance x) { - List classValues = new LinkedList(); - //get all class attributes - for (int j = 0; j < x.numberOutputTargets(); j++) { - if (x.classValue(j) > 0.0) { - classValues.add(j); - } - } - return classValues; - } -} diff --git a/moa/src/main/java/moa/classifiers/trees/ORTO2.java.orig b/moa/src/main/java/moa/classifiers/trees/ORTO2.java.orig deleted file mode 100644 index 99b0cc910..000000000 --- a/moa/src/main/java/moa/classifiers/trees/ORTO2.java.orig +++ /dev/null @@ -1,543 +0,0 @@ -/* - * ORTO.java - * Copyright (C) 2015 Jožef Stefan Institute, Ljubljana, Slovenia - * @author Aljaž Osojnik - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ - -package moa.classifiers.trees; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.Stack; - -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.github.javacliparser.MultiChoiceOption; -import com.yahoo.labs.samoa.instances.Instance; - -import moa.classifiers.Regressor; -import moa.classifiers.core.AttributeSplitSuggestion; -import moa.classifiers.core.attributeclassobservers.AttributeClassObserver; -import moa.classifiers.core.attributeclassobservers.FIMTDDNumericAttributeClassObserver; -import moa.classifiers.core.splitcriteria.SplitCriterion; -import moa.core.AutoExpandVector; -import moa.core.Measurement; -import moa.core.StringUtils; -<<<<<<< HEAD:moa/src/main/java/moa/classifiers/trees/ORTO2.java - -======= ->>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe:moa/src/main/java/moa/classifiers/trees/ORTO2.java - -/* - * Implementation of ORTO, option trees for data streams. - */ - -public class ORTO2 extends FIMTDD2 implements Regressor { - - private static final long serialVersionUID = 1L; - - private int innerNodeCount = 0; - private int optionNodeCount = 0; - - private int numTrees = 1; - - - //region ================ OPTIONS ================ - - public IntOption maxTreesOption = new IntOption( - "maxTrees", - 'm', - "The maximum number of trees contained in the option tree.", - 10, 1, Integer.MAX_VALUE); - - public IntOption maxOptionLevelOption = new IntOption( - "maxOptionLevel", - 'x', - "The maximal depth at which option nodes can be created.", - 10, 0, Integer.MAX_VALUE); - - public FloatOption optionDecayFactorOption = new FloatOption( - "optionDecayFactor", - 'z', - "The option decay factor that determines how many options can be selected at a given level.", - 0.9, 0.0, 1.0); - - public MultiChoiceOption optionNodeAggregationOption = new MultiChoiceOption( - "optionNodeAggregation", - 'o', - "The aggregation method used to combine predictions in option nodes.", - new String[]{"average", "bestTree"}, new String[]{"Average", "Best tree"}, 0); - - public FloatOption optionFadingFactorOption = new FloatOption( - "optionFadingFactor", - 'q', - "The fading factor used for comparing subtrees of an option node.", - 0.9995, 0.0, 1.0); - - //endregion ================ OPTIONS ================ - - //region ================ CLASSES ================ - - public static class OptionNode extends InnerNode { - - private static final long serialVersionUID = 1L; - - protected double[] optionFFSSL; - protected double[] optionFFSeen; - - public OptionNode(FIMTDD2 tree) { - super(tree); - } - - public void resetFF() { - optionFFSSL = new double[children.size()]; - optionFFSeen = new double[children.size()]; - - for (int i = 0; i < children.size(); i++) { - optionFFSSL[i] = 0.0; - optionFFSeen[i] = 0.0; - } - } - - public int getNumSubtrees() { - int num = 0; - for (Node child : children) { - num += child.getNumSubtrees(); - } - return num; - } - - public int directionForBestTree() { - int d = 0; - double tmp = 0.0, min = Double.MAX_VALUE; - for (int i = 0; i < children.size(); i++) { - tmp = getFFRatio(i); - if (tmp < min) { - min = tmp; - d = i; - } - } - return d; - } - - public double getPrediction(Instance inst) { - double[] predictions = new double[numChildren()]; - for (int i = 0; i < numChildren(); i++) { - predictions[i] = getChild(i).getPrediction(inst); - } - return aggregate(predictions); - } - - private double aggregate(double[] predictions) { - if (((ORTO2) tree).optionNodeAggregationOption.getChosenIndex() == 0) { // Average - double sum = 0.0; - for (int i = 0; i < predictions.length; i++) { - sum += predictions[i]; - } - return sum / predictions.length; - } else if (((ORTO2) tree).optionNodeAggregationOption.getChosenIndex() == 1) { - int d = directionForBestTree(); - return predictions[d]; - } else { - return 0.0; - } - } - - public double getFFRatio(int childIndex) { - return optionFFSSL[childIndex] / optionFFSeen[childIndex]; - } - - protected boolean skipInLevelCount() { - return true; - } - - @Override - public void describeSubtree(StringBuilder out, int indent) { - StringUtils.appendIndented(out, indent, "[option node]"); - StringUtils.appendNewline(out); - for (int childIndex = 0; childIndex < children.size(); childIndex++) { - Node split = getChild(childIndex); - StringUtils.appendIndented(out, indent, "[" + childIndex + "]"); - StringUtils.appendNewline(out); - split.describeSubtree(out, indent + 2); - } - } -<<<<<<< HEAD:moa/src/main/java/moa/classifiers/trees/ORTO2.java - -======= ->>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe:moa/src/main/java/moa/classifiers/trees/ORTO2.java - } - - //endregion ================ CLASSES ================ - - //region ================ METHODS ================ - - // region --- Regressor methods - - public String getPurposeString() { - return "Implementation of the ORTO tree as described by Ikonomovska et al."; - } - - public void resetLearningImpl() { - super.resetLearningImpl(); - this.innerNodeCount = 0; - this.optionNodeCount = 0; - } - - - protected Measurement[] getModelMeasurementsImpl() { - return new Measurement[]{ - new Measurement("number of subtrees", this.numTrees), - new Measurement("tree size (nodes)", this.leafNodeCount + this.innerNodeCount), - new Measurement("tree size (leaves)", this.leafNodeCount), - new Measurement("number of option nodes", this.optionNodeCount),}; - } - - public void processInstance(Instance inst, Node node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { - if (node instanceof OptionNode) { - processInstanceOptionNode(inst, (OptionNode) node, prediction, normalError, growthAllowed, inAlternate); - } else { - Node currentNode = node; - while (true) { - if (currentNode instanceof LeafNode) { - ((LeafNode) currentNode).learnFromInstance(inst, growthAllowed, prediction); - break; - } else { - currentNode.examplesSeen += inst.weight(); - currentNode.sumOfAbsErrors += inst.weight() * normalError; - InnerNode iNode = (InnerNode) currentNode; - if (!inAlternate && iNode.alternateTree != null) { - boolean altTree = true; - double lossO = Math.pow(inst.classValue() - prediction, 2); - double lossA = Math.pow(inst.classValue() - iNode.alternateTree.getPrediction(inst), 2); - - // Loop for compatibility with bagging methods - for (int i = 0; i < inst.weight(); i++) { - iNode.lossFadedSumOriginal = lossO + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumOriginal; - iNode.lossFadedSumAlternate = lossA + alternateTreeFadingFactorOption.getValue() * iNode.lossFadedSumAlternate; - iNode.lossExamplesSeen++; - - double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - iNode.lossSumQi += Qi; - iNode.lossNumQiTests += 1; - } - double Qi = Math.log((iNode.lossFadedSumOriginal) / (iNode.lossFadedSumAlternate)); - double previousQiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - double QiAverage = iNode.lossSumQi / iNode.lossNumQiTests; - - if (iNode.lossExamplesSeen - iNode.previousWeight >= alternateTreeTMinOption.getValue()) { - iNode.previousWeight = iNode.lossExamplesSeen; - if (Qi > 0) { - // Switch the subtrees - Node parent = iNode.getParent(); - - if (parent != null) { - Node replacementTree = iNode.alternateTree; - parent.setChild(parent.getChildIndex(iNode), replacementTree); - if (growthAllowed) replacementTree.restartChangeDetection(); - } else { - treeRoot = iNode.alternateTree; - treeRoot.restartChangeDetection(); - } - optionNodeCount += iNode.alternateTree.getNumSubtrees() - iNode.getNumSubtrees(); - removeExcessTrees(); - - currentNode = iNode.alternateTree; - currentNode.originalNode = null; - altTree = false; - } else if (QiAverage < previousQiAverage && iNode.lossExamplesSeen >= (10 * alternateTreeTMinOption.getValue()) || iNode.lossExamplesSeen >= alternateTreeTimeOption.getValue()) { - // Remove the alternate tree - iNode.alternateTree = null; - if (growthAllowed) iNode.restartChangeDetection(); - altTree = false; - } - } - if (altTree) { - growthAllowed = false; // this is the growth of the original tree - processInstance(inst, iNode.alternateTree, prediction, normalError, true, true); // growth is allowed in the alt tree - } else if (currentNode instanceof OptionNode) { - // this happens when an option node is switched into the tree - for (Node child : ((OptionNode) currentNode).children) { - processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed, inAlternate); - } - break; - } - } - - if (iNode.changeDetection && !inAlternate) { - if (iNode.PageHinckleyTest(normalError - iNode.sumOfAbsErrors / iNode.examplesSeen - PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { - iNode.initializeAlternateTree(); - } - } - if (currentNode instanceof SplitNode) { - currentNode = ((SplitNode) currentNode).descendOneStep(inst); - } else if (currentNode instanceof OptionNode) { - processInstanceOptionNode(inst, (OptionNode) currentNode, prediction, normalError, growthAllowed, inAlternate); - break; - } - } - } - } - - } - - public void processInstanceOptionNode(Instance inst, OptionNode node, double prediction, double normalError, boolean growthAllowed, boolean inAlternate) { - node.examplesSeen += inst.weight(); - node.sumOfAbsErrors += inst.weight() * normalError; -<<<<<<< HEAD:moa/src/main/java/moa/classifiers/trees/ORTO2.java - -======= ->>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe:moa/src/main/java/moa/classifiers/trees/ORTO2.java - if (node.changeDetection) { - double error = Math.abs(prediction - inst.classValue()); - node.sumOfAbsErrors += error; - - if (((InnerNode) node).PageHinckleyTest(error - node.sumOfAbsErrors / node.examplesSeen + PageHinckleyAlphaOption.getValue(), PageHinckleyThresholdOption.getValue())) { - node.initializeAlternateTree(); - growthAllowed = false; - } - } - - for (Node child : node.children) { - int index = node.getChildIndex(child); - double childPrediction = child.getPrediction(inst); - - // Loop for compatibility with bagging methods - for (int i = 0; i < inst.weight(); i++) { - node.optionFFSeen[index] = node.optionFFSeen[index] * optionFadingFactorOption.getValue() + 1; - node.optionFFSSL[index] = node.optionFFSSL[index] * optionFadingFactorOption.getValue() + Math.pow(childPrediction - inst.classValue(), 2); - } - } - - for (Node child : node.children) { - processInstance(inst, child, child.getPrediction(inst), normalError, growthAllowed && node.alternateTree == null, inAlternate); - } - } - - // endregion --- Regressor methods - - // region --- Object instantiation methods - - protected OptionNode newOptionNode() { - maxID++; - return new OptionNode(this); - } - - // endregion --- Object instantiation methods - - // region --- Processing methods - - protected void attemptToSplit(LeafNode node, Node parent, int parentIndex, Instance inst, double prediction) { - // Initialize the split criterion - SplitCriterion splitCriterion = (SplitCriterion) getPreparedClassOption(splitCriterionOption); - - // Using this criterion, find the best split per attribute and rank the results - AttributeSplitSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); - List acceptedSplits = new LinkedList(); - Arrays.sort(bestSplitSuggestions); - - // Declare a variable to determine the number of splits to be performed - int numSplits = 0; - - // If only one split was returned, use it (this generally shouldn't happen) - if (bestSplitSuggestions.length == 1) { - numSplits = 1; - acceptedSplits.add(bestSplitSuggestions[0]); - } else if (bestSplitSuggestions.length > 1) { // Otherwise, consider which of the splits proposed may be worth trying - - // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision - // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); - - // Determine the top two ranked splitting suggestions - AttributeSplitSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; - AttributeSplitSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; - - - // If the upper bound of the sample mean for the ratio of SDR(best suggestion) to SDR(second best suggestion), - // as determined using the Hoeffding bound, is less than 1, then the true mean is also less than 1, and thus at this - // particular moment of observation the bestSuggestion is indeed the best split option with confidence 1-delta, and - // splitting should occur. - // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit - // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two - // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - if (secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) { - numSplits = 1; - acceptedSplits.add(bestSuggestion); - } else if (numTrees < maxTreesOption.getValue() && node.getLevel() <= maxOptionLevelOption.getValue()) { - for (int i = 0; i < bestSplitSuggestions.length; i++) { - AttributeSplitSuggestion suggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1 - i]; - if (suggestion.merit / bestSuggestion.merit >= 1 - hoeffdingBound) { - numSplits++; - acceptedSplits.add(suggestion); - } else { - break; - } - } - } else if (hoeffdingBound < tieThresholdOption.getValue()) { - numSplits = 1; - acceptedSplits.add(bestSuggestion); - } else { // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - for (int i = 0; i < node.attributeObservers.size(); i++) { - AttributeClassObserver obs = node.attributeObservers.get(i); - if (obs != null) { - ((FIMTDDNumericAttributeClassObserver) obs).removeBadSplits(splitCriterion, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound); - } - } - } - } - - // If the splitting criterion was met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - if (numSplits > 0) { - double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); - - if (numSplits == 1 || optionFactor < 2.0 || maxTreesOption.getValue() - numTrees <= 1) { - AttributeSplitSuggestion splitDecision = acceptedSplits.get(0); - SplitNode newSplit = newSplitNode(splitDecision.splitTest); - for (int i = 0; i < splitDecision.numSplits(); i++) { - LeafNode newChild = newLeafNode(); - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - } - leafNodeCount--; - innerNodeCount++; - leafNodeCount += splitDecision.numSplits(); - if (parent == null && node.originalNode == null) { - treeRoot = newSplit; - } else if (parent == null && node.originalNode != null) { - node.originalNode.alternateTree = newSplit; - } else { - parent.setChild(parentIndex, newSplit); - newSplit.setParent(parent); - } - } else { - OptionNode optionNode = newOptionNode(); - leafNodeCount--; - int j = 0; - - for (AttributeSplitSuggestion splitDecision : acceptedSplits) { - if (j > optionFactor || maxTreesOption.getValue() - numTrees <= 0) { - break; - } - SplitNode newSplit = newSplitNode(splitDecision.splitTest); - for (int i = 0; i < splitDecision.numSplits(); i++) { - LeafNode newChild = newLeafNode(); - newChild.setParent(newSplit); - newSplit.setChild(i, newChild); - } - - leafNodeCount += splitDecision.numSplits(); - innerNodeCount++; - numTrees++; - - newSplit.setParent(optionNode); - optionNode.setChild(j, newSplit); - j++; - } - - innerNodeCount++; - optionNodeCount++; - - if (parent == null) { - treeRoot = optionNode; - } else { - parent.setChild(parentIndex, optionNode); - optionNode.setParent(parent); - } - - optionNode.resetFF(); - } - } - } - - // endregion --- Processing methods - - // region --- Option tree methods - protected Node findWorstOption() { - Stack stack = new Stack(); - stack.add(treeRoot); - - double ratio = Double.MIN_VALUE; - Node out = null; - - while (!stack.empty()) { - Node node = stack.pop(); - if (node.getParent() instanceof OptionNode) { - OptionNode myParent = (OptionNode) node.getParent(); - int nodeIndex = myParent.getChildIndex(node); - double nodeRatio = myParent.getFFRatio(nodeIndex); - - if (nodeRatio > ratio) { - ratio = nodeRatio; - out = node; - } - } - if (node instanceof InnerNode) { - for (Node child : ((InnerNode) node).children) { - stack.add(child); - } - } - } - - return out; - } - - protected void removeExcessTrees() { - while (numTrees > maxTreesOption.getValue()) { - Node option = findWorstOption(); - OptionNode parent = (OptionNode) option.parent; - int index = parent.getChildIndex(option); - - if (parent.children.size() == 2) { - parent.children.remove(index); - for (Node chld : parent.children) { - chld.parent = parent.parent; - parent.parent.setChild(parent.parent.getChildIndex(parent), chld); - } - } else { - AutoExpandVector children = new AutoExpandVector(); - double[] optionFFSSL = new double[parent.children.size() - 1]; - double[] optionFFSeen = new double[parent.children.size() - 1]; - - int seen = 0; - - for (int i = 0; i < parent.children.size() - 1; i++) { - if (parent.getChild(i) != option) { - children.add(parent.getChild(i)); - optionFFSSL[i] = parent.optionFFSSL[i + seen]; - optionFFSeen[i] = parent.optionFFSeen[i + seen]; - } else { - seen = 1; - } - } - - parent.children = children; - parent.optionFFSSL = optionFFSSL; - parent.optionFFSeen = optionFFSeen; - - assert parent.children.size() == parent.optionFFSSL.length; - } - numTrees--; - } - } - - // endregion --- Option tree methods - - //endregion ================ METHODS ================ -} diff --git a/moa/src/main/java/moa/clusterers/clustree/ClusTree.java.orig b/moa/src/main/java/moa/clusterers/clustree/ClusTree.java.orig deleted file mode 100644 index ed142e454..000000000 --- a/moa/src/main/java/moa/clusterers/clustree/ClusTree.java.orig +++ /dev/null @@ -1,891 +0,0 @@ -/* - * ClusTree.java - * Copyright (C) 2010 RWTH Aachen University, Germany - * @author Sanchez Villaamil (moa@cs.rwth-aachen.de) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - */ - -package moa.clusterers.clustree; - -import java.util.ArrayList; - -import java.util.LinkedList; -import moa.clusterers.clustree.util.*; -import moa.cluster.Clustering; -import moa.clusterers.AbstractClusterer; -import moa.core.Measurement; -<<<<<<< Updated upstream -<<<<<<< HEAD -======= -<<<<<<< c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 -import com.github.javacliparser.IntOption; -import com.github.javacliparser.FlagOption; -import com.yahoo.labs.samoa.instances.Instance; -======= ->>>>>>> Instances rework, new iSOUPTree models and import cleanup ->>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe -======= -import com.github.javacliparser.IntOption; -import com.github.javacliparser.FlagOption; -import com.yahoo.labs.samoa.instances.Instance; ->>>>>>> Stashed changes - -/** - * Citation: ClusTree: Philipp Kranen, Ira Assent, Corinna Baldauf, Thomas Seidl: - * The ClusTree: indexing micro-clusters for anytime stream mining. - * Knowl. Inf. Syst. 29(2): 249-272 (2011) -*/ -public class ClusTree extends AbstractClusterer{ - private static final long serialVersionUID = 1L; - - public IntOption horizonOption = new IntOption("horizon", - 'h', "Range of the window.", 1000); - - public IntOption maxHeightOption = new IntOption( - "maxHeight", 'H', - "The maximal height of the tree", getDefaultHeight()); - - public FlagOption breadthFirstStrategyOption = new FlagOption( - "breadthFirstStrategy", 'B', - "Use breadth first strategy"); - - public FlagOption breadthFirstStrategyOption = new FlagOption( - "breadthFirstStrategy", 'B', - "Use breadth first strategy"); - - protected int getDefaultHeight() { - return 8; - } - - private static int INSERTIONS_BETWEEN_CLEANUPS = 10000; - /** - * The root node of the tree. - */ - protected Node root; - // Information about the data represented in this tree. - /** - * Dimensionality of the data points managed by this tree. - */ - private int numberDimensions; - /** - * Parameter for the weighting function use to weight the entries. - */ - protected double negLambda; - /** - * The current height of the tree. Should always be smaller than maxHeight. - */ - private int height; - /** - * The maximal height of the tree. - */ - protected int maxHeight; - /** - * This variable is used to keep the inverse height that is stored in every - * node correct. - */ - private int numRootSplits; - /** - * The threshold for the weighting of an Entry. An Entry is irrelevant, if - * it is in a leaf and the weightedN of the data Cluster is smaller than - * this threshold. - * @see Entry#data - */ - private double weightThreshold = 0.05; - /** - * Number of points inserted into the tree. - */ - private int numberInsertions; - private long timestamp; - - /** - * Parameter to determine wich strategy to use - */ - protected boolean breadthFirstStrat = false; - - //TODO: cleanup - private Entry alsoUpdate; - - @Override - public void resetLearningImpl() { - breadthFirstStrat = breadthFirstStrategyOption.isSet(); - negLambda = (1.0 / (double) horizonOption.getValue()) - * (Math.log(weightThreshold) / Math.log(2)); - maxHeight = maxHeightOption.getValue(); - numberDimensions = -1; - root = null; - timestamp = 0; - height = 0; - numRootSplits = 0; - numberInsertions = 0; - } - - - @Override - protected Measurement[] getModelMeasurementsImpl() { - return null; - } - - public boolean isRandomizable() { - return false; - } - - @Override - public void getModelDescription(StringBuilder out, int indent) { - } - - public Prediction getPredictionForInstance(Instance inst) { - return null; - } - - @Override - public boolean implementsMicroClusterer() { - return true; - } - - - - @Override - public void trainOnInstanceImpl(Instance instance) { - timestamp++; - - //TODO check if instance contains label - if(root == null){ - numberDimensions = instance.numAttributes(); - root = new Node(numberDimensions, 0); - } - else{ - if(numberDimensions!=instance.numAttributes()) - System.out.println("Wrong dimensionality, expected:"+numberDimensions+ "found:"+instance.numAttributes()); - } - - ClusKernel newPointAsKernel = new ClusKernel(instance.toDoubleArray(), numberDimensions); - insert(newPointAsKernel, new SimpleBudget(1000),timestamp); - } - - - /** - * Insert a new point in the Tree. The point should be - * represented as a cluster with a single data point(i.e. N = 1). A - * Budget class is also given, which is informed of the number - * of operation the tree does, and informs the tree when it does not have - * time left and should stop the insertion. - * @param newPoint The point to be inserted. - * @param budget The budget and statistics recollector for the insertion. - * @param timestamp The moment at which this point is inserted. - * @see Kernel - * @see Budget - */ - public void insert(ClusKernel newPoint, Budget budget, long timestamp) { - if (breadthFirstStrat){ - insertBreadthFirst(newPoint, budget, timestamp); - } - else{ - Entry rootEntry = new Entry(this.numberDimensions, - root, timestamp, null, null); - ClusKernel carriedBuffer = new ClusKernel(this.numberDimensions); - Entry toInsertHere = insert(newPoint, carriedBuffer, root, rootEntry, - budget, timestamp); - - if (toInsertHere != null) { - this.numRootSplits++; - this.height += this.height < this.maxHeight ? 1 : 0; - - Node newRoot = new Node(this.numberDimensions, - toInsertHere.getChild().getRawLevel() + 1); - newRoot.addEntry(rootEntry, timestamp); - newRoot.addEntry(toInsertHere, timestamp); - rootEntry.setNode(newRoot); - toInsertHere.setNode(newRoot); - this.root = newRoot; - } - } - - this.numberInsertions++; - if (this.numberInsertions % INSERTIONS_BETWEEN_CLEANUPS == 0) { - cleanUp(this.root, 0); - } - } - - /** - * insert newPoint into the tree using the BreadthFirst strategy, i.e.: insert into - * the closest entry in a leaf node. - * @param newPoint - * @param budget - * @param timestamp - * @return - */ - private Entry insertBreadthFirst(ClusKernel newPoint, Budget budget, long timestamp) { - //check all leaf nodes and get the one with the closest entry to newPoint - Node bestFit = findBestLeafNode(newPoint); - bestFit.makeOlder(timestamp, negLambda); - Entry parent = bestFit.getEntries()[0].getParentEntry(); - // Search for an Entry with a weight under the threshold. - Entry irrelevantEntry = bestFit.getIrrelevantEntry(this.weightThreshold); - int numFreeEntries = bestFit.numFreeEntries(); - Entry newEntry = new Entry(newPoint.getCenter().length, - newPoint, timestamp, parent, bestFit); - //if there is space, add it to the node ( doesn't ever occur, since nodes are created with 3 entries) - if (numFreeEntries>0){ - bestFit.addEntry(newEntry, timestamp); - } - //if outdated cluster in this best fitting node, replace it - else if (irrelevantEntry != null) { - irrelevantEntry.overwriteOldEntry(newEntry); - } - //if there is space/outdated cluster on path to top, split. Else merge without split - else { - if (existsOutdatedEntryOnPath(bestFit)||!this.hasMaximalSize()){ - // We have to split. - insertHereWithSplit(newEntry, bestFit, timestamp); - } - else { - mergeEntryWithoutSplit(bestFit, newEntry, - timestamp); - } - } - //update all nodes on path to top. - if (bestFit.getEntries()[0].getParentEntry()!=null) - updateToTop(bestFit.getEntries()[0].getParentEntry().getNode()); - return null; - } - /** - * This method checks if there is an outdated (or empty) entry on the path from node to root. - * It updates the weights of nodes on path and then checks if it is outdated. - * @param node - * @return true if an outdated/empty entry exists on the path - */ - private boolean existsOutdatedEntryOnPath(Node node) { - if (node == root){ - node.makeOlder(timestamp, negLambda); - return node.getIrrelevantEntry(this.weightThreshold)!=null; - } - do{ - node = node.getEntries()[0].getParentEntry().getNode(); - node.makeOlder(timestamp, negLambda); - for (Entry e : node.getEntries()){ - e.recalculateData(); - } - if (node.numFreeEntries()>0) - return true; - if (node.getIrrelevantEntry(this.weightThreshold)!=null) - return true; - }while(node.getEntries()[0].getParentEntry()!=null); - return false; - } - - /** - * recalculates data for all entries, that lie on the path from the root to the - * Entry toUpdate. - */ - private void updateToTop(Node toUpdate) { - while(toUpdate!=null){ - for (Entry e: toUpdate.getEntries()) - e.recalculateData(); - if (toUpdate.getEntries()[0].getParentEntry()==null) - break; - toUpdate=toUpdate.getEntries()[0].getParentEntry().getNode(); - } - } - - /** - * Method called by insertBreadthFirst. - * @param toInsert - * @param insertNode - * @param timestamp - * @return - */ - private Entry insertHereWithSplit(Entry toInsert, Node insertNode, - long timestamp) { - //Handle root split - if (insertNode.getEntries()[0].getParentEntry()==null){ - root.makeOlder(timestamp, negLambda); - Entry irrelevantEntry = insertNode.getIrrelevantEntry(this.weightThreshold); - int numFreeEntries = insertNode.numFreeEntries(); - if (irrelevantEntry != null) { - irrelevantEntry.overwriteOldEntry(toInsert); - } - else if (numFreeEntries>0){ - insertNode.addEntry(toInsert, timestamp); - } - else{ - this.numRootSplits++; - this.height += this.height < this.maxHeight ? 1 : 0; - Entry oldRootEntry = new Entry(this.numberDimensions, - root, timestamp, null, null); - Node newRoot = new Node(this.numberDimensions, - this.height); - Entry newRootEntry = split(toInsert, root, oldRootEntry, timestamp); - newRoot.addEntry(oldRootEntry, timestamp); - newRoot.addEntry(newRootEntry, timestamp); - this.root = newRoot; - for (Entry c : oldRootEntry.getChild().getEntries()) - c.setParentEntry(root.getEntries()[0]); - for (Entry c : newRootEntry.getChild().getEntries()) - c.setParentEntry(root.getEntries()[1]); - } - return null; - } - insertNode.makeOlder(timestamp, negLambda); - Entry irrelevantEntry = insertNode.getIrrelevantEntry(this.weightThreshold); - int numFreeEntries = insertNode.numFreeEntries(); - if (irrelevantEntry != null) { - irrelevantEntry.overwriteOldEntry(toInsert); - } - else if (numFreeEntries>0){ - insertNode.addEntry(toInsert, timestamp); - } - else { - // We have to split. - Entry parentEntry = insertNode.getEntries()[0].getParentEntry(); - Entry residualEntry = split(toInsert, insertNode, parentEntry, timestamp); - if (alsoUpdate!=null){ - alsoUpdate = residualEntry; - } - Node nodeForResidualEntry = insertNode.getEntries()[0].getParentEntry().getNode(); - //recursive call - return insertHereWithSplit(residualEntry, nodeForResidualEntry, timestamp); - } - - //no Split - return null; - } - - - // XXX: Document the insertion when the final implementation is done. - private Entry insertHere(Entry newEntry, Node currentNode, - Entry parentEntry, ClusKernel carriedBuffer, Budget budget, - long timestamp) { - - int numFreeEntries = currentNode.numFreeEntries(); - - // Insert the buffer that we carry. - if (!carriedBuffer.isEmpty()) { - Entry bufferEntry = new Entry(this.numberDimensions, - carriedBuffer, timestamp, parentEntry, currentNode); - - if (numFreeEntries <= 1) { - // Distance from buffer to entries. - Entry nearestEntryToCarriedBuffer = - currentNode.nearestEntry(newEntry); - double distanceNearestEntryToBuffer = - nearestEntryToCarriedBuffer.calcDistance(newEntry); - - // Distance between buffer and point to insert. - double distanceBufferNewEntry = - newEntry.calcDistance(carriedBuffer); - - // Best distance between Entrys in the Node. - BestMergeInNode bestMergeInNode = - calculateBestMergeInNode(currentNode); - - // See what the minimal distance is and do the correspoding - // action. - if (distanceNearestEntryToBuffer <= distanceBufferNewEntry - && distanceNearestEntryToBuffer <= bestMergeInNode.distance) { - // Aggregate buffer entry to nearest entry in node. - nearestEntryToCarriedBuffer.aggregateEntry(bufferEntry, - timestamp, this.negLambda); - } else if (distanceBufferNewEntry <= distanceNearestEntryToBuffer - && distanceBufferNewEntry <= bestMergeInNode.distance) { - newEntry.mergeWith(bufferEntry); - } else { - currentNode.mergeEntries(bestMergeInNode.entryPos1, - bestMergeInNode.entryPos2); - currentNode.addEntry(bufferEntry, timestamp); - } - - } else { - assert (currentNode.isLeaf()); - currentNode.addEntry(bufferEntry, timestamp); - } - } - - // Normally the insertion of the carries buffer does not change the - // number of free entries, but in case of future changes we calculate - // the number again. - numFreeEntries = currentNode.numFreeEntries(); - - // Search for an Entry with a weight under the threshold. - Entry irrelevantEntry = currentNode.getIrrelevantEntry(this.weightThreshold); - if (currentNode.isLeaf() && irrelevantEntry != null) { - irrelevantEntry.overwriteOldEntry(newEntry); - } else if (numFreeEntries >= 1) { - currentNode.addEntry(newEntry, timestamp); - } else { - if (currentNode.isLeaf() && (this.hasMaximalSize() - || !budget.hasMoreTime())) { - mergeEntryWithoutSplit(currentNode, newEntry, - timestamp); - } else { - // We have to split. - return split(newEntry, currentNode, parentEntry, timestamp); - } - } - - return null; - } - - /** - * This method calculates the distances between the new point and each Entry in a leaf node. - * It returns the node that contains the entry with the smallest distance - * to the new point. - * @param newPoint - * @return best fitting node - */ - private Node findBestLeafNode(ClusKernel newPoint) { - double minDist = Double.MAX_VALUE; - Node bestFit = null; - for (Node e: collectLeafNodes(root)){ - if (newPoint.calcDistance(e.nearestEntry(newPoint).getData()) collectLeafNodes(Node curr){ - ArrayList toReturn = new ArrayList(); - if (curr==null) - return toReturn; - if (curr.isLeaf()){ - toReturn.add(curr); - return toReturn; - } - else{ - for (Entry e : curr.getEntries()) - toReturn.addAll(collectLeafNodes(e.getChild())); - return toReturn; - } - } - - // TODO: Expand all function that work on entries to work with the Budget. - private Entry insert(ClusKernel pointToInsert, ClusKernel carriedBuffer, - Node currentNode, Entry parentEntry, Budget budget, long timestamp) { - assert (currentNode != null); - assert (currentNode.isLeaf() - || currentNode.getEntries()[0].getChild() != null); - - currentNode.makeOlder(timestamp, this.negLambda); - - // This variable will be changed from to null to an actual reference - // in the following if-else block if we have to insert something here, - // either because this is a leaf, or because of split propagation. - Entry toInsertHere = null; - - if (currentNode.isLeaf()) { - // At the end of the function the entry will be inserted. - toInsertHere = new Entry(this.numberDimensions, - pointToInsert, timestamp, parentEntry, currentNode); - } else { - - Entry bestEntry = currentNode.nearestEntry(pointToInsert); - bestEntry.aggregateCluster(pointToInsert, timestamp, - this.negLambda); - - boolean isCarriedBufferEmpty = carriedBuffer.isEmpty(); - - Entry bestBufferEntry = null; - if (!isCarriedBufferEmpty) { - bestBufferEntry = currentNode.nearestEntry(carriedBuffer); - bestBufferEntry.aggregateCluster(carriedBuffer, timestamp, - this.negLambda); - } - - if (!budget.hasMoreTime()) { - bestEntry.aggregateToBuffer(pointToInsert, timestamp, - this.negLambda); - if (!isCarriedBufferEmpty) { - bestBufferEntry.aggregateToBuffer(carriedBuffer, - timestamp, this.negLambda); - } - return null; - } - - // If the way of the buffer differs from the way of the point to - // be inserted, leave the buffer here. - if (!isCarriedBufferEmpty && (bestEntry != bestBufferEntry)) { - bestBufferEntry.aggregateToBuffer(carriedBuffer, timestamp, - this.negLambda); - carriedBuffer.clear(); - } - // Take the buffer of the best entry for the point to be inserted - // along. - ClusKernel takeAlongBuffer = bestEntry.emptyBuffer(timestamp, - this.negLambda); - carriedBuffer.add(takeAlongBuffer); - - // Recursive call. - toInsertHere = insert(pointToInsert, carriedBuffer, - bestEntry.getChild(), bestEntry, budget, timestamp); - } - - // If the above block has a new Entry for this place insert it. - if (toInsertHere != null) { - return this.insertHere(toInsertHere, currentNode, parentEntry, - carriedBuffer, budget, timestamp); - } - - // If nothing else needs to be done in all the above levels - // return null to signalize it. - return null; - } - - /** - * Inserts an Entry into a Node without inducing - * a split. - * @param node The node at which the entry is to be inserted. - * @param newEntry The entry to be inserted. - * @param timestamp The moment at which this occurs. - */ - private void mergeEntryWithoutSplit(Node node, - Entry newEntry, long timestamp) { - - Entry nearestEntryToCarriedBuffer = - node.nearestEntry(newEntry); - double distanceNearestEntryToBuffer = - nearestEntryToCarriedBuffer.calcDistance(newEntry); - - BestMergeInNode bestMergeInNode = - calculateBestMergeInNode(node); - - if (distanceNearestEntryToBuffer < bestMergeInNode.distance) { - nearestEntryToCarriedBuffer.aggregateEntry(newEntry, timestamp, - this.negLambda); - } else { - node.mergeEntries(bestMergeInNode.entryPos1, - bestMergeInNode.entryPos2); - node.addEntry(newEntry, timestamp); - } - } - - /** - * Calculates the best merge possible between two nodes in a node. This - * means that the pair with the smallest distance is found. - * @param node The node in which these two entries have to be found. - * @return An object which encodes the two position of the entries with the - * smallest distance in the node and the distance between them. - * @see BestMergeInNode - * @see Entry#calcDistance(tree.Entry) - */ - private BestMergeInNode calculateBestMergeInNode(Node node) { - assert (node.numFreeEntries() == 0); - - Entry[] entries = node.getEntries(); - - int toMerge1 = -1; - int toMerge2 = -1; - double distanceBetweenMergeEntries = Double.NaN; - - double minDistance = Double.MAX_VALUE; - for (int i = 0; i < entries.length; i++) { - Entry e1 = entries[i]; - for (int j = i + 1; j < entries.length; j++) { - Entry e2 = entries[j]; - double distance = e1.calcDistance(e2); - if (distance < minDistance) { - toMerge1 = i; - toMerge2 = j; - distanceBetweenMergeEntries = distance; - } - } - } - - assert (toMerge1 != -1 && toMerge2 != -1); - if (Double.isNaN(distanceBetweenMergeEntries)) { - throw new RuntimeException("The minimal distance between two " - + "Entrys in a Node was Double.MAX_VAUE. That can hardly " - + "be right."); - } - - return new BestMergeInNode(toMerge1, toMerge2, - distanceBetweenMergeEntries); - } - - private boolean hasMaximalSize() { - // TODO: Improve hasMaximalSize(). For now it just works somehow for testing. - return this.height == this.maxHeight; - } - - /** - * Performs a (2,2) split on the given node with the given entry. This - * implementation only works if the nodes have three entries each. The split - * will generate two new nodes. One of them will be put where the old node - * was, and for the other a new Entry will be generated and - * returned. - * @param newEntry The entry to be added to the node. - * @param node The node that is going to be splitted. - * @param parentEntry The entry in the tree that points at the node that - * is going to be splitted. - * @param timestamp The moment at which this split occurs. - * @return An entry which points at the second node created in the split. - * This entry has to be introduced later in the tree. - */ - private Entry split(Entry newEntry, Node node, Entry parentEntry, - long timestamp) { - // The implemented split function only works in trees where node - // have three entries. - // Splitting only makes sense on full nodes. - assert (node.numFreeEntries() == 0); - assert (parentEntry.getChild() == node); - - // All the entries we have to separate in two nodes. - Entry[] allEntries = new Entry[4]; - Entry[] nodeEntries = node.getEntries(); - for (int i = 0; i < nodeEntries.length; i++) { - allEntries[i] = new Entry(nodeEntries[i]); - } - allEntries[3] = newEntry; - - // Clear the given node, since we are going to refill it later. - node = new Node(this.numberDimensions, node.getRawLevel()); - - // Calculate the distance of all the possible pairings, since we want - // to do a (2,2) split. - double select01 = allEntries[0].calcDistance(allEntries[1]) - + allEntries[2].calcDistance(allEntries[3]); - - double select02 = allEntries[0].calcDistance(allEntries[2]) - + allEntries[1].calcDistance(allEntries[3]); - - double select03 = allEntries[0].calcDistance(allEntries[3]) - + allEntries[1].calcDistance(allEntries[2]); - - // See which of the pairings is minimal and distribute the entries - // accordingly. - Node residualNode = new Node(this.numberDimensions, - node.getRawLevel()); - if (select01 < select02) { - if (select01 < select03) {//select01 smallest - node.addEntry(allEntries[0], timestamp); - node.addEntry(allEntries[1], timestamp); - residualNode.addEntry(allEntries[2], timestamp); - residualNode.addEntry(allEntries[3], timestamp); - } else {//select03 smallest - node.addEntry(allEntries[0], timestamp); - node.addEntry(allEntries[3], timestamp); - residualNode.addEntry(allEntries[1], timestamp); - residualNode.addEntry(allEntries[2], timestamp); - } - } else { - if (select02 < select03) {//select02 smallest - node.addEntry(allEntries[0], timestamp); - node.addEntry(allEntries[2], timestamp); - residualNode.addEntry(allEntries[1], timestamp); - residualNode.addEntry(allEntries[3], timestamp); - } else {//select03 smallest - node.addEntry(allEntries[0], timestamp); - node.addEntry(allEntries[3], timestamp); - residualNode.addEntry(allEntries[1], timestamp); - residualNode.addEntry(allEntries[2], timestamp); - } - } - - // Set the other node into the tree. - parentEntry.setChild(node); - parentEntry.recalculateData(); - int count = 0; - for (Entry e : node.getEntries()){ - e.setParentEntry(parentEntry); - if (e.getData().getN() != 0) - count++; - } - //System.out.println(count); - // Generate a new entry for the residual node. - Entry residualEntry = new Entry(this.numberDimensions, - residualNode, timestamp, parentEntry, node); - count=0; - for (Entry e: residualNode.getEntries()){ - e.setParentEntry(residualEntry); - if (e.getData().getN() != 0) - count++; - } - //System.out.println(count); - return residualEntry; - } - - /** - * Return the number of time the tree has grown in size. If the tree grows - * and is then cutted from a certain depth, it also counts. - * @return The number of times the root node was splitted. - */ - public int getNumRootSplits() { - return numRootSplits; - } - - /** - * Return the current height of the tree. This should never be greater than - * maxHeight. - * @return The height of the tree. - * @see #maxHeight - */ - public int getHeight() { - assert (height <= maxHeight); - return height; - } - - private void cleanUp(Node currentNode, int level) { - if (currentNode == null) { - return; - } - - Entry[] entries = currentNode.getEntries(); - if (level == this.maxHeight) { - for (int i = 0; i < entries.length; i++) { - Entry e = entries[i]; - e.setChild(null); - } - } else { - for (int i = 0; i < entries.length; i++) { - Entry e = entries[i]; - cleanUp(e.getChild(), level + 1); - } - } - } - - /** - * @param currentTime The current time - * @return The kernels at the leaf level as a clustering - */ - //TODO: Microcluster unter dem Threshhold nich zur�ckgeben (WIe bei outdated entries) - @Override - public Clustering getMicroClusteringResult() { - return getClustering(timestamp, -1); - } - - @Override - public Clustering getClusteringResult() { - return null; - } - - - /** - * @param currentTime The current time - * @return The kernels at the given level as a clustering. - */ - public Clustering getClustering(long currentTime, int targetLevel) { - if (root == null) { - return null; - } - - Clustering clusters = new Clustering(); - LinkedList queue = new LinkedList(); - queue.add(root); - - while (!queue.isEmpty()) { - Node current = queue.remove(); - // if (current == null) - // continue; - int currentLevel = current.getLevel(this); - boolean isLeaf = (current.isLeaf() && currentLevel <= maxHeight) - || currentLevel == maxHeight; - - if (currentLevel == targetLevel - || (targetLevel == - 1 && isLeaf)) { - assert (currentLevel <= maxHeight); - - Entry[] entries = current.getEntries(); - for (int i = 0; i < entries.length; i++) { - Entry entry = entries[i]; - if (entry == null || entry.isEmpty()) { - continue; - } - // XXX - entry.makeOlder(currentTime, this.negLambda); - if (entry.isIrrelevant(this.weightThreshold)) - continue; - - ClusKernel gaussKernel = new ClusKernel(entry.getData()); - -// long diff = currentTime - entry.getTimestamp(); -// if (diff > 0) { -// gaussKernel.makeOlder(diff, negLambda); -// } - - clusters.add(gaussKernel); - } - } else if (!current.isLeaf()) { - Entry[] entries = current.getEntries(); - for (int i = 0; i < entries.length; i++) { - Entry entry = entries[i]; - - if (entry.isEmpty()) { - continue; - } - - if (entry.isIrrelevant(weightThreshold)) { - continue; - } - - queue.add(entry.getChild()); - } - } - } - - return clusters; - } - - - - /************************************************************************** - * LOCAL CLASSES - **************************************************************************/ - /** - * A class to code the return value of searching the smallest merge in a - * node. - */ - class BestMergeInNode { - - /** - * The position of the first entry in the array of the node. - */ - public int entryPos1; - /** - * The position of the second entry in the array of the node. - */ - public int entryPos2; - /** - * The distance between the two entries. - */ - public double distance; - - /** - * The constructor of this return value. It will automatically make - * sure that the first position is the smaller one of the two. - * @param pos1 One of the position. - * @param pos2 One of the position. - * @param distance The distance between the entries at these positions. - */ - public BestMergeInNode(int pos1, int pos2, - double distance) { - assert (pos1 != pos2); - - this.distance = distance; - - if (pos1 < pos2) { - this.entryPos1 = pos1; - this.entryPos2 = pos2; - } else { - this.entryPos1 = pos2; - this.entryPos2 = pos1; - } - } - } - -} diff --git a/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java.orig b/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java.orig deleted file mode 100644 index a9f314477..000000000 --- a/moa/src/main/java/moa/tasks/EvaluatePeriodicHeldOutTest.java.orig +++ /dev/null @@ -1,308 +0,0 @@ -/* - * EvaluatePeriodicHeldOutTest.java - * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * @author Ammar Shaker (shaker@mathematik.uni-marburg.de) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package moa.tasks; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.List; -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FlagOption; -import com.github.javacliparser.IntOption; -<<<<<<< Updated upstream -<<<<<<< HEAD -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; - -======= -<<<<<<< c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 -import moa.classifiers.Classifier; -======= -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstancesHeader; - ->>>>>>> Instances rework, new iSOUPTree models and import cleanup ->>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe -======= -import moa.classifiers.Classifier; ->>>>>>> Stashed changes -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; -import moa.core.StringUtils; -import moa.core.TimingUtils; -import moa.evaluation.LearningCurve; -import moa.evaluation.LearningEvaluation; -import moa.evaluation.LearningPerformanceEvaluator; -import moa.learners.Learner; -import moa.options.ClassOption; -import moa.streams.CachedInstancesStream; -import moa.streams.ExampleStream; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceHeader; - -/** - * Task for evaluating a classifier on a stream by periodically testing on a heldout set. - * - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * @version $Revision: 7 $ - */ -public class EvaluatePeriodicHeldOutTest extends MainTask { - - @Override - public String getPurposeString() { - return "Evaluates a classifier on a stream by periodically testing on a heldout set."; - } - - private static final long serialVersionUID = 1L; - - public ClassOption learnerOption = new ClassOption("learner", 'l', - "Classifier to train.", Classifier.class, "moa.classifiers.trees.HoeffdingTree"); - - public ClassOption streamOption = new ClassOption("stream", 's', - "Stream to learn from.", ExampleStream.class, - "generators.RandomTreeGenerator"); - - public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', - "Learning performance evaluation method.", - LearningPerformanceEvaluator.class, - "BasicClassificationPerformanceEvaluator"); - - public IntOption testSizeOption = new IntOption("testSize", 'n', - "Number of testing examples.", 1000000, 0, Integer.MAX_VALUE); - - public IntOption trainSizeOption = new IntOption("trainSize", 'i', - "Number of training examples, <1 = unlimited.", 0, 0, - Integer.MAX_VALUE); - - public IntOption trainTimeOption = new IntOption("trainTime", 't', - "Number of training seconds.", 10 * 60 * 60, 0, Integer.MAX_VALUE); - - public IntOption sampleFrequencyOption = new IntOption( - "sampleFrequency", - 'f', - "Number of training examples between samples of learning performance.", - 100000, 0, Integer.MAX_VALUE); - - public FileOption dumpFileOption = new FileOption("dumpFile", 'd', - "File to append intermediate csv results to.", null, "csv", true); - - public FlagOption cacheTestOption = new FlagOption("cacheTest", 'c', - "Cache test instances in memory."); - - @Override - protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { - Learner learner = (Learner) getPreparedClassOption(this.learnerOption); - ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); - LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); - learner.setModelContext(stream.getHeader()); - long instancesProcessed = 0; - LearningCurve learningCurve = new LearningCurve("evaluation instances"); - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - boolean firstDump = true; - ExampleStream testStream = null; - int testSize = this.testSizeOption.getValue(); - if (this.cacheTestOption.isSet()) { - monitor.setCurrentActivity("Caching test examples...", -1.0); - InstancesHeader testInstances = new InstancesHeader(stream.getHeader(), - this.testSizeOption.getValue()); - while (testInstances.numInstances() < testSize) { - testInstances.add((Instance) stream.nextInstance().getData()); - if (testInstances.numInstances() - % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { - if (monitor.taskShouldAbort()) { - return null; - } - monitor.setCurrentActivityFractionComplete((double) testInstances.numInstances() - / (double) (this.testSizeOption.getValue())); - } - } - testStream = new CachedInstancesStream(testInstances); - } else { - //testStream = (InstanceStream) stream.copy(); - testStream = stream; - /*monitor.setCurrentActivity("Skipping test examples...", -1.0); - for (int i = 0; i < testSize; i++) { - stream.nextInstance(); - }*/ - } - instancesProcessed = 0; - TimingUtils.enablePreciseTiming(); - double totalTrainTime = 0.0; - while ((this.trainSizeOption.getValue() < 1 - || instancesProcessed < this.trainSizeOption.getValue()) - && stream.hasMoreInstances() == true) { - monitor.setCurrentActivityDescription("Training..."); - long instancesTarget = instancesProcessed - + this.sampleFrequencyOption.getValue(); - long trainStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - while (instancesProcessed < instancesTarget && stream.hasMoreInstances() == true) { - learner.trainOnInstance(stream.nextInstance()); - instancesProcessed++; - if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { - if (monitor.taskShouldAbort()) { - return null; - } - monitor.setCurrentActivityFractionComplete((double) (instancesProcessed) - / (double) (this.trainSizeOption.getValue())); - } - } - double lastTrainTime = TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() - - trainStartTime); - totalTrainTime += lastTrainTime; - if (totalTrainTime > this.trainTimeOption.getValue()) { - break; - } - if (this.cacheTestOption.isSet()) { - testStream.restart(); - } - evaluator.reset(); - long testInstancesProcessed = 0; - monitor.setCurrentActivityDescription("Testing (after " - + StringUtils.doubleToString( - ((double) (instancesProcessed) - / (double) (this.trainSizeOption.getValue()) * 100.0), 2) - + "% training)..."); - long testStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - int instCount = 0 ; - for (instCount = 0; instCount < testSize; instCount++) { - if (stream.hasMoreInstances() == false) { - break; - } - Example testInst = (Example) testStream.nextInstance(); //.copy(); - double trueClass = ((Instance) testInst.getData()).classValue(); - //testInst.setClassMissing(); - double[] prediction = learner.getPredictionForInstance(testInst); - //testInst.setClassValue(trueClass); - evaluator.addResult(testInst, prediction); - testInstancesProcessed++; - if (testInstancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { - if (monitor.taskShouldAbort()) { - return null; - } - monitor.setCurrentActivityFractionComplete((double) testInstancesProcessed - / (double) (testSize)); - } - } - if ( instCount != testSize) { - break; - } - double testTime = TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() - - testStartTime); - List measurements = new ArrayList(); - measurements.add(new Measurement("evaluation instances", - instancesProcessed)); - measurements.add(new Measurement("total train time", totalTrainTime)); - measurements.add(new Measurement("total train speed", - instancesProcessed / totalTrainTime)); - measurements.add(new Measurement("last train time", lastTrainTime)); - measurements.add(new Measurement("last train speed", - this.sampleFrequencyOption.getValue() / lastTrainTime)); - measurements.add(new Measurement("test time", testTime)); - measurements.add(new Measurement("test speed", this.testSizeOption.getValue() - / testTime)); - Measurement[] performanceMeasurements = evaluator.getPerformanceMeasurements(); - for (Measurement measurement : performanceMeasurements) { - measurements.add(measurement); - } - Measurement[] modelMeasurements = learner.getModelMeasurements(); - for (Measurement measurement : modelMeasurements) { - measurements.add(measurement); - } - learningCurve.insertEntry(new LearningEvaluation(measurements.toArray(new Measurement[measurements.size()]))); - if (immediateResultStream != null) { - if (firstDump) { - immediateResultStream.println(learningCurve.headerToString()); - firstDump = false; - } - immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); - immediateResultStream.flush(); - } - if (monitor.resultPreviewRequested()) { - monitor.setLatestResultPreview(learningCurve.copy()); - } - // if (learner instanceof HoeffdingTree - // || learner instanceof HoeffdingOptionTree) { - // int numActiveNodes = (int) Measurement.getMeasurementNamed( - // "active learning leaves", - // modelMeasurements).getValue(); - // // exit if tree frozen - // if (numActiveNodes < 1) { - // break; - // } - // int numNodes = (int) Measurement.getMeasurementNamed( - // "tree size (nodes)", modelMeasurements) - // .getValue(); - // if (numNodes == lastNumNodes) { - // noGrowthCount++; - // } else { - // noGrowthCount = 0; - // } - // lastNumNodes = numNodes; - // } else if (learner instanceof OzaBoost || learner instanceof - // OzaBag) { - // double numActiveNodes = Measurement.getMeasurementNamed( - // "[avg] active learning leaves", - // modelMeasurements).getValue(); - // // exit if all trees frozen - // if (numActiveNodes == 0.0) { - // break; - // } - // int numNodes = (int) (Measurement.getMeasurementNamed( - // "[avg] tree size (nodes)", - // learner.getModelMeasurements()).getValue() * Measurement - // .getMeasurementNamed("ensemble size", - // modelMeasurements).getValue()); - // if (numNodes == lastNumNodes) { - // noGrowthCount++; - // } else { - // noGrowthCount = 0; - // } - // lastNumNodes = numNodes; - // } - } - if (immediateResultStream != null) { - immediateResultStream.close(); - } - return learningCurve; - } - - @Override - public Class getTaskResultType() { - return LearningCurve.class; - } -} diff --git a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java.orig b/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java.orig deleted file mode 100644 index 55b4ceade..000000000 --- a/moa/src/main/java/moa/tasks/EvaluatePrequentialMultiTarget.java.orig +++ /dev/null @@ -1,713 +0,0 @@ -<<<<<<< c4a46917f06a4f4c3c08e67d06f6762cca1b47f9 -/* - * EvaluatePrequentialMultiTarget.java - * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package moa.tasks; - -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.InstanceData; -import com.yahoo.labs.samoa.instances.Prediction; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.PrintStream; - -import moa.classifiers.MultiTargetRegressor; -import moa.classifiers.Regressor; -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; -import moa.core.TimingUtils; -import moa.evaluation.EWMAClassificationPerformanceEvaluator; -import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; -import moa.evaluation.LearningCurve; -import moa.evaluation.LearningEvaluation; -import moa.evaluation.LearningPerformanceEvaluator; -import moa.evaluation.MultiTargetPerformanceEvaluator; -import moa.evaluation.RegressionPerformanceEvaluator; -import moa.evaluation.WindowClassificationPerformanceEvaluator; -import moa.learners.Learner; -import moa.options.ClassOption; -import moa.streams.ExampleStream; -import moa.streams.MultiTargetInstanceStream; - -/** - * Task for evaluating a classifier on a stream by testing then training with each example in sequence. - * - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) - * @version $Revision: 7 $ - */ -public class EvaluatePrequentialMultiTarget extends MultiTargetMainTask { - - @Override - public String getPurposeString() { - return "Evaluates a classifier on a stream by testing then training with each example in sequence."; - } - - private static final long serialVersionUID = 1L; - - public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); - - public ClassOption streamOption = new ClassOption("stream", 's', - "Stream to learn from.", MultiTargetInstanceStream.class, - "MultiTargetArffFileStream"); - - public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', - "Classification performance evaluation method.", - MultiTargetPerformanceEvaluator.class, - "BasicMultiTargetPerformanceEvaluator"); - - public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', - "Maximum number of instances to test/train on (-1 = no limit).", - 100000000, -1, Integer.MAX_VALUE); - - public IntOption timeLimitOption = new IntOption("timeLimit", 't', - "Maximum number of seconds to test/train for (-1 = no limit).", -1, - -1, Integer.MAX_VALUE); - - public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", - 'f', - "How many instances between samples of the learning performance.", - 100000, 0, Integer.MAX_VALUE); - - public IntOption memCheckFrequencyOption = new IntOption( - "memCheckFrequency", 'q', - "How many instances between memory bound checks.", 100000, 0, - Integer.MAX_VALUE); - - public FileOption dumpFileOption = new FileOption("dumpFile", 'd', - "File to append intermediate csv results to.", null, "csv", true); - - public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', - "File to append output predictions to.", null, "pred", true); - - //New for prequential method DEPRECATED - public IntOption widthOption = new IntOption("width", - 'w', "Size of Window", 1000); - - public FloatOption alphaOption = new FloatOption("alpha", - 'a', "Fading factor or exponential smoothing factor", .01); - //End New for prequential methods - - @Override - public Class getTaskResultType() { - return LearningCurve.class; - } - - @Override - protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { - Learner learner = (Learner) getPreparedClassOption(this.learnerOption); - ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); - LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); - LearningCurve learningCurve = new LearningCurve( - "learning evaluation instances"); - - //New for prequential methods - if (evaluator instanceof WindowClassificationPerformanceEvaluator) { - //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); - if (widthOption.getValue() != 1000) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); - return learningCurve; -======= -/* - * EvaluatePrequentialMultiTarget.java - * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package moa.tasks; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.PrintStream; - -import com.github.javacliparser.FileOption; -import com.github.javacliparser.FloatOption; -import com.github.javacliparser.IntOption; -import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.Prediction; - -import moa.classifiers.MultiTargetRegressor; -import moa.core.Example; -import moa.core.Measurement; -import moa.core.ObjectRepository; -import moa.core.TimingUtils; -import moa.evaluation.EWMAClassificationPerformanceEvaluator; -import moa.evaluation.FadingFactorClassificationPerformanceEvaluator; -import moa.evaluation.LearningCurve; -import moa.evaluation.LearningEvaluation; -import moa.evaluation.LearningPerformanceEvaluator; -import moa.evaluation.MultiTargetPerformanceEvaluator; -import moa.evaluation.WindowClassificationPerformanceEvaluator; -import moa.learners.Learner; -import moa.options.ClassOption; -import moa.streams.ExampleStream; -import moa.streams.MultiTargetInstanceStream; - -/** - * Task for evaluating a classifier on a stream by testing then training with each example in sequence. - * - * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) - * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) - * @version $Revision: 7 $ - */ -public class EvaluatePrequentialMultiTarget extends MultiTargetMainTask { - - @Override - public String getPurposeString() { - return "Evaluates a classifier on a stream by testing then training with each example in sequence."; - } -<<<<<<< HEAD - - private static final long serialVersionUID = 1L; - - public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); - - public ClassOption streamOption = new ClassOption("stream", 's', - "Stream to learn from.", MultiTargetInstanceStream.class, - "MultiTargetArffFileStream"); - - public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', - "Classification performance evaluation method.", - MultiTargetPerformanceEvaluator.class, - "BasicMultiTargetPerformanceEvaluator"); - - public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', - "Maximum number of instances to test/train on (-1 = no limit).", - 100000000, -1, Integer.MAX_VALUE); - - public IntOption timeLimitOption = new IntOption("timeLimit", 't', - "Maximum number of seconds to test/train for (-1 = no limit).", -1, - -1, Integer.MAX_VALUE); - - public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", - 'f', - "How many instances between samples of the learning performance.", - 100000, 0, Integer.MAX_VALUE); - - public IntOption memCheckFrequencyOption = new IntOption( - "memCheckFrequency", 'q', - "How many instances between memory bound checks.", 100000, 0, - Integer.MAX_VALUE); - - public FileOption dumpFileOption = new FileOption("dumpFile", 'd', - "File to append intermediate csv results to.", null, "csv", true); - - public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', - "File to append output predictions to.", null, "pred", true); - - //New for prequential method DEPRECATED - public IntOption widthOption = new IntOption("width", - 'w', "Size of Window", 1000); - - public FloatOption alphaOption = new FloatOption("alpha", - 'a', "Fading factor or exponential smoothing factor", .01); - //End New for prequential methods - - @Override - public Class getTaskResultType() { - return LearningCurve.class; - } - - @Override - protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { - Learner learner = (Learner) getPreparedClassOption(this.learnerOption); - ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); - LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); - LearningCurve learningCurve = new LearningCurve( - "learning evaluation instances"); - - //New for prequential methods - if (evaluator instanceof WindowClassificationPerformanceEvaluator) { - //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); - if (widthOption.getValue() != 1000) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { - //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { - //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - //End New for prequential methods - - learner.setModelContext(stream.getHeader()); - int maxInstances = this.instanceLimitOption.getValue(); - long instancesProcessed = 0; - int maxSeconds = this.timeLimitOption.getValue(); - int secondsElapsed = 0; - monitor.setCurrentActivity("Evaluating learner...", -1.0); - - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - //File for output predictions - File outputPredictionFile = this.outputPredictionFileOption.getFile(); - PrintStream outputPredictionResultStream = null; - if (outputPredictionFile != null) { - try { - if (outputPredictionFile.exists()) { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile, true), true); - } else { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open prediction result file: " + outputPredictionFile, ex); - } - } - boolean firstDump = true; - boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); - long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - long lastEvaluateStartTime = evaluateStartTime; - double RAMHours = 0.0; - while (stream.hasMoreInstances() - && ((maxInstances < 0) || (instancesProcessed < maxInstances)) - && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { - Example trainInst = stream.nextInstance(); - Example testInst = (Example) trainInst; //.copy(); - //testInst.setClassMissing(); - //double[] prediction = learner.getPredictionForInstance(testInst); - Prediction prediction = learner.getPredictionForInstance(testInst); - // Output prediction - if (outputPredictionFile != null) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { - sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); - } - outputPredictionResultStream.println(prediction + "," + sb.toString()); - } - - //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); - evaluator.addResult(testInst, prediction); - learner.trainOnInstance(trainInst); - instancesProcessed++; - if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 - || stream.hasMoreInstances() == false) { - long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); - double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); - double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs - RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours - RAMHours += RAMHoursIncrement; - lastEvaluateStartTime = evaluateTime; - learningCurve.insertEntry(new LearningEvaluation( - new Measurement[]{ - new Measurement( - "learning evaluation instances", - instancesProcessed), - new Measurement( - "evaluation time (" - + (preciseCPUTiming ? "cpu " - : "") + "seconds)", - time), - new Measurement( - "model cost (RAM-Hours)", - RAMHours) - }, - evaluator, learner)); - - if (immediateResultStream != null) { - if (firstDump) { - immediateResultStream.println(learningCurve.headerToString()); - firstDump = false; - } - immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); - immediateResultStream.flush(); - } - } - if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { - if (monitor.taskShouldAbort()) { - return null; - } - long estimatedRemainingInstances = stream.estimatedRemainingInstances(); - if (maxInstances > 0) { - long maxRemaining = maxInstances - instancesProcessed; - if ((estimatedRemainingInstances < 0) - || (maxRemaining < estimatedRemainingInstances)) { - estimatedRemainingInstances = maxRemaining; - } - } - monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 - : (double) instancesProcessed - / (double) (instancesProcessed + estimatedRemainingInstances)); - if (monitor.resultPreviewRequested()) { - monitor.setLatestResultPreview(learningCurve.copy()); - } - secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() - - evaluateStartTime); - } - } - StringBuilder sb= new StringBuilder(); - learner.getDescription(sb, 0); - System.out.println(sb.toString()); - if (immediateResultStream != null) { - immediateResultStream.close(); - } - if (outputPredictionResultStream != null) { - outputPredictionResultStream.close(); - } - return learningCurve; - } -} -======= - - private static final long serialVersionUID = 1L; - - public ClassOption learnerOption = new ClassOption("learner", 'l', - "Learner to train.", MultiTargetRegressor.class, "moa.classifiers.multitarget.functions.MultiTargetNoChange"); - - public ClassOption streamOption = new ClassOption("stream", 's', - "Stream to learn from.", MultiTargetInstanceStream.class, - "MultiTargetArffFileStream"); - - public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', - "Classification performance evaluation method.", - MultiTargetPerformanceEvaluator.class, - "BasicMultiTargetPerformanceEvaluator"); - - public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', - "Maximum number of instances to test/train on (-1 = no limit).", - 100000000, -1, Integer.MAX_VALUE); - - public IntOption timeLimitOption = new IntOption("timeLimit", 't', - "Maximum number of seconds to test/train for (-1 = no limit).", -1, - -1, Integer.MAX_VALUE); - - public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", - 'f', - "How many instances between samples of the learning performance.", - 100000, 0, Integer.MAX_VALUE); - - public IntOption memCheckFrequencyOption = new IntOption( - "memCheckFrequency", 'q', - "How many instances between memory bound checks.", 100000, 0, - Integer.MAX_VALUE); - - public FileOption dumpFileOption = new FileOption("dumpFile", 'd', - "File to append intermediate csv results to.", null, "csv", true); - - public FileOption outputPredictionFileOption = new FileOption("outputPredictionFile", 'o', - "File to append output predictions to.", null, "pred", true); - - //New for prequential method DEPRECATED - public IntOption widthOption = new IntOption("width", - 'w', "Size of Window", 1000); - - public FloatOption alphaOption = new FloatOption("alpha", - 'a', "Fading factor or exponential smoothing factor", .01); - //End New for prequential methods - - @Override - public Class getTaskResultType() { - return LearningCurve.class; - } - - @Override - protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { - Learner learner = (Learner) getPreparedClassOption(this.learnerOption); - ExampleStream stream = (ExampleStream) getPreparedClassOption(this.streamOption); - LearningPerformanceEvaluator evaluator = (LearningPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); - LearningCurve learningCurve = new LearningCurve( - "learning evaluation instances"); - - //New for prequential methods - if (evaluator instanceof WindowClassificationPerformanceEvaluator) { - //((WindowClassificationPerformanceEvaluator) evaluator).setWindowWidth(widthOption.getValue()); - if (widthOption.getValue() != 1000) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (WindowClassificationPerformanceEvaluator -w " + widthOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { - //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { - //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - //End New for prequential methods - - learner.setModelContext(stream.getHeader()); - int maxInstances = this.instanceLimitOption.getValue(); - long instancesProcessed = 0; - int maxSeconds = this.timeLimitOption.getValue(); - int secondsElapsed = 0; - monitor.setCurrentActivity("Evaluating learner...", -1.0); - - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - //File for output predictions - File outputPredictionFile = this.outputPredictionFileOption.getFile(); - PrintStream outputPredictionResultStream = null; - if (outputPredictionFile != null) { - try { - if (outputPredictionFile.exists()) { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile, true), true); - } else { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open prediction result file: " + outputPredictionFile, ex); - } - } - boolean firstDump = true; - boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); - long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - long lastEvaluateStartTime = evaluateStartTime; - double RAMHours = 0.0; - while (stream.hasMoreInstances() - && ((maxInstances < 0) || (instancesProcessed < maxInstances)) - && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { - Example trainInst = stream.nextInstance(); - Example testInst = (Example) trainInst; //.copy(); - //testInst.setClassMissing(); - //double[] prediction = learner.getPredictionForInstance(testInst); - Prediction prediction = learner.getPredictionForInstance(testInst); - // Output prediction - if (outputPredictionFile != null) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { - sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); - } - outputPredictionResultStream.println(prediction + "," + sb.toString()); ->>>>>>> Instances rework, new iSOUPTree models and import cleanup - } - } - if (evaluator instanceof EWMAClassificationPerformanceEvaluator) { - //((EWMAClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (EWMAClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - if (evaluator instanceof FadingFactorClassificationPerformanceEvaluator) { - //((FadingFactorClassificationPerformanceEvaluator) evaluator).setalpha(alphaOption.getValue()); - if (alphaOption.getValue() != .01) { - System.out.println("DEPRECATED! Use EvaluatePrequential -e (FadingFactorClassificationPerformanceEvaluator -a " + alphaOption.getValue() + ")"); - return learningCurve; - } - } - //End New for prequential methods - - learner.setModelContext(stream.getHeader()); - int maxInstances = this.instanceLimitOption.getValue(); - long instancesProcessed = 0; - int maxSeconds = this.timeLimitOption.getValue(); - int secondsElapsed = 0; - monitor.setCurrentActivity("Evaluating learner...", -1.0); - - File dumpFile = this.dumpFileOption.getFile(); - PrintStream immediateResultStream = null; - if (dumpFile != null) { - try { - if (dumpFile.exists()) { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile, true), true); - } else { - immediateResultStream = new PrintStream( - new FileOutputStream(dumpFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open immediate result file: " + dumpFile, ex); - } - } - //File for output predictions - File outputPredictionFile = this.outputPredictionFileOption.getFile(); - PrintStream outputPredictionResultStream = null; - if (outputPredictionFile != null) { - try { - if (outputPredictionFile.exists()) { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile, true), true); - } else { - outputPredictionResultStream = new PrintStream( - new FileOutputStream(outputPredictionFile), true); - } - } catch (Exception ex) { - throw new RuntimeException( - "Unable to open prediction result file: " + outputPredictionFile, ex); - } - } - boolean firstDump = true; - boolean preciseCPUTiming = TimingUtils.enablePreciseTiming(); - long evaluateStartTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - long lastEvaluateStartTime = evaluateStartTime; - double RAMHours = 0.0; - while (stream.hasMoreInstances() - && ((maxInstances < 0) || (instancesProcessed < maxInstances)) - && ((maxSeconds < 0) || (secondsElapsed < maxSeconds))) { - Example trainInst = stream.nextInstance(); - Example testInst = (Example) trainInst; //.copy(); - //testInst.setClassMissing(); - //double[] prediction = learner.getPredictionForInstance(testInst); - Prediction prediction = learner.getPredictionForInstance(testInst); - // Output prediction - if (outputPredictionFile != null) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ((Instance) trainInst.getData()).numOutputAttributes(); i++) { - sb.append("Out " + i + ": " + ((Instance) trainInst.getData()).valueOutputAttribute(i) + " "); - } - outputPredictionResultStream.println(prediction + "," + sb.toString()); - } - - //evaluator.addClassificationAttempt(trueClass, prediction, testInst.weight()); - evaluator.addResult(testInst, prediction); - learner.trainOnInstance(trainInst); - instancesProcessed++; - if (instancesProcessed % this.sampleFrequencyOption.getValue() == 0 - || stream.hasMoreInstances() == false) { - long evaluateTime = TimingUtils.getNanoCPUTimeOfCurrentThread(); - double time = TimingUtils.nanoTimeToSeconds(evaluateTime - evaluateStartTime); - double timeIncrement = TimingUtils.nanoTimeToSeconds(evaluateTime - lastEvaluateStartTime); - double RAMHoursIncrement = learner.measureByteSize() / (1024.0 * 1024.0 * 1024.0); //GBs - RAMHoursIncrement *= (timeIncrement / 3600.0); //Hours - RAMHours += RAMHoursIncrement; - lastEvaluateStartTime = evaluateTime; - learningCurve.insertEntry(new LearningEvaluation( - new Measurement[]{ - new Measurement( - "learning evaluation instances", - instancesProcessed), - new Measurement( - "evaluation time (" - + (preciseCPUTiming ? "cpu " - : "") + "seconds)", - time), - new Measurement( - "model cost (RAM-Hours)", - RAMHours) - }, - evaluator, learner)); - - if (immediateResultStream != null) { - if (firstDump) { - immediateResultStream.println(learningCurve.headerToString()); - firstDump = false; - } - immediateResultStream.println(learningCurve.entryToString(learningCurve.numEntries() - 1)); - immediateResultStream.flush(); - } - } - if (instancesProcessed % INSTANCES_BETWEEN_MONITOR_UPDATES == 0) { - if (monitor.taskShouldAbort()) { - return null; - } - long estimatedRemainingInstances = stream.estimatedRemainingInstances(); - if (maxInstances > 0) { - long maxRemaining = maxInstances - instancesProcessed; - if ((estimatedRemainingInstances < 0) - || (maxRemaining < estimatedRemainingInstances)) { - estimatedRemainingInstances = maxRemaining; - } - } - monitor.setCurrentActivityFractionComplete(estimatedRemainingInstances < 0 ? -1.0 - : (double) instancesProcessed - / (double) (instancesProcessed + estimatedRemainingInstances)); - if (monitor.resultPreviewRequested()) { - monitor.setLatestResultPreview(learningCurve.copy()); - } - secondsElapsed = (int) TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfCurrentThread() - - evaluateStartTime); - } - } - StringBuilder sb= new StringBuilder(); - learner.getDescription(sb, 0); - System.out.println(sb.toString()); - if (immediateResultStream != null) { - immediateResultStream.close(); - } - if (outputPredictionResultStream != null) { - outputPredictionResultStream.close(); - } - return learningCurve; - } -} ->>>>>>> 32d534d2e43c28db1711ab2fe7ff580d214e22fe From e3549e933bc02f752c7e7e5a221a20b7af52e1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Tue, 17 Apr 2018 13:33:01 +0200 Subject: [PATCH 32/33] Transitional commit --- .../yahoo/labs/samoa/instances/Attribute.java | 12 + .../yahoo/labs/samoa/instances/Instance.java | 15 + .../labs/samoa/instances/InstanceImpl.java | 17 +- .../MultiTargetRegressionPrediction.java | 8 +- .../classifiers/AbstractEnsembleLearner.java | 23 +- .../classifiers/AbstractInstanceLearner.java | 55 +- .../classifiers/meta/AbstractOzaBagAdwin.java | 3 +- .../MultiLabelBSTree.java | 44 +- .../MultiLabelBSTreePCT.java | 104 ++-- .../splitcriteria/ICVarianceReduction.java | 11 +- .../PCTWeightedICVarianceReduction.java | 22 +- .../WeightedICVarianceReduction.java | 2 + ...tiveRandomForestMultiTargetRegression.java | 516 ++++++++++++++++++ .../OzaBagAdwinMultiTargetRegression.java | 17 +- .../mlc/meta/OzaBagMultiTargetRegression.java | 2 +- .../LocalMultiTargetRegressor.java | 10 +- .../mtr/trees/ISOUPOptionTree.java | 13 +- .../moa/classifiers/mtr/trees/ISOUPTree.java | 310 +++++------ .../classifiers/mtr/trees/ISOUPTreeRF.java | 42 +- .../core/AttributeExpansionSuggestion.java | 3 + .../rules/core/NominalRulePredicate.java | 5 + .../rules/core/NumericRulePredicate.java | 5 +- moa/src/main/java/moa/core/DoubleVector.java | 4 +- moa/src/main/java/moa/learners/Learner.java | 6 + 24 files changed, 928 insertions(+), 321 deletions(-) create mode 100644 moa/src/main/java/moa/classifiers/mlc/meta/AdaptiveRandomForestMultiTargetRegression.java rename moa/src/main/java/moa/classifiers/{mlc => mtr}/LocalMultiTargetRegressor.java (91%) diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java index 0d1dc9a3a..2122a1796 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Attribute.java @@ -336,4 +336,16 @@ public final String toString() { } return null; } + + + public String attributeType() { + if (this.isNominal()) + return "nominal"; + else if (this.isNumeric()) + return "numeric"; + else if (this.isHierarchical()) + return "hierarchical"; + else + return "other"; + } } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java index b188919bf..336134838 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/Instance.java @@ -176,6 +176,21 @@ public interface Instance extends Serializable { * @param instAttIndex, the attribute's index */ public void setMissing(int instAttIndex); + + /** + * Sets an input attribute as missing + * + * @param inputAttributeIndex the index of the input attribute + */ + public void setInputMissing(int inputAttributeIndex); + + /** + * Sets an output attribute as missing + * + * @param outputAttributeIndex the index of the output attribute + */ + public void setOutputMissing(int outputAttributeIndex); + /** * Sets an attribute as missing diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java index 831866220..d4c8e8194 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/InstanceImpl.java @@ -24,6 +24,8 @@ */ public class InstanceImpl implements StructuredInstance { + private static final long serialVersionUID = 1L; + /** * The weight. */ @@ -328,7 +330,7 @@ public boolean missingOutputs() { return classIsMissing(); else { for (int i = 0; i < this.instanceHeader.numOutputAttributes(); i++) { - if (this.instanceData.isMissing(this.indexOf(outputAttribute(i)))) { + if (this.isOutputMissing(i)) { return true; } } @@ -508,11 +510,22 @@ public String outputAttributesToString() { else { String ret = "{"; for (int i = 0; i < numOutputAttributes(); i++) { - ret += String.valueOf(this.valueOutputAttribute(i)) + (i != numOutputAttributes() - 1 ? "," : ""); + ret += String.valueOf(this.valueOutputAttribute(i)) + (i != numOutputAttributes() - 1 ? "|" : ""); } ret += "}"; return ret; } } + @Override + public void setInputMissing(int inputAttributeIndex) { + this.setMissing(this.instanceHeader.getInputInstanceIndex(inputAttributeIndex)); + + } + + @Override + public void setOutputMissing(int outputAttributeIndex) { + this.setMissing(this.instanceHeader.getOutputInstanceIndex(outputAttributeIndex)); + } + } diff --git a/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/MultiTargetRegressionPrediction.java b/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/MultiTargetRegressionPrediction.java index 7023a1316..ff0543994 100644 --- a/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/MultiTargetRegressionPrediction.java +++ b/moa/src/main/java/com/yahoo/labs/samoa/instances/predictions/MultiTargetRegressionPrediction.java @@ -41,7 +41,8 @@ public MultiTargetRegressionPrediction(DoubleVector prediction) { } public MultiTargetRegressionPrediction(double[] prediction) { - this.prediction = new DoubleVector(prediction); + if (prediction != null) + this.prediction = new DoubleVector(prediction); } @@ -122,7 +123,10 @@ public double[] asDoubleArray() { } public String asPredictionString() { - return String.valueOf(prediction.toString()); + if (prediction != null) + return String.valueOf(prediction.toString().replace(",", "")); + else + return "?"; } @Override diff --git a/moa/src/main/java/moa/classifiers/AbstractEnsembleLearner.java b/moa/src/main/java/moa/classifiers/AbstractEnsembleLearner.java index 67984cfa3..22d8c759e 100644 --- a/moa/src/main/java/moa/classifiers/AbstractEnsembleLearner.java +++ b/moa/src/main/java/moa/classifiers/AbstractEnsembleLearner.java @@ -27,18 +27,29 @@ public long measureByteSize() { size += c.measureByteSize(); return size; } - + @SuppressWarnings("unchecked") @Override public void resetLearningImpl() { - this.ensemble = new ArrayList(this.ensembleSizeOption.getValue()); + this.ensemble = new ArrayList<>(this.ensembleSizeOption.getValue()); MLTask baseLearner = (MLTask) getPreparedClassOption(this.baseLearnerOption); - for (int i = 0; i < this.ensemble.size(); i++) { - this.ensemble.set(i, (MLTask) baseLearner.copy()); - this.ensemble.get(i).setRandomSeed(this.randomSeed + i * 100); + for (int i = 0; i < this.ensembleSizeOption.getValue(); i++) { + MLTask learner = (MLTask) baseLearner.copy(); + learner.setRandomSeed(this.randomSeed + i + 1); + learner.prepareForUse(); + this.ensemble.add(learner); } } - + + public void setRandomSeed(int seed) { + super.setRandomSeed(seed); + if (this.ensemble != null) + for (int i = 0; i < this.ensembleSizeOption.getValue(); i++) { + if (this.ensemble.get(i) != null) + this.ensemble.get(i).setRandomSeed(this.randomSeed + i + 1); + } + } + public abstract Prediction combinePredictions(Prediction[] predictions); public Prediction getPredictionForInstance(Instance inst) { diff --git a/moa/src/main/java/moa/classifiers/AbstractInstanceLearner.java b/moa/src/main/java/moa/classifiers/AbstractInstanceLearner.java index 723e3b831..62522c20a 100644 --- a/moa/src/main/java/moa/classifiers/AbstractInstanceLearner.java +++ b/moa/src/main/java/moa/classifiers/AbstractInstanceLearner.java @@ -57,7 +57,7 @@ public String getPurposeString() { protected double trainingWeightSeenByModel = 0.0; /** Random seed used in randomizable learners */ - protected int randomSeed = 1; + public int randomSeed = 1; /** Option for randomizable learners to change the random seed */ public IntOption randomSeedOption; @@ -127,6 +127,11 @@ public void setRandomSeed(int s) { } } + @Override + public int getRandomSeed() { + return this.randomSeed; + } + @Override public boolean trainingHasStarted() { return this.trainingWeightSeenByModel > 0.0; @@ -289,40 +294,30 @@ public String getNominalValueString(int attIndex, int valIndex) { */ public static boolean contextIsCompatible(InstancesHeader originalContext, InstancesHeader newContext) { - - if (newContext.numClasses() < originalContext.numClasses()) { - return false; // rule 1 - } - if (newContext.numAttributes() < originalContext.numAttributes()) { - return false; // rule 2 - } - int oPos = 0; - int nPos = 0; - while (oPos < originalContext.numAttributes()) { - if (oPos == originalContext.classIndex()) { - oPos++; - if (!(oPos < originalContext.numAttributes())) { - break; - } + if (newContext.numInputAttributes() < originalContext.numInputAttributes()) { + return false; // rule 2 + } + if (newContext.numOutputAttributes() < originalContext.numOutputAttributes()) { + return false; // rule 2 + } + for (int i = 0; i < originalContext.numOutputAttributes(); i++) { + if (originalContext.inputAttribute(i).attributeType() != newContext.inputAttribute(i).attributeType()) { + return false; // rule 4 } - if (nPos == newContext.classIndex()) { - nPos++; + if (newContext.outputAttribute(i).numValues() < originalContext.outputAttribute(i).numValues()) { + return false; // rule 1 + } + } + // Input attributes + for (int i = 0; i < originalContext.numInputAttributes(); i++) { + if (originalContext.inputAttribute(i).attributeType() != newContext.inputAttribute(i).attributeType()) { + return false; // rule 4 } - if (originalContext.attribute(oPos).isNominal()) { - if (!newContext.attribute(nPos).isNominal()) { - return false; // rule 4 - } - if (newContext.attribute(nPos).numValues() < originalContext.attribute(oPos).numValues()) { + else if (originalContext.inputAttribute(i).isNumeric()) { + if (newContext.inputAttribute(i).numValues() < originalContext.inputAttribute(i).numValues()) { return false; // rule 3 } - } else { - assert (originalContext.attribute(oPos).isNumeric()); - if (!newContext.attribute(nPos).isNumeric()) { - return false; // rule 4 - } } - oPos++; - nPos++; } return true; // all checks clear } diff --git a/moa/src/main/java/moa/classifiers/meta/AbstractOzaBagAdwin.java b/moa/src/main/java/moa/classifiers/meta/AbstractOzaBagAdwin.java index e20c2dfeb..30573ad0e 100644 --- a/moa/src/main/java/moa/classifiers/meta/AbstractOzaBagAdwin.java +++ b/moa/src/main/java/moa/classifiers/meta/AbstractOzaBagAdwin.java @@ -104,7 +104,7 @@ public void resetLearningImpl() { public void trainOnInstanceImpl(Instance inst) { boolean Change = false; for (int i = 0; i < this.ensemble.size(); i++) { - int k = MiscUtils.poisson(1.0, this.classifierRandom); + int k = MiscUtils.poisson(6.0, this.classifierRandom); if (k > 0) { Instance weightedInst = (Instance) inst.copy(); weightedInst.setWeight(inst.weight() * k); @@ -128,6 +128,7 @@ public void trainOnInstanceImpl(Instance inst) { } if (imax != -1) { this.ensemble.get(imax).resetLearning(); + this.ensemble.get(imax).setRandomSeed(this.ensemble.get(imax).getRandomSeed() * 2); this.ensemble.get(imax).trainOnInstance(inst); this.ADError[imax] = new ADWIN(); } diff --git a/moa/src/main/java/moa/classifiers/mlc/core/attributeclassobservers/MultiLabelBSTree.java b/moa/src/main/java/moa/classifiers/mlc/core/attributeclassobservers/MultiLabelBSTree.java index 2bd4160ea..97b2a82cd 100644 --- a/moa/src/main/java/moa/classifiers/mlc/core/attributeclassobservers/MultiLabelBSTree.java +++ b/moa/src/main/java/moa/classifiers/mlc/core/attributeclassobservers/MultiLabelBSTree.java @@ -30,24 +30,20 @@ public class MultiLabelBSTree extends AbstractOptionHandler implements NumericSt protected DoubleVector[] rightStatistics; public static double roundToSignificantFigures(double num, int n) { - final double d = Math.ceil(Math.log10(num < 0 ? -num: num)); - final int power = n - (int) d; + final double d = Math.ceil(Math.log10(num < 0 ? -num: num)); + final int power = n - (int) d; - final double magnitude = Math.pow(10, power); - final long shifted = (long) (num*magnitude); - return shifted/magnitude; + final double magnitude = Math.pow(10, power); + final long shifted = (long) (num*magnitude); + return shifted/magnitude; } - + @Override - public void observeAttribute(double inputAttributeValue, - DoubleVector[] statistics) { - if (!Double.isNaN(inputAttributeValue)) - { -// if ((long) inputAttributeValue != inputAttributeValue) -// inputAttributeValue = roundToSignificantFigures(inputAttributeValue, 4); + public void observeAttribute(double inputAttributeValue, DoubleVector[] statistics) { + if (!Double.isNaN(inputAttributeValue)) { if (this.root == null) { this.root = new Node(inputAttributeValue, statistics); - maxNodes=maxNodesOption.getValue(); + maxNodes = maxNodesOption.getValue(); } else { this.root.observeAttribute(inputAttributeValue, statistics); } @@ -57,8 +53,7 @@ public void observeAttribute(double inputAttributeValue, @Override - public AttributeExpansionSuggestion getBestEvaluatedSplitSuggestion( - MultiLabelSplitCriterion criterion, DoubleVector[] preSplitStatistics, int inputAttributeIndex) { + public AttributeExpansionSuggestion getBestEvaluatedSplitSuggestion(MultiLabelSplitCriterion criterion, DoubleVector[] preSplitStatistics, int inputAttributeIndex) { // Initialize global variables int numOutputs = preSplitStatistics.length; leftStatistics = new DoubleVector[numOutputs]; @@ -69,10 +64,13 @@ public AttributeExpansionSuggestion getBestEvaluatedSplitSuggestion( rightStatistics[i] = new DoubleVector(preSplitStatistics[i]); } - return searchForBestSplitOption(this.root, null, criterion, preSplitStatistics, inputAttributeIndex); + AttributeExpansionSuggestion out = searchForBestSplitOption(this.root, null, criterion, preSplitStatistics, inputAttributeIndex); + leftStatistics = null; + rightStatistics = null; + return out; } - protected AttributeExpansionSuggestion searchForBestSplitOption(Node currentNode, AttributeExpansionSuggestion currentBestOption, MultiLabelSplitCriterion criterion, DoubleVector [] preSplitStatistics, int inputAttributeIndex) { + protected AttributeExpansionSuggestion searchForBestSplitOption(Node currentNode, AttributeExpansionSuggestion currentBestOption, MultiLabelSplitCriterion criterion, DoubleVector[] preSplitStatistics, int inputAttributeIndex) { // Return null if the current node is null or we have finished looking through all the possible splits if (currentNode == null) { // TODO: JD check || countRightTotal == 0.0 return currentBestOption; @@ -81,7 +79,7 @@ protected AttributeExpansionSuggestion searchForBestSplitOption(Node currentNode if (currentNode.left != null) { currentBestOption = searchForBestSplitOption(currentNode.left, currentBestOption, criterion, preSplitStatistics, inputAttributeIndex); } - + for (int i=0; i currentBestOption.merit)) { + if ((!Double.isNaN(merit)) && (currentBestOption == null || (merit > currentBestOption.merit))) { currentBestOption = new AttributeExpansionSuggestion(new NumericRulePredicate(inputAttributeIndex, currentNode.cutPoint, true), Utils.copy(postSplitTargetDists), merit); } @@ -178,7 +149,7 @@ protected AttributeExpansionSuggestion searchForBestSplitOption(Node currentNode leftInputStatistics[i].subtractValues(currentNode.inputStatistics[i]); rightInputStatistics[i].addValues(currentNode.inputStatistics[i]); } - + return currentBestOption; } @@ -213,7 +184,7 @@ protected class Node implements Serializable { // E-BST statistics private DoubleVector[] targetStatistics; private DoubleVector[] inputStatistics; - + // Child nodes private Node left; @@ -225,8 +196,11 @@ public Node(double inputAttributeValue, DoubleVector[] targetStatistics, DoubleV int numInputAttributes = inputStatistics.length; this.targetStatistics = new DoubleVector[numOutputAttributes]; this.inputStatistics = new DoubleVector[numInputAttributes]; - for (int i=0; i=0.05*preSplitDist.getValue(0)) + if(postSplitDists[i].getValue(0) >= 0.05 * preSplitDist.getValue(0)) count = count +1; //Consider split if all branches have required weight seen if(count == postSplitDists.length){ @@ -82,9 +82,12 @@ protected double getMeritOfSplitForAttribute(DoubleVector preSplitDist, DoubleVe } double [] variances=getBranchSplitVarianceOutput(postSplitDists); for(int i = 0; i < variances.length; i++) - if(postSplitDists[i].getValue(0)>0) - sumVarPostSplit+=(postSplitDists[i].getValue(0)/weightTotal*variances[i]); //weight variance - merit= 1 - sumVarPostSplit / varPreSplit; + if(postSplitDists[i].getValue(0) > 0) + sumVarPostSplit += (postSplitDists[i].getValue(0)/weightTotal*variances[i]); //weight variance + if (sumVarPostSplit == 0 && varPreSplit == 0) + merit = 0; + else + merit= 1 - sumVarPostSplit / varPreSplit; } /*if(merit<0 || merit>1) System.out.println("out of range");*/ diff --git a/moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/PCTWeightedICVarianceReduction.java b/moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/PCTWeightedICVarianceReduction.java index 5efe79e7b..0f74bb7fb 100644 --- a/moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/PCTWeightedICVarianceReduction.java +++ b/moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/PCTWeightedICVarianceReduction.java @@ -4,6 +4,8 @@ public class PCTWeightedICVarianceReduction extends WeightedICVarianceReduction { + private static final long serialVersionUID = 1L; + public DoubleVector inputWeights; public double targetInputTradeoff; // \in [0, 1] @@ -19,12 +21,15 @@ public double getMeritOfSplit(DoubleVector[] preSplitTargetDist, DoubleVector[][ double inputError = 0; int numTargets=preSplitTargetDist.length; int numInputs=preSplitInputDist.length; - for (int i=0; i0) - sumVarPostSplit+=(postSplitDists[i].getValue(0)/weightTotal*variances[i]); //weight variance - merit= 1 - sumVarPostSplit / varPreSplit; + sumVarPostSplit += (postSplitDists[i].getValue(0)/weightTotal*variances[i]); //weight variance + if (varPreSplit > 0.0) + merit = 1 - sumVarPostSplit / varPreSplit; + else + merit = 0.0; } /*if(merit<0 || merit>1) System.out.println("out of range");*/ diff --git a/moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/WeightedICVarianceReduction.java b/moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/WeightedICVarianceReduction.java index 98f9d3c19..a78ffab05 100644 --- a/moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/WeightedICVarianceReduction.java +++ b/moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/WeightedICVarianceReduction.java @@ -29,6 +29,8 @@ public double getMeritOfSplit(DoubleVector[] preSplitDist, DoubleVector[][] post double error=0; int numOutputs=preSplitDist.length; for (int i=0; iAdaptive Random Forest (ARF). The 3 most important aspects of this + * ensemble classifier are: (1) inducing diversity through resampling; + * (2) inducing diversity through randomly selecting subsets of features for + * node splits (See moa.classifiers.trees.ARFHoeffdingTree.java); (3) drift + * detectors per base tree, which cause selective resets in response to drifts. + * It also allows training background trees, which start training if a warning + * is detected and replace the active tree if the warning escalates to a drift.

+ * + *

See details in:
Heitor Murilo Gomes, Albert Bifet, Jesse Read, + * Jean Paul Barddal, Fabricio Enembreck, Bernhard Pfharinger, Geoff Holmes, + * Talel Abdessalem. Adaptive random forests for evolving data stream classification. + * In Machine Learning, DOI: 10.1007/s10994-017-5642-8, Springer, 2017.

+ * + *

Parameters:

    + *
  • -l : Classifier to train. Must be set to ARFHoeffdingTree
  • + *
  • -s : The number of trees in the ensemble
  • + *
  • -o : How the number of features is interpreted (4 options): + * "Specified m (integer value)", "sqrt(M)+1", "M-(sqrt(M)+1)"
  • + *
  • -m : Number of features allowed considered for each split. Negative + * values corresponds to M - m
  • + *
  • -a : The lambda value for bagging (lambda=6 corresponds to levBag)
  • + *
  • -j : Number of threads to be used for training
  • + *
  • -x : Change detector for drifts and its parameters
  • + *
  • -p : Change detector for warnings (start training bkg learner)
  • + *
  • -w : Should use weighted voting?
  • + *
  • -u : Should use drift detection? If disabled then bkg learner is also disabled
  • + *
  • -q : Should use bkg learner? If disabled then reset tree immediately
  • + *
+ * + * @author Heitor Murilo Gomes (heitor_murilo_gomes at yahoo dot com dot br) + * @version $Revision: 1 $ + */ +public class AdaptiveRandomForestMultiTargetRegression extends AbstractMultiTargetRegressor implements MultiTargetRegressor { + + @Override + public String getPurposeString() { + return "Adaptive Random Forest algorithm for evolving data streams from Gomes et al."; + } + + private static final long serialVersionUID = 1L; + + public ClassOption treeLearnerOption = new ClassOption("treeLearner", 'l', + "Random Forest Tree.", MultiTargetRegressor.class, + "iSOUPTreeRF"); + + public IntOption ensembleSizeOption = new IntOption("ensembleSize", 's', + "The number of trees.", 10, 1, Integer.MAX_VALUE); + + public MultiChoiceOption mFeaturesModeOption = new MultiChoiceOption("mFeaturesMode", 'o', + "Defines how m, defined by mFeaturesPerTreeSize, is interpreted. M represents the total number of features.", + new String[]{"Specified m (integer value)", "sqrt(M)+1", "M-(sqrt(M)+1)", + "Percentage (M * (m / 100))"}, + new String[]{"SpecifiedM", "SqrtM1", "MSqrtM1", "Percentage"}, 1); + + public IntOption mFeaturesPerTreeSizeOption = new IntOption("mFeaturesPerTreeSize", 'm', + "Number of features allowed considered for each split. Negative values corresponds to M - m", 2, Integer.MIN_VALUE, Integer.MAX_VALUE); + + public FloatOption lambdaOption = new FloatOption("lambda", 'a', + "The lambda parameter for bagging.", 6.0, 1.0, Float.MAX_VALUE); + + public IntOption numberOfJobsOption = new IntOption("numberOfJobs", 'j', + "Total number of concurrent jobs used for processing (-1 = as much as possible, 0 = do not use multithreading)", 1, -1, Integer.MAX_VALUE); + + public ClassOption driftDetectionMethodOption = new ClassOption("driftDetectionMethod", 'x', + "Change detector for drifts and its parameters", ChangeDetector.class, "ADWINChangeDetector -a 1.0E-5"); + + public ClassOption warningDetectionMethodOption = new ClassOption("warningDetectionMethod", 'p', + "Change detector for warnings (start training bkg learner)", ChangeDetector.class, "ADWINChangeDetector -a 1.0E-4"); + + public FlagOption disableWeightedVote = new FlagOption("disableWeightedVote", 'w', + "Should use weighted voting?"); + + public FlagOption disableDriftDetectionOption = new FlagOption("disableDriftDetection", 'u', + "Should use drift detection? If disabled then bkg learner is also disabled"); + + public FlagOption disableBackgroundLearnerOption = new FlagOption("disableBackgroundLearner", 'q', + "Should use bkg learner? If disabled then reset tree immediately."); + + protected static final int FEATURES_M = 0; + protected static final int FEATURES_SQRT = 1; + protected static final int FEATURES_SQRT_INV = 2; + protected static final int FEATURES_PERCENT = 3; + + protected static final int SINGLE_THREAD = 0; + + protected ARFBaseLearnerMTR[] ensemble; + protected long instancesSeen; + protected int subspaceSize; + protected BasicClassificationPerformanceEvaluator evaluator; + + private ExecutorService executor; + + @Override + public void resetLearningImpl() { + // Reset attributes + this.ensemble = null; + this.subspaceSize = 0; + this.instancesSeen = 0; + this.evaluator = new BasicClassificationPerformanceEvaluator(); + + // Multi-threading + int numberOfJobs; + if(this.numberOfJobsOption.getValue() == -1) + numberOfJobs = Runtime.getRuntime().availableProcessors(); + else + numberOfJobs = this.numberOfJobsOption.getValue(); + // SINGLE_THREAD and requesting for only 1 thread are equivalent. + // this.executor will be null and not used... + if(numberOfJobs != AdaptiveRandomForestMultiTargetRegression.SINGLE_THREAD && numberOfJobs != 1) + this.executor = Executors.newFixedThreadPool(numberOfJobs); + } + + @Override + public void trainOnInstanceImpl(Instance instance) { + ++this.instancesSeen; + if(this.ensemble == null) + initEnsemble(instance); + + Collection trainers = new ArrayList(); + for (int i = 0 ; i < this.ensemble.length ; i++) { + DoubleVector vote = this.ensemble[i].getPredictionForInstance(instance).asDoubleVector(); + InstanceExample example = new InstanceExample(instance); + this.ensemble[i].evaluator.addResult(example, vote.getArrayRef()); + int k = MiscUtils.poisson(this.lambdaOption.getValue(), this.classifierRandom); + if (k > 0) { + if(this.executor != null) { + TrainingRunnable trainer = new TrainingRunnable(this.ensemble[i], + instance, k, this.instancesSeen); + trainers.add(trainer); + } + else { // SINGLE_THREAD is in-place... + this.ensemble[i].trainOnInstance(instance, k, this.instancesSeen); + } + } + } + if(this.executor != null) { + try { + this.executor.invokeAll(trainers); + } catch (InterruptedException ex) { + throw new RuntimeException("Could not call invokeAll() on training threads."); + } + } + } + + public Prediction getPredictionForInstance(Instance instance) { + Instance testInstance = instance.copy(); + if(this.ensemble == null) + initEnsemble(testInstance); + DoubleVector combinedVote = new DoubleVector(); + + for(int i = 0 ; i < this.ensemble.length ; ++i) { + DoubleVector vote = this.ensemble[i].getPredictionForInstance(testInstance).asDoubleVector(); + if (vote.sumOfValues() > 0.0) { + vote.normalize(); + double acc = this.ensemble[i].evaluator.getPerformanceMeasurements()[1].getValue(); + if(! this.disableWeightedVote.isSet() && acc > 0.0) { + for(int v = 0 ; v < vote.numValues() ; ++v) { + vote.setValue(v, vote.getValue(v) * acc); + } + } + combinedVote.addValues(vote); + } + } + return new MultiTargetRegressionPrediction(combinedVote); + } + + //@Override + public double[] getVotesForInstance(Instance instance) { + Instance testInstance = instance.copy(); + if(this.ensemble == null) + initEnsemble(testInstance); + DoubleVector combinedVote = new DoubleVector(); + + for(int i = 0 ; i < this.ensemble.length ; ++i) { + DoubleVector vote = new DoubleVector(this.ensemble[i].getVotesForInstance(testInstance)); + if (vote.sumOfValues() > 0.0) { + vote.normalize(); + double acc = this.ensemble[i].evaluator.getPerformanceMeasurements()[1].getValue(); + if(! this.disableWeightedVote.isSet() && acc > 0.0) { + for(int v = 0 ; v < vote.numValues() ; ++v) { + vote.setValue(v, vote.getValue(v) * acc); + } + } + combinedVote.addValues(vote); + } + } + return combinedVote.getArrayRef(); + } + + @Override + public boolean isRandomizable() { + return true; + } + + @Override + public void getModelDescription(StringBuilder arg0, int arg1) { + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + return null; + } + + protected void initEnsemble(Instance instance) { + // Init the ensemble. + int ensembleSize = this.ensembleSizeOption.getValue(); + this.ensemble = new ARFBaseLearnerMTR[ensembleSize]; + + // TODO: this should be an option with default = BasicClassificationPerformanceEvaluator +// BasicClassificationPerformanceEvaluator classificationEvaluator = (BasicClassificationPerformanceEvaluator) getPreparedClassOption(this.evaluatorOption); + BasicClassificationPerformanceEvaluator classificationEvaluator = new BasicClassificationPerformanceEvaluator(); + + this.subspaceSize = this.mFeaturesPerTreeSizeOption.getValue(); + + // The size of m depends on: + // 1) mFeaturesPerTreeSizeOption + // 2) mFeaturesModeOption + int n = instance.numAttributes()-1; // Ignore class label ( -1 ) + + switch(this.mFeaturesModeOption.getChosenIndex()) { + case AdaptiveRandomForestMultiTargetRegression.FEATURES_SQRT: + this.subspaceSize = (int) Math.round(Math.sqrt(n)) + 1; + break; + case AdaptiveRandomForestMultiTargetRegression.FEATURES_SQRT_INV: + this.subspaceSize = n - (int) Math.round(Math.sqrt(n) + 1); + break; + case AdaptiveRandomForestMultiTargetRegression.FEATURES_PERCENT: + // If subspaceSize is negative, then first find out the actual percent, i.e., 100% - m. + double percent = this.subspaceSize < 0 ? (100 + this.subspaceSize)/100.0 : this.subspaceSize / 100.0; + this.subspaceSize = (int) Math.round(n * percent); + break; + } + // Notice that if the selected mFeaturesModeOption was + // AdaptiveRandomForest.FEATURES_M then nothing is performed in the + // previous switch-case, still it is necessary to check (and adjusted) + // for when a negative value was used. + + // m is negative, use size(features) + -m + if(this.subspaceSize < 0) + this.subspaceSize = n + this.subspaceSize; + // Other sanity checks to avoid runtime errors. + // m <= 0 (m can be negative if this.subspace was negative and + // abs(m) > n), then use m = 1 + if(this.subspaceSize <= 0) + this.subspaceSize = 1; + // m > n, then it should use n + if(this.subspaceSize > n) + this.subspaceSize = n; + + ISOUPTreeRF treeLearner = (ISOUPTreeRF) getPreparedClassOption(this.treeLearnerOption); + treeLearner.resetLearning(); + + for(int i = 0 ; i < ensembleSize ; ++i) { + treeLearner.subspaceSize = this.subspaceSize; + this.ensemble[i] = new ARFBaseLearnerMTR( + i, + (ISOUPTreeRF) treeLearner.copy(), + (BasicClassificationPerformanceEvaluator) classificationEvaluator.copy(), + this.instancesSeen, + ! this.disableBackgroundLearnerOption.isSet(), + ! this.disableDriftDetectionOption.isSet(), + driftDetectionMethodOption, + warningDetectionMethodOption, + false); + } + } + + /** + * Inner class that represents a single tree member of the forest. + * It contains some analysis information, such as the numberOfDriftsDetected, + */ + protected final class ARFBaseLearnerMTR extends AbstractMOAObject { + public int indexOriginal; + public long createdOn; + public long lastDriftOn; + public long lastWarningOn; + public ISOUPTreeRF classifier; + public boolean isBackgroundLearner; + + // The drift and warning object parameters. + protected ClassOption driftOption; + protected ClassOption warningOption; + + // Drift and warning detection + protected ChangeDetector driftDetectionMethod; + protected ChangeDetector warningDetectionMethod; + + public boolean useBkgLearner; + public boolean useDriftDetector; + + // Bkg learner + protected ARFBaseLearnerMTR bkgLearner; + // Statistics + public BasicClassificationPerformanceEvaluator evaluator; + protected int numberOfDriftsDetected; + protected int numberOfWarningsDetected; + + private void init(int indexOriginal, ISOUPTreeRF instantiatedClassifier, BasicClassificationPerformanceEvaluator evaluatorInstantiated, + long instancesSeen, boolean useBkgLearner, boolean useDriftDetector, ClassOption driftOption, ClassOption warningOption, boolean isBackgroundLearner) { + this.indexOriginal = indexOriginal; + this.createdOn = instancesSeen; + this.lastDriftOn = 0; + this.lastWarningOn = 0; + + this.classifier = instantiatedClassifier; + this.evaluator = evaluatorInstantiated; + this.useBkgLearner = useBkgLearner; + this.useDriftDetector = useDriftDetector; + + this.numberOfDriftsDetected = 0; + this.numberOfWarningsDetected = 0; + this.isBackgroundLearner = isBackgroundLearner; + + if(this.useDriftDetector) { + this.driftOption = driftOption; + this.driftDetectionMethod = ((ChangeDetector) getPreparedClassOption(this.driftOption)).copy(); + } + + // Init Drift Detector for Warning detection. + if(this.useBkgLearner) { + this.warningOption = warningOption; + this.warningDetectionMethod = ((ChangeDetector) getPreparedClassOption(this.warningOption)).copy(); + } + } + + public ARFBaseLearnerMTR(int indexOriginal, ISOUPTreeRF instantiatedClassifier, BasicClassificationPerformanceEvaluator evaluatorInstantiated, + long instancesSeen, boolean useBkgLearner, boolean useDriftDetector, ClassOption driftOption, ClassOption warningOption, boolean isBackgroundLearner) { + init(indexOriginal, instantiatedClassifier, evaluatorInstantiated, instancesSeen, useBkgLearner, useDriftDetector, driftOption, warningOption, isBackgroundLearner); + } + + public void reset() { + if(this.useBkgLearner && this.bkgLearner != null) { + this.classifier = this.bkgLearner.classifier; + + this.driftDetectionMethod = this.bkgLearner.driftDetectionMethod; + this.warningDetectionMethod = this.bkgLearner.warningDetectionMethod; + + this.evaluator = this.bkgLearner.evaluator; + this.createdOn = this.bkgLearner.createdOn; + this.bkgLearner = null; + } + else { + this.classifier.resetLearning(); + this.createdOn = instancesSeen; + this.driftDetectionMethod = ((ChangeDetector) getPreparedClassOption(this.driftOption)).copy(); + } + this.evaluator.reset(); + } + + public void trainOnInstance(Instance instance, double weight, long instancesSeen) { + Instance weightedInstance = (Instance) instance.copy(); + weightedInstance.setWeight(instance.weight() * weight); + this.classifier.trainOnInstance(weightedInstance); + + if(this.bkgLearner != null) + this.bkgLearner.classifier.trainOnInstance(instance); + + // Should it use a drift detector? Also, is it a backgroundLearner? If so, then do not "incept" another one. + if(this.useDriftDetector && !this.isBackgroundLearner) { + // boolean correctlyClassifies = this.classifier.(instance); + // public double getAdwinError(Instance inst, int i) { + double sum = 0.0; + if (this.classifier instanceof ISOUPTree) { + double[] normalizedError = ((ISOUPTree) this.classifier).getNormalizedError(instance, this.classifier.getPredictionForInstance(instance).asDoubleArray()); + for (int j = 0; j < instance.numOutputAttributes(); j++) { + sum += normalizedError[j]; + } + } else { + Prediction prediction = this.classifier.getPredictionForInstance(instance); + for (int j = 0; j < instance.numOutputAttributes(); j++) { + sum += Math.abs(prediction.getPrediction(j) - instance.valueOutputAttribute(j)); + } + } + sum = sum / instance.numOutputAttributes(); + //return sum; + //} + // Check for warning only if useBkgLearner is active + if(this.useBkgLearner) { + // Update the warning detection method + this.warningDetectionMethod.input(sum); + // Check if there was a change + if(this.warningDetectionMethod.getChange()) { + this.lastWarningOn = instancesSeen; + this.numberOfWarningsDetected++; + // Create a new bkgTree classifier + ISOUPTreeRF bkgClassifier = (ISOUPTreeRF) this.classifier.copy(); + bkgClassifier.resetLearning(); + + // Resets the evaluator + BasicClassificationPerformanceEvaluator bkgEvaluator = (BasicClassificationPerformanceEvaluator) this.evaluator.copy(); + bkgEvaluator.reset(); + + // Create a new bkgLearner object + this.bkgLearner = new ARFBaseLearnerMTR(indexOriginal, bkgClassifier, bkgEvaluator, instancesSeen, + this.useBkgLearner, this.useDriftDetector, this.driftOption, this.warningOption, true); + + // Update the warning detection object for the current object + // (this effectively resets changes made to the object while it was still a bkg learner). + this.warningDetectionMethod = ((ChangeDetector) getPreparedClassOption(this.warningOption)).copy(); + } + } + + /*********** drift detection ***********/ + + // Update the DRIFT detection method + this.driftDetectionMethod.input(sum); + // Check if there was a change + if(this.driftDetectionMethod.getChange()) { + this.lastDriftOn = instancesSeen; + this.numberOfDriftsDetected++; + this.reset(); + } + } + } + + public Prediction getPredictionForInstance(Instance instance) { + return this.classifier.getPredictionForInstance(instance); + } + + public double[] getVotesForInstance(Instance instance) { + DoubleVector vote = new DoubleVector(this.classifier.getPredictionForInstance(instance).asDoubleArray()); + return vote.getArrayRef(); + } + + @Override + public void getDescription(StringBuilder sb, int indent) { + } + } + + /*** + * Inner class to assist with the multi-thread execution. + */ + protected class TrainingRunnable implements Runnable, Callable { + final private ARFBaseLearnerMTR learner; + final private Instance instance; + final private double weight; + final private long instancesSeen; + + public TrainingRunnable(ARFBaseLearnerMTR learner, Instance instance, + double weight, long instancesSeen) { + this.learner = learner; + this.instance = instance; + this.weight = weight; + this.instancesSeen = instancesSeen; + } + + @Override + public void run() { + learner.trainOnInstance(this.instance, this.weight, this.instancesSeen); + } + + @Override + public Integer call() throws Exception { + run(); + return 0; + } + } +} \ No newline at end of file diff --git a/moa/src/main/java/moa/classifiers/mlc/meta/OzaBagAdwinMultiTargetRegression.java b/moa/src/main/java/moa/classifiers/mlc/meta/OzaBagAdwinMultiTargetRegression.java index 76fda53b4..3ad3f21ea 100644 --- a/moa/src/main/java/moa/classifiers/mlc/meta/OzaBagAdwinMultiTargetRegression.java +++ b/moa/src/main/java/moa/classifiers/mlc/meta/OzaBagAdwinMultiTargetRegression.java @@ -25,6 +25,7 @@ import com.yahoo.labs.samoa.instances.predictions.Prediction; import moa.classifiers.meta.AbstractOzaBagAdwin; +import moa.classifiers.mtr.trees.ISOUPTree; import moa.core.DoubleVector; import moa.learners.MultiTargetRegressor; @@ -33,14 +34,22 @@ public class OzaBagAdwinMultiTargetRegression extends AbstractOzaBagAdwin acceptedSplits = new LinkedList(); - Arrays.sort(bestSplitSuggestions); // Declare a variable to determine the number of splits to be performed int numSplits = 0; @@ -324,10 +322,11 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) numSplits = 1; acceptedSplits.add(bestSplitSuggestions[0]); } else if (bestSplitSuggestions.length > 1) { // Otherwise, consider which of the splits proposed may be worth trying - + Arrays.sort(bestSplitSuggestions); // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + double numExamples = node.examplesSeen.getValue(node.examplesSeen.maxIndex()); // Use the max index (TODO for partially labeled) + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), numExamples); // Determine the top two ranked splitting suggestions AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; @@ -381,7 +380,7 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) // make two new branches leading to (empty) leaves if (numSplits > 0) { double optionFactor = numSplits * Math.pow(optionDecayFactorOption.getValue(), (double) node.getLevel()); - log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); + log(Integer.toString(node.ID) + ',' + this.examplesSeen.toString()); if (numSplits == 1) { AttributeExpansionSuggestion splitDecision = acceptedSplits.get(0); diff --git a/moa/src/main/java/moa/classifiers/mtr/trees/ISOUPTree.java b/moa/src/main/java/moa/classifiers/mtr/trees/ISOUPTree.java index 33d476674..b1ccf9312 100644 --- a/moa/src/main/java/moa/classifiers/mtr/trees/ISOUPTree.java +++ b/moa/src/main/java/moa/classifiers/mtr/trees/ISOUPTree.java @@ -1,5 +1,5 @@ /* - * FIMTDDMultilabel.java + * ISOUPTree.java * Copyright (C) 2014 Jožef Stefan Institute, Ljubljana, Slovenia * @author Aljaž Osojnik * @@ -43,11 +43,11 @@ import com.github.javacliparser.IntOption; import com.yahoo.labs.samoa.instances.Attribute; import com.yahoo.labs.samoa.instances.Instance; -import com.yahoo.labs.samoa.instances.StructuredInstance; -import com.yahoo.labs.samoa.instances.predictions.MultiLabelClassificationPrediction; +import com.yahoo.labs.samoa.instances.predictions.MultiTargetRegressionPrediction; import com.yahoo.labs.samoa.instances.predictions.Prediction; import moa.classifiers.AbstractMultiTargetRegressor; +import moa.classifiers.SemiSupervisedLearner; import moa.classifiers.mlc.core.attributeclassobservers.AttributeStatisticsObserver; import moa.classifiers.mlc.core.attributeclassobservers.MultiLabelBSTree; import moa.classifiers.mlc.core.attributeclassobservers.MultiLabelBSTreePCT; @@ -72,18 +72,21 @@ * @author Aljaž Osojnik (aljaz.osojnik@ijs.si) * @version $Revision: 1 $ */ -public class ISOUPTree extends AbstractMultiTargetRegressor implements MultiTargetRegressor { +public class ISOUPTree extends AbstractMultiTargetRegressor implements MultiTargetRegressor, SemiSupervisedLearner { private static final long serialVersionUID = 1L; public Node treeRoot; - protected double examplesSeen = 0.0; - private DoubleVector sumOfValues = new DoubleVector(); - private DoubleVector sumOfSquares = new DoubleVector(); + protected double learningWeight = 0.0; - private DoubleVector sumOfAttrValues = new DoubleVector(); - private DoubleVector sumOfAttrSquares = new DoubleVector(); + public DoubleVector examplesSeen = new DoubleVector(); + public DoubleVector sumOfValues = new DoubleVector(); + public DoubleVector sumOfSquares = new DoubleVector(); + + public DoubleVector weightOfInputs = new DoubleVector(); + public DoubleVector sumOfAttrValues = new DoubleVector(); + public DoubleVector sumOfAttrSquares = new DoubleVector(); private int numInputAttributes; private int numOutputAttributes; @@ -205,17 +208,19 @@ public abstract static class Node implements Serializable { protected boolean changeDetection = true; // The statistics for this node: - // Number of instances that have reached it - protected double examplesSeen; + // Number of instances with the given target that have reached it + public DoubleVector examplesSeen = new DoubleVector(); // Sum of y values - protected DoubleVector sumOfValues = new DoubleVector(); + public DoubleVector sumOfValues = new DoubleVector(); // Sum of squared y values - protected DoubleVector sumOfSquares = new DoubleVector(); + public DoubleVector sumOfSquares = new DoubleVector(); // Sum of y values - protected DoubleVector sumOfInputValues; + public DoubleVector weightOfInputs; + // Sum of y values + public DoubleVector sumOfInputValues; // Sum of squared y values - protected DoubleVector sumOfInputSquares; + public DoubleVector sumOfInputSquares; public Node(ISOUPTree tree) { @@ -224,19 +229,20 @@ public Node(ISOUPTree tree) { } public void copyStatistics(Node node) { - examplesSeen = node.examplesSeen; + examplesSeen = (DoubleVector) node.examplesSeen.copy(); sumOfValues = (DoubleVector) node.sumOfValues.copy(); sumOfSquares = (DoubleVector) node.sumOfSquares.copy(); if (tree.runAsPCTOption.isSet()) { + weightOfInputs = (DoubleVector) node.weightOfInputs.copy(); sumOfInputValues = (DoubleVector) node.sumOfInputValues.copy(); sumOfInputSquares = (DoubleVector) node.sumOfInputSquares.copy(); } } public long calcByteSize() { - long size = SizeOf.sizeOf(this) + SizeOf.sizeOf(sumOfSquares) + SizeOf.sizeOf(sumOfValues); + long size = SizeOf.sizeOf(this) + SizeOf.sizeOf(sumOfSquares) + SizeOf.sizeOf(sumOfValues) + SizeOf.sizeOf(examplesSeen); if (tree.runAsPCTOption.isSet()) { - size += SizeOf.sizeOf(sumOfInputSquares) + SizeOf.sizeOf(sumOfInputValues); + size += SizeOf.sizeOf(sumOfInputSquares) + SizeOf.sizeOf(sumOfInputValues) + SizeOf.sizeOf(weightOfInputs); } return size; } @@ -265,9 +271,7 @@ public void restartChangeDetection() { public void getDescription(StringBuilder sb, int i) {} - public double[] getPrediction(Instance inst) { - return null; - } + public abstract double[] getPrediction(Instance inst); public void describeSubtree(StringBuilder out, int indent) { StringUtils.appendIndented(out, indent, "Leaf"); @@ -313,6 +317,8 @@ public static class LeafNode extends Node { // Perceptron model that carries out the actual learning in each node public MultitargetPerceptron learningModel; + + public double learningWeight = 0.0; public DoubleVector errorP = new DoubleVector(); public DoubleVector errorM = new DoubleVector(); @@ -332,10 +338,12 @@ public LeafNode(ISOUPTree tree) { learningModel = tree.newLeafModel(); } initializeInputIndexes(); - examplesSeen = 0; + learningWeight = 0.0; + examplesSeen = new DoubleVector(); sumOfValues = new DoubleVector(); sumOfSquares = new DoubleVector(); if (tree.runAsPCTOption.isSet()) { + weightOfInputs = new DoubleVector(); sumOfInputValues = new DoubleVector(); sumOfInputSquares = new DoubleVector(); } @@ -369,12 +377,19 @@ public void learnFromInstance(Instance inst, double[] prediction, boolean growth double[] predictionP = tree.buildingModelTree() ? getPredictionModel(inst) : null; double[] predictionM = getPredictionTargetMean(inst); + DoubleVector[] observations = new DoubleVector[tree.numOutputAttributes]; + DoubleVector[] inputObservations = null; + + learningWeight += weight; + // number of instances passing through the node - examplesSeen += weight; + if (tree.buildingModelTree() && !inst.missingOutputs()) learningModel.updatePerceptron(inst); + for (int i = 0; i < tree.numOutputAttributes; i++) { if (!inst.isOutputMissing(i)) { double outVal = inst.valueOutputAttribute(i); + examplesSeen.addToValue(i, weight); // sum of y values sumOfValues.addToValue(i, weight * outVal); @@ -385,50 +400,25 @@ public void learnFromInstance(Instance inst, double[] prediction, boolean growth errorP.setValue(i, errorP.getValue(i) * 0.95 + Math.abs(predictionP[i] - outVal)); errorM.setValue(i, errorM.getValue(i) * 0.95 + Math.abs(predictionM[i] - outVal)); } + + observations[i] = new DoubleVector(new double[] {weight, weight * outVal, weight * outVal * outVal}); } } if (tree.runAsPCTOption.isSet()) { - for (int i = 0; i < tree.numInputAttributes; i++) { + inputObservations = new DoubleVector[tree.numInputAttributes]; + for (int i : inputIndexes) { if (!inst.isInputMissing(i)) { double inVal = inst.valueInputAttribute(i); + weightOfInputs.addToValue(i, weight); // sum of attr values sumOfInputValues.addToValue(i, weight * inVal); // sum of squared attr values sumOfInputSquares.addToValue(i, weight * inVal * inVal); - } - } - } - - - if (tree.buildingModelTree()) learningModel.updatePerceptron(inst); - - DoubleVector[] observations = new DoubleVector[tree.numOutputAttributes]; - DoubleVector[] inputObservations = null; - - for (int j = 0; j < tree.numOutputAttributes; j++) { - observations[j] = new DoubleVector(); - if (!inst.isOutputMissing(j)) { - double outVal = inst.valueOutputAttribute(j); - observations[j].setValue(0, weight); - observations[j].setValue(1, weight * outVal); - observations[j].setValue(2, weight * outVal * outVal); - } - } - - if (tree.runAsPCTOption.isSet()) { - inputObservations = new DoubleVector[tree.numInputAttributes]; - for (int j = 0; j < tree.numInputAttributes; j++) { - - inputObservations[j] = new DoubleVector(); - if (!inst.isInputMissing(j)) { - double inVal = inst.valueInputAttribute(j); - inputObservations[j].setValue(0, weight); - inputObservations[j].setValue(1, weight * inVal); - inputObservations[j].setValue(2, weight * inVal * inVal); + inputObservations[i] = new DoubleVector(new double[] {weight, weight * inVal, weight * inVal * inVal}); } } } @@ -436,7 +426,6 @@ public void learnFromInstance(Instance inst, double[] prediction, boolean growth for (int i : inputIndexes) { AttributeStatisticsObserver obs = attributeObservers.get(i); if (obs == null) { - // At this stage all nominal attributes are ignored if (inst.inputAttribute(i).isNumeric()) { obs = tree.newNumericClassObserver(); attributeObservers.set(i, obs); @@ -446,14 +435,10 @@ public void learnFromInstance(Instance inst, double[] prediction, boolean growth } } - if (obs != null ) { - if (!tree.runAsPCTOption.isSet() || !inst.inputAttribute(i).isNumeric()) { - obs.observeAttribute(inst.valueInputAttribute(i), observations); - } else { - ((MultiLabelBSTreePCT) obs).observeAttribute(inst.valueInputAttribute(i), observations, inputObservations); - } - - //obs.observeAttributeClassVector(inst.valueInputAttribute(i), getTargetVector(inst), inst.weight()); + if (!tree.runAsPCTOption.isSet() || !inst.inputAttribute(i).isNumeric()) { + obs.observeAttribute(inst.valueInputAttribute(i), observations); + } else { + ((MultiLabelBSTreePCT) obs).observeAttribute(inst.valueInputAttribute(i), observations, inputObservations); } } @@ -476,16 +461,16 @@ public AttributeExpansionSuggestion[] getBestSplitSuggestions(MultiLabelSplitCri DoubleVector[] preSplitInputStatistics = null; for (int j = 0; j < tree.numOutputAttributes; j++) { preSplitStatistics[j] = new DoubleVector(); - preSplitStatistics[j].setValue(0, examplesSeen); + preSplitStatistics[j].setValue(0, examplesSeen.getValue(j)); preSplitStatistics[j].setValue(1, sumOfValues.getValue(j)); preSplitStatistics[j].setValue(2, sumOfSquares.getValue(j)); } - + if (tree.runAsPCTOption.isSet() && tree.modelContext.inputAttribute(i).isNumeric()) { preSplitInputStatistics = new DoubleVector[tree.numInputAttributes]; for (int j = 0; j < tree.numInputAttributes; j++) { preSplitInputStatistics[j] = new DoubleVector(); - preSplitInputStatistics[j].setValue(0, examplesSeen); + preSplitInputStatistics[j].setValue(0, weightOfInputs.getValue(j)); preSplitInputStatistics[j].setValue(1, sumOfInputValues.getValue(j)); preSplitInputStatistics[j].setValue(2, sumOfInputSquares.getValue(j)); } @@ -517,8 +502,8 @@ public double[] getPredictionModel(Instance inst) { public double[] getPredictionTargetMean(Instance inst) { double[] pred = new double[tree.numOutputAttributes]; for (int i = 0; i < tree.numOutputAttributes; i++) { - if (examplesSeen > 0) { - pred[i] = sumOfValues.getValue(i) / examplesSeen; + if (examplesSeen.getValue(i) > 0) { + pred[i] = sumOfValues.getValue(i) / examplesSeen.getValue(i); } else { pred[i] = 0; } @@ -526,7 +511,7 @@ public double[] getPredictionTargetMean(Instance inst) { return pred; } - public double[] getPrediction(StructuredInstance inst) { + public double[] getPrediction(Instance inst) { if (tree.buildingModelTree()) { double[] predictionP = getPredictionModel(inst); double[] predictionM = getPredictionTargetMean(inst); @@ -551,12 +536,13 @@ public double[] getPrediction(StructuredInstance inst) { public void checkForSplit() { // If it has seen Nmin examples since it was last tested for splitting, attempt a split of this node - if (examplesSeen - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { + // TODO How does this interact with partially labeled examples + if (learningWeight - examplesSeenAtLastSplitEvaluation >= tree.gracePeriodOption.getValue()) { int index = (parent != null) ? parent.getChildIndex(this) : 0; tree.attemptToSplit(this, parent, index); // Take note of how many instances were seen when this split evaluation was made, so we know when to perform the next split evaluation - examplesSeenAtLastSplitEvaluation = examplesSeen; + examplesSeenAtLastSplitEvaluation = learningWeight; } } @@ -688,7 +674,7 @@ public static class SplitNode extends InnerNode { private static final long serialVersionUID = 1L; - protected Predicate predicate; + public Predicate predicate; /** * Create a new SplitNode @@ -731,7 +717,12 @@ public double[] getPrediction(Instance inst) { } } - public class MultitargetPerceptron { + public class MultitargetPerceptron implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; protected ISOUPTree tree; @@ -743,7 +734,10 @@ public class MultitargetPerceptron { public MultitargetPerceptron(ISOUPTree tree, MultitargetPerceptron original) { this.tree = tree; - weights = original.weights.clone(); + weights = new double[original.weights.length][original.weights[0].length]; + for (int i = 0; i < original.weights.length; i++) + for (int j = 0; j < original.weights[0].length; j++) + weights[i][j] = original.weights[i][j]; } public MultitargetPerceptron(ISOUPTree tree) { @@ -765,7 +759,6 @@ public void initializeWeights() { int numTargets = tree.numOutputAttributes; int numInputs = tree.numInputAttributes; weights = new double[numTargets][numInputs+1]; - tree.classifierRandom.setSeed(1234); for (int i = 0; i < numTargets; i++) { for (int j = 0; j < numInputs + 1; j++) { // The last index corresponds to the constant b @@ -787,7 +780,7 @@ public void updatePerceptron(Instance inst) { if (tree.learningRatioConstOption.isSet()) { learningRatio = tree.learningRatioOption.getValue(); } else { - learningRatio = learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); + learningRatio = tree.learningRatioOption.getValue() / (1 + instancesSeen * tree.learningRateDecayFactorOption.getValue()); } // Loop for compatibility with bagging methods @@ -804,7 +797,7 @@ public void updateWeights(Instance inst, double learningRatio) { double[] normalizedTarget = tree.normalizedTargetVector(inst); for (int i = 0; i < tree.numOutputAttributes; i++){ - if (normalizedTarget[i] != Double.NaN) { /* to account for missing target values */ + if (!Double.isNaN(normalizedTarget[i])) { /* to account for missing target values */ double delta = normalizedTarget[i] - normalizedPrediction[i]; for (int j = 0; j < normalizedInput.length; j++) { weights[i][j] += delta * learningRatio * normalizedInput[j]; @@ -849,9 +842,9 @@ private double[] denormalizePrediction(double[] normalizedPrediction) { double[] out = new double[normalizedPrediction.length]; if (tree.normalize()) { for (int i = 0; i < tree.numOutputAttributes; i++) { - double mean = tree.sumOfValues.getValue(i) / tree.examplesSeen; - double sd = computeSD(tree.sumOfSquares.getValue(i), tree.sumOfValues.getValue(i), tree.examplesSeen); - if (examplesSeen > 1) + double mean = tree.sumOfValues.getValue(i) / tree.examplesSeen.getValue(i); + double sd = computeSD(tree.sumOfSquares.getValue(i), tree.sumOfValues.getValue(i), tree.examplesSeen.getValue(i)); + if (examplesSeen.getValue(i) > 1) out[i] = normalizedPrediction[i] * sd + mean; else out[i] = 0; @@ -902,10 +895,16 @@ public String getPurposeString() { public void resetLearningImpl() { treeRoot = null; - examplesSeen = 0.0; + + if (this.getModelContext() != null) + checkRoot(); + + learningWeight = 0.0; + examplesSeen = new DoubleVector(); sumOfValues = new DoubleVector(); sumOfSquares = new DoubleVector(); + weightOfInputs = new DoubleVector(); sumOfAttrValues = new DoubleVector(); sumOfAttrSquares = new DoubleVector(); @@ -913,7 +912,6 @@ public void resetLearningImpl() { @Override public void modelContextSet() { - assert getModelContext() != null; this.numInputAttributes = getModelContext().numInputAttributes(); this.numOutputAttributes = getModelContext().numOutputAttributes(); loadWeights(); @@ -946,15 +944,16 @@ protected Measurement[] getModelMeasurementsImpl() { }; } - public long measureByteSize() { - return calcByteSize(); - } +// public long measureByteSize() { +// return calcByteSize(); +// } public long calcByteSize() { long size = SizeOf.sizeOf(this); if (this.treeRoot != null) { size += this.treeRoot.calcByteSize(); } + size += SizeOf.sizeOf(examplesSeen) + SizeOf.sizeOf(weightOfInputs); size += SizeOf.sizeOf(sumOfValues) + SizeOf.sizeOf(sumOfSquares); size += SizeOf.sizeOf(sumOfAttrValues) + SizeOf.sizeOf(sumOfAttrSquares); size += SizeOf.sizeOf(targetWeights); @@ -963,11 +962,7 @@ public long calcByteSize() { public Prediction getPredictionForInstance(Instance inst) { double[] predictionVector = treeRoot.getPrediction(inst); - MultiLabelClassificationPrediction prediction = new MultiLabelClassificationPrediction(this.numOutputAttributes); - for (int i = 0; i < this.numOutputAttributes; i++) { - prediction.setVote(i, 1, predictionVector[i]); - } - return prediction; + return new MultiTargetRegressionPrediction(predictionVector); } public double[] normalizedInputVector(Instance inst) { @@ -977,9 +972,9 @@ public double[] normalizedInputVector(Instance inst) { for (int j = 0; j < this.numInputAttributes; j++) { Attribute attr = inst.inputAttribute(j); double value = inst.valueInputAttribute(j); - double mean = sumOfAttrValues.getValue(j) / examplesSeen; - double sd = computeSD(sumOfAttrSquares.getValue(j), sumOfAttrValues.getValue(j), examplesSeen); - if (examplesSeen > 1 && sd > 0.00001) { + double mean = sumOfAttrValues.getValue(j) / weightOfInputs.getValue(j); + double sd = computeSD(sumOfAttrSquares.getValue(j), sumOfAttrValues.getValue(j), weightOfInputs.getValue(j)); + if (weightOfInputs.getValue(j) > 1 && sd > 0.00001) { if (attr.isNumeric()) normalizedInput[j] = (value - mean) / sd; else @@ -987,10 +982,7 @@ public double[] normalizedInputVector(Instance inst) { } else normalizedInput[j] = 0; } - if (examplesSeen > 1) - normalizedInput[this.numInputAttributes] = 1.0; // Value to be multiplied with the constant factor - else - normalizedInput[this.numInputAttributes] = 0.0; + normalizedInput[this.numInputAttributes] = 1.0; // Value to be multiplied with the constant factor } else { for (int j = 0; j < this.numInputAttributes; j++) { normalizedInput[j] = inst.valueInputAttribute(j); @@ -1005,10 +997,10 @@ public double[] normalizedTargetVector(Instance inst) { if (normalize()) { for (int i = 0; i < this.numOutputAttributes; i++) { double value = (inst.isOutputMissing(i)) ? Double.NaN : inst.valueOutputAttribute(i);; - if (value != Double.NaN) { - double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); - double average = sumOfValues.getValue(i) / examplesSeen; - if (sd > 0 && examplesSeen > 1) + if (!Double.isNaN(value)) { + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen.getValue(i)); + double average = sumOfValues.getValue(i) / examplesSeen.getValue(i); + if (sd > 0 && examplesSeen.getValue(i) > 1) out[i] = (value - average) / (sd); else out[i] = 0; @@ -1023,13 +1015,13 @@ public double[] normalizedTargetVector(Instance inst) { } public double[] normalizeTargetVector(double[] pred) { - if (normalize()) { + if (pred != null && normalize()) { double[] out = new double[pred.length]; for (int i = 0; i < pred.length; i++) { double value = pred[i]; - double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); - double average = sumOfValues.getValue(i) / examplesSeen; - if (sd > 0 && examplesSeen > 1) + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen.getValue(i)); + double average = sumOfValues.getValue(i) / examplesSeen.getValue(i); + if (sd > 0 && examplesSeen.getValue(i) > 1) out[i] = (value - average) / sd; else out[i] = 0; @@ -1039,12 +1031,12 @@ public double[] normalizeTargetVector(double[] pred) { } - public double normalizeTargetValue(StructuredInstance inst, int i) { + public double normalizeTargetValue(Instance inst, int i) { if (normalize()) { - if (examplesSeen > 1) { + if (examplesSeen.getValue(i) > 1) { double value = inst.valueOutputAttribute(i); - double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); - double average = sumOfValues.getValue(i) / examplesSeen; + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen.getValue(i)); + double average = sumOfValues.getValue(i) / examplesSeen.getValue(i); if (sd > 0) return (value - average) / sd; else @@ -1056,9 +1048,9 @@ public double normalizeTargetValue(StructuredInstance inst, int i) { public double normalizeTargetValue(double value, int i) { if (normalize()) { - if (examplesSeen > 1) { - double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen); - double average = sumOfValues.getValue(i) / examplesSeen; + if (examplesSeen.getValue(i) > 1) { + double sd = computeSD(sumOfSquares.getValue(i), sumOfValues.getValue(i), examplesSeen.getValue(i)); + double average = sumOfValues.getValue(i) / examplesSeen.getValue(i); if (sd > 0) return (value - average) / sd; else @@ -1072,9 +1064,10 @@ public double[] getNormalizedError(Instance inst, double[] prediction) { double[] normalPrediction = normalizeTargetVector(prediction); double[] normalValue = normalizedTargetVector(inst); double[] out = new double[this.numOutputAttributes]; - for (int i = 0; i < this.numOutputAttributes; i++) { - out[i] = Math.abs(normalValue[i] - normalPrediction[i]); - } + if (normalPrediction != null) + for (int i = 0; i < this.numOutputAttributes; i++) { + out[i] = Math.abs(normalValue[i] - normalPrediction[i]); + } return out; } @@ -1086,23 +1079,30 @@ public void trainOnInstanceImpl(Instance inst) { if (inst.weight() > 0) { double[] prediction = treeRoot.getPrediction(inst); - double[] normalError = getNormalizedError(inst, prediction); + //double[] normalError = getNormalizedError(inst, prediction); + double[] normalError = null; processInstance(inst, treeRoot, prediction, normalError, true, false); double weight = inst.weight(); - examplesSeen += weight; + learningWeight += weight; for (int i = 0; i < this.numOutputAttributes; i++) { - double iVal = inst.valueOutputAttribute(i); - sumOfValues.addToValue(i, weight * iVal); - sumOfSquares.addToValue(i, weight * iVal * iVal); + if (!inst.isOutputMissing(i)) { + double iVal = inst.valueOutputAttribute(i); + examplesSeen.addToValue(i, weight); + sumOfValues.addToValue(i, weight * iVal); + sumOfSquares.addToValue(i, weight * iVal * iVal); + } } for (int i = 0; i < this.numInputAttributes; i++) { - double iVal = inst.valueInputAttribute(i); - sumOfAttrValues.addToValue(i, weight * iVal); - sumOfAttrSquares.addToValue(i, weight * iVal * iVal); + if (!inst.isInputMissing(i)) { + double iVal = inst.valueInputAttribute(i); + weightOfInputs.addToValue(i, weight); + sumOfAttrValues.addToValue(i, weight * iVal); + sumOfAttrSquares.addToValue(i, weight * iVal * iVal); + } } } } @@ -1114,8 +1114,8 @@ public void processInstance(Instance inst, Node node, double[] prediction, doubl ((LeafNode) currentNode).learnFromInstance(inst, prediction, growthAllowed); break; } else { - currentNode.examplesSeen += inst.weight(); - //currentNode.sumOfAbsErrors.addValues(normalError); + // currentNode.examplesSeen += inst.weight(); + // currentNode.sumOfAbsErrors.addValues(normalError); // SplitNode iNode = (SplitNode) currentNode; // if (!inAlternate && iNode.alternateTree != null) { // boolean altTree = true; @@ -1247,12 +1247,12 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) } else { DoubleVector inputWeights = new DoubleVector(); for (int i = 0; i < numInputAttributes; i++) inputWeights.setValue(i, 1); - splitCriterion = new PCTWeightedICVarianceReduction(targetWeights, new DoubleVector(), 0.5); + splitCriterion = new PCTWeightedICVarianceReduction(targetWeights, inputWeights, 0.5); } // Using this criterion, find the best split per attribute and rank the results AttributeExpansionSuggestion[] bestSplitSuggestions = node.getBestSplitSuggestions(splitCriterion); // TODO update with split criterion option - + // Declare a variable to determine if any of the splits should be performed @@ -1264,7 +1264,8 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) Arrays.sort(bestSplitSuggestions); // Determine the Hoeffding bound value, used to select how many instances should be used to make a test decision // to feel reasonably confident that the test chosen by this sample is the same as what would be chosen using infinite examples - double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), node.examplesSeen); + double numExamples = node.learningWeight; + double hoeffdingBound = computeHoeffdingBound(1, splitConfidenceOption.getValue(), numExamples); // Determine the top two ranked splitting suggestions AttributeExpansionSuggestion bestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 1]; AttributeExpansionSuggestion secondBestSuggestion = bestSplitSuggestions[bestSplitSuggestions.length - 2]; @@ -1276,33 +1277,27 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) // Alternatively, if two or more splits are very similar or identical in terms of their splits, then a threshold limit // (default 0.05) is applied to the Hoeffding bound; if the Hoeffding bound is smaller than this limit then the two // competing attributes are equally good, and the split will be made on the one with the higher SDR value. - if ((secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue())) { - shouldSplit = true; - } + shouldSplit = (secondBestSuggestion.merit / bestSuggestion.merit < 1 - hoeffdingBound) || (hoeffdingBound < this.tieThresholdOption.getValue()); + // shouldSplit = true; + // If the splitting criterion was not met, initiate pruning of the E-BST structures in each attribute observer - else { - // TODO pruning is currently disabled - for (int i = 0; i < node.attributeObservers.size(); i++) { - AttributeStatisticsObserver obs = node.attributeObservers.get(i); - if (obs != null) { - if (getModelContext().attribute(i).isNumeric()); - //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); - if (getModelContext().attribute(i).isNominal()); - // TODO nominal class observers - } - } - } +// if (!shouldSplit) { +// // TODO pruning is currently disabled +// for (int i = 0; i < node.attributeObservers.size(); i++) { +// AttributeStatisticsObserver obs = node.attributeObservers.get(i); +// if (obs != null) { +// if (getModelContext().attribute(i).isNumeric()); +// //TODO obs.removeBadSplits(null, secondBestSuggestion.merit / bestSuggestion.merit, bestSuggestion.merit, hoeffdingBound, getModelContext().numOutputAttributes()); +// if (getModelContext().attribute(i).isNominal()); +// // TODO nominal class observers +// } +// } +// } } + + // If the splitting criterion were met, split the current node using the chosen attribute test, and - // make two new branches leading to (empty) leaves - // try { - // Thread.sleep(20000); - // } catch (InterruptedException e) { - // // TODO Auto-generated catch block - // e.printStackTrace(); - // } - if (shouldSplit) { AttributeExpansionSuggestion splitDecision = bestSplitSuggestions[bestSplitSuggestions.length - 1]; @@ -1310,14 +1305,21 @@ protected void attemptToSplit(LeafNode node, InnerNode parent, int parentIndex) newSplit.ID = node.ID; newSplit.copyStatistics(node); newSplit.changeDetection = node.changeDetection; - newSplit.ID = node.ID; - log(Integer.toString(node.ID) + ',' + Integer.toString((int) this.examplesSeen)); + log(Integer.toString(node.ID) + ',' + this.examplesSeen.toString()); for (int i = 0; i < 2; i++) { // Hardcoded for 2 values (due to the use of the Predicate class) LeafNode newChild = newLeafNode(); if (buildingModelTree()) { // Copy the splitting node's perceptron to it's children newChild.learningModel = new MultitargetPerceptron(this, node.learningModel); - + newChild.errorM = (DoubleVector) node.errorM.copy(); + newChild.errorP = (DoubleVector) node.errorP.copy(); + } else { + // Retrieve the seen average from the split + for (int j = 0; j < getModelContext().numOutputAttributes(); j++) { + newChild.examplesSeen.setValue(j, splitDecision.getResultingNodeStatistics()[j][i].getValue(0)); + newChild.sumOfValues.setValue(j, splitDecision.getResultingNodeStatistics()[j][i].getValue(1)); + newChild.sumOfSquares.setValue(j, splitDecision.getResultingNodeStatistics()[j][i].getValue(2)); + } } newChild.changeDetection = node.changeDetection; newChild.setParent(newSplit); diff --git a/moa/src/main/java/moa/classifiers/mtr/trees/ISOUPTreeRF.java b/moa/src/main/java/moa/classifiers/mtr/trees/ISOUPTreeRF.java index d2d92e6c9..1ac0b1075 100644 --- a/moa/src/main/java/moa/classifiers/mtr/trees/ISOUPTreeRF.java +++ b/moa/src/main/java/moa/classifiers/mtr/trees/ISOUPTreeRF.java @@ -5,24 +5,37 @@ import com.github.javacliparser.MultiChoiceOption; +import moa.core.DoubleVector; + public class ISOUPTreeRF extends ISOUPTree { - public MultiChoiceOption radndomForestFunAttrsOption = new MultiChoiceOption( + /** + * + */ + private static final long serialVersionUID = 1L; + + public MultiChoiceOption subspaceSizeOption = new MultiChoiceOption( "randomForestFunAttr", 'z', "The function of the number of input attribtues to use in the random forest construction.", new String[]{"sqrt", "log", "percent"}, new String[]{"Square root", "Logarithm", "10% percent"}, 0); + public Integer subspaceSize = null; + public int numRFAttrs() { - switch (radndomForestFunAttrsOption.getChosenLabel()) { - case "sqrt": return (int) Math.ceil(Math.sqrt(this.getModelContext().numInputAttributes())); - case "log": return (int) Math.ceil(Math.log(this.getModelContext().numInputAttributes())) + 1; - case "percent": return (int) Math.ceil(0.1 * this.getModelContext().numInputAttributes()); + if (subspaceSize == null) { + switch (subspaceSizeOption.getChosenLabel()) { + case "sqrt": this.subspaceSize = 1 + (int) Math.ceil(Math.sqrt(this.getModelContext().numInputAttributes())); + case "log": this.subspaceSize = 1 + (int) Math.ceil(Math.log(this.getModelContext().numInputAttributes())); + case "percent": this.subspaceSize = (int) Math.ceil(0.1 * this.getModelContext().numInputAttributes()); + } } - return 0; + return this.subspaceSize; } + + @Override public List newInputIndexes() { List indexes = new Vector(); @@ -39,4 +52,21 @@ public List newInputIndexes() { return indexes.subList(0, numRFAttrs()); } + public DoubleVector getFeatureScores() { + return getNodeFeatureScore(treeRoot); + } + + public DoubleVector getNodeFeatureScore(ISOUPTree.Node node) { + if (node instanceof ISOUPTree.SplitNode) { + DoubleVector scores = new DoubleVector(new double[getModelContext().numInputAttributes()]); + for (ISOUPTree.Node child : ((ISOUPTree.SplitNode) node).children) { + scores.addValues(getNodeFeatureScore(child)); + } + scores.setValue(((ISOUPTree.SplitNode) node).predicate.getAttributeIndex(), Math.pow(0.5, node.getLevel())); + return scores; + } else { + return new DoubleVector(); + } + } + } diff --git a/moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java b/moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java index a1e24bbb6..05f8dd162 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java +++ b/moa/src/main/java/moa/classifiers/rules/core/AttributeExpansionSuggestion.java @@ -73,6 +73,9 @@ public AttributeExpansionSuggestion(Predicate predicate, DoubleVector[][] resul @Override public int compareTo(AttributeExpansionSuggestion comp) { + if (Double.isNaN(this.merit) && Double.isNaN(comp.merit)) return 0; + if (Double.isNaN(this.merit)) return -1; + if (Double.isNaN(comp.merit)) return 1; return Double.compare(this.merit, comp.merit); } diff --git a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java index fb5505ef7..3e493ba81 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NominalRulePredicate.java @@ -40,6 +40,11 @@ public boolean evaluate(StructuredInstance instance) { } + public double getAttributeValue() { + return attributeValue; + } + + @Override public void negateCondition() { isEqual=!isEqual; diff --git a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java index 8387610c0..c246d2ce7 100644 --- a/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java +++ b/moa/src/main/java/moa/classifiers/rules/core/NumericRulePredicate.java @@ -49,9 +49,9 @@ public void negateCondition() { @Override public void getDescription(StringBuilder sb, int indent) { if(isEqualOrLower) - StringUtils.appendIndented(sb, indent+1, "In" + inputAttributeIndex + " <= " + attributeValue); + StringUtils.appendIndented(sb, indent+1, inputAttributeIndex + " <= " + attributeValue); else - StringUtils.appendIndented(sb, indent+1, "In" + inputAttributeIndex + " > " + attributeValue); + StringUtils.appendIndented(sb, indent+1, inputAttributeIndex + " > " + attributeValue); } @Override public String toString(){ @@ -73,6 +73,7 @@ public boolean isEqualOrLess() { public double getAttributeValue() { return attributeValue; } + @Override public void getDescription(StringBuilder sb, int indent, InstancesHeader header) { if(isEqualOrLower) diff --git a/moa/src/main/java/moa/core/DoubleVector.java b/moa/src/main/java/moa/core/DoubleVector.java index c929911a0..9d7f94f27 100644 --- a/moa/src/main/java/moa/core/DoubleVector.java +++ b/moa/src/main/java/moa/core/DoubleVector.java @@ -43,7 +43,7 @@ public DoubleVector(double[] toCopy) { } public DoubleVector(DoubleVector toCopy) { - this(toCopy.getArrayRef()); + this(toCopy.getArrayCopy()); } public int numValues() { @@ -190,7 +190,7 @@ public void getSingleLineDescription(StringBuilder out, int numValues) { if (i > 0) { out.append("|"); } - out.append(StringUtils.doubleToString(getValue(i), 3)); + out.append(String.valueOf(this.array[i])); } out.append("}"); } diff --git a/moa/src/main/java/moa/learners/Learner.java b/moa/src/main/java/moa/learners/Learner.java index aeaa9a589..7da113f7a 100644 --- a/moa/src/main/java/moa/learners/Learner.java +++ b/moa/src/main/java/moa/learners/Learner.java @@ -52,6 +52,12 @@ public interface Learner extends MOAObject, OptionHandler, AW */ public void setRandomSeed(int s); + /** + * Gets the seed for random number generation. + */ + public int getRandomSeed(); + + /** * Gets whether training has started. * From 5e8945eaee00e4d72cf69768c7fcfe0c08d02395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Osojnik?= Date: Mon, 16 Sep 2019 15:20:20 +0200 Subject: [PATCH 33/33] Code reorganization --- moa/.classpath | 1 - .../javacliparser/AbstractClassOption.java | 390 +- .../github/javacliparser/AbstractOption.java | 195 +- .../com/github/javacliparser/ClassOption.java | 298 +- .../github/javacliparser/Configurable.java | 84 +- .../com/github/javacliparser/FileOption.java | 58 +- .../com/github/javacliparser/FlagOption.java | 82 +- .../com/github/javacliparser/FloatOption.java | 159 +- .../com/github/javacliparser/IntOption.java | 158 +- .../github/javacliparser/JavaCLIParser.java | 188 +- .../com/github/javacliparser/ListOption.java | 126 +- .../javacliparser/MultiChoiceOption.java | 175 +- .../java/com/github/javacliparser/Option.java | 130 +- .../com/github/javacliparser/Options.java | 470 +-- .../github/javacliparser/SerializeUtils.java | 117 +- .../github/javacliparser/StringOption.java | 61 +- .../com/github/javacliparser/StringUtils.java | 100 +- .../gui/ClassOptionEditComponent.java | 217 +- .../ClassOptionWithNamesEditComponent.java | 182 +- .../gui/FileOptionEditComponent.java | 117 +- .../gui/FlagOptionEditComponent.java | 43 +- .../gui/FloatOptionEditComponent.java | 144 +- .../gui/IntOptionEditComponent.java | 89 +- .../gui/ListOptionEditComponent.java | 11 +- .../gui/MultiChoiceOptionEditComponent.java | 59 +- .../gui/OptionEditComponent.java | 40 +- .../gui/OptionsConfigurationPanel.java | 398 +- .../gui/RangeOptionEditComponent.java | 10 +- .../gui/StringOptionEditComponent.java | 41 +- .../labs/samoa/instances/ArffLoader.java | 860 ++-- .../yahoo/labs/samoa/instances/Attribute.java | 536 +-- .../instances/AttributesInformation.java | 38 +- .../labs/samoa/instances/DAGStructure.java | 41 +- .../labs/samoa/instances/DenseInstance.java | 76 +- .../samoa/instances/DenseInstanceData.java | 335 +- .../instances/FeatureRelevanceResult.java | 14 +- .../instances/FilteredSparseInstance.java | 94 +- .../instances/FilteredSparseInstanceData.java | 77 +- .../yahoo/labs/samoa/instances/Instance.java | 697 ++-- .../labs/samoa/instances/InstanceData.java | 167 +- .../labs/samoa/instances/InstanceImpl.java | 976 ++--- .../samoa/instances/InstanceInformation.java | 114 +- .../labs/samoa/instances/InstancesHeader.java | 148 +- .../samoa/instances/MultiLabelInstance.java | 26 +- .../instances/MultilabelInstancesHeader.java | 22 +- .../SamoaToWekaInstanceConverter.java | 222 +- .../labs/samoa/instances/SparseInstance.java | 78 +- .../samoa/instances/SparseInstanceData.java | 638 ++- .../samoa/instances/StructuredInstance.java | 30 - .../WekaToSamoaInstanceConverter.java | 195 +- .../predictions/ClassificationPrediction.java | 66 +- .../MultiLabelClassificationPrediction.java | 95 +- .../MultiTargetRegressionPrediction.java | 88 +- .../instances/predictions/Prediction.java | 241 +- .../predictions/RegressionPrediction.java | 64 +- moa/src/main/java/moa/AbstractMOAObject.java | 88 +- moa/src/main/java/moa/DoTask.java | 390 +- moa/src/main/java/moa/MOAObject.java | 50 +- moa/src/main/java/moa/MakeObject.java | 67 +- .../java/moa/capabilities/Capabilities.java | 149 +- .../moa/capabilities/CapabilitiesHandler.java | 48 +- .../java/moa/capabilities/Capability.java | 62 +- .../capabilities/CapabilityRequirement.java | 258 +- .../capabilities/ImmutableCapabilities.java | 197 +- .../moa/classifiers/AbstractClassifier.java | 280 -- .../classifiers/AbstractEnsembleLearner.java | 96 - .../classifiers/AbstractInstanceLearner.java | 397 -- .../MultiTargetLearnerSemiSupervised.java | 41 - .../moa/classifiers/active/ALUncertainty.java | 278 -- .../moa/classifiers/bayes/NaiveBayes.java | 198 - .../bayes/NaiveBayesMultinomial.java | 270 -- .../core/AttributeSplitSuggestion.java | 66 - .../AttributeClassObserver.java | 74 - ...naryTreeNumericAttributeClassObserver.java | 184 - ...mericAttributeClassObserverRegression.java | 151 - .../FIMTDDNumericAttributeClassObserver.java | 251 -- ...GaussianNumericAttributeClassObserver.java | 176 - ...ldKhannaNumericAttributeClassObserver.java | 126 - .../NominalAttributeClassObserver.java | 177 - .../NullAttributeClassObserver.java | 80 - .../VFMLNumericAttributeClassObserver.java | 225 - .../InstanceConditionalTest.java | 76 - .../NominalAttributeBinaryTest.java | 72 - .../NumericAttributeBinaryTest.java | 91 - .../core/driftdetection/ADWIN.java | 608 --- .../AbstractChangeDetector.java | 148 - .../core/driftdetection/ChangeDetector.java | 100 - .../core/driftdetection/CusumDM.java | 116 - .../classifiers/core/driftdetection/DDM.java | 142 - .../classifiers/core/driftdetection/EDDM.java | 159 - .../core/driftdetection/EWMAChartDM.java | 131 - .../EnsembleDriftDetectionMethods.java | 144 - .../GeometricMovingAverageDM.java | 114 - .../core/driftdetection/HDDM_A_Test.java | 182 - .../core/driftdetection/HDDM_W_Test.java | 215 - .../core/driftdetection/PageHinkleyDM.java | 117 - .../classifiers/core/driftdetection/RDDM.java | 238 -- .../driftdetection/SEEDChangeDetector.java | 626 --- .../core/driftdetection/STEPD.java | 144 - .../SeqDrift1ChangeDetector.java | 510 --- .../SeqDrift2ChangeDetector.java | 595 --- .../splitcriteria/GiniSplitCriterion.java | 86 - .../splitcriteria/InfoGainSplitCriterion.java | 119 - .../VarianceReductionSplitCriterion.java | 106 - .../core/statisticaltests/Cramer.java | 744 ---- .../core/statisticaltests/KNN.java | 434 -- .../drift/DriftDetectionMethodClassifier.java | 201 - .../moa/classifiers/functions/AdaGrad.java | 190 - .../classifiers/functions/MajorityClass.java | 97 - .../moa/classifiers/functions/Perceptron.java | 159 - .../java/moa/classifiers/functions/SGD.java | 390 -- .../classifiers/functions/SGDMultiClass.java | 408 -- .../moa/classifiers/functions/SPegasos.java | 357 -- .../main/java/moa/classifiers/lazy/kNN.java | 137 - .../java/moa/classifiers/lazy/kNNwithPAW.java | 80 - .../classifiers/lazy/kNNwithPAWandADWIN.java | 111 - .../neighboursearch/DistanceFunction.java | 129 - .../neighboursearch/EuclideanDistance.java | 228 - .../lazy/neighboursearch/KDTree.java | 1129 ----- .../lazy/neighboursearch/LinearNNSearch.java | 281 -- .../NearestNeighbourSearch.java | 742 ---- .../neighboursearch/NormalizableDistance.java | 722 ---- .../neighboursearch/kdtrees/KDTreeNode.java | 186 - .../kdtrees/KDTreeNodeSplitter.java | 242 -- .../kdtrees/KMeansInpiredMethod.java | 348 -- .../kdtrees/MedianOfWidestDimension.java | 189 - .../kdtrees/MidPointOfWidestDimension.java | 156 - .../kdtrees/SlidingMidPointOfWidestSide.java | 229 - .../main/java/moa/classifiers/meta/ADACC.java | 307 -- .../main/java/moa/classifiers/meta/ADOB.java | 208 - .../classifiers/meta/AbstractOzaBagAdwin.java | 168 - .../classifiers/meta/AbstractOzaBoost.java | 147 - .../meta/AccuracyWeightedEnsemble.java | 468 --- .../meta/AdaptiveRandomForest.java | 477 --- .../meta/AdaptiveRandomForestRegressor.java | 370 -- .../main/java/moa/classifiers/meta/BOLE.java | 225 - .../main/java/moa/classifiers/meta/DACC.java | 430 -- .../meta/DynamicWeightedMajority.java | 187 - .../java/moa/classifiers/meta/LearnNSE.java | 283 -- .../moa/classifiers/meta/LeveragingBag.java | 285 -- .../classifiers/meta/LimAttClassifier.java | 539 --- .../java/moa/classifiers/meta/OCBoost.java | 189 - .../classifiers/meta/OnlineSmoothBoost.java | 149 - .../java/moa/classifiers/meta/OzaBagASHT.java | 192 - .../moa/classifiers/meta/OzaBoostAdwin.java | 280 -- .../moa/classifiers/meta/PairedLearners.java | 147 - .../main/java/moa/classifiers/meta/RCD.java | 287 -- .../meta/TemporallyAugmentedClassifier.java | 189 - .../moa/classifiers/meta/WEKAClassifier.java | 209 - .../meta/WeightedMajorityAlgorithm.java | 208 - .../moa/classifiers/mlc/MEKAClassifier.java | 194 - .../moa/classifiers/mlc/MajorityLabelset.java | 110 - .../mlc/MultilabelHoeffdingTree.java | 986 ----- .../AttributeStatisticsObserver.java | 59 - .../MultiLabelNominalAttributeObserver.java | 109 - .../splitcriteria/ICVarianceReduction.java | 114 - .../MultiLabelSplitCriterion.java | 16 - .../PCTWeightedICVarianceReduction.java | 84 - ...tiveRandomForestMultiTargetRegression.java | 511 --- .../mtr/BasicMultiTargetRegressor.java | 160 - .../mtr/functions/MultiTargetNoChange.java | 70 - .../classifiers/rules/AbstractAMRules.java | 453 -- .../classifiers/rules/RuleClassification.java | 125 - .../moa/classifiers/rules/RuleClassifier.java | 1316 ------ .../rules/RuleClassifierNBayes.java | 248 -- .../rules/core/RuleActiveLearningNode.java | 337 -- .../moa/classifiers/rules/core/Utils.java | 142 - .../AnomalinessRatioScore.java | 165 - .../core/anomalydetection/OddsRatioScore.java | 193 - ...TDDNumericAttributeClassLimitObserver.java | 114 - .../changedetection/NoChangeDetection.java | 49 - .../NumericAttributeBinaryRulePredicate.java | 179 - .../splitcriteria/AMRulesSplitCriterion.java | 12 - .../SDRSplitCriterionAMRulesNode.java | 67 - .../core/splitcriteria/VRSplitCriterion.java | 52 - .../VarianceRatioSplitCriterion.java | 79 - .../rules/driftdetection/PageHinkleyTest.java | 74 - .../featureranking/MeritFeatureRanking.java | 181 - .../WeightedMajorityFeatureRanking.java | 214 - .../functions/AMRulesRegressorFunction.java | 26 - .../rules/meta/RandomAMRulesOld.java | 208 - .../AMRulesMultiLabelClassifier.java | 96 - .../multilabel/AMRulesMultiLabelLearner.java | 572 --- .../AMRulesMultiLabelLearnerSemiSuper.java | 613 --- .../AMRulesMultiTargetRegressor.java | 104 - .../AMRulesMultiTargetRegressorSemiSuper.java | 67 - .../MultiLabelBSTreeFloat.java | 224 - .../attributeclassobservers/SingleVector.java | 204 - .../core/LearningLiteralClassification.java | 381 -- .../core/LearningLiteralRegression.java | 335 -- .../MultiTargetVarianceRatio.java | 110 - .../MultilabelInformationGain.java | 144 - .../core/voting/MultiLabelVote.java | 51 - .../RelativeMeanAbsoluteDeviationMT.java | 101 - .../RelativeRootMeanSquaredErrorMT.java | 101 - .../AdaptiveMultiTargetRegressor.java | 176 - .../MultiLabelPerceptronClassification.java | 57 - .../functions/StackedPredictor.java | 419 -- .../inputselectors/MeritThreshold.java | 85 - .../meta/MultiLabelRandomAMRules.java | 243 -- .../java/moa/classifiers/trees/ARFFIMTDD.java | 1010 ----- .../classifiers/trees/ARFHoeffdingTree.java | 188 - .../classifiers/trees/ASHoeffdingTree.java | 183 - .../trees/AdaHoeffdingOptionTree.java | 114 - .../moa/classifiers/trees/DecisionStump.java | 160 - .../main/java/moa/classifiers/trees/EFDT.java | 1615 -------- .../trees/HoeffdingAdaptiveTree.java | 521 --- .../HoeffdingAdaptiveTreeClassifLeaves.java | 189 - .../trees/HoeffdingOptionTree.java | 1219 ------ .../moa/classifiers/trees/HoeffdingTree.java | 938 ----- .../trees/HoeffdingTreeClassifLeaves.java | 190 - .../trees/LimAttHoeffdingTree.java | 196 - .../trees/RandomHoeffdingTree.java | 171 - .../moa/classifiers/trees/iadem/Iadem2.java | 2072 ---------- .../moa/classifiers/trees/iadem/Iadem3.java | 1323 ------ .../trees/iadem/Iadem3Subtree.java | 163 - .../trees/iadem/IademCommonProcedures.java | 166 - ...GaussianNumericAttributeClassObserver.java | 223 - ...ldKhannaNumericAttributeClassObserver.java | 262 -- .../iadem/IademNumericAttributeObserver.java | 62 - .../trees/iadem/IademSplitCriterion.java | 367 -- ...ademVFMLNumericAttributeClassObserver.java | 651 --- moa/src/main/java/moa/cluster/CFCluster.java | 133 +- moa/src/main/java/moa/cluster/Cluster.java | 270 +- moa/src/main/java/moa/cluster/Clustering.java | 499 ++- moa/src/main/java/moa/cluster/Miniball.java | 840 ++-- .../main/java/moa/cluster/SphereCluster.java | 133 +- .../java/moa/clusterers/ClusterGenerator.java | 370 -- moa/src/main/java/moa/clusterers/CobWeb.java | 997 ----- moa/src/main/java/moa/clusterers/KMeans.java | 202 - .../clusterers/WekaClusteringAlgorithm.java | 227 - .../clusterers/clustream/ClustreamKernel.java | 274 -- .../moa/clusterers/clustree/ClusKernel.java | 338 -- .../moa/clusterers/clustree/ClusTree.java | 879 ---- .../java/moa/clusterers/clustree/Entry.java | 464 --- .../java/moa/clusterers/clustree/Node.java | 332 -- .../moa/clusterers/clustree/util/Budget.java | 117 - .../clustree/util/SimpleBudget.java | 102 - .../clusterers/denstream/MicroCluster.java | 157 - .../java/moa/clusterers/macro/ColorArray.java | 148 - .../outliers/AbstractC/AbstractC.java | 168 - .../outliers/AbstractC/AbstractCBase.java | 213 - .../outliers/AbstractC/ISBIndex.java | 173 - .../outliers/AbstractC/MyMTree.java | 67 - .../outliers/AbstractC/StreamObj.java | 96 - .../clusterers/outliers/AbstractC/Test.java | 63 - .../outliers/Angiulli/ApproxSTORM.java | 354 -- .../outliers/Angiulli/ExactSTORM.java | 305 -- .../outliers/Angiulli/ISBIndex.java | 167 - .../clusterers/outliers/Angiulli/MyMTree.java | 65 - .../outliers/Angiulli/STORMBase.java | 160 - .../outliers/Angiulli/StreamObj.java | 96 - .../clusterers/outliers/Angiulli/Test.java | 62 - .../outliers/AnyOut/util/DataObject.java | 133 - .../outliers/AnyOut/util/DataSet.java | 273 -- .../clusterers/outliers/MCOD/ISBIndex.java | 275 -- .../moa/clusterers/outliers/MCOD/MCOD.java | 408 -- .../clusterers/outliers/MCOD/MCODBase.java | 372 -- .../outliers/MCOD/MTreeMicroClusters.java | 65 - .../outliers/MCOD/MTreeStreamObjects.java | 65 - .../outliers/MCOD/MicroCluster.java | 104 - .../clusterers/outliers/MCOD/StreamObj.java | 96 - .../moa/clusterers/outliers/MCOD/Test.java | 63 - .../outliers/MyBaseOutlierDetector.java | 476 --- .../outliers/SimpleCOD/ISBIndex.java | 262 -- .../outliers/SimpleCOD/MyMTree.java | 65 - .../outliers/SimpleCOD/SimpleCOD.java | 208 - .../outliers/SimpleCOD/SimpleCODBase.java | 319 -- .../outliers/SimpleCOD/StreamObj.java | 96 - .../clusterers/outliers/SimpleCOD/Test.java | 57 - .../moa/clusterers/outliers/TestSpeed.java | 74 - .../clusterers/streamkm/BucketManager.java | 159 - .../moa/clusterers/streamkm/MTRandom.java | 390 -- .../moa/clusterers/streamkm/StreamKM.java | 386 -- .../moa/clusterers/streamkm/TreeCoreset.java | 614 --- .../java/moa/core/AutoClassDiscovery.java | 272 +- .../main/java/moa/core/AutoExpandVector.java | 194 +- moa/src/main/java/moa/core/DoubleVector.java | 350 +- moa/src/main/java/moa/core/Example.java | 14 +- moa/src/main/java/moa/core/FastVector.java | 52 +- .../main/java/moa/core/FixedLengthList.java | 73 +- .../main/java/moa/core/GaussianEstimator.java | 183 +- moa/src/main/java/moa/core/Globals.java | 38 +- .../core/GreenwaldKhannaQuantileSummary.java | 430 +- .../moa/core/InputStreamProgressMonitor.java | 12 +- .../main/java/moa/core/InstanceExample.java | 15 +- moa/src/main/java/moa/core/Measurement.java | 147 +- moa/src/main/java/moa/core/MiscUtils.java | 75 +- .../main/java/moa/core/ObjectRepository.java | 4 +- .../main/java/moa/core/PropertiesReader.java | 129 +- .../main/java/moa/core/SerializeUtils.java | 111 +- moa/src/main/java/moa/core/SizeOf.java | 96 +- moa/src/main/java/moa/core/Statistics.java | 1993 +++++---- moa/src/main/java/moa/core/StringUtils.java | 112 +- moa/src/main/java/moa/core/TimingUtils.java | 62 +- moa/src/main/java/moa/core/Utils.java | 3679 ++++++++--------- moa/src/main/java/moa/core/WekaUtils.java | 56 +- .../core/utils/AttributeDefinitionUtil.java | 229 +- .../main/java/moa/core/utils/Converter.java | 89 +- .../moa/evaluation/ALMeasureCollection.java | 15 +- .../main/java/moa/evaluation/Accuracy.java | 35 +- ...sicClassificationPerformanceEvaluator.java | 339 -- ...BasicConceptDriftPerformanceEvaluator.java | 210 - .../BasicMultiLabelPerformanceEvaluator.java | 187 - .../BasicMultiTargetPerformanceEvaluator.java | 113 - .../BasicRegressionPerformanceEvaluator.java | 146 - moa/src/main/java/moa/evaluation/CMM.java | 920 ++--- .../java/moa/evaluation/CMM_GTAnalysis.java | 1567 ++++--- .../evaluation/ChangeDetectionMeasures.java | 41 +- .../ClassificationMeasureCollection.java | 5 +- .../moa/evaluation/EntropyCollection.java | 307 +- moa/src/main/java/moa/evaluation/F1.java | 168 +- moa/src/main/java/moa/evaluation/General.java | 291 +- .../moa/evaluation/LearningEvaluation.java | 54 +- .../moa/evaluation/MeasureCollection.java | 457 +- .../java/moa/evaluation/MembershipMatrix.java | 238 +- ...dowClassificationPerformanceEvaluator.java | 150 - .../moa/evaluation/OutlierPerformance.java | 42 +- .../moa/evaluation/RegressionAccuracy.java | 22 +- moa/src/main/java/moa/evaluation/SSQ.java | 76 +- .../main/java/moa/evaluation/Separation.java | 93 +- .../moa/evaluation/SilhouetteCoefficient.java | 224 +- .../moa/evaluation/StatisticalCollection.java | 318 +- ...dowClassificationPerformanceEvaluator.java | 102 - ...iTargetRegressionPerformanceEvaluator.java | 175 - ...nPerformanceRelativeMeasuresEvaluator.java | 213 - .../WindowRegressionPerformanceEvaluator.java | 172 - .../ALClassificationPerformanceEvaluator.java | 25 +- ...dowClassificationPerformanceEvaluator.java | 65 +- ...winClassificationPerformanceEvaluator.java | 48 +- ...asicAUCImbalancedPerformanceEvaluator.java | 28 +- ...sicClassificationPerformanceEvaluator.java | 332 ++ ...BasicConceptDriftPerformanceEvaluator.java | 191 + .../BasicMultiLabelPerformanceEvaluator.java | 179 + .../BasicMultiTargetPerformanceEvaluator.java | 107 + ...tPerformanceRelativeMeasuresEvaluator.java | 92 +- .../BasicRegressionPerformanceEvaluator.java | 130 + .../ClassificationPerformanceEvaluator.java | 4 +- ...WMAClassificationPerformanceEvaluator.java | 55 +- ...torClassificationPerformanceEvaluator.java | 77 +- .../LearningPerformanceEvaluator.java | 55 +- ...belClassificationPerformanceEvaluator.java | 10 +- ...dowClassificationPerformanceEvaluator.java | 147 + ...iTargetRegressionPerformanceEvaluator.java | 10 +- .../RegressionPerformanceEvaluator.java | 10 +- ...ndowAUCImbalancedPerformanceEvaluator.java | 311 +- ...dowClassificationPerformanceEvaluator.java | 105 + ...iTargetRegressionPerformanceEvaluator.java | 168 + ...nPerformanceRelativeMeasuresEvaluator.java | 205 + .../WindowRegressionPerformanceEvaluator.java | 162 + .../moa/evaluation/preview/LearningCurve.java | 250 +- .../preview/MeanPreviewCollection.java | 613 ++- .../java/moa/evaluation/preview/Preview.java | 17 +- .../evaluation/preview/PreviewCollection.java | 29 +- ...PreviewCollectionLearningCurveWrapper.java | 31 +- moa/src/main/java/moa/gui/ALTabPanel.java | 16 +- .../java/moa/gui/AWTInteractiveRenderer.java | 4 +- moa/src/main/java/moa/gui/AWTRenderable.java | 8 +- moa/src/main/java/moa/gui/AWTRenderer.java | 9 +- .../main/java/moa/gui/AbstractTabPanel.java | 29 +- .../main/java/moa/gui/AuxiliarTabPanel.java | 16 +- .../moa/gui/AuxiliarTaskManagerPanel.java | 923 ++--- moa/src/main/java/moa/gui/BatchCmd.java | 162 +- .../moa/gui/ClassOptionSelectionPanel.java | 274 +- ...OptionWithListenerOptionEditComponent.java | 16 +- .../ClassOptionWithNamesSelectionPanel.java | 275 +- .../java/moa/gui/ClassificationTabPanel.java | 16 +- .../java/moa/gui/ConceptDriftTabPanel.java | 16 +- ...ditableMultiChoiceOptionEditComponent.java | 21 +- .../java/moa/gui/FileExtensionFilter.java | 42 +- moa/src/main/java/moa/gui/GUI.java | 199 +- moa/src/main/java/moa/gui/GUIDefaults.java | 534 ++- moa/src/main/java/moa/gui/GUIUtils.java | 27 +- .../main/java/moa/gui/LineGraphViewPanel.java | 263 +- moa/src/main/java/moa/gui/LookAndFeel.java | 381 +- .../gui/MultiLabelClassificationTabPanel.java | 16 +- ...tiLabelClassificationTaskManagerPanel.java | 926 ++--- .../gui/MultiTargetRegressionTabPanel.java | 16 +- ...MultiTargetRegressionTaskManagerPanel.java | 903 ++-- moa/src/main/java/moa/gui/PreviewPanel.java | 338 +- .../main/java/moa/gui/PreviewTableModel.java | 58 +- .../main/java/moa/gui/RegressionTabPanel.java | 16 +- .../moa/gui/RegressionTaskManagerPanel.java | 900 ++-- .../main/java/moa/gui/ScriptingTabPanel.java | 101 +- moa/src/main/java/moa/gui/TaskLauncher.java | 7 +- .../main/java/moa/gui/TaskManagerPanel.java | 972 +++-- .../java/moa/gui/TaskTextViewerPanel.java | 1344 +++--- .../main/java/moa/gui/TextViewerPanel.java | 114 +- .../moa/gui/WEKAClassOptionEditComponent.java | 160 +- .../java/moa/gui/active/ALPreviewPanel.java | 403 +- .../moa/gui/active/ALTaskManagerPanel.java | 914 ++-- .../moa/gui/active/ALTaskTextViewerPanel.java | 383 +- .../java/moa/gui/active/MeasureOverview.java | 476 +-- .../gui/clustertab/ClusteringAlgoPanel.java | 411 +- .../gui/clustertab/ClusteringEvalPanel.java | 313 +- .../gui/clustertab/ClusteringSetupTab.java | 563 +-- .../gui/clustertab/ClusteringTabPanel.java | 158 +- .../clustertab/ClusteringVisualEvalPanel.java | 484 ++- .../gui/clustertab/ClusteringVisualTab.java | 1457 +++---- .../gui/colorGenerator/ColorGenerator.java | 12 +- .../gui/colorGenerator/HSVColorGenerator.java | 74 +- .../gui/conceptdrift/CDTaskManagerPanel.java | 936 ++--- .../moa/gui/experimentertab/Algorithm.java | 283 +- .../moa/gui/experimentertab/AnalyzeTab.java | 1248 +++--- .../java/moa/gui/experimentertab/Buffer.java | 77 +- .../gui/experimentertab/ExpPreviewPanel.java | 308 +- .../gui/experimentertab/ExpTaskThread.java | 321 +- .../experimentertab/ExperimenterTabPanel.java | 79 +- .../gui/experimentertab/ExperimeterCLI.java | 622 +-- .../moa/gui/experimentertab/ImageChart.java | 397 +- .../moa/gui/experimentertab/ImagePanel.java | 235 +- .../gui/experimentertab/ImageTreePanel.java | 215 +- .../moa/gui/experimentertab/ImageViewer.java | 151 +- .../java/moa/gui/experimentertab/Measure.java | 326 +- .../java/moa/gui/experimentertab/PlotTab.java | 2573 ++++++------ .../experimentertab/PreviewExperiments.java | 50 +- .../moa/gui/experimentertab/RankingGraph.java | 976 +++-- .../moa/gui/experimentertab/ReadFile.java | 607 ++- .../java/moa/gui/experimentertab/Stream.java | 125 +- .../java/moa/gui/experimentertab/Summary.java | 1132 +++-- .../moa/gui/experimentertab/SummaryTab.java | 1090 +++-- .../moa/gui/experimentertab/SummaryTable.java | 13 +- .../gui/experimentertab/SummaryViewer.java | 193 +- .../gui/experimentertab/TaskManagerForm.java | 511 ++- .../experimentertab/TaskManagerTabPanel.java | 2555 ++++++------ .../experimentertab/TaskTextViewerPanel.java | 944 ++--- .../statisticaltests/CDF_Normal.java | 334 +- .../statisticaltests/Fichero.java | 143 +- .../PValuePerTwoAlgorithm.java | 81 +- .../statisticaltests/Pareja.java | 47 +- .../statisticaltests/RankPerAlgorithm.java | 48 +- .../statisticaltests/Relation.java | 33 +- .../statisticaltests/StatisticalTest.java | 1271 +++--- .../tasks/ConceptDriftMainTask.java | 19 +- .../tasks/EvaluateConceptDrift.java | 67 +- .../tasks/EvaluateInterleavedChunks.java | 65 +- .../EvaluateInterleavedTestThenTrain.java | 72 +- .../tasks/EvaluatePeriodicHeldOutTest.java | 68 +- .../tasks/EvaluatePrequential.java | 78 +- .../tasks/EvaluatePrequentialCV.java | 124 +- .../tasks/ExperimenterTask.java | 5 +- .../moa/gui/outliertab/OutlierAlgoPanel.java | 416 +- .../moa/gui/outliertab/OutlierEvalPanel.java | 254 +- .../moa/gui/outliertab/OutlierSetupTab.java | 582 +-- .../moa/gui/outliertab/OutlierTabPanel.java | 158 +- .../outliertab/OutlierVisualEvalPanel.java | 442 +- .../moa/gui/outliertab/OutlierVisualTab.java | 1666 ++++---- .../gui/visualization/AbstractGraphAxes.java | 424 +- .../visualization/AbstractGraphCanvas.java | 644 ++- .../gui/visualization/AbstractGraphPlot.java | 236 +- .../moa/gui/visualization/ClusterPanel.java | 356 +- .../java/moa/gui/visualization/DataPoint.java | 206 +- .../java/moa/gui/visualization/GraphAxes.java | 275 +- .../moa/gui/visualization/GraphCanvas.java | 476 +-- .../moa/gui/visualization/GraphCurve.java | 301 +- .../gui/visualization/GraphMultiCurve.java | 117 +- .../moa/gui/visualization/GraphScatter.java | 128 +- .../java/moa/gui/visualization/InfoPanel.java | 57 +- .../moa/gui/visualization/OutlierEvent.java | 62 +- .../moa/gui/visualization/OutlierPanel.java | 410 +- .../moa/gui/visualization/ParamGraphAxes.java | 53 +- .../gui/visualization/ParamGraphCanvas.java | 128 +- .../moa/gui/visualization/PointPanel.java | 521 ++- .../gui/visualization/ProcessGraphAxes.java | 42 +- .../gui/visualization/ProcessGraphCanvas.java | 28 +- .../visualization/RunOutlierVisualizer.java | 1221 +++--- .../moa/gui/visualization/RunVisualizer.java | 1108 ++--- .../gui/visualization/StreamOutlierPanel.java | 850 ++-- .../moa/gui/visualization/StreamPanel.java | 783 ++-- .../moa/gui/visualization/WekaExplorer.java | 166 +- .../moa/learners/ChangeDetectorLearner.java | 80 - .../main/java/moa/learners/Classifier.java | 63 - moa/src/main/java/moa/learners/MLTask.java | 221 +- .../moa/learners/MultiLabelClassifier.java | 51 - .../moa/learners/MultiTargetRegressor.java | 75 - .../clusterers/AbstractClusterer.java | 119 +- .../learners/clusterers/ClusterGenerator.java | 355 ++ .../{ => learners}/clusterers/Clusterer.java | 39 +- .../java/moa/learners/clusterers/CobWeb.java | 964 +++++ .../java/moa/learners/clusterers/KMeans.java | 197 + .../clusterers/WekaClusteringAlgorithm.java | 223 + .../clusterers/clustream/Clustream.java | 185 +- .../clusterers/clustream/ClustreamKernel.java | 274 ++ .../clusterers/clustream/WithKmeans.java | 246 +- .../clusterers/clustree/ClusKernel.java | 340 ++ .../clusterers/clustree/ClusTree.java | 832 ++++ .../learners/clusterers/clustree/Entry.java | 480 +++ .../learners/clusterers/clustree/Node.java | 340 ++ .../clusterers/clustree/util/Budget.java | 124 + .../clustree/util/SimpleBudget.java | 102 + .../clusterers/denstream/MicroCluster.java | 159 + .../clusterers/denstream/Timestamp.java | 46 +- .../clusterers/denstream/WithDBSCAN.java | 107 +- .../dstream/CharacteristicVector.java | 219 +- .../clusterers/dstream/DensityGrid.java | 204 +- .../clusterers/dstream/Dstream.java | 1254 +++--- .../clusterers/dstream/GridCluster.java | 270 +- .../clusterers/kmeanspm/BICO.java | 123 +- .../kmeanspm/ClusteringFeature.java | 102 +- .../kmeanspm/ClusteringTreeHeadNode.java | 95 +- .../kmeanspm/ClusteringTreeNode.java | 46 +- .../clusterers/kmeanspm/CoresetKMeans.java | 37 +- .../clusterers/kmeanspm/CuckooHashing.java | 99 +- .../kmeanspm/DietzfelbingerHash.java | 18 +- .../clusterers/kmeanspm/Metric.java | 164 +- .../macro/AbstractMacroClusterer.java | 17 +- .../learners/clusterers/macro/ColorArray.java | 124 + .../clusterers/macro/ColorObject.java | 9 +- .../clusterers/macro/IDenseMacroCluster.java | 12 +- .../clusterers/macro/IMacroClusterer.java | 10 +- .../clusterers/macro/NonConvexCluster.java | 16 +- .../clusterers/macro/dbscan/DBScan.java | 48 +- .../macro/dbscan/DenseMicroCluster.java | 36 +- .../outliers/AbstractC/AbstractC.java | 182 + .../outliers/AbstractC/AbstractCBase.java | 216 + .../outliers/AbstractC/ISBIndex.java | 170 + .../outliers/AbstractC/MyMTree.java | 66 + .../outliers/AbstractC/StreamObj.java | 96 + .../clusterers/outliers/AbstractC/Test.java | 65 + .../outliers/Angiulli/ApproxSTORM.java | 359 ++ .../outliers/Angiulli/ExactSTORM.java | 308 ++ .../outliers/Angiulli/ISBIndex.java | 165 + .../clusterers/outliers/Angiulli/MyMTree.java | 65 + .../outliers/Angiulli/STORMBase.java | 163 + .../outliers/Angiulli/StreamObj.java | 96 + .../clusterers/outliers/Angiulli/Test.java | 60 + .../clusterers/outliers/AnyOut/AnyOut.java | 143 +- .../outliers/AnyOut/AnyOutCore.java | 226 +- .../outliers/AnyOut/util/DataObject.java | 140 + .../outliers/AnyOut/util/DataSet.java | 296 ++ .../AnyOut/util/EMProjectedClustering.java | 141 +- .../AnyOut/util/EMTopDownTreeBuilder.java | 85 +- .../clusterers/outliers/MCOD/ISBIndex.java | 273 ++ .../clusterers/outliers/MCOD/MCOD.java | 464 +++ .../clusterers/outliers/MCOD/MCODBase.java | 374 ++ .../outliers/MCOD/MTreeMicroClusters.java | 66 + .../outliers/MCOD/MTreeStreamObjects.java | 65 + .../outliers/MCOD/MicroCluster.java | 104 + .../clusterers/outliers/MCOD/StreamObj.java | 96 + .../clusterers/outliers/MCOD/Test.java | 64 + .../outliers/MyBaseOutlierDetector.java | 457 ++ .../outliers/SimpleCOD/ISBIndex.java | 259 ++ .../outliers/SimpleCOD/MyMTree.java | 65 + .../outliers/SimpleCOD/SimpleCOD.java | 229 + .../outliers/SimpleCOD/SimpleCODBase.java | 321 ++ .../outliers/SimpleCOD/StreamObj.java | 96 + .../clusterers/outliers/SimpleCOD/Test.java | 55 + .../clusterers/outliers/TestSpeed.java | 73 + .../utils/mtree/ComposedSplitFunction.java | 19 +- .../utils/mtree/DistanceFunction.java | 8 +- .../utils/mtree/DistanceFunctions.java | 139 +- .../outliers/utils/mtree/MTree.java | 551 ++- .../utils/mtree/PartitionFunction.java | 26 +- .../utils/mtree/PartitionFunctions.java | 77 +- .../utils/mtree/PromotionFunction.java | 18 +- .../utils/mtree/PromotionFunctions.java | 28 +- .../outliers/utils/mtree/SplitFunction.java | 37 +- .../outliers/utils/mtree/utils/Pair.java | 33 +- .../outliers/utils/mtree/utils/Utils.java | 55 +- .../clusterers/streamkm/BucketManager.java | 157 + .../streamkm/CoresetCostTriple.java | 31 +- .../clusterers/streamkm/MTRandom.java | 410 ++ .../clusterers/streamkm/Point.java | 141 +- .../clusterers/streamkm/StreamKM.java | 365 ++ .../clusterers/streamkm/TreeCoreset.java | 613 +++ .../predictors/AbstractClassifier.java | 248 ++ .../predictors/AbstractEnsembleLearner.java | 97 + .../predictors/AbstractInstanceLearner.java | 385 ++ .../AbstractMultiLabelClassifier.java | 7 +- .../AbstractMultiTargetRegressor.java | 7 +- .../predictors}/AbstractRegressor.java | 4 +- .../predictors/ChangeDetectorLearner.java | 86 + .../moa/learners/predictors/Classifier.java | 63 + .../{ => predictors}/InstanceLearner.java | 46 +- .../LearnerSemiSupervised.java | 15 +- .../predictors/MultiLabelClassifier.java | 51 + .../predictors/MultiTargetRegressor.java | 76 + .../predictors}/OneClassClassifier.java | 29 +- .../learners/{ => predictors}/Regressor.java | 12 +- .../predictors/SemiSupervisedClassifier.java} | 29 +- .../SemiSupervisedInstanceLearner.java | 35 + .../SemiSupervisedMultiLabelClassifier.java | 31 + .../SemiSupervisedMultiTargetRegressor.java | 31 + .../predictors/SemiSupervisedRegressor.java} | 13 +- .../predictors}/active/ALClassifier.java | 21 +- .../predictors}/active/ALRandom.java | 68 +- .../predictors/active/ALUncertainty.java | 277 ++ .../active/budget/BudgetManager.java | 20 +- .../predictors}/active/budget/FixedBM.java | 30 +- .../learners/predictors/bayes/NaiveBayes.java | 198 + .../bayes/NaiveBayesMultinomial.java | 278 ++ .../core/AttributeSplitSuggestion.java | 65 + .../predictors}/core/LearningLiteral.java | 199 +- .../core/LearningLiteralClassification.java | 381 ++ .../core/LearningLiteralRegression.java | 341 ++ .../predictors}/core/Literal.java | 27 +- .../predictors}/core/MultiLabelRule.java | 155 +- .../core/MultiLabelRuleClassification.java | 14 +- .../core/MultiLabelRuleRegression.java | 11 +- .../predictors}/core/MultiLabelRuleSet.java | 8 +- .../predictors}/core/ObservableMOAObject.java | 29 +- .../predictors}/core/ObserverMOAObject.java | 4 +- .../AbstractAttributeClassObserver.java | 4 +- .../AttributeClassObserver.java | 71 + .../AttributeStatisticsObserver.java | 58 + ...naryTreeNumericAttributeClassObserver.java | 177 + ...mericAttributeClassObserverRegression.java | 151 + .../DiscreteAttributeClassObserver.java | 14 +- ...TDDNumericAttributeClassLimitObserver.java | 106 + .../FIMTDDNumericAttributeClassObserver.java | 268 ++ ...GaussianNumericAttributeClassObserver.java | 170 + ...ldKhannaNumericAttributeClassObserver.java | 122 + .../MultiLabelBSTree.java | 111 +- .../MultiLabelBSTreeFloat.java | 218 + .../MultiLabelBSTreePCT.java | 132 +- .../MultiLabelNominalAttributeObserver.java | 101 + .../NominalAttributeClassObserver.java | 166 + .../NominalStatisticsObserver.java | 3 +- .../NullAttributeClassObserver.java | 76 + .../NumericAttributeClassObserver.java | 11 +- .../NumericStatisticsObserver.java | 3 +- .../attributeclassobservers/SingleVector.java | 202 + .../VFMLNumericAttributeClassObserver.java | 212 + .../InstanceConditionalBinaryTest.java | 15 +- .../InstanceConditionalTest.java | 77 + .../NominalAttributeBinaryTest.java | 69 + .../NominalAttributeMultiwayTest.java | 65 +- .../NumericAttributeBinaryTest.java | 88 + .../predictors/core/driftdetection/ADWIN.java | 597 +++ .../driftdetection/ADWINChangeDetector.java | 65 +- .../AbstractChangeDetector.java | 153 + .../core/driftdetection/ChangeDetector.java | 102 + .../core/driftdetection/CusumDM.java | 107 + .../predictors/core/driftdetection/DDM.java | 137 + .../predictors/core/driftdetection/EDDM.java | 158 + .../core/driftdetection/EWMAChartDM.java | 130 + .../EnsembleDriftDetectionMethods.java | 136 + .../GeometricMovingAverageDM.java | 109 + .../core/driftdetection/HDDM_A_Test.java | 184 + .../core/driftdetection/HDDM_W_Test.java | 223 + .../driftdetection/NoChangeDetection.java | 45 + .../core/driftdetection/PageHinkleyDM.java | 113 + .../predictors/core/driftdetection/RDDM.java | 228 + .../driftdetection/SEEDChangeDetector.java | 536 +++ .../predictors/core/driftdetection/STEPD.java | 140 + .../SeqDrift1ChangeDetector.java | 513 +++ .../SeqDrift2ChangeDetector.java | 584 +++ .../AbstractMultiLabelErrorMeasurer.java | 55 +- .../AbstractMultiTargetErrorMeasurer.java | 16 +- .../MeanAbsoluteDeviationMT.java | 58 +- .../MultiLabelErrorMeasurer.java | 14 +- .../MultiTargetErrorMeasurer.java | 2 +- .../RelativeMeanAbsoluteDeviationMT.java | 100 + .../RelativeRootMeanSquaredErrorMT.java | 97 + .../RootMeanSquaredErrorMT.java | 59 +- .../AbstractFeatureRanking.java | 18 +- .../featureranking/BasicFeatureRanking.java | 83 +- .../core}/featureranking/FeatureRanking.java | 8 +- .../featureranking/MeritFeatureRanking.java | 164 + .../featureranking/NoFeatureRanking.java | 19 +- .../WeightedMajorityFeatureRanking.java | 199 + .../messages/ChangeDetectedMessage.java | 3 +- .../messages/FeatureRankingMessage.java | 2 +- .../messages/MeritCheckMessage.java | 17 +- .../messages/RuleExpandedMessage.java | 6 +- .../core}/functions/AMRulesFunction.java | 7 +- ...AbstractAMRulesFunctionBasicMlLearner.java | 26 +- .../AdaptiveMultiTargetRegressor.java | 175 + .../functions/DominantLabelsClassifier.java | 54 +- .../core}/functions/MultiLabelNaiveBayes.java | 30 +- .../MultiLabelPerceptronClassification.java | 57 + .../functions/MultiTargetMeanRegressor.java | 33 +- .../MultiTargetPerceptronRegressor.java | 36 +- .../core/functions/StackedPredictor.java | 405 ++ .../InputAttributesSelector.java | 8 +- .../core/inputselectors/MeritThreshold.java | 82 + .../core}/inputselectors/SelectAllInputs.java | 32 +- .../InstanceAttributesSelector.java | 55 +- .../InstanceOutputAttributesSelector.java | 55 +- .../InstanceTransformer.java | 11 +- .../NoInstanceTransformation.java | 13 +- .../outputselectors/EntropyThreshold.java | 75 +- .../OutputAttributesSelector.java | 7 +- .../outputselectors/SelectAllOutputs.java | 11 +- .../outputselectors/StdDevThreshold.java | 55 +- .../outputselectors/VarianceThreshold.java | 55 +- .../splitcriteria/GiniSplitCriterion.java | 81 + .../splitcriteria/ICVarianceReduction.java | 110 + .../splitcriteria/InfoGainSplitCriterion.java | 112 + .../InfoGainSplitCriterionMultilabel.java | 38 +- .../MultiLabelSplitCriterion.java | 14 + .../MultiTargetVarianceRatio.java | 104 + .../MultilabelInformationGain.java | 131 + .../PCTWeightedICVarianceReduction.java | 91 + .../core/splitcriteria/SDRSplitCriterion.java | 18 +- .../core/splitcriteria/SplitCriterion.java | 49 +- .../VarianceReductionSplitCriterion.java | 97 + .../WeightedICVarianceReduction.java | 29 +- .../core/statisticaltests/Cramer.java | 740 ++++ .../predictors/core/statisticaltests/KNN.java | 412 ++ .../statisticaltests/StatisticalTest.java | 35 +- .../AbstractErrorWeightedVoteMultiLabel.java | 127 +- .../voting/ErrorWeightedVoteMultiLabel.java | 93 +- .../core/voting/FirstHitVoteMultiLabel.java | 44 +- .../InverseErrorWeightedVoteMultiLabel.java | 61 +- .../core/voting/MultiLabelVote.java | 48 + .../voting/UniformWeightedVoteMultiLabel.java | 49 +- .../drift/DriftDetectionMethodClassifier.java | 204 + .../predictors/functions/AdaGrad.java | 182 + .../predictors/functions/MajorityClass.java | 99 + .../functions/MajorityLabelset.java | 110 + .../predictors}/functions/Mean.java | 10 +- .../functions/MultiTargetNoChange.java | 70 + .../predictors}/functions/NoChange.java | 70 +- .../predictors/functions/Perceptron.java | 166 + .../learners/predictors/functions/SGD.java | 383 ++ .../predictors/functions/SGDMultiClass.java | 402 ++ .../predictors/functions/SPegasos.java | 354 ++ .../predictors}/lazy/SAMkNN.java | 352 +- .../moa/learners/predictors/lazy/kNN.java | 141 + .../learners/predictors/lazy/kNNwithPAW.java | 80 + .../predictors/lazy/kNNwithPAWandADWIN.java | 111 + .../neighboursearch/DistanceFunction.java | 126 + .../neighboursearch/EuclideanDistance.java | 231 ++ .../lazy/neighboursearch/KDTree.java | 1091 +++++ .../lazy/neighboursearch/LinearNNSearch.java | 284 ++ .../NearestNeighbourSearch.java | 717 ++++ .../neighboursearch/NormalizableDistance.java | 702 ++++ .../neighboursearch/kdtrees/KDTreeNode.java | 172 + .../kdtrees/KDTreeNodeSplitter.java | 227 + .../kdtrees/KMeansInpiredMethod.java | 320 ++ .../kdtrees/MedianOfWidestDimension.java | 183 + .../kdtrees/MidPointOfWidestDimension.java | 143 + .../kdtrees/SlidingMidPointOfWidestSide.java | 211 + .../moa/learners/predictors/meta/ADACC.java | 295 ++ .../moa/learners/predictors/meta/ADOB.java | 208 + .../predictors}/meta/AbstractOzaBag.java | 58 +- .../predictors/meta/AbstractOzaBagAdwin.java | 175 + .../predictors/meta/AbstractOzaBoost.java | 154 + .../meta/AccuracyUpdatedEnsemble.java | 94 +- .../meta/AccuracyWeightedEnsemble.java | 481 +++ .../predictors/meta/AdaptiveRandomForest.java | 486 +++ .../moa/learners/predictors/meta/BOLE.java | 221 + .../moa/learners/predictors/meta/DACC.java | 430 ++ .../meta/DynamicWeightedMajority.java | 184 + .../meta/HeterogeneousEnsembleAbstract.java | 53 +- .../meta/HeterogeneousEnsembleBlast.java | 15 +- ...terogeneousEnsembleBlastFadingFactors.java | 13 +- .../learners/predictors/meta/LearnNSE.java | 276 ++ .../predictors/meta/LeveragingBag.java | 285 ++ .../predictors/meta/LimAttClassifier.java | 538 +++ .../moa/learners/predictors/meta/OCBoost.java | 200 + .../meta/OnlineAccuracyUpdatedEnsemble.java | 328 +- .../predictors/meta/OnlineSmoothBoost.java | 153 + .../learners/predictors/meta/OzaBagASHT.java | 192 + .../predictors/meta/OzaBoostAdwin.java | 277 ++ .../predictors/meta/PairedLearners.java | 147 + .../moa/learners/predictors/meta/RCD.java | 272 ++ .../predictors}/meta/RandomRules.java | 96 +- .../predictors}/meta/RegressionViaMTR.java | 19 +- .../meta/TemporallyAugmentedClassifier.java | 198 + .../predictors/meta/WEKAClassifier.java | 207 + .../meta/WeightedMajorityAlgorithm.java | 193 + .../predictors/meta/classifiers/OzaBag.java} | 19 +- .../meta/classifiers/OzaBagAdwin.java} | 13 +- .../meta/classifiers/OzaBoost.java} | 11 +- .../meta/mlc/LocalMultiLabelClassifier.java} | 141 +- .../predictors/meta/mlc/MEKAClassifier.java | 174 + .../OzaBagAdwinMultiLabelClassification.java | 46 +- .../mlc}/OzaBagMultiLabelClassification.java | 28 +- .../meta/mtr/AdaptiveRandomForest.java | 523 +++ .../meta}/mtr/LocalMultiTargetRegressor.java | 81 +- .../predictors/meta/mtr/OzaBag.java} | 28 +- .../predictors/meta/mtr/OzaBagAdwin.java} | 27 +- .../AdaptiveRandomForestRegressor.java | 376 ++ .../predictors/meta/regressors/OzaBag.java} | 16 +- .../meta/regressors/OzaBagAdwin.java} | 13 +- .../predictors}/oneclass/Autoencoder.java | 348 +- .../predictors}/oneclass/HSTreeNode.java | 140 +- .../predictors}/oneclass/HSTrees.java | 197 +- .../oneclass/NearestNeighbourDescription.java | 218 +- .../rules/AMRulesMultiLabelClassifier.java | 86 + .../rules/AMRulesMultiLabelLearner.java | 552 +++ .../AMRulesMultiLabelLearnerSemiSuper.java | 608 +++ .../rules/AMRulesMultiTargetRegressor.java | 96 + .../AMRulesMultiTargetRegressorSemiSuper.java | 71 + .../predictors}/rules/AMRulesRegressor.java | 7 +- .../rules/AMRulesRegressorOld.java | 173 +- .../predictors/rules/AbstractAMRules.java | 410 ++ .../rules/BinaryClassifierFromRegressor.java | 46 +- .../rules/MultiLabelRandomAMRules.java | 234 ++ .../predictors}/rules/Predicates.java | 70 +- .../predictors/rules/RuleClassification.java | 124 + .../predictors/rules/RuleClassifier.java | 1426 +++++++ .../rules/RuleClassifierNBayes.java | 261 ++ .../core/AttributeExpansionSuggestion.java | 67 +- .../rules/core/NominalRulePredicate.java | 53 +- .../rules/core/NumericRulePredicate.java | 56 +- .../predictors}/rules/core/Predicate.java | 27 +- .../predictors}/rules/core/Rule.java | 112 +- .../rules/core/RuleActiveLearningNode.java | 399 ++ .../rules/core/RuleActiveRegressionNode.java | 413 +- .../predictors}/rules/core/RuleSet.java | 8 +- .../predictors}/rules/core/RuleSplitNode.java | 42 +- .../learners/predictors/rules/core/Utils.java | 132 + .../AbstractAnomalyDetector.java | 5 +- .../AnomalinessRatioScore.java | 149 + .../anomalydetection/AnomalyDetector.java | 26 +- .../anomalydetection/NoAnomalyDetection.java | 37 +- .../core/anomalydetection/OddsRatioScore.java | 176 + .../CantellisInequality.java | 31 +- .../ChebyshevInequality.java | 44 +- .../probabilityfunctions/GaussInequality.java | 60 +- .../ProbabilityFunction.java | 2 +- .../NominalAttributeBinaryRulePredicate.java | 48 +- .../NumericAttributeBinaryRulePredicate.java | 165 + .../splitcriteria/AMRulesSplitCriterion.java | 14 + .../SDRSplitCriterionAMRules.java | 40 +- .../SDRSplitCriterionAMRulesNode.java | 64 + .../core/splitcriteria/VRSplitCriterion.java | 49 + .../VarianceRatioSplitCriterion.java | 73 + .../voting/AbstractErrorWeightedVote.java | 47 +- .../rules/core/voting/ErrorWeightedVote.java | 65 +- .../core/voting/ExpNegErrorWeightedVote.java | 68 +- .../core/voting/InverseErrorWeightedVote.java | 79 +- .../core/voting/MinErrorWeightedVote.java | 43 +- .../voting/OneMinusErrorWeightedVote.java | 47 +- .../core/voting/UniformWeightedVote.java | 35 +- .../predictors}/rules/core/voting/Vote.java | 47 +- .../driftdetection/PageHinkleyFading.java | 46 +- .../rules/driftdetection/PageHinkleyTest.java | 74 + .../errormeasurers/ErrorMeasurement.java | 27 +- .../errormeasurers/MeanAbsoluteDeviation.java | 18 +- .../errormeasurers/RootMeanSquaredError.java | 24 +- .../functions/AMRulesClassifierFunction.java | 2 +- .../rules/functions/AMRulesLearner.java | 8 +- .../functions/AdaptiveNodePredictor.java | 41 +- .../rules/functions/FadingTargetMean.java | 27 +- .../functions/LowPassFilteredLearner.java | 58 +- .../rules/functions/Perceptron.java | 281 +- .../rules/functions/TargetMean.java | 97 +- .../predictors}/rules/meta/RandomAMRules.java | 13 +- .../rules/meta/RandomAMRulesOld.java | 204 + .../learners/predictors/trees/ARFFIMTDD.java | 1049 +++++ .../predictors/trees/ARFHoeffdingTree.java | 189 + .../predictors/trees/ASHoeffdingTree.java | 184 + .../trees/AdaHoeffdingOptionTree.java | 115 + .../predictors/trees/DecisionStump.java | 157 + .../moa/learners/predictors/trees/EFDT.java | 1536 +++++++ .../predictors}/trees/FIMTDD.java | 402 +- .../trees/HoeffdingAdaptiveTree.java | 514 +++ .../HoeffdingAdaptiveTreeClassifLeaves.java | 185 + .../predictors/trees/HoeffdingOptionTree.java | 1157 ++++++ .../predictors/trees/HoeffdingTree.java | 888 ++++ .../trees/HoeffdingTreeClassifLeaves.java | 189 + .../predictors}/trees/ISOUPOptionTree.java | 232 +- .../predictors}/trees/ISOUPTree.java | 596 +-- .../predictors}/trees/ISOUPTreeRF.java | 40 +- .../predictors/trees/LimAttHoeffdingTree.java | 196 + .../trees/MultilabelHoeffdingTree.java | 919 ++++ .../predictors}/trees/ORTO.java | 220 +- .../predictors/trees/RandomHoeffdingTree.java | 168 + .../predictors/trees/iadem/Iadem2.java | 1900 +++++++++ .../predictors/trees/iadem/Iadem3.java | 1151 ++++++ .../predictors/trees/iadem/Iadem3Subtree.java | 158 + .../iadem/IademAttributeSplitSuggestion.java | 34 +- .../trees/iadem/IademCommonProcedures.java | 161 + .../trees/iadem/IademException.java | 41 +- ...GaussianNumericAttributeClassObserver.java | 219 + ...ldKhannaNumericAttributeClassObserver.java | 261 ++ .../IademGreenwaldKhannaQuantileSummary.java | 38 +- .../IademNominalAttributeBinaryTest.java | 27 +- .../IademNominalAttributeMultiwayTest.java | 30 +- .../IademNumericAttributeBinaryTest.java | 24 +- .../iadem/IademNumericAttributeObserver.java | 60 + .../trees/iadem/IademSplitCriterion.java | 359 ++ ...ademVFMLNumericAttributeClassObserver.java | 632 +++ .../java/moa/options/AbstractClassOption.java | 388 +- .../moa/options/AbstractOptionHandler.java | 284 +- .../main/java/moa/options/ClassOption.java | 247 +- .../ClassOptionWithListenerOption.java | 61 +- .../moa/options/ClassOptionWithNames.java | 262 +- .../moa/options/DependentOptionsUpdater.java | 142 +- .../options/EditableMultiChoiceOption.java | 70 +- .../main/java/moa/options/OptionHandler.java | 80 +- .../main/java/moa/options/OptionsHandler.java | 291 +- .../RequiredOptionNotSpecifiedException.java | 1 - .../java/moa/options/WEKAClassOption.java | 70 +- .../recommender/data/MemRecommenderData.java | 40 +- .../moa/recommender/data/RecommenderData.java | 8 +- .../java/moa/recommender/dataset/Dataset.java | 18 +- .../dataset/impl/FlixsterDataset.java | 173 +- .../dataset/impl/JesterDataset.java | 172 +- .../dataset/impl/MovielensDataset.java | 166 +- .../predictor/BRISMFPredictor.java | 161 +- .../predictor/BaselinePredictor.java | 78 +- .../predictor/RatingPredictor.java | 25 +- .../rc/data/AbstractRecommenderData.java | 179 +- .../recommender/rc/data/RecommenderData.java | 90 +- .../rc/data/impl/MemRecommenderData.java | 641 ++- .../rc/predictor/RatingPredictor.java | 15 +- .../rc/predictor/impl/BRISMFPredictor.java | 793 ++-- .../rc/predictor/impl/BaselinePredictor.java | 71 +- .../moa/recommender/rc/utils/DenseVector.java | 149 +- .../java/moa/recommender/rc/utils/Hash.java | 22 +- .../java/moa/recommender/rc/utils/Pair.java | 68 +- .../java/moa/recommender/rc/utils/Rating.java | 22 +- .../recommender/rc/utils/SparseVector.java | 141 +- .../moa/recommender/rc/utils/Updatable.java | 21 +- .../java/moa/recommender/rc/utils/Vector.java | 85 +- .../main/java/moa/streams/ArffFileStream.java | 297 +- .../java/moa/streams/BootstrappedStream.java | 77 +- .../moa/streams/CachedInstancesStream.java | 25 +- .../moa/streams/ConceptDriftRealStream.java | 338 +- .../java/moa/streams/ConceptDriftStream.java | 220 +- .../main/java/moa/streams/ExampleStream.java | 93 +- .../main/java/moa/streams/FilteredStream.java | 154 +- .../java/moa/streams/ImbalancedStream.java | 257 +- .../main/java/moa/streams/InstanceStream.java | 8 +- .../IrrelevantFeatureAppenderStream.java | 311 +- .../java/moa/streams/MultiFilteredStream.java | 163 +- .../moa/streams/MultiLabelFilteredStream.java | 154 +- .../streams/MultiTargetArffFileStream.java | 13 +- .../streams/MultiTargetInstanceStream.java | 9 +- .../java/moa/streams/PartitioningStream.java | 88 +- .../streams/RecurrentConceptDriftStream.java | 139 +- .../moa/streams/clustering/ClusterEvent.java | 40 +- .../clustering/ClusterEventListener.java | 7 +- .../streams/clustering/ClusteringStream.java | 41 +- .../moa/streams/clustering/FileStream.java | 238 +- .../clustering/RandomRBFGeneratorEvents.java | 1777 ++++---- .../streams/clustering/SimpleCSVStream.java | 82 +- .../AbstractMultiLabelStreamFilter.java | 75 +- .../streams/filters/AbstractStreamFilter.java | 97 +- .../moa/streams/filters/AddNoiseFilter.java | 132 +- .../filters/MultiLabelStreamFilter.java | 12 +- .../java/moa/streams/filters/RBFFilter.java | 58 +- .../java/moa/streams/filters/ReLUFilter.java | 50 +- .../RemoveDiscreteAttributeFilter.java | 128 +- .../filters/ReplacingMissingValuesFilter.java | 212 +- .../filters/SelectAttributesFilter.java | 59 +- .../moa/streams/filters/StreamFilter.java | 22 +- .../streams/generators/AgrawalGenerator.java | 739 ++-- .../generators/AssetNegotiationGenerator.java | 682 ++- .../generators/HyperplaneGenerator.java | 299 +- .../moa/streams/generators/LEDGenerator.java | 243 +- .../streams/generators/LEDGeneratorDrift.java | 130 +- .../streams/generators/MixedGenerator.java | 293 +- .../generators/RandomRBFGenerator.java | 303 +- .../generators/RandomRBFGeneratorDrift.java | 142 +- .../generators/RandomTreeGenerator.java | 436 +- .../moa/streams/generators/SEAGenerator.java | 356 +- .../streams/generators/STAGGERGenerator.java | 345 +- .../moa/streams/generators/SineGenerator.java | 335 +- .../moa/streams/generators/TextGenerator.java | 331 +- .../streams/generators/WaveformGenerator.java | 258 +- .../generators/WaveformGeneratorDrift.java | 158 +- .../generators/cd/AbruptChangeGenerator.java | 18 +- .../cd/AbstractConceptDriftGenerator.java | 250 +- .../generators/cd/ConceptDriftGenerator.java | 2 +- .../generators/cd/GradualChangeGenerator.java | 26 +- .../generators/cd/NoChangeGenerator.java | 12 +- .../multilabel/MetaMultilabelGenerator.java | 1039 ++--- .../multilabel/MultilabelArffFileStream.java | 41 +- ...tractEvaluateInterleavedTestThenTrain.java | 332 +- .../java/moa/tasks/AbstractEvaluateModel.java | 231 +- .../tasks/AbstractEvaluatePrequential.java | 151 +- .../tasks/AbstractEvaluatePrequentialCV.java | 147 +- .../java/moa/tasks/AbstractLearnModel.java | 161 +- moa/src/main/java/moa/tasks/AbstractTask.java | 89 +- .../java/moa/tasks/CacheShuffledStream.java | 88 +- .../main/java/moa/tasks/FailedTaskReport.java | 40 +- moa/src/main/java/moa/tasks/MainTask.java | 112 +- .../java/moa/tasks/MainTaskInterface.java | 10 +- moa/src/main/java/moa/tasks/NullMonitor.java | 143 +- moa/src/main/java/moa/tasks/Plot.java | 916 ++-- .../java/moa/tasks/ResultPreviewListener.java | 21 +- .../main/java/moa/tasks/RunStreamTasks.java | 77 +- moa/src/main/java/moa/tasks/RunTasks.java | 90 +- .../java/moa/tasks/StandardTaskMonitor.java | 231 +- moa/src/main/java/moa/tasks/Task.java | 54 +- .../moa/tasks/TaskCompletionListener.java | 22 +- moa/src/main/java/moa/tasks/TaskMonitor.java | 223 +- moa/src/main/java/moa/tasks/TaskThread.java | 326 +- .../moa/tasks/auxiliar/AuxiliarMainTask.java | 20 +- .../auxiliar/EvaluateOnlineRecommender.java | 187 +- .../tasks/auxiliar/MeasureStreamSpeed.java | 65 +- .../auxiliar/WriteMultipleStreamsToARFF.java | 116 +- .../tasks/auxiliar/WriteStreamToARFFFile.java | 90 +- .../EvaluateInterleavedChunks.java | 201 +- .../EvaluateInterleavedTestThenTrain.java | 38 +- .../EvaluatePeriodicHeldOutTest.java | 447 +- .../classification/EvaluatePrequential.java | 21 +- .../classification/EvaluatePrequentialCV.java | 19 +- .../EvaluatePrequentialDelayed.java | 543 ++- .../EvaluatePrequentialDelayedCV.java | 503 ++- .../moa/tasks/classification/LearnModel.java | 31 +- .../tasks/clustering/EvaluateClustering.java | 196 +- .../EvaluateMultipleClusterings.java | 325 +- .../conceptdrift/ConceptDriftMainTask.java | 22 +- .../conceptdrift/EvaluateConceptDrift.java | 369 +- .../main/java/moa/tasks/meta/ALMainTask.java | 17 +- .../java/moa/tasks/meta/ALMultiParamTask.java | 314 +- .../tasks/meta/ALPartitionEvaluationTask.java | 162 +- .../meta/ALPrequentialEvaluationTask.java | 354 +- .../java/moa/tasks/meta/ALTaskThread.java | 127 +- .../java/moa/tasks/meta/MetaMainTask.java | 101 +- .../moa/tasks/regression/EvaluateModel.java | 32 +- .../tasks/regression/EvaluatePrequential.java | 31 +- .../regression/EvaluatePrequentialCV.java | 21 +- .../java/moa/tasks/regression/LearnModel.java | 37 +- .../tasks/regression/RegressionMainTask.java | 1 - .../EvaluateModel.java | 224 +- .../EvaluatePrequential.java | 43 +- .../multilabelclassification/LearnModel.java | 28 +- .../multitargetregression/EvaluateModel.java | 23 +- .../EvaluatePrequential.java | 37 +- ...aluatePrequentialMultiTargetSemiSuper.java | 401 -- .../EvaluatePrequentialSemiSupervised.java | 382 ++ .../multitargetregression/LearnModel.java | 29 +- .../main/java/weka/classifiers/meta/MOA.java | 139 +- moa/src/main/java/weka/core/MOAUtils.java | 144 +- .../classifiers/classification/MOA.java | 607 +-- .../java/weka/gui/MOAClassOptionEditor.java | 56 +- .../gui/clustertab/ClusteringSetupTab.form | 6 +- .../gui/clustertab/ClusteringTabPanel.form | 4 +- .../gui/clustertab/ClusteringVisualTab.form | 8 +- .../ArffLoaderAttributeSelectionTest.java | 15 +- .../ArffLoaderClassificationTest.java | 3 +- ...rffLoaderMultiLabelClassificationTest.java | 5 +- .../ArffLoaderMultiTargetRegressionTest.java | 15 +- .../instances/ArffLoaderRegressionTest.java | 15 +- .../AbstractClassifierTestCase.java | 149 - .../AbstractMultiTargetRegressorTestCase.java | 148 - .../AbstractRegressorTestCase.java | 148 - .../moa/classifiers/active/ALRandomTest.java | 74 - .../classifiers/active/ALUncertaintyTest.java | 85 - .../bayes/NaiveBayesMultinomialTest.java | 75 - .../moa/classifiers/bayes/NaiveBayesTest.java | 75 - .../DriftDetectionMethodClassifierTest.java | 75 - .../drift/SingleClassifierDriftTest.java | 76 - .../functions/MajorityClassTest.java | 75 - .../classifiers/functions/NoChangeTest.java | 76 - .../classifiers/functions/PerceptronTest.java | 75 - .../moa/classifiers/functions/SGDTest.java | 75 - .../classifiers/functions/SPegasosTest.java | 75 - .../java/moa/classifiers/meta/ADOBTest.java | 74 - .../meta/AccuracyUpdatedEnsembleTest.java | 75 - .../meta/AccuracyWeightedEnsembleTest.java | 76 - .../meta/AdaptiveRandomForestTest.java | 76 - .../java/moa/classifiers/meta/BOLETest.java | 74 - .../meta/DynamicWeightedMajorityTest.java | 73 - .../classifiers/meta/LeveragingBagTest.java | 76 - .../meta/LimAttClassifierTest.java | 75 - .../moa/classifiers/meta/OCBoostTest.java | 75 - .../OnlineAccuracyUpdatedEnsembleTest.java | 76 - .../moa/classifiers/meta/OzaBagASHTTest.java | 79 - .../meta/OzaBagAdwinClassificationTest.java | 75 - .../meta/OzaBagClassificationTest.java | 75 - .../classifiers/meta/OzaBoostAdwinTest.java | 75 - .../meta/OzaBoostClassificationTest.java | 74 - .../TemporallyAugmentedClassifierTest.java | 75 - .../classifiers/meta/WEKAClassifierTest.java | 76 - .../meta/WeightedMajorityAlgorithmTest.java | 75 - .../rules/RuleClassifierNBayesTest.java | 75 - .../classifiers/rules/RuleClassifierTest.java | 75 - .../moa/classifiers/rules/core/UtilsTest.java | 58 - ...ulesMultiTargetRegressorSemiSuperTest.java | 75 - .../voting/FirstHitVoteMultiLabelTest.java | 112 - ...nverseErrorWeightedVoteMultiLabelTest.java | 99 - .../UniformWeightedVoteMultiLabelTest.java | 105 - .../RelativeMeanAbsoluteDeviationMTTest.java | 80 - .../RelativeRootMeanSquaredErrorMTTest.java | 76 - .../InstanceOutputAttributesSelectorTest.java | 71 - .../trees/ASHoeffdingTreeTest.java | 76 - .../trees/AdaHoeffdingOptionTreeTest.java | 75 - .../classifiers/trees/DecisionStumpTest.java | 75 - .../java/moa/classifiers/trees/EFDTTest.java | 80 - .../moa/classifiers/trees/FIMTDDTest.java | 75 - .../trees/HoeffdingAdaptiveTreeTest.java | 76 - .../trees/HoeffdingOptionTreeTest.java | 76 - .../classifiers/trees/HoeffdingTreeTest.java | 80 - .../trees/LimAttHoeffdingTreeTest.java | 78 - .../java/moa/classifiers/trees/ORTOTest.java | 76 - .../trees/RandomHoeffdingTreeTest.java | 76 - .../moa/integration/SimpleClusterTest.java | 271 +- .../AbstractClassifierTestCase.java | 149 + .../AbstractInstanceLearnerTestCase.java | 176 +- .../AbstractMultiTargetRegressorTestCase.java | 150 + .../predictors/AbstractRegressorTestCase.java | 149 + .../predictors/active/ALRandomTest.java | 72 + .../predictors/active/ALUncertaintyTest.java | 83 + .../bayes/NaiveBayesMultinomialTest.java | 73 + .../predictors/bayes/NaiveBayesTest.java | 73 + .../DriftDetectionMethodClassifierTest.java | 73 + .../functions/MajorityClassTest.java | 73 + .../predictors/functions/NoChangeTest.java | 73 + .../predictors/functions/PerceptronTest.java | 73 + .../predictors/functions/SGDTest.java | 73 + .../predictors/functions/SPegasosTest.java | 73 + .../learners/predictors/meta/ADOBTest.java | 72 + .../meta/AccuracyUpdatedEnsembleTest.java | 73 + .../meta/AccuracyWeightedEnsembleTest.java | 73 + .../meta/AdaptiveRandomForestTest.java | 74 + .../learners/predictors/meta/BOLETest.java | 72 + .../meta/DynamicWeightedMajorityTest.java | 72 + .../meta/HeterogeneousEnsembleBlastTest.java | 29 +- .../predictors/meta/LeveragingBagTest.java | 73 + .../predictors/meta/LimAttClassifierTest.java | 73 + .../learners/predictors/meta/OCBoostTest.java | 73 + .../OnlineAccuracyUpdatedEnsembleTest.java | 73 + .../predictors/meta/OzaBagASHTTest.java | 77 + .../predictors/meta/OzaBoostAdwinTest.java | 73 + .../TemporallyAugmentedClassifierTest.java | 73 + .../predictors/meta/WEKAClassifierTest.java | 73 + .../meta/WeightedMajorityAlgorithmTest.java | 73 + .../meta/classifiers/OzaBagAdwinTest.java | 73 + .../meta/classifiers/OzaBagTest.java | 73 + .../meta/classifiers/OzaBoostTest.java | 73 + ...ulesMultiTargetRegressorSemiSuperTest.java | 71 + .../rules/AMRulesRegressorTest.java | 29 +- .../rules/RuleClassifierNBayesTest.java | 73 + .../predictors/rules/RuleClassifierTest.java | 73 + .../predictors/rules/core/UtilsTest.java | 61 + .../voting/FirstHitVoteMultiLabelTest.java | 114 + ...nverseErrorWeightedVoteMultiLabelTest.java | 101 + .../UniformWeightedVoteMultiLabelTest.java | 104 + .../RelativeMeanAbsoluteDeviationMTTest.java | 81 + .../RelativeRootMeanSquaredErrorMTTest.java | 80 + .../InstanceOutputAttributesSelectorTest.java | 74 + .../predictors/trees/ASHoeffdingTreeTest.java | 73 + .../trees/AdaHoeffdingOptionTreeTest.java | 73 + .../predictors/trees/DecisionStumpTest.java | 73 + .../learners/predictors/trees/EFDTTest.java | 79 + .../learners/predictors/trees/FIMTDDTest.java | 73 + .../trees/HoeffdingAdaptiveTreeTest.java | 73 + .../trees/HoeffdingOptionTreeTest.java | 73 + .../predictors/trees/HoeffdingTreeTest.java | 79 + .../trees/LimAttHoeffdingTreeTest.java | 77 + .../learners/predictors/trees/ORTOTest.java | 73 + .../trees/RandomHoeffdingTreeTest.java | 73 + .../filters/SelectAttributesFilterTest.java | 44 +- .../java/moa/test/AbstractTestHelper.java | 404 +- moa/src/test/java/moa/test/DiffUtils.java | 1308 +++--- moa/src/test/java/moa/test/FileUtils.java | 476 ++- moa/src/test/java/moa/test/MoaTestCase.java | 551 ++- moa/src/test/java/moa/test/Regression.java | 488 +-- .../test/java/moa/test/SerializedObject.java | 383 +- moa/src/test/java/moa/test/TestHelper.java | 67 +- moa/src/test/java/moa/test/TmpFile.java | 51 +- moa/src/test/java/moa/test/Utils.java | 194 +- .../drift/SingleClassifierDrift.ref | 175 - .../moa/classifiers/functions/Perceptron.ref | 145 - .../moa/classifiers/meta/OzaBagAdwin.ref | 315 -- .../classifiers/meta/OzaBagClassification.ref | 315 -- .../meta/OzaBoostClassification.ref | 315 -- .../classifiers/rules/AMRulesRegressor.ref | 185 - .../AMRulesMultiTargetRegressorSemiSuper.ref | 185 - .../predictors}/active/ALRandom.ref | 2 +- .../predictors}/active/ALUncertainty.ref | 8 +- .../predictors}/bayes/NaiveBayes.ref | 2 +- .../bayes/NaiveBayesMultinomial.ref | 2 +- .../predictors}/data/classification.arff | 0 .../predictors}/data/regression.arff | 0 .../data/small_classification.arff | 0 .../predictors}/data/small_regression.arff | 0 .../drift/DriftDetectionMethodClassifier.ref | 2 +- .../predictors}/functions/MajorityClass.ref | 2 +- .../predictors}/functions/NoChange.ref | 2 +- .../predictors/functions/Perceptron.ref | 145 + .../predictors}/functions/SGD.ref | 2 +- .../predictors}/functions/SPegasos.ref | 2 +- .../predictors}/meta/ADOB.ref | 2 +- .../meta/AccuracyUpdatedEnsemble.ref | 2 +- .../meta/AccuracyWeightedEnsemble.ref | 2 +- .../predictors}/meta/AdaptiveRandomForest.ref | 2 +- .../predictors}/meta/BOLE.ref | 2 +- .../meta/DynamicWeightedMajority.ref | 2 +- .../meta/HeterogeneousEnsembleBlast.ref | 4 +- .../predictors}/meta/LeveragingBag.ref | 2 +- .../predictors}/meta/LimAttClassifier.ref | 2 +- .../predictors}/meta/OCBoost.ref | 80 +- .../meta/OnlineAccuracyUpdatedEnsemble.ref | 2 +- .../predictors}/meta/OzaBagASHT.ref | 2 +- .../predictors}/meta/OzaBoostAdwin.ref | 2 +- .../meta/TemporallyAugmentedClassifier.ref | 2 +- .../predictors}/meta/WEKAClassifier.ref | 2 +- .../meta/WeightedMajorityAlgorithm.ref | 2 +- .../predictors/meta/classifiers}/OzaBag.ref | 122 +- .../meta/classifiers/OzaBagAdwin.ref} | 2 +- .../predictors/meta/classifiers}/OzaBoost.ref | 2 +- .../AMRulesMultiTargetRegressorSemiSuper.ref | 185 + .../predictors/rules/AMRulesRegressor.ref | 195 + .../predictors}/rules/RuleClassifier.ref | 2 +- .../rules/RuleClassifierNBayes.ref | 2 +- .../predictors}/trees/ASHoeffdingTree.ref | 2 +- .../trees/AdaHoeffdingOptionTree.ref | 2 +- .../predictors}/trees/DecisionStump.ref | 2 +- .../predictors}/trees/EFDT.ref | 4 +- .../predictors}/trees/FIMTDD.ref | 2 +- .../trees/HoeffdingAdaptiveTree.ref | 2 +- .../predictors}/trees/HoeffdingOptionTree.ref | 2 +- .../predictors}/trees/HoeffdingTree.ref | 4 +- .../predictors}/trees/LimAttHoeffdingTree.ref | 2 +- .../predictors}/trees/ORTO.ref | 2 +- .../predictors}/trees/RandomHoeffdingTree.ref | 2 +- 1206 files changed, 120425 insertions(+), 124939 deletions(-) delete mode 100644 moa/src/main/java/com/yahoo/labs/samoa/instances/StructuredInstance.java delete mode 100644 moa/src/main/java/moa/classifiers/AbstractClassifier.java delete mode 100644 moa/src/main/java/moa/classifiers/AbstractEnsembleLearner.java delete mode 100644 moa/src/main/java/moa/classifiers/AbstractInstanceLearner.java delete mode 100644 moa/src/main/java/moa/classifiers/MultiTargetLearnerSemiSupervised.java delete mode 100644 moa/src/main/java/moa/classifiers/active/ALUncertainty.java delete mode 100644 moa/src/main/java/moa/classifiers/bayes/NaiveBayes.java delete mode 100644 moa/src/main/java/moa/classifiers/bayes/NaiveBayesMultinomial.java delete mode 100644 moa/src/main/java/moa/classifiers/core/AttributeSplitSuggestion.java delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/AttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/BinaryTreeNumericAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/BinaryTreeNumericAttributeClassObserverRegression.java delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/FIMTDDNumericAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/GaussianNumericAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/GreenwaldKhannaNumericAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/NominalAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/NullAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/core/attributeclassobservers/VFMLNumericAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/core/conditionaltests/InstanceConditionalTest.java delete mode 100644 moa/src/main/java/moa/classifiers/core/conditionaltests/NominalAttributeBinaryTest.java delete mode 100644 moa/src/main/java/moa/classifiers/core/conditionaltests/NumericAttributeBinaryTest.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/ADWIN.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/AbstractChangeDetector.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/ChangeDetector.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/CusumDM.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/DDM.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/EDDM.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/EWMAChartDM.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/EnsembleDriftDetectionMethods.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/GeometricMovingAverageDM.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/HDDM_A_Test.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/HDDM_W_Test.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/PageHinkleyDM.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/RDDM.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/SEEDChangeDetector.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/STEPD.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/SeqDrift1ChangeDetector.java delete mode 100644 moa/src/main/java/moa/classifiers/core/driftdetection/SeqDrift2ChangeDetector.java delete mode 100644 moa/src/main/java/moa/classifiers/core/splitcriteria/GiniSplitCriterion.java delete mode 100644 moa/src/main/java/moa/classifiers/core/splitcriteria/InfoGainSplitCriterion.java delete mode 100644 moa/src/main/java/moa/classifiers/core/splitcriteria/VarianceReductionSplitCriterion.java delete mode 100644 moa/src/main/java/moa/classifiers/core/statisticaltests/Cramer.java delete mode 100644 moa/src/main/java/moa/classifiers/core/statisticaltests/KNN.java delete mode 100644 moa/src/main/java/moa/classifiers/drift/DriftDetectionMethodClassifier.java delete mode 100644 moa/src/main/java/moa/classifiers/functions/AdaGrad.java delete mode 100644 moa/src/main/java/moa/classifiers/functions/MajorityClass.java delete mode 100644 moa/src/main/java/moa/classifiers/functions/Perceptron.java delete mode 100644 moa/src/main/java/moa/classifiers/functions/SGD.java delete mode 100644 moa/src/main/java/moa/classifiers/functions/SGDMultiClass.java delete mode 100644 moa/src/main/java/moa/classifiers/functions/SPegasos.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/kNN.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/kNNwithPAW.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/kNNwithPAWandADWIN.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/DistanceFunction.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/EuclideanDistance.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/KDTree.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/LinearNNSearch.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/NearestNeighbourSearch.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/NormalizableDistance.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNode.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/MedianOfWidestDimension.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/MidPointOfWidestDimension.java delete mode 100644 moa/src/main/java/moa/classifiers/lazy/neighboursearch/kdtrees/SlidingMidPointOfWidestSide.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/ADACC.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/ADOB.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/AbstractOzaBagAdwin.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/AbstractOzaBoost.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/AccuracyWeightedEnsemble.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/AdaptiveRandomForest.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/AdaptiveRandomForestRegressor.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/BOLE.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/DACC.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/DynamicWeightedMajority.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/LearnNSE.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/LeveragingBag.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/LimAttClassifier.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/OCBoost.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/OnlineSmoothBoost.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/OzaBagASHT.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/OzaBoostAdwin.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/PairedLearners.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/RCD.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/TemporallyAugmentedClassifier.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/WEKAClassifier.java delete mode 100644 moa/src/main/java/moa/classifiers/meta/WeightedMajorityAlgorithm.java delete mode 100644 moa/src/main/java/moa/classifiers/mlc/MEKAClassifier.java delete mode 100644 moa/src/main/java/moa/classifiers/mlc/MajorityLabelset.java delete mode 100644 moa/src/main/java/moa/classifiers/mlc/MultilabelHoeffdingTree.java delete mode 100644 moa/src/main/java/moa/classifiers/mlc/core/attributeclassobservers/AttributeStatisticsObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/mlc/core/attributeclassobservers/MultiLabelNominalAttributeObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/ICVarianceReduction.java delete mode 100644 moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/MultiLabelSplitCriterion.java delete mode 100644 moa/src/main/java/moa/classifiers/mlc/core/splitcriteria/PCTWeightedICVarianceReduction.java delete mode 100644 moa/src/main/java/moa/classifiers/mlc/meta/AdaptiveRandomForestMultiTargetRegression.java delete mode 100644 moa/src/main/java/moa/classifiers/mtr/BasicMultiTargetRegressor.java delete mode 100644 moa/src/main/java/moa/classifiers/mtr/functions/MultiTargetNoChange.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/AbstractAMRules.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/RuleClassification.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/RuleClassifier.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/RuleClassifierNBayes.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/RuleActiveLearningNode.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/Utils.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/anomalydetection/AnomalinessRatioScore.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/anomalydetection/OddsRatioScore.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/changedetection/NoChangeDetection.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/splitcriteria/AMRulesSplitCriterion.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/splitcriteria/SDRSplitCriterionAMRulesNode.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/splitcriteria/VRSplitCriterion.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/core/splitcriteria/VarianceRatioSplitCriterion.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/driftdetection/PageHinkleyTest.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/featureranking/MeritFeatureRanking.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/featureranking/WeightedMajorityFeatureRanking.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/functions/AMRulesRegressorFunction.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/meta/RandomAMRulesOld.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelClassifier.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearner.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiLabelLearnerSemiSuper.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressor.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressorSemiSuper.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/MultiLabelBSTreeFloat.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/attributeclassobservers/SingleVector.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralClassification.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/core/LearningLiteralRegression.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultiTargetVarianceRatio.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/core/splitcriteria/MultilabelInformationGain.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/core/voting/MultiLabelVote.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RelativeMeanAbsoluteDeviationMT.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/errormeasurers/RelativeRootMeanSquaredErrorMT.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/functions/AdaptiveMultiTargetRegressor.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/functions/MultiLabelPerceptronClassification.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/functions/StackedPredictor.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/inputselectors/MeritThreshold.java delete mode 100644 moa/src/main/java/moa/classifiers/rules/multilabel/meta/MultiLabelRandomAMRules.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/ARFFIMTDD.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/ARFHoeffdingTree.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/ASHoeffdingTree.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/AdaHoeffdingOptionTree.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/DecisionStump.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/EFDT.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTree.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/HoeffdingAdaptiveTreeClassifLeaves.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/HoeffdingOptionTree.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/HoeffdingTree.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/HoeffdingTreeClassifLeaves.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/LimAttHoeffdingTree.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/RandomHoeffdingTree.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/iadem/Iadem2.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/iadem/Iadem3.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/iadem/Iadem3Subtree.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/iadem/IademCommonProcedures.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/iadem/IademGaussianNumericAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/iadem/IademGreenwaldKhannaNumericAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/iadem/IademNumericAttributeObserver.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/iadem/IademSplitCriterion.java delete mode 100644 moa/src/main/java/moa/classifiers/trees/iadem/IademVFMLNumericAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/clusterers/ClusterGenerator.java delete mode 100644 moa/src/main/java/moa/clusterers/CobWeb.java delete mode 100644 moa/src/main/java/moa/clusterers/KMeans.java delete mode 100644 moa/src/main/java/moa/clusterers/WekaClusteringAlgorithm.java delete mode 100644 moa/src/main/java/moa/clusterers/clustream/ClustreamKernel.java delete mode 100644 moa/src/main/java/moa/clusterers/clustree/ClusKernel.java delete mode 100644 moa/src/main/java/moa/clusterers/clustree/ClusTree.java delete mode 100644 moa/src/main/java/moa/clusterers/clustree/Entry.java delete mode 100644 moa/src/main/java/moa/clusterers/clustree/Node.java delete mode 100644 moa/src/main/java/moa/clusterers/clustree/util/Budget.java delete mode 100644 moa/src/main/java/moa/clusterers/clustree/util/SimpleBudget.java delete mode 100644 moa/src/main/java/moa/clusterers/denstream/MicroCluster.java delete mode 100644 moa/src/main/java/moa/clusterers/macro/ColorArray.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractC.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/AbstractC/AbstractCBase.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/AbstractC/ISBIndex.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/AbstractC/MyMTree.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/AbstractC/StreamObj.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/AbstractC/Test.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/Angiulli/ApproxSTORM.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/Angiulli/ExactSTORM.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/Angiulli/ISBIndex.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/Angiulli/MyMTree.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/Angiulli/STORMBase.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/Angiulli/StreamObj.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/Angiulli/Test.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/AnyOut/util/DataObject.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/AnyOut/util/DataSet.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/MCOD/ISBIndex.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/MCOD/MCOD.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/MCOD/MCODBase.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeMicroClusters.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/MCOD/MTreeStreamObjects.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/MCOD/MicroCluster.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/MCOD/StreamObj.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/MCOD/Test.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/MyBaseOutlierDetector.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/SimpleCOD/ISBIndex.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/SimpleCOD/MyMTree.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCOD.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/SimpleCOD/SimpleCODBase.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/SimpleCOD/StreamObj.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/SimpleCOD/Test.java delete mode 100644 moa/src/main/java/moa/clusterers/outliers/TestSpeed.java delete mode 100644 moa/src/main/java/moa/clusterers/streamkm/BucketManager.java delete mode 100644 moa/src/main/java/moa/clusterers/streamkm/MTRandom.java delete mode 100644 moa/src/main/java/moa/clusterers/streamkm/StreamKM.java delete mode 100644 moa/src/main/java/moa/clusterers/streamkm/TreeCoreset.java delete mode 100644 moa/src/main/java/moa/evaluation/BasicClassificationPerformanceEvaluator.java delete mode 100644 moa/src/main/java/moa/evaluation/BasicConceptDriftPerformanceEvaluator.java delete mode 100644 moa/src/main/java/moa/evaluation/BasicMultiLabelPerformanceEvaluator.java delete mode 100644 moa/src/main/java/moa/evaluation/BasicMultiTargetPerformanceEvaluator.java delete mode 100644 moa/src/main/java/moa/evaluation/BasicRegressionPerformanceEvaluator.java delete mode 100644 moa/src/main/java/moa/evaluation/MultiLabelWindowClassificationPerformanceEvaluator.java delete mode 100644 moa/src/main/java/moa/evaluation/WindowClassificationPerformanceEvaluator.java delete mode 100644 moa/src/main/java/moa/evaluation/WindowMultiTargetRegressionPerformanceEvaluator.java delete mode 100644 moa/src/main/java/moa/evaluation/WindowMultiTargetRegressionPerformanceRelativeMeasuresEvaluator.java delete mode 100644 moa/src/main/java/moa/evaluation/WindowRegressionPerformanceEvaluator.java rename moa/src/main/java/moa/evaluation/{ => evaluators}/ALClassificationPerformanceEvaluator.java (74%) rename moa/src/main/java/moa/evaluation/{ => evaluators}/ALWindowClassificationPerformanceEvaluator.java (62%) rename moa/src/main/java/moa/evaluation/{ => evaluators}/AdwinClassificationPerformanceEvaluator.java (63%) rename moa/src/main/java/moa/evaluation/{ => evaluators}/BasicAUCImbalancedPerformanceEvaluator.java (95%) create mode 100644 moa/src/main/java/moa/evaluation/evaluators/BasicClassificationPerformanceEvaluator.java create mode 100644 moa/src/main/java/moa/evaluation/evaluators/BasicConceptDriftPerformanceEvaluator.java create mode 100644 moa/src/main/java/moa/evaluation/evaluators/BasicMultiLabelPerformanceEvaluator.java create mode 100644 moa/src/main/java/moa/evaluation/evaluators/BasicMultiTargetPerformanceEvaluator.java rename moa/src/main/java/moa/evaluation/{ => evaluators}/BasicMultiTargetPerformanceRelativeMeasuresEvaluator.java (58%) create mode 100644 moa/src/main/java/moa/evaluation/evaluators/BasicRegressionPerformanceEvaluator.java rename moa/src/main/java/moa/evaluation/{ => evaluators}/ClassificationPerformanceEvaluator.java (96%) rename moa/src/main/java/moa/evaluation/{ => evaluators}/EWMAClassificationPerformanceEvaluator.java (57%) rename moa/src/main/java/moa/evaluation/{ => evaluators}/FadingFactorClassificationPerformanceEvaluator.java (50%) rename moa/src/main/java/moa/evaluation/{ => evaluators}/LearningPerformanceEvaluator.java (58%) rename moa/src/main/java/moa/evaluation/{ => evaluators}/MultiLabelClassificationPerformanceEvaluator.java (88%) create mode 100644 moa/src/main/java/moa/evaluation/evaluators/MultiLabelWindowClassificationPerformanceEvaluator.java rename moa/src/main/java/moa/evaluation/{ => evaluators}/MultiTargetRegressionPerformanceEvaluator.java (88%) rename moa/src/main/java/moa/evaluation/{ => evaluators}/RegressionPerformanceEvaluator.java (88%) rename moa/src/main/java/moa/evaluation/{ => evaluators}/WindowAUCImbalancedPerformanceEvaluator.java (66%) create mode 100644 moa/src/main/java/moa/evaluation/evaluators/WindowClassificationPerformanceEvaluator.java create mode 100644 moa/src/main/java/moa/evaluation/evaluators/WindowMultiTargetRegressionPerformanceEvaluator.java create mode 100644 moa/src/main/java/moa/evaluation/evaluators/WindowMultiTargetRegressionPerformanceRelativeMeasuresEvaluator.java create mode 100644 moa/src/main/java/moa/evaluation/evaluators/WindowRegressionPerformanceEvaluator.java delete mode 100644 moa/src/main/java/moa/learners/ChangeDetectorLearner.java delete mode 100644 moa/src/main/java/moa/learners/Classifier.java delete mode 100644 moa/src/main/java/moa/learners/MultiLabelClassifier.java delete mode 100644 moa/src/main/java/moa/learners/MultiTargetRegressor.java rename moa/src/main/java/moa/{ => learners}/clusterers/AbstractClusterer.java (79%) create mode 100644 moa/src/main/java/moa/learners/clusterers/ClusterGenerator.java rename moa/src/main/java/moa/{ => learners}/clusterers/Clusterer.java (63%) create mode 100644 moa/src/main/java/moa/learners/clusterers/CobWeb.java create mode 100644 moa/src/main/java/moa/learners/clusterers/KMeans.java create mode 100644 moa/src/main/java/moa/learners/clusterers/WekaClusteringAlgorithm.java rename moa/src/main/java/moa/{ => learners}/clusterers/clustream/Clustream.java (56%) create mode 100644 moa/src/main/java/moa/learners/clusterers/clustream/ClustreamKernel.java rename moa/src/main/java/moa/{ => learners}/clusterers/clustream/WithKmeans.java (72%) create mode 100644 moa/src/main/java/moa/learners/clusterers/clustree/ClusKernel.java create mode 100644 moa/src/main/java/moa/learners/clusterers/clustree/ClusTree.java create mode 100644 moa/src/main/java/moa/learners/clusterers/clustree/Entry.java create mode 100644 moa/src/main/java/moa/learners/clusterers/clustree/Node.java create mode 100644 moa/src/main/java/moa/learners/clusterers/clustree/util/Budget.java create mode 100644 moa/src/main/java/moa/learners/clusterers/clustree/util/SimpleBudget.java create mode 100644 moa/src/main/java/moa/learners/clusterers/denstream/MicroCluster.java rename moa/src/main/java/moa/{ => learners}/clusterers/denstream/Timestamp.java (56%) rename moa/src/main/java/moa/{ => learners}/clusterers/denstream/WithDBSCAN.java (83%) rename moa/src/main/java/moa/{ => learners}/clusterers/dstream/CharacteristicVector.java (63%) rename moa/src/main/java/moa/{ => learners}/clusterers/dstream/DensityGrid.java (60%) rename moa/src/main/java/moa/{ => learners}/clusterers/dstream/Dstream.java (54%) rename moa/src/main/java/moa/{ => learners}/clusterers/dstream/GridCluster.java (60%) rename moa/src/main/java/moa/{ => learners}/clusterers/kmeanspm/BICO.java (76%) rename moa/src/main/java/moa/{ => learners}/clusterers/kmeanspm/ClusteringFeature.java (72%) rename moa/src/main/java/moa/{ => learners}/clusterers/kmeanspm/ClusteringTreeHeadNode.java (70%) rename moa/src/main/java/moa/{ => learners}/clusterers/kmeanspm/ClusteringTreeNode.java (85%) rename moa/src/main/java/moa/{ => learners}/clusterers/kmeanspm/CoresetKMeans.java (85%) rename moa/src/main/java/moa/{ => learners}/clusterers/kmeanspm/CuckooHashing.java (72%) rename moa/src/main/java/moa/{ => learners}/clusterers/kmeanspm/DietzfelbingerHash.java (81%) rename moa/src/main/java/moa/{ => learners}/clusterers/kmeanspm/Metric.java (70%) rename moa/src/main/java/moa/{ => learners}/clusterers/macro/AbstractMacroClusterer.java (90%) create mode 100644 moa/src/main/java/moa/learners/clusterers/macro/ColorArray.java rename moa/src/main/java/moa/{ => learners}/clusterers/macro/ColorObject.java (95%) rename moa/src/main/java/moa/{ => learners}/clusterers/macro/IDenseMacroCluster.java (87%) rename moa/src/main/java/moa/{ => learners}/clusterers/macro/IMacroClusterer.java (88%) rename moa/src/main/java/moa/{ => learners}/clusterers/macro/NonConvexCluster.java (91%) rename moa/src/main/java/moa/{ => learners}/clusterers/macro/dbscan/DBScan.java (83%) rename moa/src/main/java/moa/{ => learners}/clusterers/macro/dbscan/DenseMicroCluster.java (80%) create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/AbstractC/AbstractC.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/AbstractC/AbstractCBase.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/AbstractC/ISBIndex.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/AbstractC/MyMTree.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/AbstractC/StreamObj.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/AbstractC/Test.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/Angiulli/ApproxSTORM.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/Angiulli/ExactSTORM.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/Angiulli/ISBIndex.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/Angiulli/MyMTree.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/Angiulli/STORMBase.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/Angiulli/StreamObj.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/Angiulli/Test.java rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/AnyOut/AnyOut.java (57%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/AnyOut/AnyOutCore.java (61%) create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/AnyOut/util/DataObject.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/AnyOut/util/DataSet.java rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/AnyOut/util/EMProjectedClustering.java (83%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/AnyOut/util/EMTopDownTreeBuilder.java (81%) create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/MCOD/ISBIndex.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/MCOD/MCOD.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/MCOD/MCODBase.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/MCOD/MTreeMicroClusters.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/MCOD/MTreeStreamObjects.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/MCOD/MicroCluster.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/MCOD/StreamObj.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/MCOD/Test.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/MyBaseOutlierDetector.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/SimpleCOD/ISBIndex.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/SimpleCOD/MyMTree.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/SimpleCOD/SimpleCOD.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/SimpleCOD/SimpleCODBase.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/SimpleCOD/StreamObj.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/SimpleCOD/Test.java create mode 100644 moa/src/main/java/moa/learners/clusterers/outliers/TestSpeed.java rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/ComposedSplitFunction.java (81%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/DistanceFunction.java (93%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/DistanceFunctions.java (73%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/MTree.java (72%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/PartitionFunction.java (71%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/PartitionFunctions.java (71%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/PromotionFunction.java (82%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/PromotionFunctions.java (73%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/SplitFunction.java (76%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/utils/Pair.java (85%) rename moa/src/main/java/moa/{ => learners}/clusterers/outliers/utils/mtree/utils/Utils.java (72%) create mode 100644 moa/src/main/java/moa/learners/clusterers/streamkm/BucketManager.java rename moa/src/main/java/moa/{ => learners}/clusterers/streamkm/CoresetCostTriple.java (80%) create mode 100644 moa/src/main/java/moa/learners/clusterers/streamkm/MTRandom.java rename moa/src/main/java/moa/{ => learners}/clusterers/streamkm/Point.java (54%) create mode 100644 moa/src/main/java/moa/learners/clusterers/streamkm/StreamKM.java create mode 100644 moa/src/main/java/moa/learners/clusterers/streamkm/TreeCoreset.java create mode 100644 moa/src/main/java/moa/learners/predictors/AbstractClassifier.java create mode 100644 moa/src/main/java/moa/learners/predictors/AbstractEnsembleLearner.java create mode 100644 moa/src/main/java/moa/learners/predictors/AbstractInstanceLearner.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/AbstractMultiLabelClassifier.java (56%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/AbstractMultiTargetRegressor.java (56%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/AbstractRegressor.java (76%) create mode 100644 moa/src/main/java/moa/learners/predictors/ChangeDetectorLearner.java create mode 100644 moa/src/main/java/moa/learners/predictors/Classifier.java rename moa/src/main/java/moa/learners/{ => predictors}/InstanceLearner.java (61%) rename moa/src/main/java/moa/learners/{ => predictors}/LearnerSemiSupervised.java (80%) create mode 100644 moa/src/main/java/moa/learners/predictors/MultiLabelClassifier.java create mode 100644 moa/src/main/java/moa/learners/predictors/MultiTargetRegressor.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/OneClassClassifier.java (64%) rename moa/src/main/java/moa/learners/{ => predictors}/Regressor.java (90%) rename moa/src/main/java/moa/{classifiers/drift/SingleClassifierDrift.java => learners/predictors/SemiSupervisedClassifier.java} (54%) create mode 100644 moa/src/main/java/moa/learners/predictors/SemiSupervisedInstanceLearner.java create mode 100644 moa/src/main/java/moa/learners/predictors/SemiSupervisedMultiLabelClassifier.java create mode 100644 moa/src/main/java/moa/learners/predictors/SemiSupervisedMultiTargetRegressor.java rename moa/src/main/java/moa/{classifiers/SemiSupervisedLearner.java => learners/predictors/SemiSupervisedRegressor.java} (78%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/active/ALClassifier.java (79%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/active/ALRandom.java (57%) create mode 100644 moa/src/main/java/moa/learners/predictors/active/ALUncertainty.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/active/budget/BudgetManager.java (87%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/active/budget/FixedBM.java (82%) create mode 100644 moa/src/main/java/moa/learners/predictors/bayes/NaiveBayes.java create mode 100644 moa/src/main/java/moa/learners/predictors/bayes/NaiveBayesMultinomial.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/AttributeSplitSuggestion.java rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/LearningLiteral.java (54%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/LearningLiteralClassification.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/LearningLiteralRegression.java rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/Literal.java (75%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/MultiLabelRule.java (51%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/MultiLabelRuleClassification.java (73%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/MultiLabelRuleRegression.java (72%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/MultiLabelRuleSet.java (90%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/ObservableMOAObject.java (70%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/ObserverMOAObject.java (87%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/attributeclassobservers/AbstractAttributeClassObserver.java (79%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/AttributeClassObserver.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/AttributeStatisticsObserver.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/BinaryTreeNumericAttributeClassObserver.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/BinaryTreeNumericAttributeClassObserverRegression.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/attributeclassobservers/DiscreteAttributeClassObserver.java (79%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/FIMTDDNumericAttributeClassLimitObserver.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/FIMTDDNumericAttributeClassObserver.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/GaussianNumericAttributeClassObserver.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/GreenwaldKhannaNumericAttributeClassObserver.java rename moa/src/main/java/moa/{classifiers/mlc => learners/predictors}/core/attributeclassobservers/MultiLabelBSTree.java (55%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/MultiLabelBSTreeFloat.java rename moa/src/main/java/moa/{classifiers/mlc => learners/predictors}/core/attributeclassobservers/MultiLabelBSTreePCT.java (60%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/MultiLabelNominalAttributeObserver.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/NominalAttributeClassObserver.java rename moa/src/main/java/moa/{classifiers/mlc => learners/predictors}/core/attributeclassobservers/NominalStatisticsObserver.java (57%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/NullAttributeClassObserver.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/attributeclassobservers/NumericAttributeClassObserver.java (86%) rename moa/src/main/java/moa/{classifiers/mlc => learners/predictors}/core/attributeclassobservers/NumericStatisticsObserver.java (57%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/SingleVector.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/attributeclassobservers/VFMLNumericAttributeClassObserver.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/conditionaltests/InstanceConditionalBinaryTest.java (87%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/conditionaltests/InstanceConditionalTest.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/conditionaltests/NominalAttributeBinaryTest.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/conditionaltests/NominalAttributeMultiwayTest.java (51%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/conditionaltests/NumericAttributeBinaryTest.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/ADWIN.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/driftdetection/ADWINChangeDetector.java (56%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/AbstractChangeDetector.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/ChangeDetector.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/CusumDM.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/DDM.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/EDDM.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/EWMAChartDM.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/EnsembleDriftDetectionMethods.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/GeometricMovingAverageDM.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/HDDM_A_Test.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/HDDM_W_Test.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/NoChangeDetection.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/PageHinkleyDM.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/RDDM.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/SEEDChangeDetector.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/STEPD.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/SeqDrift1ChangeDetector.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/driftdetection/SeqDrift2ChangeDetector.java rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/errormeasurers/AbstractMultiLabelErrorMeasurer.java (73%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/errormeasurers/AbstractMultiTargetErrorMeasurer.java (80%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/errormeasurers/MeanAbsoluteDeviationMT.java (58%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/errormeasurers/MultiLabelErrorMeasurer.java (70%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/errormeasurers/MultiTargetErrorMeasurer.java (93%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/errormeasurers/RelativeMeanAbsoluteDeviationMT.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/errormeasurers/RelativeRootMeanSquaredErrorMT.java rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/errormeasurers/RootMeanSquaredErrorMT.java (55%) rename moa/src/main/java/moa/{classifiers/rules => learners/predictors/core}/featureranking/AbstractFeatureRanking.java (82%) rename moa/src/main/java/moa/{classifiers/rules => learners/predictors/core}/featureranking/BasicFeatureRanking.java (56%) rename moa/src/main/java/moa/{classifiers/rules => learners/predictors/core}/featureranking/FeatureRanking.java (77%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/featureranking/MeritFeatureRanking.java rename moa/src/main/java/moa/{classifiers/rules => learners/predictors/core}/featureranking/NoFeatureRanking.java (84%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/featureranking/WeightedMajorityFeatureRanking.java rename moa/src/main/java/moa/{classifiers/rules => learners/predictors/core}/featureranking/messages/ChangeDetectedMessage.java (92%) rename moa/src/main/java/moa/{classifiers/rules => learners/predictors/core}/featureranking/messages/FeatureRankingMessage.java (92%) rename moa/src/main/java/moa/{classifiers/rules => learners/predictors/core}/featureranking/messages/MeritCheckMessage.java (79%) rename moa/src/main/java/moa/{classifiers/rules => learners/predictors/core}/featureranking/messages/RuleExpandedMessage.java (95%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/functions/AMRulesFunction.java (83%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/functions/AbstractAMRulesFunctionBasicMlLearner.java (65%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/functions/AdaptiveMultiTargetRegressor.java rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/functions/DominantLabelsClassifier.java (62%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/functions/MultiLabelNaiveBayes.java (68%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/functions/MultiLabelPerceptronClassification.java rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/functions/MultiTargetMeanRegressor.java (69%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/functions/MultiTargetPerceptronRegressor.java (67%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/functions/StackedPredictor.java rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/inputselectors/InputAttributesSelector.java (79%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/inputselectors/MeritThreshold.java rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/inputselectors/SelectAllInputs.java (65%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/instancetransformers/InstanceAttributesSelector.java (64%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/instancetransformers/InstanceOutputAttributesSelector.java (63%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/instancetransformers/InstanceTransformer.java (78%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/instancetransformers/NoInstanceTransformation.java (88%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/outputselectors/EntropyThreshold.java (53%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/outputselectors/OutputAttributesSelector.java (81%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/outputselectors/SelectAllOutputs.java (89%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/outputselectors/StdDevThreshold.java (53%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors/core}/outputselectors/VarianceThreshold.java (53%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/splitcriteria/GiniSplitCriterion.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/splitcriteria/ICVarianceReduction.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/splitcriteria/InfoGainSplitCriterion.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/splitcriteria/InfoGainSplitCriterionMultilabel.java (67%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/splitcriteria/MultiLabelSplitCriterion.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/splitcriteria/MultiTargetVarianceRatio.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/splitcriteria/MultilabelInformationGain.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/splitcriteria/PCTWeightedICVarianceReduction.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/splitcriteria/SDRSplitCriterion.java (83%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/splitcriteria/SplitCriterion.java (50%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/splitcriteria/VarianceReductionSplitCriterion.java rename moa/src/main/java/moa/{classifiers/mlc => learners/predictors}/core/splitcriteria/WeightedICVarianceReduction.java (62%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/statisticaltests/Cramer.java create mode 100644 moa/src/main/java/moa/learners/predictors/core/statisticaltests/KNN.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/core/statisticaltests/StatisticalTest.java (65%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/voting/AbstractErrorWeightedVoteMultiLabel.java (54%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/voting/ErrorWeightedVoteMultiLabel.java (59%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/voting/FirstHitVoteMultiLabel.java (67%) rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/voting/InverseErrorWeightedVoteMultiLabel.java (55%) create mode 100644 moa/src/main/java/moa/learners/predictors/core/voting/MultiLabelVote.java rename moa/src/main/java/moa/{classifiers/rules/multilabel => learners/predictors}/core/voting/UniformWeightedVoteMultiLabel.java (64%) create mode 100644 moa/src/main/java/moa/learners/predictors/drift/DriftDetectionMethodClassifier.java create mode 100644 moa/src/main/java/moa/learners/predictors/functions/AdaGrad.java create mode 100644 moa/src/main/java/moa/learners/predictors/functions/MajorityClass.java create mode 100644 moa/src/main/java/moa/learners/predictors/functions/MajorityLabelset.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/functions/Mean.java (85%) create mode 100644 moa/src/main/java/moa/learners/predictors/functions/MultiTargetNoChange.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/functions/NoChange.java (55%) create mode 100644 moa/src/main/java/moa/learners/predictors/functions/Perceptron.java create mode 100644 moa/src/main/java/moa/learners/predictors/functions/SGD.java create mode 100644 moa/src/main/java/moa/learners/predictors/functions/SGDMultiClass.java create mode 100644 moa/src/main/java/moa/learners/predictors/functions/SPegasos.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/lazy/SAMkNN.java (65%) create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/kNN.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/kNNwithPAW.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/kNNwithPAWandADWIN.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/DistanceFunction.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/EuclideanDistance.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/KDTree.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/LinearNNSearch.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/NearestNeighbourSearch.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/NormalizableDistance.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/kdtrees/KDTreeNode.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/kdtrees/KDTreeNodeSplitter.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/kdtrees/KMeansInpiredMethod.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/kdtrees/MedianOfWidestDimension.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/kdtrees/MidPointOfWidestDimension.java create mode 100644 moa/src/main/java/moa/learners/predictors/lazy/neighboursearch/kdtrees/SlidingMidPointOfWidestSide.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/ADACC.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/ADOB.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/meta/AbstractOzaBag.java (70%) create mode 100644 moa/src/main/java/moa/learners/predictors/meta/AbstractOzaBagAdwin.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/AbstractOzaBoost.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/meta/AccuracyUpdatedEnsemble.java (84%) create mode 100644 moa/src/main/java/moa/learners/predictors/meta/AccuracyWeightedEnsemble.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/AdaptiveRandomForest.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/BOLE.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/DACC.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/DynamicWeightedMajority.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/meta/HeterogeneousEnsembleAbstract.java (81%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/meta/HeterogeneousEnsembleBlast.java (95%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/meta/HeterogeneousEnsembleBlastFadingFactors.java (91%) create mode 100644 moa/src/main/java/moa/learners/predictors/meta/LearnNSE.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/LeveragingBag.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/LimAttClassifier.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/OCBoost.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/meta/OnlineAccuracyUpdatedEnsemble.java (61%) create mode 100644 moa/src/main/java/moa/learners/predictors/meta/OnlineSmoothBoost.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/OzaBagASHT.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/OzaBoostAdwin.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/PairedLearners.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/RCD.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/meta/RandomRules.java (69%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/meta/RegressionViaMTR.java (72%) create mode 100644 moa/src/main/java/moa/learners/predictors/meta/TemporallyAugmentedClassifier.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/WEKAClassifier.java create mode 100644 moa/src/main/java/moa/learners/predictors/meta/WeightedMajorityAlgorithm.java rename moa/src/main/java/moa/{classifiers/meta/OzaBagClassification.java => learners/predictors/meta/classifiers/OzaBag.java} (65%) rename moa/src/main/java/moa/{classifiers/meta/OzaBagAdwinClassification.java => learners/predictors/meta/classifiers/OzaBagAdwin.java} (65%) rename moa/src/main/java/moa/{classifiers/meta/OzaBoostClassification.java => learners/predictors/meta/classifiers/OzaBoost.java} (76%) rename moa/src/main/java/moa/{classifiers/mlc/BasicMultiLabelLearner.java => learners/predictors/meta/mlc/LocalMultiLabelClassifier.java} (55%) create mode 100644 moa/src/main/java/moa/learners/predictors/meta/mlc/MEKAClassifier.java rename moa/src/main/java/moa/{classifiers/mlc/meta => learners/predictors/meta/mlc}/OzaBagAdwinMultiLabelClassification.java (78%) rename moa/src/main/java/moa/{classifiers/mlc/meta => learners/predictors/meta/mlc}/OzaBagMultiLabelClassification.java (81%) create mode 100644 moa/src/main/java/moa/learners/predictors/meta/mtr/AdaptiveRandomForest.java rename moa/src/main/java/moa/{classifiers => learners/predictors/meta}/mtr/LocalMultiTargetRegressor.java (67%) rename moa/src/main/java/moa/{classifiers/mlc/meta/OzaBagMultiTargetRegression.java => learners/predictors/meta/mtr/OzaBag.java} (77%) rename moa/src/main/java/moa/{classifiers/mlc/meta/OzaBagAdwinMultiTargetRegression.java => learners/predictors/meta/mtr/OzaBagAdwin.java} (77%) create mode 100644 moa/src/main/java/moa/learners/predictors/meta/regressors/AdaptiveRandomForestRegressor.java rename moa/src/main/java/moa/{classifiers/meta/OzaBagRegression.java => learners/predictors/meta/regressors/OzaBag.java} (55%) rename moa/src/main/java/moa/{classifiers/meta/OzaBagAdwinRegression.java => learners/predictors/meta/regressors/OzaBagAdwin.java} (63%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/oneclass/Autoencoder.java (61%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/oneclass/HSTreeNode.java (61%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/oneclass/HSTrees.java (69%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/oneclass/NearestNeighbourDescription.java (59%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/AMRulesMultiLabelClassifier.java create mode 100644 moa/src/main/java/moa/learners/predictors/rules/AMRulesMultiLabelLearner.java create mode 100644 moa/src/main/java/moa/learners/predictors/rules/AMRulesMultiLabelLearnerSemiSuper.java create mode 100644 moa/src/main/java/moa/learners/predictors/rules/AMRulesMultiTargetRegressor.java create mode 100644 moa/src/main/java/moa/learners/predictors/rules/AMRulesMultiTargetRegressorSemiSuper.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/AMRulesRegressor.java (69%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/AMRulesRegressorOld.java (55%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/AbstractAMRules.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/BinaryClassifierFromRegressor.java (67%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/MultiLabelRandomAMRules.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/Predicates.java (69%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/RuleClassification.java create mode 100644 moa/src/main/java/moa/learners/predictors/rules/RuleClassifier.java create mode 100644 moa/src/main/java/moa/learners/predictors/rules/RuleClassifierNBayes.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/AttributeExpansionSuggestion.java (55%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/NominalRulePredicate.java (60%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/NumericRulePredicate.java (62%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/Predicate.java (69%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/Rule.java (75%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/core/RuleActiveLearningNode.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/RuleActiveRegressionNode.java (50%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/RuleSet.java (91%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/RuleSplitNode.java (53%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/core/Utils.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/anomalydetection/AbstractAnomalyDetector.java (94%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/core/anomalydetection/AnomalinessRatioScore.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/anomalydetection/AnomalyDetector.java (68%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/anomalydetection/NoAnomalyDetection.java (68%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/core/anomalydetection/OddsRatioScore.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/anomalydetection/probabilityfunctions/CantellisInequality.java (73%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/anomalydetection/probabilityfunctions/ChebyshevInequality.java (65%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/anomalydetection/probabilityfunctions/GaussInequality.java (62%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/anomalydetection/probabilityfunctions/ProbabilityFunction.java (91%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/conditionaltests/NominalAttributeBinaryRulePredicate.java (66%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/core/conditionaltests/NumericAttributeBinaryRulePredicate.java create mode 100644 moa/src/main/java/moa/learners/predictors/rules/core/splitcriteria/AMRulesSplitCriterion.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/splitcriteria/SDRSplitCriterionAMRules.java (71%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/core/splitcriteria/SDRSplitCriterionAMRulesNode.java create mode 100644 moa/src/main/java/moa/learners/predictors/rules/core/splitcriteria/VRSplitCriterion.java create mode 100644 moa/src/main/java/moa/learners/predictors/rules/core/splitcriteria/VarianceRatioSplitCriterion.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/voting/AbstractErrorWeightedVote.java (73%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/voting/ErrorWeightedVote.java (62%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/voting/ExpNegErrorWeightedVote.java (58%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/voting/InverseErrorWeightedVote.java (54%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/voting/MinErrorWeightedVote.java (71%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/voting/OneMinusErrorWeightedVote.java (62%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/voting/UniformWeightedVote.java (75%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/core/voting/Vote.java (74%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/driftdetection/PageHinkleyFading.java (56%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/driftdetection/PageHinkleyTest.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/errormeasurers/ErrorMeasurement.java (75%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/errormeasurers/MeanAbsoluteDeviation.java (76%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/errormeasurers/RootMeanSquaredError.java (73%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/functions/AMRulesClassifierFunction.java (94%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/functions/AMRulesLearner.java (86%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/functions/AdaptiveNodePredictor.java (76%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/functions/FadingTargetMean.java (78%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/functions/LowPassFilteredLearner.java (68%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/functions/Perceptron.java (54%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/functions/TargetMean.java (65%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/rules/meta/RandomAMRules.java (76%) create mode 100644 moa/src/main/java/moa/learners/predictors/rules/meta/RandomAMRulesOld.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/ARFFIMTDD.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/ARFHoeffdingTree.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/ASHoeffdingTree.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/AdaHoeffdingOptionTree.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/DecisionStump.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/EFDT.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/trees/FIMTDD.java (77%) create mode 100644 moa/src/main/java/moa/learners/predictors/trees/HoeffdingAdaptiveTree.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/HoeffdingAdaptiveTreeClassifLeaves.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/HoeffdingOptionTree.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/HoeffdingTree.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/HoeffdingTreeClassifLeaves.java rename moa/src/main/java/moa/{classifiers/mtr => learners/predictors}/trees/ISOUPOptionTree.java (75%) rename moa/src/main/java/moa/{classifiers/mtr => learners/predictors}/trees/ISOUPTree.java (74%) rename moa/src/main/java/moa/{classifiers/mtr => learners/predictors}/trees/ISOUPTreeRF.java (71%) create mode 100644 moa/src/main/java/moa/learners/predictors/trees/LimAttHoeffdingTree.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/MultilabelHoeffdingTree.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/trees/ORTO.java (77%) create mode 100644 moa/src/main/java/moa/learners/predictors/trees/RandomHoeffdingTree.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/iadem/Iadem2.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/iadem/Iadem3.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/iadem/Iadem3Subtree.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/trees/iadem/IademAttributeSplitSuggestion.java (53%) create mode 100644 moa/src/main/java/moa/learners/predictors/trees/iadem/IademCommonProcedures.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/trees/iadem/IademException.java (56%) create mode 100644 moa/src/main/java/moa/learners/predictors/trees/iadem/IademGaussianNumericAttributeClassObserver.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/iadem/IademGreenwaldKhannaNumericAttributeClassObserver.java rename moa/src/main/java/moa/{classifiers => learners/predictors}/trees/iadem/IademGreenwaldKhannaQuantileSummary.java (57%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/trees/iadem/IademNominalAttributeBinaryTest.java (66%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/trees/iadem/IademNominalAttributeMultiwayTest.java (66%) rename moa/src/main/java/moa/{classifiers => learners/predictors}/trees/iadem/IademNumericAttributeBinaryTest.java (66%) create mode 100644 moa/src/main/java/moa/learners/predictors/trees/iadem/IademNumericAttributeObserver.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/iadem/IademSplitCriterion.java create mode 100644 moa/src/main/java/moa/learners/predictors/trees/iadem/IademVFMLNumericAttributeClassObserver.java delete mode 100644 moa/src/main/java/moa/tasks/structuredoutput/multitargetregression/EvaluatePrequentialMultiTargetSemiSuper.java create mode 100644 moa/src/main/java/moa/tasks/structuredoutput/multitargetregression/EvaluatePrequentialSemiSupervised.java delete mode 100644 moa/src/test/java/moa/classifiers/AbstractClassifierTestCase.java delete mode 100644 moa/src/test/java/moa/classifiers/AbstractMultiTargetRegressorTestCase.java delete mode 100644 moa/src/test/java/moa/classifiers/AbstractRegressorTestCase.java delete mode 100644 moa/src/test/java/moa/classifiers/active/ALRandomTest.java delete mode 100644 moa/src/test/java/moa/classifiers/active/ALUncertaintyTest.java delete mode 100644 moa/src/test/java/moa/classifiers/bayes/NaiveBayesMultinomialTest.java delete mode 100644 moa/src/test/java/moa/classifiers/bayes/NaiveBayesTest.java delete mode 100644 moa/src/test/java/moa/classifiers/drift/DriftDetectionMethodClassifierTest.java delete mode 100644 moa/src/test/java/moa/classifiers/drift/SingleClassifierDriftTest.java delete mode 100644 moa/src/test/java/moa/classifiers/functions/MajorityClassTest.java delete mode 100644 moa/src/test/java/moa/classifiers/functions/NoChangeTest.java delete mode 100644 moa/src/test/java/moa/classifiers/functions/PerceptronTest.java delete mode 100644 moa/src/test/java/moa/classifiers/functions/SGDTest.java delete mode 100644 moa/src/test/java/moa/classifiers/functions/SPegasosTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/ADOBTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/AccuracyUpdatedEnsembleTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/AccuracyWeightedEnsembleTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/AdaptiveRandomForestTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/BOLETest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/DynamicWeightedMajorityTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/LeveragingBagTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/LimAttClassifierTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/OCBoostTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/OnlineAccuracyUpdatedEnsembleTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/OzaBagASHTTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/OzaBagAdwinClassificationTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/OzaBagClassificationTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/OzaBoostAdwinTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/OzaBoostClassificationTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/TemporallyAugmentedClassifierTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/WEKAClassifierTest.java delete mode 100644 moa/src/test/java/moa/classifiers/meta/WeightedMajorityAlgorithmTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/RuleClassifierNBayesTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/RuleClassifierTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/core/UtilsTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressorSemiSuperTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/FirstHitVoteMultiLabelTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabelTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/multilabel/errormeasurers/RelativeMeanAbsoluteDeviationMTTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/multilabel/errormeasurers/RelativeRootMeanSquaredErrorMTTest.java delete mode 100644 moa/src/test/java/moa/classifiers/rules/multilabel/instancetransformers/InstanceOutputAttributesSelectorTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/ASHoeffdingTreeTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/AdaHoeffdingOptionTreeTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/DecisionStumpTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/EFDTTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/FIMTDDTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/HoeffdingAdaptiveTreeTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/HoeffdingOptionTreeTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/HoeffdingTreeTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/LimAttHoeffdingTreeTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/ORTOTest.java delete mode 100644 moa/src/test/java/moa/classifiers/trees/RandomHoeffdingTreeTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/AbstractClassifierTestCase.java rename moa/src/test/java/moa/{classifiers => learners/predictors}/AbstractInstanceLearnerTestCase.java (69%) create mode 100644 moa/src/test/java/moa/learners/predictors/AbstractMultiTargetRegressorTestCase.java create mode 100644 moa/src/test/java/moa/learners/predictors/AbstractRegressorTestCase.java create mode 100644 moa/src/test/java/moa/learners/predictors/active/ALRandomTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/active/ALUncertaintyTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/bayes/NaiveBayesMultinomialTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/bayes/NaiveBayesTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/drift/DriftDetectionMethodClassifierTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/functions/MajorityClassTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/functions/NoChangeTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/functions/PerceptronTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/functions/SGDTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/functions/SPegasosTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/ADOBTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/AccuracyUpdatedEnsembleTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/AccuracyWeightedEnsembleTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/AdaptiveRandomForestTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/BOLETest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/DynamicWeightedMajorityTest.java rename moa/src/test/java/moa/{classifiers => learners/predictors}/meta/HeterogeneousEnsembleBlastTest.java (75%) create mode 100644 moa/src/test/java/moa/learners/predictors/meta/LeveragingBagTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/LimAttClassifierTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/OCBoostTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/OnlineAccuracyUpdatedEnsembleTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/OzaBagASHTTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/OzaBoostAdwinTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/TemporallyAugmentedClassifierTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/WEKAClassifierTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/WeightedMajorityAlgorithmTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/classifiers/OzaBagAdwinTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/classifiers/OzaBagTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/meta/classifiers/OzaBoostTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/rules/AMRulesMultiTargetRegressorSemiSuperTest.java rename moa/src/test/java/moa/{classifiers => learners/predictors}/rules/AMRulesRegressorTest.java (72%) create mode 100644 moa/src/test/java/moa/learners/predictors/rules/RuleClassifierNBayesTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/rules/RuleClassifierTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/rules/core/UtilsTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/rules/multilabel/core/voting/FirstHitVoteMultiLabelTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/rules/multilabel/core/voting/InverseErrorWeightedVoteMultiLabelTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/rules/multilabel/core/voting/UniformWeightedVoteMultiLabelTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/rules/multilabel/errormeasurers/RelativeMeanAbsoluteDeviationMTTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/rules/multilabel/errormeasurers/RelativeRootMeanSquaredErrorMTTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/rules/multilabel/instancetransformers/InstanceOutputAttributesSelectorTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/ASHoeffdingTreeTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/AdaHoeffdingOptionTreeTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/DecisionStumpTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/EFDTTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/FIMTDDTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/HoeffdingAdaptiveTreeTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/HoeffdingOptionTreeTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/HoeffdingTreeTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/LimAttHoeffdingTreeTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/ORTOTest.java create mode 100644 moa/src/test/java/moa/learners/predictors/trees/RandomHoeffdingTreeTest.java delete mode 100644 moa/src/test/resources/moa/classifiers/drift/SingleClassifierDrift.ref delete mode 100644 moa/src/test/resources/moa/classifiers/functions/Perceptron.ref delete mode 100644 moa/src/test/resources/moa/classifiers/meta/OzaBagAdwin.ref delete mode 100644 moa/src/test/resources/moa/classifiers/meta/OzaBagClassification.ref delete mode 100644 moa/src/test/resources/moa/classifiers/meta/OzaBoostClassification.ref delete mode 100644 moa/src/test/resources/moa/classifiers/rules/AMRulesRegressor.ref delete mode 100644 moa/src/test/resources/moa/classifiers/rules/multilabel/AMRulesMultiTargetRegressorSemiSuper.ref rename moa/src/test/resources/moa/{classifiers => learners/predictors}/active/ALRandom.ref (97%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/active/ALUncertainty.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/bayes/NaiveBayes.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/bayes/NaiveBayesMultinomial.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/data/classification.arff (100%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/data/regression.arff (100%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/data/small_classification.arff (100%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/data/small_regression.arff (100%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/drift/DriftDetectionMethodClassifier.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/functions/MajorityClass.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/functions/NoChange.ref (98%) create mode 100644 moa/src/test/resources/moa/learners/predictors/functions/Perceptron.ref rename moa/src/test/resources/moa/{classifiers => learners/predictors}/functions/SGD.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/functions/SPegasos.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/ADOB.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/AccuracyUpdatedEnsemble.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/AccuracyWeightedEnsemble.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/AdaptiveRandomForest.ref (97%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/BOLE.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/DynamicWeightedMajority.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/HeterogeneousEnsembleBlast.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/LeveragingBag.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/LimAttClassifier.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/OCBoost.ref (84%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/OnlineAccuracyUpdatedEnsemble.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/OzaBagASHT.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/OzaBoostAdwin.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/TemporallyAugmentedClassifier.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/WEKAClassifier.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/meta/WeightedMajorityAlgorithm.ref (99%) rename moa/src/test/resources/moa/{classifiers/meta => learners/predictors/meta/classifiers}/OzaBag.ref (77%) rename moa/src/test/resources/moa/{classifiers/meta/OzaBagAdwinClassification.ref => learners/predictors/meta/classifiers/OzaBagAdwin.ref} (99%) rename moa/src/test/resources/moa/{classifiers/meta => learners/predictors/meta/classifiers}/OzaBoost.ref (99%) create mode 100644 moa/src/test/resources/moa/learners/predictors/rules/AMRulesMultiTargetRegressorSemiSuper.ref create mode 100644 moa/src/test/resources/moa/learners/predictors/rules/AMRulesRegressor.ref rename moa/src/test/resources/moa/{classifiers => learners/predictors}/rules/RuleClassifier.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/rules/RuleClassifierNBayes.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/ASHoeffdingTree.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/AdaHoeffdingOptionTree.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/DecisionStump.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/EFDT.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/FIMTDD.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/HoeffdingAdaptiveTree.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/HoeffdingOptionTree.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/HoeffdingTree.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/LimAttHoeffdingTree.ref (99%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/ORTO.ref (98%) rename moa/src/test/resources/moa/{classifiers => learners/predictors}/trees/RandomHoeffdingTree.ref (99%) diff --git a/moa/.classpath b/moa/.classpath index 079c3f879..0ca1374d8 100644 --- a/moa/.classpath +++ b/moa/.classpath @@ -20,7 +20,6 @@
- diff --git a/moa/src/main/java/com/github/javacliparser/AbstractClassOption.java b/moa/src/main/java/com/github/javacliparser/AbstractClassOption.java index b232a7d3b..c9c34cd49 100644 --- a/moa/src/main/java/com/github/javacliparser/AbstractClassOption.java +++ b/moa/src/main/java/com/github/javacliparser/AbstractClassOption.java @@ -1,18 +1,18 @@ /* * Copyright 2007 University of Waikato. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the - * License. + * License. */ package com.github.javacliparser; @@ -27,201 +27,189 @@ */ public abstract class AbstractClassOption extends AbstractOption { - private static final long serialVersionUID = 1L; - - /** The prefix text to use to indicate file. */ - public static final String FILE_PREFIX_STRING = "file:"; - - /** The prefix text to use to indicate inmem. */ - public static final String INMEM_PREFIX_STRING = "inmem:"; - - /** The current object */ - protected Object currentValue; - - /** The class type */ - protected Class requiredType; - - /** The default command line interface text. */ - protected String defaultCLIString; - - /** The null text. */ - protected String nullString; - - /** - * Creates a new instance of an abstract option given its class name, - * command line interface text, its purpose, its class type and its default - * command line interface text. - * - * @param name the name of this option - * @param cliChar the command line interface text - * @param purpose the text describing the purpose of this option - * @param requiredType the class type - * @param defaultCLIString the default command line interface text - */ - public AbstractClassOption(String name, char cliChar, String purpose, - Class requiredType, String defaultCLIString) { - this(name, cliChar, purpose, requiredType, defaultCLIString, null); - } - - /** - * Creates a new instance of an abstract option given its class name, - * command line interface text, its purpose, its class type, default - * command line interface text, and its null text. - * - * @param name the name of this option - * @param cliChar the command line interface text - * @param purpose the text describing the purpose of this option - * @param requiredType the class type - * @param defaultCLIString the default command line interface text - * @param nullString the null text - */ - public AbstractClassOption(String name, char cliChar, String purpose, - Class requiredType, String defaultCLIString, String nullString) { - super(name, cliChar, purpose); - this.requiredType = requiredType; - this.defaultCLIString = defaultCLIString; - this.nullString = nullString; - resetToDefault(); - } - - /** - * Sets current object. - * - * @param obj the object to set as current. - */ - public void setCurrentObject(Object obj) { - if (((obj == null) && (this.nullString != null)) - || this.requiredType.isInstance(obj) - || (obj instanceof String) - || (obj instanceof File) - // || ((obj instanceof Task) && this.requiredType.isAssignableFrom(((Task) obj).getTaskResultType())) - ) { - this.currentValue = obj; - } else { - throw new IllegalArgumentException("Object not of required type."); - } - } - - /** - * Returns the current object. - * - * @return the current object - */ - public Object getValue() { //getPreMaterializedObject() { - return this.currentValue; - } - - /** - * Gets the class type of this option. - * - * @return the class type of this option - */ - public Class getRequiredType() { - return this.requiredType; - } - - /** - * Gets the null string of this option. - * - * @return the null string of this option - */ - public String getNullString() { - return this.nullString; - } - - /** - * Gets a materialized object of this option. - * - * @return the materialized object - */ - public Object materializeObject() { - if ((this.currentValue == null) - || this.requiredType.isInstance(this.currentValue)) { - return this.currentValue; - /* } else if (this.currentValue instanceof String) { - if (repository != null) { - Object inmemObj = repository.getObjectNamed((String) this.currentValue); - if (inmemObj == null) { - throw new RuntimeException("No object named " - + this.currentValue + " found in repository."); - } - return inmemObj; - } - throw new RuntimeException("No object repository available."); - */ - // } else if (this.currentValue instanceof Task) { - // Task task = (Task) this.currentValue; - // Object result = task.doTask(monitor, repository); - // return result; - } else if (this.currentValue instanceof File) { - File inputFile = (File) this.currentValue; - Object result = null; - try { - result = SerializeUtils.readFromFile(inputFile); - } catch (Exception ex) { - throw new RuntimeException("Problem loading " - + this.requiredType.getName() + " object from file '" - + inputFile.getName() + "':\n" + ex.getMessage(), ex); - } - return result; - } else { - throw new RuntimeException( - "Could not materialize object of required type " - + this.requiredType.getName() + ", found " - + this.currentValue.getClass().getName() - + " instead."); - } - } - - @Override - public String getDefaultCLIString() { - return this.defaultCLIString; - } - - /** - * Gets the command line interface text of the class. - * - * @param aClass the class - * @param requiredType the class type - * @return the command line interface text of the class - */ - public static String classToCLIString(Class aClass, Class requiredType) { - String className = aClass.getName(); - String packageName = requiredType.getPackage().getName(); - if (className.startsWith(packageName)) { - // cut off package name - className = className.substring(packageName.length() + 1, className.length()); - } /*else if (Task.class.isAssignableFrom(aClass)) { - packageName = Task.class.getPackage().getName(); - if (className.startsWith(packageName)) { - // cut off task package name - className = className.substring(packageName.length() + 1, - className.length()); - } - }*/ - return className; - } - - @Override - public abstract String getValueAsCLIString(); - - @Override - public abstract void setValueViaCLIString(String s); - - //@Override - //public abstract JComponent getEditComponent(); - - /** - * Gets the class name without its package name prefix. - * - * @param className the name of the class - * @param expectedType the type of the class - * @return the class name without its package name prefix - */ - public static String stripPackagePrefix(String className, Class expectedType) { - if (className.startsWith(expectedType.getPackage().getName())) { - return className.substring(expectedType.getPackage().getName().length() + 1); - } - return className; - } + private static final long serialVersionUID = 1L; + + /** The prefix text to use to indicate file. */ + public static final String FILE_PREFIX_STRING = "file:"; + + /** The prefix text to use to indicate inmem. */ + public static final String INMEM_PREFIX_STRING = "inmem:"; + + /** The current object */ + protected Object currentValue; + + /** The class type */ + protected Class requiredType; + + /** The default command line interface text. */ + protected String defaultCLIString; + + /** The null text. */ + protected String nullString; + + /** + * Creates a new instance of an abstract option given its class name, command + * line interface text, its purpose, its class type and its default command line + * interface text. + * + * @param name the name of this option + * @param cliChar the command line interface text + * @param purpose the text describing the purpose of this option + * @param requiredType the class type + * @param defaultCLIString the default command line interface text + */ + public AbstractClassOption(String name, char cliChar, String purpose, Class requiredType, + String defaultCLIString) { + this(name, cliChar, purpose, requiredType, defaultCLIString, null); + } + + /** + * Creates a new instance of an abstract option given its class name, command + * line interface text, its purpose, its class type, default command line + * interface text, and its null text. + * + * @param name the name of this option + * @param cliChar the command line interface text + * @param purpose the text describing the purpose of this option + * @param requiredType the class type + * @param defaultCLIString the default command line interface text + * @param nullString the null text + */ + public AbstractClassOption(String name, char cliChar, String purpose, Class requiredType, + String defaultCLIString, String nullString) { + super(name, cliChar, purpose); + this.requiredType = requiredType; + this.defaultCLIString = defaultCLIString; + this.nullString = nullString; + resetToDefault(); + } + + /** + * Sets current object. + * + * @param obj the object to set as current. + */ + public void setCurrentObject(Object obj) { + if (((obj == null) && (this.nullString != null)) || this.requiredType.isInstance(obj) || (obj instanceof String) + || (obj instanceof File) + // || ((obj instanceof Task) && this.requiredType.isAssignableFrom(((Task) + // obj).getTaskResultType())) + ) { + this.currentValue = obj; + } else { + throw new IllegalArgumentException("Object not of required type."); + } + } + + /** + * Returns the current object. + * + * @return the current object + */ + public Object getValue() { // getPreMaterializedObject() { + return this.currentValue; + } + + /** + * Gets the class type of this option. + * + * @return the class type of this option + */ + public Class getRequiredType() { + return this.requiredType; + } + + /** + * Gets the null string of this option. + * + * @return the null string of this option + */ + public String getNullString() { + return this.nullString; + } + + /** + * Gets a materialized object of this option. + * + * @return the materialized object + */ + public Object materializeObject() { + if ((this.currentValue == null) || this.requiredType.isInstance(this.currentValue)) { + return this.currentValue; + /* + * } else if (this.currentValue instanceof String) { if (repository != null) { + * Object inmemObj = repository.getObjectNamed((String) this.currentValue); if + * (inmemObj == null) { throw new RuntimeException("No object named " + + * this.currentValue + " found in repository."); } return inmemObj; } throw new + * RuntimeException("No object repository available."); + */ + // } else if (this.currentValue instanceof Task) { + // Task task = (Task) this.currentValue; + // Object result = task.doTask(monitor, repository); + // return result; + } else if (this.currentValue instanceof File) { + File inputFile = (File) this.currentValue; + Object result = null; + try { + result = SerializeUtils.readFromFile(inputFile); + } catch (Exception ex) { + throw new RuntimeException("Problem loading " + this.requiredType.getName() + " object from file '" + + inputFile.getName() + "':\n" + ex.getMessage(), ex); + } + return result; + } else { + throw new RuntimeException("Could not materialize object of required type " + this.requiredType.getName() + + ", found " + this.currentValue.getClass().getName() + " instead."); + } + } + + @Override + public String getDefaultCLIString() { + return this.defaultCLIString; + } + + /** + * Gets the command line interface text of the class. + * + * @param aClass the class + * @param requiredType the class type + * @return the command line interface text of the class + */ + public static String classToCLIString(Class aClass, Class requiredType) { + String className = aClass.getName(); + String packageName = requiredType.getPackage().getName(); + if (className.startsWith(packageName)) { + // cut off package name + className = className.substring(packageName.length() + 1, className.length()); + } /* + * else if (Task.class.isAssignableFrom(aClass)) { packageName = + * Task.class.getPackage().getName(); if (className.startsWith(packageName)) { + * // cut off task package name className = + * className.substring(packageName.length() + 1, className.length()); } } + */ + return className; + } + + @Override + public abstract String getValueAsCLIString(); + + @Override + public abstract void setValueViaCLIString(String s); + + // @Override + // public abstract JComponent getEditComponent(); + + /** + * Gets the class name without its package name prefix. + * + * @param className the name of the class + * @param expectedType the type of the class + * @return the class name without its package name prefix + */ + public static String stripPackagePrefix(String className, Class expectedType) { + if (className.startsWith(expectedType.getPackage().getName())) { + return className.substring(expectedType.getPackage().getName().length() + 1); + } + return className; + } } diff --git a/moa/src/main/java/com/github/javacliparser/AbstractOption.java b/moa/src/main/java/com/github/javacliparser/AbstractOption.java index 7c5e8a5c4..88082158c 100644 --- a/moa/src/main/java/com/github/javacliparser/AbstractOption.java +++ b/moa/src/main/java/com/github/javacliparser/AbstractOption.java @@ -1,18 +1,18 @@ /* * Copyright 2007 University of Waikato. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the - * License. + * License. */ package com.github.javacliparser; @@ -25,99 +25,96 @@ */ public abstract class AbstractOption implements Option { - /** Array of characters not valid to use in option names. */ - public static final char[] illegalNameCharacters = new char[]{' ', '-', - '(', ')'}; - - /** Name of this option. */ - protected String name; - - /** Command line interface text of this option. */ - protected char cliChar; - - /** Text of the purpose of this option. */ - protected String purpose; - - /** - * Gets whether the name is valid or not. - * - * @param optionName the name of the option - * @return true if the name that not contain any illegal character - */ - public static boolean nameIsLegal(String optionName) { - for (char illegalChar : illegalNameCharacters) { - if (optionName.indexOf(illegalChar) >= 0) { - return false; - } - } - return true; - } - - /** - * Creates a new instance of an abstract option given its class name, - * command line interface text and its purpose. - * - * @param name the name of this option - * @param cliChar the command line interface text - * @param purpose the text describing the purpose of this option - */ - public AbstractOption(String name, char cliChar, String purpose) { - if (!nameIsLegal(name)) { - throw new IllegalArgumentException("Illegal option name: " + name); - } - this.name = name; - this.cliChar = cliChar; - this.purpose = purpose; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public char getCLIChar() { - return this.cliChar; - } - - @Override - public String getPurpose() { - return this.purpose; - } - - @Override - public void resetToDefault() { - setValueViaCLIString(getDefaultCLIString()); - } - - @Override - public String getStateString() { - return getValueAsCLIString(); - } - - - @Override - public Option copy() { - try { - return (Option) SerializeUtils.copyObject(this); - } catch (Exception e) { - throw new RuntimeException("Object copy failed.", e); - } - } - - //@Override - //public Option copy() { - // return (Option) super.copy(); - //} - - - //@Override - //public void getDescription(StringBuilder sb, int indent) { - // TODO Auto-generated method stub - //} - - //@Override - //public JComponent getEditComponent() { - // return new StringOptionEditComponent(this); - //} + /** Array of characters not valid to use in option names. */ + public static final char[] illegalNameCharacters = new char[] { ' ', '-', '(', ')' }; + + /** Name of this option. */ + protected String name; + + /** Command line interface text of this option. */ + protected char cliChar; + + /** Text of the purpose of this option. */ + protected String purpose; + + /** + * Gets whether the name is valid or not. + * + * @param optionName the name of the option + * @return true if the name that not contain any illegal character + */ + public static boolean nameIsLegal(String optionName) { + for (char illegalChar : illegalNameCharacters) { + if (optionName.indexOf(illegalChar) >= 0) { + return false; + } + } + return true; + } + + /** + * Creates a new instance of an abstract option given its class name, command + * line interface text and its purpose. + * + * @param name the name of this option + * @param cliChar the command line interface text + * @param purpose the text describing the purpose of this option + */ + public AbstractOption(String name, char cliChar, String purpose) { + if (!nameIsLegal(name)) { + throw new IllegalArgumentException("Illegal option name: " + name); + } + this.name = name; + this.cliChar = cliChar; + this.purpose = purpose; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public char getCLIChar() { + return this.cliChar; + } + + @Override + public String getPurpose() { + return this.purpose; + } + + @Override + public void resetToDefault() { + setValueViaCLIString(getDefaultCLIString()); + } + + @Override + public String getStateString() { + return getValueAsCLIString(); + } + + @Override + public Option copy() { + try { + return (Option) SerializeUtils.copyObject(this); + } catch (Exception e) { + throw new RuntimeException("Object copy failed.", e); + } + } + + // @Override + // public Option copy() { + // return (Option) super.copy(); + // } + + // @Override + // public void getDescription(StringBuilder sb, int indent) { + // TODO Auto-generated method stub + // } + + // @Override + // public JComponent getEditComponent() { + // return new StringOptionEditComponent(this); + // } } diff --git a/moa/src/main/java/com/github/javacliparser/ClassOption.java b/moa/src/main/java/com/github/javacliparser/ClassOption.java index da14691e6..09801c5d5 100644 --- a/moa/src/main/java/com/github/javacliparser/ClassOption.java +++ b/moa/src/main/java/com/github/javacliparser/ClassOption.java @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * */ package com.github.javacliparser; @@ -31,166 +31,152 @@ */ public class ClassOption extends AbstractClassOption { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; + + public ClassOption(String name, char cliChar, String purpose, Class requiredType, String defaultCLIString) { + super(name, cliChar, purpose, requiredType, defaultCLIString); + } + + public ClassOption(String name, char cliChar, String purpose, Class requiredType, String defaultCLIString, + String nullString) { + super(name, cliChar, purpose, requiredType, defaultCLIString, nullString); + } - public ClassOption(String name, char cliChar, String purpose, - Class requiredType, String defaultCLIString) { - super(name, cliChar, purpose, requiredType, defaultCLIString); - } + @Override + public String getValueAsCLIString() { + if ((this.currentValue == null) && (this.nullString != null)) { + return this.nullString; + } + return objectToCLIString(this.currentValue, this.requiredType); + } - public ClassOption(String name, char cliChar, String purpose, - Class requiredType, String defaultCLIString, String nullString) { - super(name, cliChar, purpose, requiredType, defaultCLIString, nullString); - } + @Override + public void setValueViaCLIString(String s) { + if ((this.nullString != null) && ((s == null) || (s.length() == 0) || s.equals(this.nullString))) { + this.currentValue = null; + } else { + try { + this.currentValue = cliStringToObject(s, this.requiredType, null); + } catch (Exception e) { + throw new IllegalArgumentException("Problems with option: " + getName(), e); + } + } + } - @Override - public String getValueAsCLIString() { - if ((this.currentValue == null) && (this.nullString != null)) { - return this.nullString; - } - return objectToCLIString(this.currentValue, this.requiredType); - } + public static String objectToCLIString(Object obj, Class requiredType) { + if (obj == null) { + return ""; + } + if (obj instanceof File) { + return (FILE_PREFIX_STRING + ((File) obj).getPath()); + } + if (obj instanceof String) { + return (INMEM_PREFIX_STRING + obj); + } + String className = classToCLIString(obj.getClass(), requiredType); + if (obj instanceof Configurable) { + // String subOptions = ((Configurable) obj).getOptions().getAsCLIString(); + // Add cli parser + JavaCLIParser config = new JavaCLIParser(obj, ""); + String subOptions = config.getOptions().getAsCLIString(); + if (subOptions.length() > 0) { + return (className + " " + subOptions); + } + } + return className; + } - @Override - public void setValueViaCLIString(String s) { - if ((this.nullString != null) - && ((s == null) || (s.length() == 0) || s.equals(this.nullString))) { - this.currentValue = null; - } else { - try { - this.currentValue = cliStringToObject(s, this.requiredType, - null); - } catch (Exception e) { - throw new IllegalArgumentException("Problems with option: " + getName(), e); - } - } - } + public static Object createObject(String cliString, Class requiredType) throws Exception { + return cliStringToObject(cliString, requiredType, null); + } - public static String objectToCLIString(Object obj, Class requiredType) { - if (obj == null) { - return ""; - } - if (obj instanceof File) { - return (FILE_PREFIX_STRING + ((File) obj).getPath()); - } - if (obj instanceof String) { - return (INMEM_PREFIX_STRING + obj); - } - String className = classToCLIString(obj.getClass(), requiredType); - if (obj instanceof Configurable) { - //String subOptions = ((Configurable) obj).getOptions().getAsCLIString(); - //Add cli parser - JavaCLIParser config = new JavaCLIParser(obj, ""); - String subOptions = config.getOptions().getAsCLIString(); - if (subOptions.length() > 0) { - return (className + " " + subOptions); - } - } - return className; - } + public static Object createObject(String[] args, Class requiredType) throws Exception { + // build a single string by concatenating cli options + StringBuilder cliString = new StringBuilder(); + for (int i = 0; i < args.length; i++) { + cliString.append(" ").append(args[i]); + } + return cliStringToObject(cliString.toString(), requiredType, null); + } - public static Object createObject(String cliString, - Class requiredType) throws Exception { - return cliStringToObject(cliString, requiredType, null); - } - - - public static Object createObject(String[] args, - Class requiredType) throws Exception { - // build a single string by concatenating cli options - StringBuilder cliString = new StringBuilder(); - for (int i = 0; i < args.length; i++) { - cliString.append(" ").append(args[i]); - } - return cliStringToObject(cliString.toString(), requiredType, null); - } - - - public static Object cliStringToObject(String cliString, - Class requiredType, Option[] externalOptions) throws Exception { - if (cliString.startsWith(FILE_PREFIX_STRING)) { - return new File(cliString.substring(FILE_PREFIX_STRING.length())); - } - if (cliString.startsWith(INMEM_PREFIX_STRING)) { - return cliString.substring(INMEM_PREFIX_STRING.length()); - } - cliString = cliString.trim(); - int firstSpaceIndex = cliString.indexOf(' ', 0); - String className; - String classOptions; - if (firstSpaceIndex > 0) { - className = cliString.substring(0, firstSpaceIndex); - classOptions = cliString.substring(firstSpaceIndex + 1, cliString.length()); - classOptions = classOptions.trim(); - } else { - className = cliString; - classOptions = ""; - } - Class classObject; - try { - classObject = Class.forName(className); - } catch (Throwable t1) { - try { - // try prepending default package - classObject = Class.forName(requiredType.getPackage().getName() - + "." + className); - /*} catch (Throwable t2) { - try { - // try prepending task package - classObject = Class.forName(Task.class.getPackage().getName() - + "." + className); - */} catch (Throwable t3) { - throw new Exception("Class not found: " + className); - //} - } - } - Object classInstance; - try { - classInstance = classObject.newInstance(); - } catch (Exception ex) { - throw new Exception("Problem creating instance of class: " - + className, ex); - } - if (requiredType.isInstance(classInstance) - // || ((classInstance instanceof Task) && requiredType.isAssignableFrom(((Task) classInstance).getTaskResultType())) - ) { - Options options = new Options(); - JavaCLIParser config = null; - if (externalOptions != null) { - for (Option option : externalOptions) { - options.addOption(option); - } - } - if (classInstance instanceof Configurable) { - config = new JavaCLIParser(classInstance, ""); - Option[] objectOptions = config.getOptions().getOptionArray(); - //Option[] objectOptions = ((Configurable) classInstance).getOptions().getOptionArray(); - for (Option option : objectOptions) { - options.addOption(option); - } - } - try { - options.setViaCLIString(classOptions); - } catch (Exception ex) { - throw new Exception("Problem with options to '" - + className - + "'." - + "\n\nValid options for " - + className - + ":\n" - + config == null ? "": config.getOptions().getHelpString(), ex); - } finally { - options.removeAllOptions(); // clean up listener refs - } - } else { - throw new Exception("Class named '" + className - + "' is not an instance of " + requiredType.getName() + "."); - } - return classInstance; - } + public static Object cliStringToObject(String cliString, Class requiredType, Option[] externalOptions) + throws Exception { + if (cliString.startsWith(FILE_PREFIX_STRING)) { + return new File(cliString.substring(FILE_PREFIX_STRING.length())); + } + if (cliString.startsWith(INMEM_PREFIX_STRING)) { + return cliString.substring(INMEM_PREFIX_STRING.length()); + } + cliString = cliString.trim(); + int firstSpaceIndex = cliString.indexOf(' ', 0); + String className; + String classOptions; + if (firstSpaceIndex > 0) { + className = cliString.substring(0, firstSpaceIndex); + classOptions = cliString.substring(firstSpaceIndex + 1, cliString.length()); + classOptions = classOptions.trim(); + } else { + className = cliString; + classOptions = ""; + } + Class classObject; + try { + classObject = Class.forName(className); + } catch (Throwable t1) { + try { + // try prepending default package + classObject = Class.forName(requiredType.getPackage().getName() + "." + className); + /* + * } catch (Throwable t2) { try { // try prepending task package classObject = + * Class.forName(Task.class.getPackage().getName() + "." + className); + */} catch (Throwable t3) { + throw new Exception("Class not found: " + className); + // } + } + } + Object classInstance; + try { + classInstance = classObject.newInstance(); + } catch (Exception ex) { + throw new Exception("Problem creating instance of class: " + className, ex); + } + if (requiredType.isInstance(classInstance) + // || ((classInstance instanceof Task) && requiredType.isAssignableFrom(((Task) + // classInstance).getTaskResultType())) + ) { + Options options = new Options(); + JavaCLIParser config = null; + if (externalOptions != null) { + for (Option option : externalOptions) { + options.addOption(option); + } + } + if (classInstance instanceof Configurable) { + config = new JavaCLIParser(classInstance, ""); + Option[] objectOptions = config.getOptions().getOptionArray(); + // Option[] objectOptions = ((Configurable) + // classInstance).getOptions().getOptionArray(); + for (Option option : objectOptions) { + options.addOption(option); + } + } + try { + options.setViaCLIString(classOptions); + } catch (Exception ex) { + throw new Exception("Problem with options to '" + className + "'." + "\n\nValid options for " + + className + ":\n" + config == null ? "" : config.getOptions().getHelpString(), ex); + } finally { + options.removeAllOptions(); // clean up listener refs + } + } else { + throw new Exception( + "Class named '" + className + "' is not an instance of " + requiredType.getName() + "."); + } + return classInstance; + } - //@Override - //public JComponent getEditComponent() { - // return new ClassOptionEditComponent(this); - //} + // @Override + // public JComponent getEditComponent() { + // return new ClassOptionEditComponent(this); + // } } diff --git a/moa/src/main/java/com/github/javacliparser/Configurable.java b/moa/src/main/java/com/github/javacliparser/Configurable.java index 0fae2408d..98c181bab 100644 --- a/moa/src/main/java/com/github/javacliparser/Configurable.java +++ b/moa/src/main/java/com/github/javacliparser/Configurable.java @@ -1,18 +1,18 @@ /* * Copyright 2007 University of Waikato. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the - * License. + * License. */ package com.github.javacliparser; @@ -20,50 +20,50 @@ /** * Configurable interface. - * + * * @author abifet */ public interface Configurable extends Serializable { - - /** - * Gets the purpose of this object - * - * @return the string with the purpose of this object - */ - //public String getPurposeString(); - /** - * Gets the options of this object - * - * @return the options of this object - */ - //public Options getOptions(); + /** + * Gets the purpose of this object + * + * @return the string with the purpose of this object + */ + // public String getPurposeString(); - /** - * This method prepares this object for use. - * - */ - //public void prepareForUse(); + /** + * Gets the options of this object + * + * @return the options of this object + */ + // public Options getOptions(); - /** - * This method prepares this object for use. - * - * @param monitor the TaskMonitor to use - * @param repository the ObjectRepository to use - */ - //public void prepareForUse(TaskMonitor monitor, ObjectRepository repository); + /** + * This method prepares this object for use. + * + */ + // public void prepareForUse(); - /** - * This method produces a copy of this object. - * - * @return a copy of this object - */ - //public Configurable copy(); + /** + * This method prepares this object for use. + * + * @param monitor the TaskMonitor to use + * @param repository the ObjectRepository to use + */ + // public void prepareForUse(TaskMonitor monitor, ObjectRepository repository); - /** - * Gets the Command Line Interface text to create the object - * - * @return the Command Line Interface text to create the object - */ - //public String getCLICreationString(Class expectedType); + /** + * This method produces a copy of this object. + * + * @return a copy of this object + */ + // public Configurable copy(); + + /** + * Gets the Command Line Interface text to create the object + * + * @return the Command Line Interface text to create the object + */ + // public String getCLICreationString(Class expectedType); } diff --git a/moa/src/main/java/com/github/javacliparser/FileOption.java b/moa/src/main/java/com/github/javacliparser/FileOption.java index d706e498f..19b2b3b7f 100644 --- a/moa/src/main/java/com/github/javacliparser/FileOption.java +++ b/moa/src/main/java/com/github/javacliparser/FileOption.java @@ -1,18 +1,18 @@ /* * Copyright 2007 University of Waikato. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the - * License. + * License. */ package com.github.javacliparser; @@ -27,36 +27,36 @@ */ public class FileOption extends StringOption { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - protected String defaultFileExtension; + protected String defaultFileExtension; - protected boolean isOutputFile; + protected boolean isOutputFile; - public FileOption(String name, char cliChar, String purpose, - String defaultFileName, String defaultExtension, boolean isOutput) { - super(name, cliChar, purpose, defaultFileName); - this.defaultFileExtension = defaultExtension; - this.isOutputFile = isOutput; - } + public FileOption(String name, char cliChar, String purpose, String defaultFileName, String defaultExtension, + boolean isOutput) { + super(name, cliChar, purpose, defaultFileName); + this.defaultFileExtension = defaultExtension; + this.isOutputFile = isOutput; + } - public String getDefaultFileExtension() { - return this.defaultFileExtension; - } + public String getDefaultFileExtension() { + return this.defaultFileExtension; + } - public boolean isOutputFile() { - return this.isOutputFile; - } + public boolean isOutputFile() { + return this.isOutputFile; + } - public File getFile() { - if ((getValue() != null) && (getValue().length() > 0)) { - return new File(getValue()); - } - return null; - } + public File getFile() { + if ((getValue() != null) && (getValue().length() > 0)) { + return new File(getValue()); + } + return null; + } - //@Override - //public JComponent getEditComponent() { - // return new FileOptionEditComponent(this); - //} + // @Override + // public JComponent getEditComponent() { + // return new FileOptionEditComponent(this); + // } } diff --git a/moa/src/main/java/com/github/javacliparser/FlagOption.java b/moa/src/main/java/com/github/javacliparser/FlagOption.java index ec51549a1..731a307e0 100644 --- a/moa/src/main/java/com/github/javacliparser/FlagOption.java +++ b/moa/src/main/java/com/github/javacliparser/FlagOption.java @@ -1,18 +1,18 @@ /* * Copyright 2007 University of Waikato. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the - * License. + * License. */ package com.github.javacliparser; @@ -25,52 +25,52 @@ */ public class FlagOption extends AbstractOption { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - protected boolean isSet = false; + protected boolean isSet = false; - public FlagOption(String name, char cliChar, String purpose) { - super(name, cliChar, purpose); - } + public FlagOption(String name, char cliChar, String purpose) { + super(name, cliChar, purpose); + } - public void setValue(boolean v) { - this.isSet = v; - } + public void setValue(boolean v) { + this.isSet = v; + } - public void set() { - setValue(true); - } + public void set() { + setValue(true); + } - public void unset() { - setValue(false); - } + public void unset() { + setValue(false); + } - public boolean isSet() { - return this.isSet; - } + public boolean isSet() { + return this.isSet; + } - @Override - public String getDefaultCLIString() { - return null; - } + @Override + public String getDefaultCLIString() { + return null; + } - @Override - public String getValueAsCLIString() { - return this.isSet ? "" : null; - } + @Override + public String getValueAsCLIString() { + return this.isSet ? "" : null; + } - @Override - public void setValueViaCLIString(String s) { - this.isSet = (s != null); - } + @Override + public void setValueViaCLIString(String s) { + this.isSet = (s != null); + } - @Override - public String getStateString() { - return this.isSet ? "true" : "false"; - } + @Override + public String getStateString() { + return this.isSet ? "true" : "false"; + } - //@Override - //public JComponent getEditComponent() { - // return new FlagOptionEditComponent(this); - //} + // @Override + // public JComponent getEditComponent() { + // return new FlagOptionEditComponent(this); + // } } diff --git a/moa/src/main/java/com/github/javacliparser/FloatOption.java b/moa/src/main/java/com/github/javacliparser/FloatOption.java index 72dc33ab0..eda92b0a4 100644 --- a/moa/src/main/java/com/github/javacliparser/FloatOption.java +++ b/moa/src/main/java/com/github/javacliparser/FloatOption.java @@ -1,18 +1,18 @@ /* * Copyright 2007 University of Waikato. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the - * License. + * License. */ package com.github.javacliparser; @@ -25,82 +25,77 @@ */ public class FloatOption extends AbstractOption { - private static final long serialVersionUID = 1L; - - protected double currentVal; - - protected double defaultVal; - - protected double minVal; - - protected double maxVal; - - public FloatOption(String name, char cliChar, String purpose, - double defaultVal) { - this(name, cliChar, purpose, defaultVal, Double.NEGATIVE_INFINITY, - Double.POSITIVE_INFINITY); - } - - public FloatOption(String name, char cliChar, String purpose, - double defaultVal, double minVal, double maxVal) { - super(name, cliChar, purpose); - this.defaultVal = defaultVal; - this.minVal = minVal; - this.maxVal = maxVal; - resetToDefault(); - } - - public void setValue(double v) { - if (v < this.minVal) { - throw new IllegalArgumentException("Option " + getName() - + " cannot be less than " + this.minVal - + ", out of range: " + v); - } - if (v > this.maxVal) { - throw new IllegalArgumentException("Option " + getName() - + " cannot be greater than " + this.maxVal - + ", out of range: " + v); - } - this.currentVal = v; - } - - public double getValue() { - return this.currentVal; - } - - public double getMinValue() { - return this.minVal; - } - - public double getMaxValue() { - return this.maxVal; - } - - @Override - public String getDefaultCLIString() { - return doubleToCLIString(this.defaultVal); - } - - @Override - public String getValueAsCLIString() { - return doubleToCLIString(this.currentVal); - } - - @Override - public void setValueViaCLIString(String s) { - setValue(cliStringToDouble(s)); - } - - public static double cliStringToDouble(String s) { - return Double.parseDouble(s.trim()); - } - - public static String doubleToCLIString(double d) { - return Double.toString(d); - } - - //@Override - //public JComponent getEditComponent() { - // return new FloatOptionEditComponent(this); - //} + private static final long serialVersionUID = 1L; + + protected double currentVal; + + protected double defaultVal; + + protected double minVal; + + protected double maxVal; + + public FloatOption(String name, char cliChar, String purpose, double defaultVal) { + this(name, cliChar, purpose, defaultVal, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); + } + + public FloatOption(String name, char cliChar, String purpose, double defaultVal, double minVal, double maxVal) { + super(name, cliChar, purpose); + this.defaultVal = defaultVal; + this.minVal = minVal; + this.maxVal = maxVal; + resetToDefault(); + } + + public void setValue(double v) { + if (v < this.minVal) { + throw new IllegalArgumentException( + "Option " + getName() + " cannot be less than " + this.minVal + ", out of range: " + v); + } + if (v > this.maxVal) { + throw new IllegalArgumentException( + "Option " + getName() + " cannot be greater than " + this.maxVal + ", out of range: " + v); + } + this.currentVal = v; + } + + public double getValue() { + return this.currentVal; + } + + public double getMinValue() { + return this.minVal; + } + + public double getMaxValue() { + return this.maxVal; + } + + @Override + public String getDefaultCLIString() { + return doubleToCLIString(this.defaultVal); + } + + @Override + public String getValueAsCLIString() { + return doubleToCLIString(this.currentVal); + } + + @Override + public void setValueViaCLIString(String s) { + setValue(cliStringToDouble(s)); + } + + public static double cliStringToDouble(String s) { + return Double.parseDouble(s.trim()); + } + + public static String doubleToCLIString(double d) { + return Double.toString(d); + } + + // @Override + // public JComponent getEditComponent() { + // return new FloatOptionEditComponent(this); + // } } diff --git a/moa/src/main/java/com/github/javacliparser/IntOption.java b/moa/src/main/java/com/github/javacliparser/IntOption.java index e7cf6b24f..6c64104d7 100644 --- a/moa/src/main/java/com/github/javacliparser/IntOption.java +++ b/moa/src/main/java/com/github/javacliparser/IntOption.java @@ -1,18 +1,18 @@ /* * Copyright 2007 University of Waikato. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the - * License. + * License. */ package com.github.javacliparser; @@ -25,81 +25,77 @@ */ public class IntOption extends AbstractOption { - private static final long serialVersionUID = 1L; - - protected int currentVal; - - protected int defaultVal; - - protected int minVal; - - protected int maxVal; - - public IntOption(String name, char cliChar, String purpose, int defaultVal) { - this(name, cliChar, purpose, defaultVal, Integer.MIN_VALUE, - Integer.MAX_VALUE); - } - - public IntOption(String name, char cliChar, String purpose, int defaultVal, - int minVal, int maxVal) { - super(name, cliChar, purpose); - this.defaultVal = defaultVal; - this.minVal = minVal; - this.maxVal = maxVal; - resetToDefault(); - } - - public void setValue(int v) { - if (v < this.minVal) { - throw new IllegalArgumentException("Option " + getName() - + " cannot be less than " + this.minVal - + ", out of range: " + v); - } - if (v > this.maxVal) { - throw new IllegalArgumentException("Option " + getName() - + " cannot be greater than " + this.maxVal - + ", out of range: " + v); - } - this.currentVal = v; - } - - public int getValue() { - return this.currentVal; - } - - public int getMinValue() { - return this.minVal; - } - - public int getMaxValue() { - return this.maxVal; - } - - @Override - public String getDefaultCLIString() { - return intToCLIString(this.defaultVal); - } - - @Override - public String getValueAsCLIString() { - return intToCLIString(this.currentVal); - } - - @Override - public void setValueViaCLIString(String s) { - setValue(cliStringToInt(s)); - } - - public static int cliStringToInt(String s) { - return Integer.parseInt(s.trim()); - } - - public static String intToCLIString(int i) { - return Integer.toString(i); - } - - //@Override - //public JComponent getEditComponent() { - // return new IntOptionEditComponent(this); - //} + private static final long serialVersionUID = 1L; + + protected int currentVal; + + protected int defaultVal; + + protected int minVal; + + protected int maxVal; + + public IntOption(String name, char cliChar, String purpose, int defaultVal) { + this(name, cliChar, purpose, defaultVal, Integer.MIN_VALUE, Integer.MAX_VALUE); + } + + public IntOption(String name, char cliChar, String purpose, int defaultVal, int minVal, int maxVal) { + super(name, cliChar, purpose); + this.defaultVal = defaultVal; + this.minVal = minVal; + this.maxVal = maxVal; + resetToDefault(); + } + + public void setValue(int v) { + if (v < this.minVal) { + throw new IllegalArgumentException( + "Option " + getName() + " cannot be less than " + this.minVal + ", out of range: " + v); + } + if (v > this.maxVal) { + throw new IllegalArgumentException( + "Option " + getName() + " cannot be greater than " + this.maxVal + ", out of range: " + v); + } + this.currentVal = v; + } + + public int getValue() { + return this.currentVal; + } + + public int getMinValue() { + return this.minVal; + } + + public int getMaxValue() { + return this.maxVal; + } + + @Override + public String getDefaultCLIString() { + return intToCLIString(this.defaultVal); + } + + @Override + public String getValueAsCLIString() { + return intToCLIString(this.currentVal); + } + + @Override + public void setValueViaCLIString(String s) { + setValue(cliStringToInt(s)); + } + + public static int cliStringToInt(String s) { + return Integer.parseInt(s.trim()); + } + + public static String intToCLIString(int i) { + return Integer.toString(i); + } + + // @Override + // public JComponent getEditComponent() { + // return new IntOptionEditComponent(this); + // } } diff --git a/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java b/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java index 68191078c..269ae7b11 100644 --- a/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java +++ b/moa/src/main/java/com/github/javacliparser/JavaCLIParser.java @@ -1,18 +1,18 @@ /* * Copyright 2007 University of Waikato. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the - * License. + * License. */ package com.github.javacliparser; @@ -32,103 +32,101 @@ */ public class JavaCLIParser implements Serializable { - public Object handler; - - public JavaCLIParser(Object c, String cliString) { - this.handler = c; - } - - private static final long serialVersionUID = 1L; + public Object handler; + + public JavaCLIParser(Object c, String cliString) { + this.handler = c; + } - /** Options to handle */ - protected Options options; + private static final long serialVersionUID = 1L; - /** Dictionary with option texts and objects */ - protected Map classOptionNamesToPreparedObjects; + /** Options to handle */ + protected Options options; + /** Dictionary with option texts and objects */ + protected Map classOptionNamesToPreparedObjects; - public String getPurposeString() { - return "Anonymous object: purpose undocumented."; - } + public String getPurposeString() { + return "Anonymous object: purpose undocumented."; + } - public Options getOptions() { - if (this.options == null) { - this.options = new Options(); - Option[] myOptions = discoverOptionsViaReflection(); - for (Option option : myOptions) { - this.options.addOption(option); - } - } - return this.options; - } + public Options getOptions() { + if (this.options == null) { + this.options = new Options(); + Option[] myOptions = discoverOptionsViaReflection(); + for (Option option : myOptions) { + this.options.addOption(option); + } + } + return this.options; + } - /** - * Gets the options of this class via reflection. - * - * @return an array of options - */ - public Option[] discoverOptionsViaReflection() { - //Class c = this.getClass(); - Class c = this.handler.getClass(); - Field[] fields = c.getFields(); - List