Search in sources :

Example 71 with KNNList

use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.

the class KNNDD method run.

/**
 * Runs the algorithm in the timed evaluation part.
 *
 * @param relation Data relation
 */
public OutlierResult run(Relation<O> relation) {
    final DistanceQuery<O> distanceQuery = relation.getDistanceQuery(getDistanceFunction());
    final KNNQuery<O> knnQuery = relation.getKNNQuery(distanceQuery, k);
    FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("kNN distance for objects", relation.size(), LOG) : null;
    WritableDoubleDataStore knnDist = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
    WritableDBIDDataStore neighbor = DataStoreUtil.makeDBIDStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
    DBIDVar var = DBIDUtil.newVar();
    // Find nearest neighbors, and store the distances.
    for (DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
        final KNNList knn = knnQuery.getKNNForDBID(it, k);
        knnDist.putDouble(it, knn.getKNNDistance());
        neighbor.put(it, knn.assignVar(knn.size() - 1, var));
        LOG.incrementProcessed(prog);
    }
    LOG.ensureCompleted(prog);
    prog = LOG.isVerbose() ? new FiniteProgress("kNN distance descriptor", relation.size(), LOG) : null;
    WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_DB);
    DoubleMinMax minmax = new DoubleMinMax();
    for (DBIDIter it = relation.iterDBIDs(); it.valid(); it.advance()) {
        // Distance
        double d = knnDist.doubleValue(it);
        // Distance of neighbor
        double nd = knnDist.doubleValue(neighbor.assignVar(it, var));
        double knndd = nd > 0 ? d / nd : d > 0 ? Double.POSITIVE_INFINITY : 1.;
        scores.put(it, knndd);
        minmax.put(knndd);
        LOG.incrementProcessed(prog);
    }
    LOG.ensureCompleted(prog);
    DoubleRelation scoreres = new MaterializedDoubleRelation("kNN Data Descriptor", "knndd-outlier", scores, relation.getDBIDs());
    OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), 0., Double.POSITIVE_INFINITY, 1.);
    return new OutlierResult(meta, scoreres);
}
Also used : DBIDVar(de.lmu.ifi.dbs.elki.database.ids.DBIDVar) WritableDoubleDataStore(de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore) FiniteProgress(de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress) OutlierResult(de.lmu.ifi.dbs.elki.result.outlier.OutlierResult) DoubleRelation(de.lmu.ifi.dbs.elki.database.relation.DoubleRelation) MaterializedDoubleRelation(de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation) BasicOutlierScoreMeta(de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta) OutlierScoreMeta(de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta) BasicOutlierScoreMeta(de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter) DoubleMinMax(de.lmu.ifi.dbs.elki.math.DoubleMinMax) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) WritableDBIDDataStore(de.lmu.ifi.dbs.elki.database.datastore.WritableDBIDDataStore) MaterializedDoubleRelation(de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation)

Example 72 with KNNList

use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.

the class MaterializeKNNAndRKNNPreprocessor method materializeKNNAndRKNNs.

/**
 * Materializes the kNNs and RkNNs of the specified object IDs.
 *
 * @param ids the IDs of the objects
 */
private void materializeKNNAndRKNNs(ArrayDBIDs ids, FiniteProgress progress) {
    // add an empty list to each rknn
    for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
        if (materialized_RkNN.get(iter) == null) {
            materialized_RkNN.put(iter, new TreeSet<DoubleDBIDPair>());
        }
    }
    // knn query
    List<? extends KNNList> kNNList = knnQuery.getKNNForBulkDBIDs(ids, k);
    int i = 0;
    for (DBIDIter id = ids.iter(); id.valid(); id.advance(), i++) {
        KNNList kNNs = kNNList.get(i);
        storage.put(id, kNNs);
        for (DoubleDBIDListIter iter = kNNs.iter(); iter.valid(); iter.advance()) {
            TreeSet<DoubleDBIDPair> rknns = materialized_RkNN.get(iter);
            rknns.add(makePair(iter, id));
        }
        getLogger().incrementProcessed(progress);
    }
    getLogger().ensureCompleted(progress);
}
Also used : DoubleDBIDListIter(de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) DoubleDBIDPair(de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter)

Example 73 with KNNList

use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.

the class MaterializeKNNAndRKNNPreprocessor method updateKNNsAndRkNNs.

/**
 * Updates the kNNs and RkNNs after insertion of the specified ids.
 *
 * @param ids the ids of newly inserted objects causing a change of
 *        materialized kNNs and RkNNs
 * @return the RkNNs of the specified ids, i.e. the kNNs which have been
 *         updated
 */
