Search in sources :

Example 1 with ResultHierarchy

use of de.lmu.ifi.dbs.elki.result.ResultHierarchy in project elki by elki-project.

the class TooltipScoreVisualization method processNewResult.

@Override
public void processNewResult(VisualizerContext context, Object result) {
    final ResultHierarchy hier = context.getHierarchy();
    // TODO: we can also visualize other scores!
    VisualizationTree.findNewSiblings(context, result, OutlierResult.class, ScatterPlotProjector.class, (o, p) -> {
        final Relation<?> rel = p.getRelation();
        if (!TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) {
            return;
        }
        addTooltips(o.getLongName() + NAME_GEN, o.getScores(), context, p, rel);
    });
    VisualizationTree.findNewSiblings(context, result, Relation.class, ScatterPlotProjector.class, (r, p) -> {
        if (hier.iterParents(r).filter(OutlierResult.class).valid()) {
            // Handled by above case already.
            return;
        }
        if (!TypeUtil.DOUBLE.isAssignableFromType(r.getDataTypeInformation()) && !TypeUtil.INTEGER.isAssignableFromType(r.getDataTypeInformation())) {
            return;
        }
        final Relation<?> rel = p.getRelation();
        if (!TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) {
            return;
        }
        addTooltips(r.getLongName() + NAME_GEN, r, context, p, rel);
    });
}
Also used : ResultHierarchy(de.lmu.ifi.dbs.elki.result.ResultHierarchy) OutlierResult(de.lmu.ifi.dbs.elki.result.outlier.OutlierResult)

Example 2 with ResultHierarchy

use of de.lmu.ifi.dbs.elki.result.ResultHierarchy in project elki by elki-project.

the class VisualizePairwiseGainMatrix method run.

