private void btnKMeansClustering_Click(object sender, EventArgs e) { try { if (PList.Count == 0) { throw new Exception("No points data exists.."); } int numClusters = int.Parse(txtClusters.Text); List <ClusterCenterPoint> CList = null; KMeans.DoKMeans(numClusters, ref PList, ref CList, 0.1, 1000, true); //true means do kplusplus MyImageProc.DrawClusters(pic1, PList, 1.0, numClusters); txtResult.Text = ComputeAndShowVarianceResults(numClusters); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
private void btnKmeans_Click(object sender, EventArgs e) { try { if (PList.Count == 0) { throw new Exception("No points data exists.."); } Stopwatch sw = new Stopwatch(); int numClusters = int.Parse(txtClusters.Text); List <ClusterCenterPoint> CList = null; sw.Start(); KMeans.DoKMeans(numClusters, ref PList, ref CList, 0.1, 1000); sw.Stop(); MessageBox.Show("Time elapsed (ms): " + sw.ElapsedMilliseconds); MyImageProc.DrawClusters(pic1, PList, 1.0, numClusters); txtResult.Text = ComputeAndShowVarianceResults(numClusters); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
public static int DoKMeansWithMinVariance(int numClusters, ref List <MyPoint> PList, ref List <ClusterCenterPoint> CList, double maxError, int maxIterations, bool minVariance) { double stddev = 0; if (minVariance == true) { stddev = double.MaxValue; } else { stddev = double.MinValue; } List <MyPoint> PListBest = new List <MyPoint>(); List <ClusterCenterPoint> CListBest = new List <ClusterCenterPoint>(); int iter = 0; for (int m = 0; m < 20; m++) //Pick best (most balanced) clustering after 20 clustering attempts { List <MyPoint> PListCopy = new List <MyPoint>(); foreach (MyPoint mp in PList) { PListCopy.Add((MyPoint)mp.Clone()); } List <ClusterCenterPoint> CListCopy = null; iter += KMeans.DoKMeans(numClusters, ref PListCopy, ref CListCopy, 0.01, 100, true); // true means do kmeansplusplus // ----compute variance of cluster memberships int[] CCount = new int[numClusters]; for (int i = 0; i < numClusters; i++) { CCount[i] = 0; } foreach (MyPoint mp in PListCopy) { CCount[mp.ClusterId] += 1; } double variance = 0; for (int i = 0; i < numClusters; i++) { variance += (CCount[i] - (PListCopy.Count) / (double)numClusters) * (CCount[i] - (PListCopy.Count) / (double)numClusters); } double stddevCopy = Math.Sqrt(variance); string out1 = ""; for (int n = 0; n < CCount.Length; n++) { out1 += "Cluster " + n.ToString() + " count = " + CCount[n].ToString() + "\n"; } //MessageBox.Show("StdDev = " + stddevCopy.ToString() + " " + out1); if (minVariance == true) { if (stddevCopy < stddev) // if it improves, copy data into best { stddev = stddevCopy; PListBest.Clear(); foreach (MyPoint mp in PListCopy) { PListBest.Add((MyPoint)mp.Clone()); } CListBest.Clear(); foreach (ClusterCenterPoint cp in CListCopy) { CListBest.Add((ClusterCenterPoint)cp.Clone()); } } } else { if (stddevCopy > stddev) // if it improves, copy data into best { stddev = stddevCopy; PListBest.Clear(); foreach (MyPoint mp in PListCopy) { PListBest.Add((MyPoint)mp.Clone()); } CListBest.Clear(); foreach (ClusterCenterPoint cp in CListCopy) { CListBest.Add((ClusterCenterPoint)cp.Clone()); } } } } CList = CListBest; PList = PListBest; return(iter); }
public static int DoKMeansWithMinVariance(int numClusters, ref List <MyPoint> PList, ref List <ClusterCenterPoint> CList, double maxError, int maxIterations, bool minVariance) { List <MyPoint> copy = new List <MyPoint>(PList); object olock = new object(); double stddev = 0; if (minVariance == true) { stddev = double.MaxValue; } else { stddev = double.MinValue; } List <MyPoint> PListBest = new List <MyPoint>(); List <ClusterCenterPoint> CListBest = new List <ClusterCenterPoint>(); int iter = 0; Parallel.For(0, 20, (m) => //for (int m = 0; m < 20; m++) //Pick best (most balanced) clustering after 20 clustering attempts { List <MyPoint> PListCopy = new List <MyPoint>(); for (int i = 0; i < copy.Count; i++) { PListCopy.Add((MyPoint)copy[i].Clone()); } //foreach (MyPoint mp in PList) //PListCopy.Add((MyPoint)mp.Clone()); List <ClusterCenterPoint> CListCopy = null; iter += KMeans.DoKMeans(numClusters, ref PListCopy, ref CListCopy, 0.01, 100, true); // true means do kmeansplusplus // ----compute variance of cluster memberships int[] CCount = new int[numClusters]; for (int i = 0; i < numClusters; i++) { CCount[i] = 0; } foreach (MyPoint mp in PListCopy) { CCount[mp.ClusterId] += 1; } double variance = 0; for (int i = 0; i < numClusters; i++) { variance += (CCount[i] - (PListCopy.Count) / (double)numClusters) * (CCount[i] - (PListCopy.Count) / (double)numClusters); } double stddevCopy = Math.Sqrt(variance); string out1 = ""; for (int n = 0; n < CCount.Length; n++) { out1 += "Cluster " + n.ToString() + " count = " + CCount[n].ToString() + "\n"; } //MessageBox.Show("StdDev = " + stddevCopy.ToString() + " " + out1); if (minVariance == true) { lock (olock) //Protect while updating stddev. // Otherwise one thread X can obtain a X stddevcopy better than the actual one stop at the if validation //then a new thread Y starts with Y stddevcopy better than actual one and X one, updates stddev and stops //thread X starts again (does not need to pass if statement again) and updates stddevcopy which would be wrong since the best one was Y { if (stddevCopy < stddev) // if it improves, copy data into best { stddev = stddevCopy; PListBest.Clear(); foreach (MyPoint mp in PListCopy) { PListBest.Add((MyPoint)mp.Clone()); } CListBest.Clear(); foreach (ClusterCenterPoint cp in CListCopy) { CListBest.Add((ClusterCenterPoint)cp.Clone()); } } } } /* * else * { * lock (olock) * { * if (stddevCopy > stddev) // if it improves, copy data into best * { * stddev = stddevCopy; * PListBest.Clear(); * foreach (MyPoint mp in PListCopy) * PListBest.Add((MyPoint)mp.Clone()); * CListBest.Clear(); * foreach (ClusterCenterPoint cp in CListCopy) * CListBest.Add((ClusterCenterPoint)cp.Clone()); * } * } * } */ }); CList = CListBest; PList = PListBest; return(iter); }