当前位置:   article > 正文

机器学习之聚类算法k-means_go语言实现k-means ++

go语言实现k-means ++

一、目的意义

内容包括:

(1)问题描述:k-means聚类算法的研究,此算法主要对二维数据点进行聚类。

二、算法阐述(占20%)

---输入:期望得到的簇的数目k,n个对象的二维数据D。

---输出:k个簇的集合。

算法步骤:

(1)输入k及n个二维数据对象

     (2)随机选择k个对象作为初始的簇的质心

(3)repeat

(4)计算每个对象与各个簇的质心的距离,将对象划分到距离     其最近的簇

(5)重新计算每个簇的质心并更新

(6)until所有分类下标都等于最小下标,算法停止

(7)输出这k个簇的集合。

三、算法实现(占30%)

 [注]:以下代码为算法的主要代码

命名为k_means.py的文件,此文件下的代码为:

  1. from numpy import *
  2. import matplotlib.pyplot as plt
  3. #计算欧氏距离
  4. def euclDistance(vector1, vector2):
  5. return sqrt(sum(power(vector2 - vector1, 2)))
  6. #初始化质心,采用随机产生质心
  7. def initCentroids(dataSet, k):
  8. numSamples, dim = dataSet.shape
  9. #numSamples = 80
  10. #dim = 2
  11. centroids = mat(zeros((k, dim)))
  12. #[[ 0. 0.]
  13. # [ 0. 0.]
  14. # [ 0. 0.]
  15. # [ 0. 0.]]
  16. for i in range(k):
  17. index = int(random.uniform(0, numSamples)) #产生随机数,如果随机数产生相等了,如22,40,22,13,那么显示的聚类将减少,因为有个聚类的结果始终为空
  18. #print(index)
  19. centroids[i, :] = dataSet[index, :]
  20. #print(centroids)
  21. return centroids
  22. #centroids
  23. #[[-2.123337 2.943366]
  24. # [ 2.046259 2.735279]
  25. # [-2.967647 2.848696]
  26. # [ 3.542056 2.778832]]
  27. #centroids, clusterAssment = k_means.kmeans(dataSet, k)
  28. #k-means
  29. def kmeans(dataSet, k):
  30. numSamples = dataSet.shape[0] #计算行数用0,计算列数用1, numSamples=80
  31. clusterAssment = mat(zeros((numSamples, 2))) #80*2的零矩阵
  32. clusterChanged = True
  33. centroids = initCentroids(dataSet, k) #初始化质心
  34. while clusterChanged:
  35. clusterChanged = False
  36. for i in range(numSamples): #循环80行
  37. minDist = 100000.0 #假设当前的这个距离最小
  38. minIndex = 0
  39. for j in range(k): # 求出每一行距离最小的下标,最小下标即是每个点所属类别
  40. distance = euclDistance(centroids[j],dataSet[i])
  41. if distance < minDist:
  42. minDist = distance
  43. minIndex = j
  44. if clusterAssment[i, 0] != minIndex: #对象的下标不等于最小下标,直到所有对象下标都等于最小下标,算法停止。
  45. clusterChange = True
  46. clusterAssment[i, :] = minIndex, minDist**2
  47. #print(clusterAssment[i, :])
  48. #[[ 2. 2.32363089]]
  49. #[[ 1. 0.14270381]]
  50. #[[ 3. 9.63189586]]
  51. for j in range(k): #将同一个簇的点放在一起
  52. pointsInCluster = dataSet[nonzero(clusterAssment[:, 0] == j)[0]]
  53. #print(pointsInCluster)
  54. #print(nonzero(clusterAssment[:, 0] == j))
  55. #(array([ 3, 27, 51, 71, 79]), array([0, 0, 0, 0, 0]))
  56. centroids[j, :] =mean(pointsInCluster, axis = 0) #计算每一列的均值,得出每个簇的质心
  57. #print(centroids) #[[ 1.09078155 -3.17263173]
  58. # [ 2.6265299 3.10868015]
  59. # [ 4.589752 -1.575316 ]
  60. # [-3.03458403 0.53734279]]
  61. return centroids, clusterAssment
  62. def showCluster(dataSet, k, centroids, clusterAssment):
  63. numSamples, dim = dataSet.shape
  64. if dim != 2:
  65. print("Sorry! I can not draw because the dimension of your data is not 2!")
  66. return 1
  67. #设定普通点颜色形状
  68. mark = ['or','ob','og','ok','^r','+r','sr','dr','<r','pr']
  69. if k > len(mark):
  70. print("Sorry! Your k is too large!")
  71. return 1
  72. ## 画出所有样例点 属于同一分类的绘制同样的颜色
  73. for i in range(numSamples):
  74. markIndex = int(clusterAssment[i, 0])
  75. plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])
  76. #设定质心颜色形状
  77. mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
  78. #画出质心
  79. for i in range(k):
  80. plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)
  81. plt.show()
  82. 命名为test_kmeans.py的文件,此文件下的代码为:
