private void clusterDown ( ) { int classIndex = this . ltm . classIndex ( ) ; for ( int c = 0 ; c <= this . maxClassValue ; c ++ ) { List < double [ ] > classSamples = new ArrayList <> ( ) ; for ( int i = this . ltm . numInstances ( ) - 1 ; i > - 1 ; i -- ) { if ( this . ltm . get ( i ) . classValue ( ) == c ) { classSamples . add ( this . ltm . get ( i ) . toDoubleArray ( ) ) ; this . ltm . delete ( i ) ; } } if ( classSamples . size ( ) > 0 ) { //used kMeans++ implementation expects the weight of each sample at the first index, // make sure that the first value gets the uniform weight 1, overwrite class value for ( double [ ] sample : classSamples ) { if ( classIndex != 0 ) { sample [ classIndex ] = sample [ 0 ] ; } sample [ 0 ] = 1 ; } List < double [ ] > centroids = this . kMeans ( classSamples , Math . max ( classSamples . size ( ) / 2 , 1 ) ) ; for ( double [ ] centroid : centroids ) { double [ ] attributes = new double [ this . ltm . numAttributes ( ) ] ; //returned centroids do not contain the weight anymore, but simply the data System . arraycopy ( centroid , 0 , attributes , 1 , this . ltm . numAttributes ( ) - 1 ) ; //switch back if necessary if ( classIndex != 0 ) { attributes [ 0 ] = attributes [ classIndex ] ; } attributes [ classIndex ] = c ; Instance inst = new InstanceImpl ( 1 , attributes ) ; inst . setDataset ( this . ltm ) ; this . ltm . add ( inst ) ; } } } }
Performs classwise kMeans ++ clustering for given samples with corresponding labels . The number of samples is halved per class .