*/
public OutlierResult run(Database database, Relation<N> nrel, Relation<? extends NumberVector<?, ?>> relation) {
final NeighborSetPredicate npred = getNeighborSetPredicateFactory().instantiate(nrel);
WritableDoubleDataStore scores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC);
MeanVariance zmv = new MeanVariance();
for(DBID id : relation.iterDBIDs()) {
DBIDs neighbors = npred.getNeighborDBIDs(id);
// Compute Mean of neighborhood
Mean localmean = new Mean();
for(DBID n : neighbors) {
if(id.equals(n)) {
continue;
}
else {
localmean.put(relation.get(n).doubleValue(1));
}
}
final double localdiff;
if(localmean.getCount() > 0) {
localdiff = relation.get(id).doubleValue(1) - localmean.getMean();
}
else {
localdiff = 0.0;
}
scores.putDouble(id, localdiff);
zmv.put(localdiff);
}
// Normalize scores using mean and variance
DoubleMinMax minmax = new DoubleMinMax();
for(DBID id : relation.iterDBIDs()) {
double score = Math.abs(scores.doubleValue(id) - zmv.getMean()) / zmv.getSampleStddev();
minmax.put(score);
scores.putDouble(id, score);
}
// Wrap result