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); } }
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 62Link to Java source.