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); }
public int CompareTo(ClusteringData <TData> other) { return(this.Value > other.Value ? 1 : this.Value < other.Value ? -1 : 0); }
public bool Equals(ClusteringData <TData> data) { return(data != null && (ReferenceEquals(data, this) || (Math.Abs(this.Value - data.Value) < Epsilon))); }