public int[] ClusterKMeans(float[][] Data, ClusterNumberIdentificationType type, int DefaultK, int MaxK) { int bestK = IdentifyOptimalClusterNumber(Data, type, DefaultK, MaxK); //Debug.Log("Best # of Clusters is " + bestK); float[][] InitCentroids = KMeansInitKZZ(Data, bestK); int[] KClass = KMeansClassification(Data, InitCentroids, 2); return(KClass); }
public int IdentifyOptimalClusterNumber(float[][] Data, ClusterNumberIdentificationType type, int DefaultK, int MaxK) { int bestK = 0; switch (type) { case ClusterNumberIdentificationType.None: return(DefaultK); // 0. Find K from N-based heuristic case ClusterNumberIdentificationType.NBased: { return(ClusterNumberNBased(Data)); } // 1. Find K from elbow in Wk "Scree" Plot case ClusterNumberIdentificationType.ScreeElbow: { return(ClusterNumberScreeElbow(Data, MaxK)); } // 2. Find K from maximum Silhouette case ClusterNumberIdentificationType.Silhouette: { return(ClusterNumberSilhouette(Data, MaxK, 2)); } // 3. Find K from Gap between actual and simulated case ClusterNumberIdentificationType.Gap: { return(ClusterNumberGap(Data, MaxK)); } // 4. Find K from cluster compactness case ClusterNumberIdentificationType.KizanowskiLai: { return(ClusterNumberKLDiff(Data, MaxK)); } // 5. Find K from change in Wk case ClusterNumberIdentificationType.Hartigan: { return(ClusterNumberHartigan(Data, MaxK)); } // 6. Find K from change in ratio between Wk and Bk case ClusterNumberIdentificationType.VRC: { return(OptimalKfromVRC(Data, MaxK)); } // 7. All of them! -> Min case ClusterNumberIdentificationType.Omnibus: { List <int> OptimalKList = new List <int>(); OptimalKList.Add(ClusterNumberNBased(Data)); OptimalKList.Add(ClusterNumberScreeElbow(Data, MaxK)); OptimalKList.Add(ClusterNumberSilhouette(Data, MaxK, 2)); OptimalKList.Add(ClusterNumberGap(Data, MaxK)); OptimalKList.Add(ClusterNumberKLDiff(Data, MaxK)); OptimalKList.Add(ClusterNumberHartigan(Data, MaxK)); OptimalKList.Add(OptimalKfromVRC(Data, MaxK)); return(OptimalKList.Min()); } } return(bestK); }