private ArrayDBIDs updateKNNsAndRkNNs(DBIDs ids) {
    ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
    DBIDs oldids = DBIDUtil.difference(relation.getDBIDs(), ids);
    for (DBIDIter id = oldids.iter(); id.valid(); id.advance()) {
        KNNList oldkNNs = storage.get(id);
        double knnDist = oldkNNs.getKNNDistance();
        // look for new kNNs
        KNNHeap heap = null;
        for (DBIDIter newid = ids.iter(); newid.valid(); newid.advance()) {
            double dist = distanceQuery.distance(id, newid);
            if (dist <= knnDist) {
                // New id changes the kNNs of oldid.
                if (heap == null) {
                    heap = DBIDUtil.newHeap(oldkNNs);
                }
                heap.insert(dist, newid);
            }
        }
        // kNNs for oldid have changed:
        if (heap != null) {
            KNNList newkNNs = heap.toKNNList();
            storage.put(id, newkNNs);
            // get the difference
            int i = 0;
            int j = 0;
            ModifiableDoubleDBIDList added = DBIDUtil.newDistanceDBIDList();
            ModifiableDoubleDBIDList removed = DBIDUtil.newDistanceDBIDList();
            // TODO: use iterators.
            while (i < oldkNNs.size() && j < newkNNs.size()) {
                DoubleDBIDPair drp1 = oldkNNs.get(i);
                DoubleDBIDPair drp2 = newkNNs.get(j);
                // NOTE: we assume that on ties they are ordered the same way!
                if (!DBIDUtil.equal(drp1, drp2)) {
                    added.add(drp2);
                    j++;
                } else {
                    i++;
                    j++;
                }
            }
            if (i != j) {
                for (; i < oldkNNs.size(); i++) {
                    removed.add(oldkNNs.get(i));
                }
                for (; j < newkNNs.size(); i++) {
                    added.add(newkNNs.get(i));
                }
            }
            // add new RkNN
            for (DoubleDBIDListIter newnn = added.iter(); newnn.valid(); newnn.advance()) {
                TreeSet<DoubleDBIDPair> rknns = materialized_RkNN.get(newnn);
                rknns.add(makePair(newnn, id));
            }
            // remove old RkNN
            for (DoubleDBIDListIter oldnn = removed.iter(); oldnn.valid(); oldnn.advance()) {
                TreeSet<DoubleDBIDPair> rknns = materialized_RkNN.get(oldnn);
                rknns.remove(makePair(oldnn, id));
            }
            rkNN_ids.add(id);
        }
    }
    return rkNN_ids;
}
Also used : DoubleDBIDListIter(de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter) ArrayModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) ModifiableDoubleDBIDList(de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList) DoubleDBIDPair(de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDPair) ArrayDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs) ArrayModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs) DBIDs(de.lmu.ifi.dbs.elki.database.ids.DBIDs) HashSetModifiableDBIDs(de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs) SetDBIDs(de.lmu.ifi.dbs.elki.database.ids.SetDBIDs) KNNHeap(de.lmu.ifi.dbs.elki.database.ids.KNNHeap) DBIDIter(de.lmu.ifi.dbs.elki.database.ids.DBIDIter)

Example 74 with KNNList

use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.

the class NNDescentTest method testKNNQueries.

private void testKNNQueries(Relation<DoubleVector> rep, KNNQuery<DoubleVector> lin_knn_query, KNNQuery<DoubleVector> preproc_knn_query, int k) {
    ArrayDBIDs sample = DBIDUtil.ensureArray(rep.getDBIDs());
    List<? extends KNNList> lin_knn_ids = lin_knn_query.getKNNForBulkDBIDs(sample, k);
    List<? extends KNNList> preproc_knn_ids = preproc_knn_query.getKNNForBulkDBIDs(sample, k);
    for (int i = 0; i < rep.size(); i++) {
        KNNList lin_knn = lin_knn_ids.get(i);
        KNNList pre_knn = preproc_knn_ids.get(i);
        DoubleDBIDListIter lin = lin_knn.iter(), pre = pre_knn.iter();
        for (; lin.valid() && pre.valid(); lin.advance(), pre.advance(), i++) {
            if (DBIDUtil.equal(lin, pre) || lin.doubleValue() == pre.doubleValue()) {
                continue;
            }
            fail(// 
            new StringBuilder(1000).append("Neighbor distances do not agree: ").append(lin_knn.toString()).append(" got: ").append(pre_knn.toString()).toString());
        }
        assertEquals("kNN sizes do not agree.", lin_knn.size(), pre_knn.size());
        for (int j = 0; j < lin_knn.size(); j++) {
            assertTrue("kNNs of linear scan and preprocessor do not match!", DBIDUtil.equal(lin_knn.get(j), pre_knn.get(j)));
            assertEquals("kNNs of linear scan and preprocessor do not match!", lin_knn.get(j).doubleValue(), pre_knn.get(j).doubleValue(), 0.);
        }
    }
}
Also used : DoubleDBIDListIter(de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) ArrayDBIDs(de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs)

