KMeansService.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using static Pipelines.Sockets.Unofficial.SocketConnection;
  5. namespace HTEX.Test.Service
  6. {
  7. public class KMeansService
  8. {
  9. public static Dictionary<double, List<double>> KMeans(IEnumerable<double> datas)
  10. {
  11. // 初始化质心,可以选择数据中的k个随机点作为初始质心
  12. List<double> centroids = new List<double>();
  13. centroids.Add(datas.Min());
  14. centroids.Add(datas.Max());
  15. centroids.Sort(); // 对质心进行排序以避免重复
  16. Dictionary<double, List<double>> clustersResults = new Dictionary<double, List<double>>();
  17. // 迭代次数
  18. int maxIterations = 100;
  19. for (int iteration = 0; iteration < maxIterations; iteration++)
  20. {
  21. // 将数据点分配给最近的质心
  22. Dictionary<double, List<double>> clusters = new Dictionary<double, List<double>>();
  23. foreach (int point in datas)
  24. {
  25. double nearestCentroid = centroids.OrderBy(c => Math.Abs(point - c)).First();
  26. if (!clusters.ContainsKey(nearestCentroid))
  27. {
  28. clusters[nearestCentroid] = new List<double>();
  29. }
  30. clusters[nearestCentroid].Add(point);
  31. }
  32. // 更新质心位置
  33. List<double> newCentroids = new List<double>();
  34. foreach (KeyValuePair<double, List<double>> cluster in clusters)
  35. {
  36. double sum = cluster.Value.Sum();
  37. int count = cluster.Value.Count;
  38. double newCentroid = sum *1.0/ count; // 计算均值
  39. newCentroids.Add(newCentroid);
  40. // 输出当前聚类的信息
  41. //Console.WriteLine($"Cluster with centroid {cluster.Key}:");
  42. //Console.WriteLine($"Min: {cluster.Value.Min()}, Max: {cluster.Value.Max()}, Average: {sum / count}");
  43. }
  44. // 检查质心是否改变
  45. newCentroids.Sort();
  46. clustersResults=clusters;
  47. if (newCentroids.SequenceEqual(centroids))
  48. {
  49. break;
  50. }
  51. centroids = newCentroids;
  52. }
  53. return clustersResults;
  54. }
  55. public static Dictionary<double, List<int>> KMeans(IEnumerable<int> datas )
  56. {
  57. // 初始化质心,可以选择数据中的k个随机点作为初始质心
  58. List<double> centroids = new List<double>();
  59. centroids.Add(datas.Min());
  60. centroids.Add(datas.Max());
  61. centroids.Sort(); // 对质心进行排序以避免重复
  62. Dictionary<double, List<int>> clustersResults = new Dictionary<double, List<int>>();
  63. // 迭代次数
  64. int maxIterations = 100;
  65. for (int iteration = 0; iteration < maxIterations; iteration++)
  66. {
  67. // 将数据点分配给最近的质心
  68. Dictionary<double, List<int>> clusters = new Dictionary<double, List<int>>();
  69. foreach (int point in datas)
  70. {
  71. double nearestCentroid = centroids.OrderBy(c => Math.Abs(point - c)).First();
  72. if (!clusters.ContainsKey(nearestCentroid))
  73. {
  74. clusters[nearestCentroid] = new List<int>();
  75. }
  76. clusters[nearestCentroid].Add(point);
  77. }
  78. // 更新质心位置
  79. List<double> newCentroids = new List<double>();
  80. foreach (KeyValuePair<double, List<int>> cluster in clusters)
  81. {
  82. int sum = cluster.Value.Sum();
  83. int count = cluster.Value.Count;
  84. double newCentroid = sum *1.0/ count; // 计算均值
  85. newCentroids.Add(newCentroid);
  86. // 输出当前聚类的信息
  87. //Console.WriteLine($"Cluster with centroid {cluster.Key}:");
  88. //Console.WriteLine($"Min: {cluster.Value.Min()}, Max: {cluster.Value.Max()}, Average: {sum / count}");
  89. }
  90. // 检查质心是否改变
  91. newCentroids.Sort();
  92. clustersResults=clusters;
  93. if (newCentroids.SequenceEqual(centroids))
  94. {
  95. break;
  96. }
  97. centroids = newCentroids;
  98. }
  99. return clustersResults ;
  100. }
  101. }
  102. }