import matplotlib matplotlib.use('Tkagg') #要想绘图成功,必须加上这两句,也可修改matplotlib的配置文件,  #则不用这两句 from numpy import * #numpy 是python的函数库, import matplotlib.pyplot as plt import k_means ##处理数据,dataSet为嵌套列表[[1.658985, 4.285136], [-3.453687, 3.424321],.....] print("loading data...") dataSet = [] fileIn = open('testSet.txt') for line in fileIn.readlines(): lineArr = line.strip().split() #['1.658985', '4.285136']  #['-3.453687', '3.424321']  dataSet.append([float(lineArr[0]), float(lineArr[1])]) #dataSet 嵌套列表  print("clustering..." ) dataSet = mat(dataSet) ####转成80*2的矩阵  k = 4 centroids, clusterAssment = k_means.kmeans(dataSet, k) print("show the result...") k_means.showCluster(dataSet, k, centroids, clusterAssment) 


测试数据文件,文件名为testSet.txt
1.658985    4.285136  
-3.453687   3.424321  
4.838138    -1.151539  
-5.379713   -3.362104  
0.972564    2.924086  
-3.567919   1.531611  
0.450614    -3.302219  
-3.487105   -1.724432  
2.668759    1.594842  
-3.156485   3.191137  
3.165506    -3.999838  
-2.786837   -3.099354  
4.208187    2.984927  
-2.123337   2.943366  
0.704199    -0.479481  
-0.392370   -3.963704  
2.831667    1.574018  
-0.790153   3.343144  
2.943496    -3.357075  
-3.195883   -2.283926  
2.336445    2.875106  
-1.786345   2.554248  
2.190101    -1.906020  
-3.403367   -2.778288  
1.778124    3.880832  
-1.688346   2.230267  
2.592976    -2.054368  
-4.007257   -3.207066  
2.257734    3.387564  
-2.679011   0.785119  
0.939512    -4.023563  
-3.674424   -2.261084  
2.046259    2.735279  
-3.189470   1.780269  
4.372646    -0.822248  
-2.579316   -3.497576  
1.889034    5.190400  
-0.798747   2.185588  
2.836520    -2.658556  
-3.837877   -3.253815  
2.096701    3.886007  
-2.709034   2.923887  
3.367037    -3.184789  
-2.121479   -4.232586  
2.329546    3.179764  
-3.284816   3.273099  
3.091414    -3.815232  
-3.762093   -2.432191  
3.542056    2.778832  
-1.736822   4.241041  
2.127073    -2.983680  
-4.323818   -3.938116  
3.792121    5.135768  
-4.786473   3.358547  
2.624081    -3.260715  
-4.009299   -2.978115  
2.493525    1.963710  
-2.513661   2.642162  
1.864375    -3.176309  
-3.171184   -3.572452  
2.894220    2.489128  
-2.562539   2.884438  
3.491078    -3.947487  
-2.565729   -2.012114  
3.332948    3.983102  
-1.616805   3.573188  
2.280615    -2.559444  
-2.651229   -3.103198  
2.321395    3.154987  
-1.685703   2.939697  
3.031012    -3.620252  
-4.599622   -2.185829  
4.196223    1.126677  
-2.133863   3.093686  
4.668892    -2.562705  
-2.793241   -2.149706  
2.884105    3.043438  
-2.967647   2.848696  
4.479332    -1.764772  
-4.905566   -2.911070

四、结果分析(占30%)

图片解释:算法输出了四个簇,此次聚类结果比较不错,四个较大的点为质心,

图片解释:此次聚类算法明显不如人意,这也是此算法的缺点,易达到局部最优。

图片解释;我们希望的算法聚类个数是4,这里只有3个聚类,出现这也的原因是:簇的四个初始质心是随机选取的,有可能随机到同一个数,如(22,13,33,22),这样导致有一个簇始终为空,不过出现这种情况的概率还是很小的,这也是此算法最糟糕的结果。

 

 

 

五、总结(占15%)

我们知道,任何算法都有它自身的优点与缺点,通过很多次的实验结果验证,我更加深刻理解了k-means的优点与缺点。

优点:k-means算法是聚类问题的经典算法,该算法简单快速。对于大数据量的数据,有相对较高的算法效率,它的伸缩性很高,常常以局部最优来结束算法。当簇是密集的,圆形的,团状的,而且簇与簇之前的区别明显时,它的聚类效果较好。

缺点:要求用户必须事先给出要生成的簇的数目k,这就好比世上先有鸡还是先有蛋的问题,这也是此算法无法避免的缺点。次算法对于初始值很敏感,对于不同的初始值,聚类的结果往往不同。对于噪声数据和孤立点数据非常敏感,少量的该数据能够对平均值产生巨大的影响。

这个算法也即将应用到一个平台上,对于这个算法的透侧研究,也将有助于我开发此软件,我知道,通过此次算法的研究,我已经学到了很多有用的东西。

本人博客

小钻风的博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/529812
推荐阅读
相关标签
  

闽ICP备14008679号