Example 75 with KNNList

use of de.lmu.ifi.dbs.elki.database.ids.KNNList in project elki by elki-project.

the class MkMaxTree method preInsert.

/**
 * Adapts the knn distances before insertion of entry q.
 *
 * @param q the entry to be inserted
 * @param nodeEntry the entry representing the root of the current subtree
 * @param knns_q the knns of q
 */
private void preInsert(MkMaxEntry q, MkMaxEntry nodeEntry, KNNHeap knns_q) {
    if (LOG.isDebugging()) {
        LOG.debugFine("preInsert " + q + " - " + nodeEntry + "\n");
    }
    double knnDist_q = knns_q.getKNNDistance();
    MkMaxTreeNode<O> node = getNode(nodeEntry);
    double knnDist_node = 0.;
    // leaf node
    if (node.isLeaf()) {
        for (int i = 0; i < node.getNumEntries(); i++) {
            MkMaxEntry p = node.getEntry(i);
            double dist_pq = distance(p.getRoutingObjectID(), q.getRoutingObjectID());
            // ==> p becomes a knn-candidate
            if (dist_pq <= knnDist_q) {
                knns_q.insert(dist_pq, p.getRoutingObjectID());
                if (knns_q.size() >= getKmax()) {
                    knnDist_q = knns_q.getKNNDistance();
                    q.setKnnDistance(knnDist_q);
                }
            }
            // q becomes knn of p
            if (dist_pq <= p.getKnnDistance()) {
                KNNList knns_p = knnq.getKNNForDBID(p.getRoutingObjectID(), getKmax() - 1);
                if (knns_p.size() + 1 < getKmax()) {
                    p.setKnnDistance(Double.NaN);
                } else {
                    double knnDist_p = Math.max(dist_pq, knns_p.getKNNDistance());
                    p.setKnnDistance(knnDist_p);
                }
            }
            knnDist_node = Math.max(knnDist_node, p.getKnnDistance());
        }
    } else // directory node
    {
        List<DoubleIntPair> entries = getSortedEntries(node, q.getRoutingObjectID());
        for (DoubleIntPair distEntry : entries) {
            MkMaxEntry dirEntry = node.getEntry(distEntry.second);
            double entry_knnDist = dirEntry.getKnnDistance();
            if (distEntry.second < entry_knnDist || distEntry.second < knnDist_q) {
                preInsert(q, dirEntry, knns_q);
                knnDist_q = knns_q.getKNNDistance();
            }
            knnDist_node = Math.max(knnDist_node, dirEntry.getKnnDistance());
        }
    }
    if (LOG.isDebugging()) {
        LOG.debugFine(nodeEntry + "set knn dist " + knnDist_node);
    }
    nodeEntry.setKnnDistance(knnDist_node);
}
Also used : KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) DoubleIntPair(de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair)

Aggregations

KNNList (de.lmu.ifi.dbs.elki.database.ids.KNNList)80 DBIDIter (de.lmu.ifi.dbs.elki.database.ids.DBIDIter)53 DoubleDBIDListIter (de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter)38 FiniteProgress (de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress)32 DBIDs (de.lmu.ifi.dbs.elki.database.ids.DBIDs)21 WritableDoubleDataStore (de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore)20 DoubleRelation (de.lmu.ifi.dbs.elki.database.relation.DoubleRelation)18 MaterializedDoubleRelation (de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation)18 OutlierResult (de.lmu.ifi.dbs.elki.result.outlier.OutlierResult)18 OutlierScoreMeta (de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta)18 DoubleMinMax (de.lmu.ifi.dbs.elki.math.DoubleMinMax)15 ArrayList (java.util.ArrayList)11 ArrayDBIDs (de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs)10 ModifiableDoubleDBIDList (de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList)9 BasicOutlierScoreMeta (de.lmu.ifi.dbs.elki.result.outlier.BasicOutlierScoreMeta)9 DBID (de.lmu.ifi.dbs.elki.database.ids.DBID)8 KNNHeap (de.lmu.ifi.dbs.elki.database.ids.KNNHeap)8 ModifiableDBIDs (de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs)8 MeanVariance (de.lmu.ifi.dbs.elki.math.MeanVariance)8 ArrayModifiableDBIDs (de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs)6