public OutlierResult run ( Database database , Relation < O > relation ) { DistanceFunction < ? super O > df = clusterer . getDistanceFunction ( ) ; DistanceQuery < O > dq = database . getDistanceQuery ( relation , df ) ; // TODO: improve ELKI api to ensure we're using the same DBIDs! Clustering < ? > c = clusterer . run ( database , relation ) ; WritableDoubleDataStore scores = DataStoreUtil . makeDoubleStorage ( relation . getDBIDs ( ) , DataStoreFactory . HINT_DB ) ; DoubleMinMax mm = new DoubleMinMax ( ) ; @ SuppressWarnings ( "unchecked" ) NumberVector . Factory < O > factory = ( NumberVector . Factory < O > ) RelationUtil . assumeVectorField ( relation ) . getFactory ( ) ; List < ? extends Cluster < ? > > clusters = c . getAllClusters ( ) ; for ( Cluster < ? > cluster : clusters ) { // FIXME: use a primitive distance function on number vectors instead. O mean = factory . newNumberVector ( ModelUtil . getPrototype ( cluster . getModel ( ) , relation ) ) ; for ( DBIDIter iter = cluster . getIDs ( ) . iter ( ) ; iter . valid ( ) ; iter . advance ( ) ) { double dist = dq . distance ( mean , iter ) ; scores . put ( iter , dist ) ; mm . put ( dist ) ; } } // Build result representation. DoubleRelation scoreResult = new MaterializedDoubleRelation ( "KMeans outlier scores" , "kmeans-outlier" , scores , relation . getDBIDs ( ) ) ; OutlierScoreMeta scoreMeta = new BasicOutlierScoreMeta ( mm . getMin ( ) , mm . getMax ( ) , 0. , Double . POSITIVE_INFINITY , 0. ) ; return new OutlierResult ( scoreMeta , scoreResult ) ; }
Run the outlier detection algorithm .