@Override
public void run() {
    final Database database = inputstep.getDatabase();
    ResultHierarchy hier = database.getHierarchy();
    Relation<NumberVector> relation = database.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
    final Relation<String> labels = DatabaseUtil.guessLabelRepresentation(database);
    final DBID firstid = DBIDUtil.deref(labels.iterDBIDs());
    final String firstlabel = labels.get(firstid);
    if (!firstlabel.matches(".*by.?label.*")) {
        throw new AbortException("No 'by label' reference outlier found, which is needed for weighting!");
    }
    relation = GreedyEnsembleExperiment.applyPrescaling(prescaling, relation, firstid);
    // Dimensionality and reference vector
    final int dim = RelationUtil.dimensionality(relation);
    final NumberVector refvec = relation.get(firstid);
    // Build the truth vector
    VectorNonZero pos = new VectorNonZero(refvec);
    ArrayModifiableDBIDs ids = DBIDUtil.newArray(relation.getDBIDs());
    ids.remove(firstid);
    ids.sort();
    final int size = ids.size();
    double[][] data = new double[size][size];
    DoubleMinMax minmax = new DoubleMinMax(), commax = new DoubleMinMax();
    {
        FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Computing ensemble gain.", size * (size + 1) >> 1, LOG) : null;
        // Vote combination buffer.
        double[] buf = new double[2];
        int a = 0;
        for (DBIDIter id = ids.iter(); id.valid(); id.advance(), a++) {
            final NumberVector veca = relation.get(id);
            // Direct AUC score:
            {
                double auc = ROCEvaluation.computeROCAUC(pos, new DecreasingVectorIter(veca));
                data[a][a] = auc;
                // minmax.put(auc);
                LOG.incrementProcessed(prog);
            }
            // Compare to others, exploiting symmetry
            DBIDArrayIter id2 = ids.iter();
            id2.seek(a + 1);
            for (int b = a + 1; b < size; b++, id2.advance()) {
                final NumberVector vecb = relation.get(id2);
                double[] combined = new double[dim];
                for (int d = 0; d < dim; d++) {
                    buf[0] = veca.doubleValue(d);
                    buf[1] = vecb.doubleValue(d);
                    combined[d] = voting.combine(buf);
                }
                double auc = ROCEvaluation.computeROCAUC(pos, new DecreasingVectorIter(DoubleVector.wrap(combined)));
                // logger.verbose(auc + " " + labels.get(ids.get(a)) + " " +
                // labels.get(ids.get(b)));
                data[a][b] = auc;
                data[b][a] = auc;
                commax.put(data[a][b]);
                // minmax.put(auc);
                LOG.incrementProcessed(prog);
            }
        }
        LOG.ensureCompleted(prog);
    }
    for (int a = 0; a < size; a++) {
        for (int b = a + 1; b < size; b++) {
            double ref = Math.max(data[a][a], data[b][b]);
            data[a][b] = (data[a][b] - ref) / (1 - ref);
            data[b][a] = (data[b][a] - ref) / (1 - ref);
            // logger.verbose(data[a][b] + " " + labels.get(ids.get(a)) + " " +
            // labels.get(ids.get(b)));
            minmax.put(data[a][b]);
        }
    }
    for (int a = 0; a < size; a++) {
        data[a][a] = 0;
    }
    LOG.verbose("Gain: " + minmax.toString() + " AUC: " + commax.toString());
    boolean hasneg = (minmax.getMin() < -1E-3);
    LinearScaling scale;
    if (!hasneg) {
        scale = LinearScaling.fromMinMax(0., minmax.getMax());
    } else {
        scale = LinearScaling.fromMinMax(0.0, Math.max(minmax.getMax(), -minmax.getMin()));
    }
    scale = LinearScaling.fromMinMax(0., .5);
    BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
    for (int x = 0; x < size; x++) {
        for (int y = x; y < size; y++) {
            double val = data[x][y];
            val = Math.max(-1, Math.min(1., scale.getScaled(val)));
            // Compute color:
            final int col;
            {
                if (val >= 0) {
                    int ival = 0xFF & (int) (255 * val);
                    col = 0xff000000 | (ival << 8);
                } else {
                    int ival = 0xFF & (int) (255 * -val);
                    col = 0xff000000 | (ival << 16);
                }
            }
            img.setRGB(x, y, col);
            img.setRGB(y, x, col);
        }
    }
    SimilarityMatrix smat = new ComputeSimilarityMatrixImage.SimilarityMatrix(img, relation, ids);
    hier.add(database, smat);
    VisualizerContext context = vispar.newContext(hier, smat);
    // Attach visualizers to results
    SimilarityMatrixVisualizer factory = new SimilarityMatrixVisualizer();
    factory.processNewResult(context, database);
    VisualizationTree.findVis(context).filter(VisualizationTask.class).forEach(task -> {
        if (task.getFactory() == factory) {
            showVisualization(context, factory, task);
        }
    });
}
Also used : DecreasingVectorIter(de.lmu.ifi.dbs.elki.evaluation.scores.adapter.DecreasingVectorIter) SimilarityMatrix(de.lmu.ifi.dbs.elki.evaluation.similaritymatrix.ComputeSimilarityMatrixImage.SimilarityMatrix) BufferedImage(java.awt.image.BufferedImage) SimilarityMatrixVisualizer(de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.SimilarityMatrixVisualizer) LinearScaling(de.lmu.ifi.dbs.elki.utilities.scaling.LinearScaling) VisualizationTask(de.lmu.ifi.dbs.elki.visualization.VisualizationTask) DoubleMinMax(de.lmu.ifi.dbs.elki.math.DoubleMinMax) Database(de.lmu.ifi.dbs.elki.database.Database) ResultHierarchy(de.lmu.ifi.dbs.elki.result.ResultHierarchy) FiniteProgress(de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress) NumberVector(de.lmu.ifi.dbs.elki.data.NumberVector) VisualizerContext(de.lmu.ifi.dbs.elki.visualization.VisualizerContext) AbortException(de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException) VectorNonZero(de.lmu.ifi.dbs.elki.evaluation.scores.adapter.VectorNonZero)

