Example 2: K-means Cluster Analysis with K-means++ Seeds

This example performs K-means cluster analysis on Fisher's iris data. The initial cluster seeds are generated using the K-means++ algorithm.


import java.text.*;
import com.imsl.stat.*;
import com.imsl.math.*;

public class ClusterKMeansEx2 {

    public static void main(String argv[]) throws Exception {
        double[][] x = {
            {5.100, 3.500, 1.400, 0.200},
            {4.900, 3.000, 1.400, 0.200},
            {4.700, 3.200, 1.300, 0.200},
            {4.600, 3.100, 1.500, 0.200},
            {5.000, 3.600, 1.400, 0.200},
            {5.400, 3.900, 1.700, 0.400},
            {4.600, 3.400, 1.400, 0.300},
            {5.000, 3.400, 1.500, 0.200},
            {4.400, 2.900, 1.400, 0.200},
            {4.900, 3.100, 1.500, 0.100},
            {5.400, 3.700, 1.500, 0.200},
            {4.800, 3.400, 1.600, 0.200},
            {4.800, 3.000, 1.400, 0.100},
            {4.300, 3.000, 1.100, 0.100},
            {5.800, 4.000, 1.200, 0.200},
            {5.700, 4.400, 1.500, 0.400},
            {5.400, 3.900, 1.300, 0.400},
            {5.100, 3.500, 1.400, 0.300},
            {5.700, 3.800, 1.700, 0.300},
            {5.100, 3.800, 1.500, 0.300},
            {5.400, 3.400, 1.700, 0.200},
            {5.100, 3.700, 1.500, 0.400},
            {4.600, 3.600, 1.000, 0.200},
            {5.100, 3.300, 1.700, 0.500},
            {4.800, 3.400, 1.900, 0.200},
            {5.000, 3.000, 1.600, 0.200},
            {5.000, 3.400, 1.600, 0.400},
            {5.200, 3.500, 1.500, 0.200},
            {5.200, 3.400, 1.400, 0.200},
            {4.700, 3.200, 1.600, 0.200},
            {4.800, 3.100, 1.600, 0.200},
            {5.400, 3.400, 1.500, 0.400},
            {5.200, 4.100, 1.500, 0.100},
            {5.500, 4.200, 1.400, 0.200},
            {4.900, 3.100, 1.500, 0.200},
            {5.000, 3.200, 1.200, 0.200},
            {5.500, 3.500, 1.300, 0.200},
            {4.900, 3.600, 1.400, 0.100},
            {4.400, 3.000, 1.300, 0.200},
            {5.100, 3.400, 1.500, 0.200},
            {5.000, 3.500, 1.300, 0.300},
            {4.500, 2.300, 1.300, 0.300},
            {4.400, 3.200, 1.300, 0.200},
            {5.000, 3.500, 1.600, 0.600},
            {5.100, 3.800, 1.900, 0.400},
            {4.800, 3.000, 1.400, 0.300},
            {5.100, 3.800, 1.600, 0.200},
            {4.600, 3.200, 1.400, 0.200},
            {5.300, 3.700, 1.500, 0.200},
            {5.000, 3.300, 1.400, 0.200},
            {7.000, 3.200, 4.700, 1.400},
            {6.400, 3.200, 4.500, 1.500},
            {6.900, 3.100, 4.900, 1.500},
            {5.500, 2.300, 4.000, 1.300},
            {6.500, 2.800, 4.600, 1.500},
            {5.700, 2.800, 4.500, 1.300},
            {6.300, 3.300, 4.700, 1.600},
            {4.900, 2.400, 3.300, 1.000},
            {6.600, 2.900, 4.600, 1.300},
            {5.200, 2.700, 3.900, 1.400},
            {5.000, 2.000, 3.500, 1.000},
            {5.900, 3.000, 4.200, 1.500},
            {6.000, 2.200, 4.000, 1.000},
            {6.100, 2.900, 4.700, 1.400},
            {5.600, 2.900, 3.600, 1.300},
            {6.700, 3.100, 4.400, 1.400},
            {5.600, 3.000, 4.500, 1.500},
            {5.800, 2.700, 4.100, 1.000},
            {6.200, 2.200, 4.500, 1.500},
            {5.600, 2.500, 3.900, 1.100},
            {5.900, 3.200, 4.800, 1.800},
            {6.100, 2.800, 4.000, 1.300},
            {6.300, 2.500, 4.900, 1.500},
            {6.100, 2.800, 4.700, 1.200},
            {6.400, 2.900, 4.300, 1.300},
            {6.600, 3.000, 4.400, 1.400},
            {6.800, 2.800, 4.800, 1.400},
            {6.700, 3.000, 5.000, 1.700},
            {6.000, 2.900, 4.500, 1.500},
            {5.700, 2.600, 3.500, 1.000},
            {5.500, 2.400, 3.800, 1.100},
            {5.500, 2.400, 3.700, 1.000},
            {5.800, 2.700, 3.900, 1.200},
            {6.000, 2.700, 5.100, 1.600},
            {5.400, 3.000, 4.500, 1.500},
            {6.000, 3.400, 4.500, 1.600},
            {6.700, 3.100, 4.700, 1.500},
            {6.300, 2.300, 4.400, 1.300},
            {5.600, 3.000, 4.100, 1.300},
            {5.500, 2.500, 4.000, 1.300},
            {5.500, 2.600, 4.400, 1.200},
            {6.100, 3.000, 4.600, 1.400},
            {5.800, 2.600, 4.000, 1.200},
            {5.000, 2.300, 3.300, 1.000},
            {5.600, 2.700, 4.200, 1.300},
            {5.700, 3.000, 4.200, 1.200},
            {5.700, 2.900, 4.200, 1.300},
            {6.200, 2.900, 4.300, 1.300},
            {5.100, 2.500, 3.000, 1.100},
            {5.700, 2.800, 4.100, 1.300},
            {6.300, 3.300, 6.000, 2.500},
            {5.800, 2.700, 5.100, 1.900},
            {7.100, 3.000, 5.900, 2.100},
            {6.300, 2.900, 5.600, 1.800},
            {6.500, 3.000, 5.800, 2.200},
            {7.600, 3.000, 6.600, 2.100},
            {4.900, 2.500, 4.500, 1.700},
            {7.300, 2.900, 6.300, 1.800},
            {6.700, 2.500, 5.800, 1.800},
            {7.200, 3.600, 6.100, 2.500},
            {6.500, 3.200, 5.100, 2.000},
            {6.400, 2.700, 5.300, 1.900},
            {6.800, 3.000, 5.500, 2.100},
            {5.700, 2.500, 5.000, 2.000},
            {5.800, 2.800, 5.100, 2.400},
            {6.400, 3.200, 5.300, 2.300},
            {6.500, 3.000, 5.500, 1.800},
            {7.700, 3.800, 6.700, 2.200},
            {7.700, 2.600, 6.900, 2.300},
            {6.000, 2.200, 5.000, 1.500},
            {6.900, 3.200, 5.700, 2.300},
            {5.600, 2.800, 4.900, 2.000},
            {7.700, 2.800, 6.700, 2.000},
            {6.300, 2.700, 4.900, 1.800},
            {6.700, 3.300, 5.700, 2.100},
            {7.200, 3.200, 6.000, 1.800},
            {6.200, 2.800, 4.800, 1.800},
            {6.100, 3.000, 4.900, 1.800},
            {6.400, 2.800, 5.600, 2.100},
            {7.200, 3.000, 5.800, 1.600},
            {7.400, 2.800, 6.100, 1.900},
            {7.900, 3.800, 6.400, 2.000},
            {6.400, 2.800, 5.600, 2.200},
            {6.300, 2.800, 5.100, 1.500},
            {6.100, 2.600, 5.600, 1.400},
            {7.700, 3.000, 6.100, 2.300},
            {6.300, 3.400, 5.600, 2.400},
            {6.400, 3.100, 5.500, 1.800},
            {6.000, 3.000, 4.800, 1.800},
            {6.900, 3.100, 5.400, 2.100},
            {6.700, 3.100, 5.600, 2.400},
            {6.900, 3.100, 5.100, 2.300},
            {5.800, 2.700, 5.100, 1.900},
            {6.800, 3.200, 5.900, 2.300},
            {6.700, 3.300, 5.700, 2.500},
            {6.700, 3.000, 5.200, 2.300},
            {6.300, 2.500, 5.000, 1.900},
            {6.500, 3.000, 5.200, 2.000},
            {6.200, 3.400, 5.400, 2.300},
            {5.900, 3.000, 5.100, 1.800}
        };

        Random r = new Random(123457L);
        r.setMultiplier(16807);
        ClusterKMeans kmean = new ClusterKMeans(x, 3, r);

        double[][] cm = kmean.compute();
        double[][] cc = kmean.getInitialCenters();
        double[] wss = kmean.getClusterSSQ();
        int[] ic = kmean.getClusterMembership();
        int[] nc = kmean.getClusterCounts();

        PrintMatrix pm = new PrintMatrix("Cluster Means");

        PrintMatrixFormat pmf = new PrintMatrixFormat();
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMinimumFractionDigits(4);
        pmf.setNumberFormat(nf);
        pm.print(pmf, cm);

        new PrintMatrix("Cluster Centers from K-means++").print(cc);
        new PrintMatrix("Sum of Squares").print(wss);
        new PrintMatrix("Number of observations").print(nc);
    }
}

Output

           Cluster Means
     0       1       2       3     
0  6.8500  3.0737  5.7421  2.0711  
1  5.0060  3.4280  1.4620  0.2460  
2  5.9016  2.7484  4.3935  1.4339  

Cluster Centers from K-means++
    0    1    2    3   
0  6.7  3.3  5.7  2.5  
1  5.7  4.4  1.5  0.4  
2  5.8  2.8  5.1  2.4  

Sum of Squares
     0     
0  23.879  
1  15.151  
2  39.821  

Number of observations
   0   
0  38  
1  50  
2  62  

Link to Java source.