use of de.lmu.ifi.dbs.elki.database.ids.generic.MaskedDBIDs in project elki by elki-project.
the class GaussianUniformMixture method run.
/**
* Run the algorithm
*
* @param relation Data relation
* @return Outlier result
*/
public OutlierResult run(Relation<V> relation) {
// Use an array list of object IDs for fast random access by an offset
ArrayDBIDs objids = DBIDUtil.ensureArray(relation.getDBIDs());
// A bit set to flag objects as anomalous, none at the beginning
long[] bits = BitsUtil.zero(objids.size());
// Positive masked collection
DBIDs normalObjs = new MaskedDBIDs(objids, bits, true);
// Positive masked collection
DBIDs anomalousObjs = new MaskedDBIDs(objids, bits, false);
// resulting scores
WritableDoubleDataStore oscores = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT);
// compute loglikelihood
double logLike = relation.size() * logml + loglikelihoodNormal(normalObjs, relation);
// LOG.debugFine("normalsize " + normalObjs.size() + " anormalsize " +
// anomalousObjs.size() + " all " + (anomalousObjs.size() +
// normalObjs.size()));
// LOG.debugFine(logLike + " loglike beginning" +
// loglikelihoodNormal(normalObjs, database));
DoubleMinMax minmax = new DoubleMinMax();
DBIDIter iter = objids.iter();
for (int i = 0; i < objids.size(); i++, iter.advance()) {
// LOG.debugFine("i " + i);
// Change mask to make the current object anomalous
BitsUtil.setI(bits, i);
// Compute new likelihoods
double currentLogLike = normalObjs.size() * logml + loglikelihoodNormal(normalObjs, relation) + anomalousObjs.size() * logl + loglikelihoodAnomalous(anomalousObjs);
// if the loglike increases more than a threshold, object stays in
// anomalous set and is flagged as outlier
final double loglikeGain = currentLogLike - logLike;
oscores.putDouble(iter, loglikeGain);
minmax.put(loglikeGain);
if (loglikeGain > c) {
// flag as outlier
// LOG.debugFine("Outlier: " + curid + " " + (currentLogLike -
// logLike));
// Update best logLike
logLike = currentLogLike;
} else {
// LOG.debugFine("Inlier: " + curid + " " + (currentLogLike - logLike));
// undo bit set
BitsUtil.clearI(bits, i);
}
}
OutlierScoreMeta meta = new BasicOutlierScoreMeta(minmax.getMin(), minmax.getMax(), Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 0.0);
DoubleRelation res = new MaterializedDoubleRelation("Gaussian Mixture Outlier Score", "gaussian-mixture-outlier", oscores, relation.getDBIDs());
return new OutlierResult(meta, res);
}
Aggregations