Example 3 with ResultHierarchy

use of de.lmu.ifi.dbs.elki.result.ResultHierarchy in project elki by elki-project.

the class RepresentativeUncertainClustering method run.

/**
 * This run method will do the wrapping.
 *
 * Its called from {@link AbstractAlgorithm#run(Database)} and performs the
 * call to the algorithms particular run method as well as the storing and
 * comparison of the resulting Clusterings.
 *
 * @param database Database
 * @param relation Data relation of uncertain objects
 * @return Clustering result
 */
public Clustering<?> run(Database database, Relation<? extends UncertainObject> relation) {
    ResultHierarchy hierarchy = database.getHierarchy();
    ArrayList<Clustering<?>> clusterings = new ArrayList<>();
    final int dim = RelationUtil.dimensionality(relation);
    DBIDs ids = relation.getDBIDs();
    // To collect samples
    Result samples = new BasicResult("Samples", "samples");
    // Step 1: Cluster sampled possible worlds:
    Random rand = random.getSingleThreadedRandom();
    FiniteProgress sampleP = LOG.isVerbose() ? new FiniteProgress("Clustering samples", numsamples, LOG) : null;
    for (int i = 0; i < numsamples; i++) {
        WritableDataStore<DoubleVector> store = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_DB, DoubleVector.class);
        for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
            store.put(iter, relation.get(iter).drawSample(rand));
        }
        clusterings.add(runClusteringAlgorithm(hierarchy, samples, ids, store, dim, "Sample " + i));
        LOG.incrementProcessed(sampleP);
    }
    LOG.ensureCompleted(sampleP);
    // Step 2: perform the meta clustering (on samples only).
    DBIDRange rids = DBIDFactory.FACTORY.generateStaticDBIDRange(clusterings.size());
    WritableDataStore<Clustering<?>> datastore = DataStoreUtil.makeStorage(rids, DataStoreFactory.HINT_DB, Clustering.class);
    {
        Iterator<Clustering<?>> it2 = clusterings.iterator();
        for (DBIDIter iter = rids.iter(); iter.valid(); iter.advance()) {
            datastore.put(iter, it2.next());
        }
    }
    assert (rids.size() == clusterings.size());
    // Build a relation, and a distance matrix.
    Relation<Clustering<?>> crel = new MaterializedRelation<Clustering<?>>(Clustering.TYPE, rids, "Clusterings", datastore);
    PrecomputedDistanceMatrix<Clustering<?>> mat = new PrecomputedDistanceMatrix<>(crel, rids, distance);
    mat.initialize();
    ProxyDatabase d = new ProxyDatabase(rids, crel);
    d.getHierarchy().add(crel, mat);
    Clustering<?> c = metaAlgorithm.run(d);
    // Detach from database
    d.getHierarchy().remove(d, c);
    // Evaluation
    Result reps = new BasicResult("Representants", "representative");
    hierarchy.add(relation, reps);
    DistanceQuery<Clustering<?>> dq = mat.getDistanceQuery(distance);
    List<? extends Cluster<?>> cl = c.getAllClusters();
    List<DoubleObjPair<Clustering<?>>> evaluated = new ArrayList<>(cl.size());
    for (Cluster<?> clus : cl) {
        double besttau = Double.POSITIVE_INFINITY;
        Clustering<?> bestc = null;
        for (DBIDIter it1 = clus.getIDs().iter(); it1.valid(); it1.advance()) {
            double tau = 0.;
            Clustering<?> curc = crel.get(it1);
            for (DBIDIter it2 = clus.getIDs().iter(); it2.valid(); it2.advance()) {
                if (DBIDUtil.equal(it1, it2)) {
                    continue;
                }
                double di = dq.distance(curc, it2);
                tau = di > tau ? di : tau;
            }
            // Cluster member with the least maximum distance.
            if (tau < besttau) {
                besttau = tau;
                bestc = curc;
            }
        }
        if (bestc == null) {
            // E.g. degenerate empty clusters
            continue;
        }
        // Global tau:
        double gtau = 0.;
        for (DBIDIter it2 = crel.iterDBIDs(); it2.valid(); it2.advance()) {
            double di = dq.distance(bestc, it2);
            gtau = di > gtau ? di : gtau;
        }
        final double cprob = computeConfidence(clus.size(), crel.size());
        // Build an evaluation result
        hierarchy.add(bestc, new RepresentativenessEvaluation(gtau, besttau, cprob));
        evaluated.add(new DoubleObjPair<Clustering<?>>(cprob, bestc));
    }
    // Sort evaluated results by confidence:
    Collections.sort(evaluated, Collections.reverseOrder());
    for (DoubleObjPair<Clustering<?>> pair : evaluated) {
        // Attach parent relation (= sample) to the representative samples.
        for (It<Relation<?>> it = hierarchy.iterParents(pair.second).filter(Relation.class); it.valid(); it.advance()) {
            hierarchy.add(reps, it.get());
        }
    }
    // Add the random samples below the representative results only:
    if (keep) {
        hierarchy.add(relation, samples);
    } else {
        hierarchy.removeSubtree(samples);
    }
    return c;
}
Also used : ArrayList(java.util.ArrayList) Result(de.lmu.ifi.dbs.elki.result.Result) EvaluationResult(de.lmu.ifi.dbs.elki.result.EvaluationResult) BasicResult(de.lmu.ifi.dbs.elki.result.BasicResult) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter) MaterializedRelation(de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation) MaterializedRelation(de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation) Relation(de.lmu.ifi.dbs.elki.database.relation.Relation) Random(java.util.Random) BasicResult(de.lmu.ifi.dbs.elki.result.BasicResult) Iterator(java.util.Iterator) ResultHierarchy(de.lmu.ifi.dbs.elki.result.ResultHierarchy) DBIDs(de.lmu.ifi.dbs.elki.database.ids.DBIDs) FiniteProgress(de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress) ProxyDatabase(de.lmu.ifi.dbs.elki.database.ProxyDatabase) PrecomputedDistanceMatrix(de.lmu.ifi.dbs.elki.index.distancematrix.PrecomputedDistanceMatrix) Clustering(de.lmu.ifi.dbs.elki.data.Clustering) DoubleObjPair(de.lmu.ifi.dbs.elki.utilities.pairs.DoubleObjPair) DBIDRange(de.lmu.ifi.dbs.elki.database.ids.DBIDRange) DoubleVector(de.lmu.ifi.dbs.elki.data.DoubleVector)

