summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java271
1 files changed, 116 insertions, 155 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java
index 2508b6b0..372bf68c 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/lof/FlexibleLOF.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.algorithm.outlier.lof;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -38,20 +38,16 @@ import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
+import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.KNNList;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
-import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.PreprocessorKNNQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
-import de.lmu.ifi.dbs.elki.database.relation.MaterializedRelation;
+import de.lmu.ifi.dbs.elki.database.relation.DoubleRelation;
+import de.lmu.ifi.dbs.elki.database.relation.MaterializedDoubleRelation;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
-import de.lmu.ifi.dbs.elki.index.preprocessed.knn.MaterializeKNNPreprocessor;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
@@ -59,6 +55,7 @@ import de.lmu.ifi.dbs.elki.math.DoubleMinMax;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierResult;
import de.lmu.ifi.dbs.elki.result.outlier.OutlierScoreMeta;
import de.lmu.ifi.dbs.elki.result.outlier.QuotientOutlierScoreMeta;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
@@ -113,12 +110,14 @@ import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
* @apiviz.has KNNQuery
*
* @param <O> the type of DatabaseObjects handled by this Algorithm
- * @param <D> Distance type
*/
@Title("LOF: Local Outlier Factor")
@Description("Algorithm to compute density-based local outlier factors in a database based on the neighborhood size parameter 'k'")
-@Reference(authors = "M. M. Breunig, H.-P. Kriegel, R. Ng, and J. Sander", title = "LOF: Identifying Density-Based Local Outliers", booktitle = "Proc. 2nd ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '00), Dallas, TX, 2000", url = "http://dx.doi.org/10.1145/342009.335388")
-public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
+@Reference(authors = "M. M. Breunig, H.-P. Kriegel, R. Ng, J. Sander", //
+title = "LOF: Identifying Density-Based Local Outliers", //
+booktitle = "Proc. 2nd ACM SIGMOD Int. Conf. on Management of Data (SIGMOD '00), Dallas, TX, 2000", //
+url = "http://dx.doi.org/10.1145/342009.335388")
+public class FlexibleLOF<O> extends AbstractAlgorithm<OutlierResult> implements OutlierAlgorithm {
/**
* The logger for this class.
*/
@@ -137,20 +136,12 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
/**
* Neighborhood distance function.
*/
- protected DistanceFunction<? super O, D> referenceDistanceFunction;
+ protected DistanceFunction<? super O> referenceDistanceFunction;
/**
* Reachability distance function.
*/
- protected DistanceFunction<? super O, D> reachabilityDistanceFunction;
-
- /**
- * Include object itself in kNN neighborhood.
- *
- * In the official LOF publication, the point itself is not considered to be
- * part of its k nearest neighbors.
- */
- private static boolean objectIsInKNN = false;
+ protected DistanceFunction<? super O> reachabilityDistanceFunction;
/**
* Constructor.
@@ -160,10 +151,10 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
* @param neighborhoodDistanceFunction the neighborhood distance function
* @param reachabilityDistanceFunction the reachability distance function
*/
- public FlexibleLOF(int krefer, int kreach, DistanceFunction<? super O, D> neighborhoodDistanceFunction, DistanceFunction<? super O, D> reachabilityDistanceFunction) {
+ public FlexibleLOF(int krefer, int kreach, DistanceFunction<? super O> neighborhoodDistanceFunction, DistanceFunction<? super O> reachabilityDistanceFunction) {
super();
- this.krefer = krefer + (objectIsInKNN ? 0 : 1);
- this.kreach = kreach + (objectIsInKNN ? 0 : 1);
+ this.krefer = krefer + 1;
+ this.kreach = kreach + 1;
this.referenceDistanceFunction = neighborhoodDistanceFunction;
this.reachabilityDistanceFunction = reachabilityDistanceFunction;
}
@@ -178,9 +169,9 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*/
public OutlierResult run(Database database, Relation<O> relation) {
StepProgress stepprog = LOG.isVerbose() ? new StepProgress("LOF", 3) : null;
- Pair<KNNQuery<O, D>, KNNQuery<O, D>> pair = getKNNQueries(database, relation, stepprog);
- KNNQuery<O, D> kNNRefer = pair.getFirst();
- KNNQuery<O, D> kNNReach = pair.getSecond();
+ Pair<KNNQuery<O>, KNNQuery<O>> pair = getKNNQueries(database, relation, stepprog);
+ KNNQuery<O> kNNRefer = pair.getFirst();
+ KNNQuery<O> kNNReach = pair.getSecond();
return doRunInTime(relation.getDBIDs(), kNNRefer, kNNReach, stepprog).getResult();
}
@@ -191,30 +182,29 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
* @param stepprog the progress logger
* @return the kNN queries for the algorithm
*/
- private Pair<KNNQuery<O, D>, KNNQuery<O, D>> getKNNQueries(Database database, Relation<O> relation, StepProgress stepprog) {
+ private Pair<KNNQuery<O>, KNNQuery<O>> getKNNQueries(Database database, Relation<O> relation, StepProgress stepprog) {
// "HEAVY" flag for knnReach since it is used more than once
- KNNQuery<O, D> knnReach = QueryUtil.getKNNQuery(relation, reachabilityDistanceFunction, kreach, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
+ KNNQuery<O> knnReach = QueryUtil.getKNNQuery(relation, reachabilityDistanceFunction, kreach, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_OPTIMIZED_ONLY, DatabaseQuery.HINT_NO_CACHE);
// No optimized kNN query - use a preprocessor!
- if (!(knnReach instanceof PreprocessorKNNQuery)) {
- if (stepprog != null) {
- if (referenceDistanceFunction.equals(reachabilityDistanceFunction)) {
+ if(!(knnReach instanceof PreprocessorKNNQuery)) {
+ if(stepprog != null) {
+ if(referenceDistanceFunction.equals(reachabilityDistanceFunction)) {
stepprog.beginStep(1, "Materializing neighborhoods w.r.t. reference neighborhood distance function.", LOG);
- } else {
+ }
+ else {
stepprog.beginStep(1, "Not materializing neighborhoods w.r.t. reference neighborhood distance function, but materializing neighborhoods w.r.t. reachability distance function.", LOG);
}
}
int kpreproc = (referenceDistanceFunction.equals(reachabilityDistanceFunction)) ? Math.max(kreach, krefer) : kreach;
- MaterializeKNNPreprocessor<O, D> preproc = new MaterializeKNNPreprocessor<>(relation, reachabilityDistanceFunction, kpreproc);
- database.addIndex(preproc);
- DistanceQuery<O, D> rdq = database.getDistanceQuery(relation, reachabilityDistanceFunction);
- knnReach = preproc.getKNNQuery(rdq, kreach);
+ knnReach = DatabaseUtil.precomputedKNNQuery(database, relation, reachabilityDistanceFunction, kpreproc);
}
// knnReach is only used once
- KNNQuery<O, D> knnRefer;
- if (referenceDistanceFunction == reachabilityDistanceFunction || referenceDistanceFunction.equals(reachabilityDistanceFunction)) {
+ KNNQuery<O> knnRefer;
+ if(referenceDistanceFunction == reachabilityDistanceFunction || referenceDistanceFunction.equals(reachabilityDistanceFunction)) {
knnRefer = knnReach;
- } else {
+ }
+ else {
// do not materialize the first neighborhood, since it is used only once
knnRefer = QueryUtil.getKNNQuery(relation, referenceDistanceFunction, krefer);
}
@@ -234,149 +224,118 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
* @param stepprog Progress logger
* @return LOF result
*/
- protected LOFResult<O, D> doRunInTime(DBIDs ids, KNNQuery<O, D> kNNRefer, KNNQuery<O, D> kNNReach, StepProgress stepprog) {
+ protected LOFResult<O> doRunInTime(DBIDs ids, KNNQuery<O> kNNRefer, KNNQuery<O> kNNReach, StepProgress stepprog) {
// Assert we got something
- if (kNNRefer == null) {
+ if(kNNRefer == null) {
throw new AbortException("No kNN queries supported by database for reference neighborhood distance function.");
}
- if (kNNReach == null) {
+ if(kNNReach == null) {
throw new AbortException("No kNN queries supported by database for reachability distance function.");
}
// Compute LRDs
- if (stepprog != null) {
- stepprog.beginStep(2, "Computing LRDs.", LOG);
- }
- WritableDoubleDataStore lrds = computeLRDs(ids, kNNReach);
+ LOG.beginStep(stepprog, 2, "Computing LRDs.");
+ WritableDoubleDataStore lrds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ computeLRDs(kNNReach, ids, lrds);
// compute LOF_SCORE of each db object
- if (stepprog != null) {
- stepprog.beginStep(3, "Computing LOFs.", LOG);
- }
- Pair<WritableDoubleDataStore, DoubleMinMax> lofsAndMax = computeLOFs(ids, lrds, kNNRefer);
- WritableDoubleDataStore lofs = lofsAndMax.getFirst();
+ LOG.beginStep(stepprog, 3, "Computing LOFs.");
+ WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
// track the maximum value for normalization.
- DoubleMinMax lofminmax = lofsAndMax.getSecond();
+ DoubleMinMax lofminmax = new DoubleMinMax();
+ computeLOFs(kNNRefer, ids, lrds, lofs, lofminmax);
- if (stepprog != null) {
- stepprog.setCompleted(LOG);
- }
+ LOG.setCompleted(stepprog);
// Build result representation.
- Relation<Double> scoreResult = new MaterializedRelation<>("Local Outlier Factor", "lof-outlier", TypeUtil.DOUBLE, lofs, ids);
+ DoubleRelation scoreResult = new MaterializedDoubleRelation("Local Outlier Factor", "lof-outlier", lofs, ids);
OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(lofminmax.getMin(), lofminmax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
OutlierResult result = new OutlierResult(scoreMeta, scoreResult);
-
return new LOFResult<>(result, kNNRefer, kNNReach, lrds, lofs);
}
/**
* Computes the local reachability density (LRD) of the specified objects.
*
- * @param ids the ids of the objects
- * @param knnReach the precomputed neighborhood of the objects w.r.t. the
+ * @param knnq the precomputed neighborhood of the objects w.r.t. the
* reachability distance
- * @return the LRDs of the objects
+ * @param ids the ids of the objects
+ * @param lrds Reachability storage
*/
- protected WritableDoubleDataStore computeLRDs(DBIDs ids, KNNQuery<O, D> knnReach) {
- WritableDoubleDataStore lrds = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
+ protected void computeLRDs(KNNQuery<O> knnq, DBIDs ids, WritableDoubleDataStore lrds) {
FiniteProgress lrdsProgress = LOG.isVerbose() ? new FiniteProgress("LRD", ids.size(), LOG) : null;
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- final KNNList<D> neighbors = knnReach.getKNNForDBID(iter, kreach);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ final KNNList neighbors = knnq.getKNNForDBID(iter, kreach);
double sum = 0.0;
int count = 0;
- if (neighbors instanceof DoubleDistanceKNNList) {
- // Fast version for double distances
- for (DoubleDistanceDBIDListIter neighbor = ((DoubleDistanceKNNList) neighbors).iter(); neighbor.valid(); neighbor.advance()) {
- if (objectIsInKNN || !DBIDUtil.equal(neighbor, iter)) {
- KNNList<D> neighborsNeighbors = knnReach.getKNNForDBID(neighbor, kreach);
- final double nkdist;
- if (neighborsNeighbors instanceof DoubleDistanceKNNList) {
- nkdist = ((DoubleDistanceKNNList) neighborsNeighbors).doubleKNNDistance();
- } else {
- nkdist = neighborsNeighbors.getKNNDistance().doubleValue();
- }
- sum += Math.max(neighbor.doubleDistance(), nkdist);
- count++;
- }
- }
- } else {
- for (DistanceDBIDListIter<D> neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
- if (objectIsInKNN || !DBIDUtil.equal(neighbor, iter)) {
- KNNList<D> neighborsNeighbors = knnReach.getKNNForDBID(neighbor, kreach);
- sum += Math.max(neighbor.getDistance().doubleValue(), neighborsNeighbors.getKNNDistance().doubleValue());
- count++;
- }
+ for(DoubleDBIDListIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ if(DBIDUtil.equal(neighbor, iter)) {
+ continue;
}
+ KNNList neighborsNeighbors = knnq.getKNNForDBID(neighbor, kreach);
+ sum += Math.max(neighbor.doubleValue(), neighborsNeighbors.getKNNDistance());
+ count++;
}
// Avoid division by 0
final double lrd = (sum > 0) ? (count / sum) : Double.POSITIVE_INFINITY;
lrds.putDouble(iter, lrd);
- if (lrdsProgress != null) {
- lrdsProgress.incrementProcessed(LOG);
- }
- }
- if (lrdsProgress != null) {
- lrdsProgress.ensureCompleted(LOG);
+ LOG.incrementProcessed(lrdsProgress);
}
- return lrds;
+ LOG.ensureCompleted(lrdsProgress);
}
/**
* Computes the Local outlier factor (LOF) of the specified objects.
*
- * @param ids the ids of the objects
- * @param lrds the LRDs of the objects
- * @param knnRefer the precomputed neighborhood of the objects w.r.t. the
+ * @param knnq the precomputed neighborhood of the objects w.r.t. the
* reference distance
- * @return the LOFs of the objects and the maximum LOF
+ * @param ids IDs to process
+ * @param lrds Local reachability distances
+ * @param lofs Local outlier factor storage
+ * @param lofminmax Score minimum/maximum tracker
*/
- protected Pair<WritableDoubleDataStore, DoubleMinMax> computeLOFs(DBIDs ids, DoubleDataStore lrds, KNNQuery<O, D> knnRefer) {
- WritableDoubleDataStore lofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC);
- // track the maximum value for normalization.
- DoubleMinMax lofminmax = new DoubleMinMax();
-
+ protected void computeLOFs(KNNQuery<O> knnq, DBIDs ids, DoubleDataStore lrds, WritableDoubleDataStore lofs, DoubleMinMax lofminmax) {
FiniteProgress progressLOFs = LOG.isVerbose() ? new FiniteProgress("LOF_SCORE for objects", ids.size(), LOG) : null;
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- final double lrdp = lrds.doubleValue(iter);
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
final double lof;
- if (lrdp > 0 && !Double.isInfinite(lrdp)) {
- final KNNList<D> neighbors = knnRefer.getKNNForDBID(iter, krefer);
- double sum = 0.0;
+ final double lrdp = lrds.doubleValue(iter);
+ final KNNList neighbors = knnq.getKNNForDBID(iter, krefer);
+ if(!Double.isInfinite(lrdp)) {
+ double sum = 0.;
int count = 0;
- for (DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
+ for(DBIDIter neighbor = neighbors.iter(); neighbor.valid(); neighbor.advance()) {
// skip the point itself
- if (objectIsInKNN || !DBIDUtil.equal(neighbor, iter)) {
- sum += lrds.doubleValue(neighbor);
- count++;
+ if(DBIDUtil.equal(neighbor, iter)) {
+ continue;
+ }
+ final double val = lrds.doubleValue(neighbor);
+ sum += val;
+ count++;
+ if(Double.isInfinite(val)) {
+ break;
}
}
- lof = sum / (count * lrdp);
- } else {
+ lof = sum / (lrdp * count);
+ }
+ else {
lof = 1.0;
}
lofs.putDouble(iter, lof);
// update minimum and maximum
- if (!Double.isInfinite(lof)) {
- lofminmax.put(lof);
- }
+ lofminmax.put(lof);
- if (progressLOFs != null) {
- progressLOFs.incrementProcessed(LOG);
- }
+ LOG.incrementProcessed(progressLOFs);
}
- if (progressLOFs != null) {
- progressLOFs.ensureCompleted(LOG);
- }
- return new Pair<>(lofs, lofminmax);
+ LOG.ensureCompleted(progressLOFs);
}
@Override
public TypeInformation[] getInputTypeRestriction() {
final TypeInformation type;
- if (reachabilityDistanceFunction.equals(referenceDistanceFunction)) {
+ if(reachabilityDistanceFunction.equals(referenceDistanceFunction)) {
type = reachabilityDistanceFunction.getInputTypeRestriction();
- } else {
+ }
+ else {
type = new CombinedTypeInformation(referenceDistanceFunction.getInputTypeRestriction(), reachabilityDistanceFunction.getInputTypeRestriction());
}
return TypeUtil.array(type);
@@ -393,7 +352,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @author Elke Achtert
*/
- public static class LOFResult<O, D extends NumberDistance<D, ?>> {
+ public static class LOFResult<O> {
/**
* The result of the run of the {@link FlexibleLOF} algorithm.
*/
@@ -402,22 +361,22 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
/**
* The kNN query w.r.t. the reference neighborhood distance.
*/
- private final KNNQuery<O, D> kNNRefer;
+ private final KNNQuery<O> kNNRefer;
/**
* The kNN query w.r.t. the reachability distance.
*/
- private final KNNQuery<O, D> kNNReach;
+ private final KNNQuery<O> kNNReach;
/**
* The RkNN query w.r.t. the reference neighborhood distance.
*/
- private RKNNQuery<O, D> rkNNRefer;
+ private RKNNQuery<O> rkNNRefer;
/**
* The rkNN query w.r.t. the reachability distance.
*/
- private RKNNQuery<O, D> rkNNReach;
+ private RKNNQuery<O> rkNNReach;
/**
* The LRD values of the objects.
@@ -439,7 +398,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
* @param lrds the LRD values of the objects
* @param lofs the LOF values of the objects
*/
- public LOFResult(OutlierResult result, KNNQuery<O, D> kNNRefer, KNNQuery<O, D> kNNReach, WritableDoubleDataStore lrds, WritableDoubleDataStore lofs) {
+ public LOFResult(OutlierResult result, KNNQuery<O> kNNRefer, KNNQuery<O> kNNReach, WritableDoubleDataStore lrds, WritableDoubleDataStore lofs) {
this.result = result;
this.kNNRefer = kNNRefer;
this.kNNReach = kNNReach;
@@ -452,7 +411,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @return the kNN query w.r.t. the reference neighborhood distance
*/
- public KNNQuery<O, D> getKNNRefer() {
+ public KNNQuery<O> getKNNRefer() {
return kNNRefer;
}
@@ -461,7 +420,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @return the kNN query w.r.t. the reachability distance
*/
- public KNNQuery<O, D> getKNNReach() {
+ public KNNQuery<O> getKNNReach() {
return kNNReach;
}
@@ -497,7 +456,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @param rkNNRefer the query to set
*/
- public void setRkNNRefer(RKNNQuery<O, D> rkNNRefer) {
+ public void setRkNNRefer(RKNNQuery<O> rkNNRefer) {
this.rkNNRefer = rkNNRefer;
}
@@ -506,7 +465,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @return the RkNN query w.r.t. the reference neighborhood distance
*/
- public RKNNQuery<O, D> getRkNNRefer() {
+ public RKNNQuery<O> getRkNNRefer() {
return rkNNRefer;
}
@@ -515,7 +474,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @return the RkNN query w.r.t. the reachability distance
*/
- public RKNNQuery<O, D> getRkNNReach() {
+ public RKNNQuery<O> getRkNNReach() {
return rkNNReach;
}
@@ -524,7 +483,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @param rkNNReach the query to set
*/
- public void setRkNNReach(RKNNQuery<O, D> rkNNReach) {
+ public void setRkNNReach(RKNNQuery<O> rkNNReach) {
this.rkNNReach = rkNNReach;
}
}
@@ -536,7 +495,7 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
*
* @apiviz.exclude
*/
- public static class Parameterizer<O, D extends NumberDistance<D, ?>> extends AbstractDistanceBasedAlgorithm.Parameterizer<O, D> {
+ public static class Parameterizer<O> extends AbstractDistanceBasedAlgorithm.Parameterizer<O> {
/**
* The distance function to determine the reachability distance between
* database objects.
@@ -545,16 +504,16 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
/**
* Parameter to specify the number of nearest neighbors of an object to be
- * considered for computing its LOF_SCORE, must be an integer greater than
- * 1.
+ * considered for computing its LOF score, must be an integer greater or
+ * equal to 1.
*/
- public static final OptionID KREF_ID = new OptionID("lof.krefer", "The number of nearest neighbors of an object to be considered for computing its LOF_SCORE.");
+ public static final OptionID KREF_ID = new OptionID("lof.krefer", "The number of nearest neighbors of an object to be considered for computing its LOF score.");
/**
* Parameter to specify the number of nearest neighbors of an object to be
* considered for computing its reachability distance.
*/
- public static final OptionID KREACH_ID = new OptionID("lof.kreach", "The number of nearest neighbors of an object to be considered for computing its LOF_SCORE.");
+ public static final OptionID KREACH_ID = new OptionID("lof.kreach", "The number of nearest neighbors of an object to be considered for computing its LOF score.");
/**
* The reference set size to use.
@@ -569,43 +528,45 @@ public class FlexibleLOF<O, D extends NumberDistance<D, ?>> extends AbstractAlgo
/**
* Neighborhood distance function.
*/
- protected DistanceFunction<O, D> neighborhoodDistanceFunction = null;
+ protected DistanceFunction<O> neighborhoodDistanceFunction = null;
/**
* Reachability distance function.
*/
- protected DistanceFunction<O, D> reachabilityDistanceFunction = null;
+ protected DistanceFunction<O> reachabilityDistanceFunction = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
final IntParameter pK = new IntParameter(KREF_ID);
- pK.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
- if (config.grab(pK)) {
+ pK.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(pK)) {
krefer = pK.intValue();
}
final IntParameter pK2 = new IntParameter(KREACH_ID);
pK2.setOptional(true);
- pK2.addConstraint(CommonConstraints.GREATER_THAN_ONE_INT);
- if (config.grab(pK2)) {
+ pK2.addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
+ if(config.grab(pK2)) {
kreach = pK2.intValue();
- } else {
+ }
+ else {
kreach = krefer;
}
- final ObjectParameter<DistanceFunction<O, D>> reachDistP = new ObjectParameter<>(REACHABILITY_DISTANCE_FUNCTION_ID, DistanceFunction.class);
+ final ObjectParameter<DistanceFunction<O>> reachDistP = new ObjectParameter<>(REACHABILITY_DISTANCE_FUNCTION_ID, DistanceFunction.class);
reachDistP.setOptional(true);
- if (config.grab(reachDistP)) {
+ if(config.grab(reachDistP)) {
reachabilityDistanceFunction = reachDistP.instantiateClass(config);
- } else {
+ }
+ else {
reachabilityDistanceFunction = distanceFunction;
}
}
@Override
- protected FlexibleLOF<O, D> makeInstance() {
+ protected FlexibleLOF<O> makeInstance() {
return new FlexibleLOF<>(kreach, krefer, distanceFunction, reachabilityDistanceFunction);
}
}