public ClusteringResult <TData> Cluster(int clustersCount, IEnumerable <ClusteringData <TData> > data)
        {
            var sw = new Stopwatch();

            sw.Start();

            var dataIndexes = this.CreateMapDataToIndex(data);

            Log.DebugFormat("KMeans: start clustering {0} data items, number of clusters set to {1}", dataIndexes.Count, clustersCount);

            // Number of clusters can not be more than number of data.
            clustersCount = Math.Min(dataIndexes.Count, clustersCount);
            Log.DebugFormat("KMeans: number of clusters changed to {0}", clustersCount);
            var clustering = this.InitiallyDevideDataByClusters(clustersCount, dataIndexes);

            // When clustersCount == 1 then do not need to clustering at all, just return given data as one cluster.
            if (clustersCount > 1)
            {
                var means     = new double[clustersCount];
                var centroids = new ClusteringData <TData> [clustersCount];

                this.CalculateCentroids(dataIndexes, clustering, means, centroids);
                var interationNum = 0;

                while (this.RecalculateClusters(dataIndexes, clustering, centroids) && interationNum++ < this.MaxIterationsCount)
                {
                    this.CalculateCentroids(dataIndexes, clustering, means, centroids);
                }
            }

            var result = this.BuildClusteredResult(clustersCount, dataIndexes, clustering);

            sw.Stop();
            Log.DebugFormat("KMeans: end clustering {0} data items, took {1} ms", dataIndexes.Count, sw.ElapsedMilliseconds);

            return(result);
        }
Example #2
0
 public int CompareTo(ClusteringData <TData> other)
 {
     return(this.Value > other.Value
                         ? 1
                         : this.Value < other.Value ? -1 : 0);
 }
Example #3
0
 public bool Equals(ClusteringData <TData> data)
 {
     return(data != null &&
            (ReferenceEquals(data, this) ||
             (Math.Abs(this.Value - data.Value) < Epsilon)));
 }