Example 4 with ResultHierarchy

use of de.lmu.ifi.dbs.elki.result.ResultHierarchy in project elki by elki-project.

the class VisualizationTree method findNewSiblings.

/**
 * Process new result combinations of an object type1 (in first hierarchy) and
 * any child of type2 (in second hierarchy)
 *
 * This is a bit painful, because we have two hierarchies with different
 * types: results, and visualizations.
 *
 * @param context Context
 * @param start Starting point
 * @param type1 First type, in first hierarchy
 * @param type2 Second type, in second hierarchy
 * @param handler Handler
 */
public static <A extends Result, B extends VisualizationItem> void findNewSiblings(VisualizerContext context, Object start, Class<? super A> type1, Class<? super B> type2, BiConsumer<A, B> handler) {
    // Search start in first hierarchy:
    final ResultHierarchy hier = context.getHierarchy();
    final Hierarchy<Object> vistree = context.getVisHierarchy();
    if (start instanceof Result) {
        // New result:
        for (It<A> it1 = hier.iterDescendantsSelf((Result) start).filter(type1); it1.valid(); it1.advance()) {
            final A result = it1.get();
            // Existing visualization:
            for (It<B> it2 = vistree.iterDescendantsSelf(context.getBaseResult()).filter(type2); it2.valid(); it2.advance()) {
                handler.accept(result, it2.get());
            }
        }
    }
    // New visualization:
    for (It<B> it2 = vistree.iterDescendantsSelf(start).filter(type2); it2.valid(); it2.advance()) {
        final B vis = it2.get();
        // Existing result:
        for (It<A> it1 = hier.iterAll().filter(type1); it1.valid(); it1.advance()) {
            handler.accept(it1.get(), vis);
        }
    }
}
Also used : ResultHierarchy(de.lmu.ifi.dbs.elki.result.ResultHierarchy) Result(de.lmu.ifi.dbs.elki.result.Result)

