public Clustering < ? > run ( final Database database , final Relation < DiscreteUncertainObject > relation ) { if ( relation . size ( ) <= 0 ) { return new Clustering <> ( "Uk-Means Clustering" , "ukmeans-clustering" ) ; } // Choose initial means randomly DBIDs sampleids = DBIDUtil . randomSample ( relation . getDBIDs ( ) , k , rnd ) ; List < double [ ] > means = new ArrayList <> ( k ) ; for ( DBIDIter iter = sampleids . iter ( ) ; iter . valid ( ) ; iter . advance ( ) ) { means . add ( ArrayLikeUtil . toPrimitiveDoubleArray ( relation . get ( iter ) . getCenterOfMass ( ) ) ) ; } // Setup cluster assignment store List < ModifiableDBIDs > clusters = new ArrayList <> ( ) ; for ( int i = 0 ; i < k ; i ++ ) { clusters . add ( DBIDUtil . newHashSet ( ( int ) ( relation . size ( ) * 2. / k ) ) ) ; } WritableIntegerDataStore assignment = DataStoreUtil . makeIntegerStorage ( relation . getDBIDs ( ) , DataStoreFactory . HINT_TEMP | DataStoreFactory . HINT_HOT , - 1 ) ; double [ ] varsum = new double [ k ] ; IndefiniteProgress prog = LOG . isVerbose ( ) ? new IndefiniteProgress ( "UK-Means iteration" , LOG ) : null ; DoubleStatistic varstat = LOG . isStatistics ( ) ? new DoubleStatistic ( this . getClass ( ) . getName ( ) + ".variance-sum" ) : null ; int iteration = 0 ; for ( ; maxiter <= 0 || iteration < maxiter ; iteration ++ ) { LOG . incrementProcessed ( prog ) ; boolean changed = assignToNearestCluster ( relation , means , clusters , assignment , varsum ) ; logVarstat ( varstat , varsum ) ; // Stop if no cluster assignment changed. if ( ! changed ) { break ; } // Recompute means. means = means ( clusters , means , relation ) ; } LOG . setCompleted ( prog ) ; if ( LOG . isStatistics ( ) ) { LOG . statistics ( new LongStatistic ( KEY + ".iterations" , iteration ) ) ; } // Wrap result Clustering < KMeansModel > result = new Clustering <> ( "Uk-Means Clustering" , "ukmeans-clustering" ) ; for ( int i = 0 ; i < clusters . size ( ) ; i ++ ) { DBIDs ids = clusters . get ( i ) ; if ( ids . isEmpty ( ) ) { continue ; } result . addToplevelCluster ( new Cluster <> ( ids , new KMeansModel ( means . get ( i ) , varsum [ i ] ) ) ) ; } return result ; }
Run the clustering .