public OutlierResult run ( Database database , Relation < O > relation ) { // Get the query functions: DistanceQuery < O > dq = database . getDistanceQuery ( relation , getDistanceFunction ( ) ) ; KNNQuery < O > knnq = database . getKNNQuery ( dq , k ) ; // Get the objects to process, and a data storage for counting and output: DBIDs ids = relation . getDBIDs ( ) ; WritableDoubleDataStore scores = DataStoreUtil . makeDoubleStorage ( ids , DataStoreFactory . HINT_DB , 0. ) ; // Process all objects for ( DBIDIter iter = ids . iter ( ) ; iter . valid ( ) ; iter . advance ( ) ) { // Find the nearest neighbors (using an index, if available!) KNNList neighbors = knnq . getKNNForDBID ( iter , k ) ; // For each neighbor, except ourselves, increase the in-degree: for ( DBIDIter nei = neighbors . iter ( ) ; nei . valid ( ) ; nei . advance ( ) ) { if ( DBIDUtil . equal ( iter , nei ) ) { continue ; } scores . put ( nei , scores . doubleValue ( nei ) + 1 ) ; } } // Compute maximum double min = Double . POSITIVE_INFINITY , max = 0.0 ; for ( DBIDIter iter = ids . iter ( ) ; iter . valid ( ) ; iter . advance ( ) ) { min = Math . min ( min , scores . doubleValue ( iter ) ) ; max = Math . max ( max , scores . doubleValue ( iter ) ) ; } // Wrap the result and add metadata. // By actually specifying theoretical min, max and baseline, we get a better // visualization (try it out - or see the screenshots in the tutorial)! OutlierScoreMeta meta = new InvertedOutlierScoreMeta ( min , max , 0. , ids . size ( ) - 1 , k ) ; DoubleRelation rel = new MaterializedDoubleRelation ( "ODIN In-Degree" , "odin" , scores , ids ) ; return new OutlierResult ( meta , rel ) ; }
Run the ODIN algorithm