C# K Means Clustering Example

[TOC]

using System;

using CenterSpace.NMath.Core;
using CenterSpace.NMath.Stats;

namespace CenterSpace.NMath.Stats.Examples.CSharp
{
  /// <summary>
  /// A .NET example in C# showing how to perform a k-means cluster analysis on a data set.
  /// </summary>
  public class KMeansClusteringExample
  {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
      // Class KMeansClustering performs k-means clustering on a set of data points.
      // Instances are constructed from a matrix of data, where each row represents
      // an object to be clustered. This code clusters 30 random vectors of length 3:
      DoubleMatrix data = new DoubleMatrix(30, 3, new RandGenUniform());
      KMeansClustering km = new KMeansClustering(data);
      Console.WriteLine();
      Console.WriteLine("{0} objects to cluster:", km.N);
      Console.WriteLine(data.ToTabDelimited());

      // The Cluster() method clusters the data into the specified number
      // of clusters. This code creates 3 clusters, using random starting
      // cluster centers:
      km.Cluster(3);
      DisplayKMeansResults(km, "K-MEANS CLUSTERING WITH RANDOM STARTING CENTERS");

      // This code specifies the starting centers. K is inferred from the
      // number of rows in the matrix.
      DoubleMatrix centers = new DoubleMatrix("3x3[ 0.25 0.25 0.25  0.50 0.50 0.50  0.75 0.75 0.75]");
      km.Cluster(centers);
      DisplayKMeansResults(km, "K-MEANS CLUSTERING WITH SPECIFIED STARTING CENTERS");

      Console.WriteLine();
      Console.WriteLine("Press Enter Key");
      Console.Read();

    }  // Main

    // Display the results of a k-means clustering
    private static void DisplayKMeansResults(KMeansClustering km, string title)
    {
      Console.WriteLine();
      Console.WriteLine(title);
      Console.WriteLine();

      Console.WriteLine("{0} clusters of sizes {1}", km.K, IntArrayToString(km.Sizes));
      Console.WriteLine();

      Console.WriteLine("Initial cluster centers:");
      Console.WriteLine(km.InitialCenters.ToTabDelimited()); 

      Console.WriteLine("{0} iterations", km.Iterations);
      Console.WriteLine("Stopped because max iterations of {0} met? {1}", km.MaxIterations, km.MaxIterationsMet);
      Console.WriteLine();

      Console.WriteLine("Final cluster centers:");
      Console.WriteLine(km.FinalCenters.ToTabDelimited());

      Console.WriteLine("Clustering assignments:");
      Console.WriteLine(km.Clusters);
      Console.WriteLine();

      Console.WriteLine("Within cluster sum of squares by cluster:\n" + km.WithinSumOfSquares);
      Console.WriteLine();
    }

    // Convert an integer array to a string
    private static string IntArrayToString(int[] intArray)
    {
      string[] sArray = Array.ConvertAll<int, string>(intArray, new Converter<int, string>(Convert.ToString));
      return String.Join(", ", sArray);
    }

  }  // class

}  // namespace

[TOC]