/// <summary> /// /// </summary> protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix UNUSED, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog) { // GET OPTIONS int k = (int)args.Parameters[0]; // CREATE RANDOM CENTRES Random rnd = new Random(); var potentialCentres = new List <Vector>(vmatrix.Vectors); List <Cluster> clusters = new List <Cluster>(); for (int n = 0; n < k; n++) { int random = rnd.Next(potentialCentres.Count); Cluster p = new Cluster((clusters.Count + 1).ToString(), tag); Vector vec = potentialCentres[random]; p.Exemplars.Add(vec.Values); potentialCentres.RemoveAt(random); clusters.Add(p); } // Assign to exemplars prog.Enter("Initialising assignments"); LegacyClustererHelper.Assign(vmatrix, clusters, ECandidateMode.Exemplars, args.Distance, prog); prog.Leave(); // Centre LegacyClustererHelper.PerformKMeansCentering(vmatrix, clusters, args.Distance, prog); return(clusters); }
/// <summary> /// d-k-means++ /// Ignores insignificant variables. /// Returns new clusters (these won't be added to the core so make sure to do so) /// </summary> private static List <Cluster> AutogenerateClusters(IntensityMatrix vmatrix, List <Cluster> seed, double?stoppingDistance, int?stoppingCount, ConfigurationMetric metric, ConfigurationClusterer tag, ProgressReporter prog) { // Make a log of whatever limits have been set if (!stoppingCount.HasValue && !stoppingDistance.HasValue) { throw new InvalidOperationException("No stopping condition set."); } // Assign all variables to nearest List <Cluster> result = new List <Cluster>(seed); // Get the actual limits int iterations = 0; int count = (stoppingCount - seed.Count) ?? Int32.MaxValue; double distance = stoppingDistance ?? Double.MinValue; // Get the most distant variable prog.Enter("Initialising assignments"); LegacyClustererHelper.Assign(vmatrix, result, ECandidateMode.Exemplars, metric, prog); Assignment mostDistant = GetMostDistantAssignment(result); prog.Leave(); // Continue until our limits are breached while ((count > 0) && (mostDistant.Score > distance)) { // Check we haven't got unreasonable limits iterations++; prog.Enter("Centre generation (iteration " + iterations + ")"); if (iterations > 1000) { throw new InvalidOperationException("Too many iterations - exiting."); } // Create a new cluster with the most distant variable as its exemplar var newCluster = new Cluster((result.Count + 1).ToString(), tag); result.Add(newCluster); newCluster.Exemplars.Add(mostDistant.Vector.Values); // todo: check to prevent multiple assignment? // Make the assignments based on the closest exemplars LegacyClustererHelper.Assign(vmatrix, result, ECandidateMode.Exemplars, metric, prog); // Basic check if (!newCluster.Assignments.Vectors.Contains(mostDistant.Vector)) { throw new InvalidOperationException("Problem creating new cluster from vector - " + mostDistant.Vector.ToString() + " doesn't like being in its own cluster. Check this vector for discrepancies."); } // Get the next most distant variable count = count - 1; mostDistant = GetMostDistantAssignment(result); prog.Leave(); } // Return the number of iterations return(result); }