Example 5 with ResultHierarchy

use of de.lmu.ifi.dbs.elki.result.ResultHierarchy in project elki by elki-project.

the class AbstractOutlierAlgorithmTest method testAUC.

/**
 * Test the AUC value for an outlier result.
 *
 * @param db Database
 * @param positive Positive class name
 * @param result Outlier result to process
 * @param expected Expected AUC value
 */
protected void testAUC(Database db, String positive, OutlierResult result, double expected) {
    OutlierROCCurve rocCurve = // 
    new ELKIBuilder<>(OutlierROCCurve.class).with(OutlierROCCurve.Parameterizer.POSITIVE_CLASS_NAME_ID, positive).build();
    // Ensure the result has been added to the hierarchy:
    ResultHierarchy hier = db.getHierarchy();
    if (hier.numParents(result) < 1) {
        hier.add(db, result);
    }
    // Compute ROC and AUC:
    rocCurve.processNewResult(hier, result);
    // Find the ROC results
    Collection<OutlierROCCurve.ROCResult> rocs = ResultUtil.filterResults(hier, result, OutlierROCCurve.ROCResult.class);
    assertTrue("No ROC result found.", !rocs.isEmpty());
    double auc = rocs.iterator().next().getAUC();
    assertFalse("More than one ROC result found.", rocs.size() > 1);
    assertEquals("ROC value does not match.", expected, auc, 0.0001);
}
Also used : ResultHierarchy(de.lmu.ifi.dbs.elki.result.ResultHierarchy) ELKIBuilder(de.lmu.ifi.dbs.elki.utilities.ELKIBuilder) OutlierROCCurve(de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierROCCurve)

Aggregations

ResultHierarchy (de.lmu.ifi.dbs.elki.result.ResultHierarchy)6 Result (de.lmu.ifi.dbs.elki.result.Result)3 FiniteProgress (de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress)2 BasicResult (de.lmu.ifi.dbs.elki.result.BasicResult)2 AbstractAlgorithm (de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm)1 Algorithm (de.lmu.ifi.dbs.elki.algorithm.Algorithm)1 Clustering (de.lmu.ifi.dbs.elki.data.Clustering)1 DoubleVector (de.lmu.ifi.dbs.elki.data.DoubleVector)1 NumberVector (de.lmu.ifi.dbs.elki.data.NumberVector)1 Database (de.lmu.ifi.dbs.elki.database.Database)1 ProxyDatabase (de.lmu.ifi.dbs.elki.database.ProxyDatabase)1 DBIDIter (de.lmu.ifi.dbs.elki.database.ids.DBIDIter)1 DBIDRange (de.lmu.ifi.dbs.elki.database.ids.DBIDRange)1 DBIDs (de.lmu.ifi.dbs.elki.database.ids.DBIDs)1 MaterializedRelation (de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation)1 Relation (de.lmu.ifi.dbs.elki.database.relation.Relation)1 OutlierROCCurve (de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierROCCurve)1 DecreasingVectorIter (de.lmu.ifi.dbs.elki.evaluation.scores.adapter.DecreasingVectorIter)1 VectorNonZero (de.lmu.ifi.dbs.elki.evaluation.scores.adapter.VectorNonZero)1 SimilarityMatrix (de.lmu.ifi.dbs.elki.evaluation.similaritymatrix.ComputeSimilarityMatrixImage.SimilarityMatrix)1