K-means聚类算法

来源:互联网 发布:mac传奇单机版 编辑:程序博客网 时间:2024/06/11 23:02

K-means聚类算法


1:K-means算法简介

       聚类算法,数据挖掘十大算法之一,算法需要接受参数k和k个初始聚类中心,即将数据集进行聚类的数目和k个簇的初始聚类“中心”,结果是同一类簇中的对象相似度极高,不同类簇中的数据相似度极低


2:K-means算法思想和描述

      思想: 以空间中k个中心点进行聚类,对最靠近他们的对象归类,通过迭代的方法,逐次更新各聚类中心

      描述:

       (1)适当选择C个类的初始中心
       (2)在第K此迭代中,对任意一个样本,求其到C各中心的距离,将该样本归到距离最短的中心所在的类
       (3)利用均值等方法更新该类的中心值
       (4)对于所有的C个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代

3:集合实例的简单介绍

                                  例如现在有四种药物A,B,C,D,他们分别有两个属性。如下图
                                                     
                                   将他们表示在坐标轴上为:
                                                                  
           第一次迭代,随机选取两个点作为初始中心点,eg c1,c2作为初始中心点,D0中分别为四个点到两个样本点的距离,X,Y为横纵坐标
                                                                        
           A点离第一个点最近,所以group-1行A点置1,剩下的三个点离第二个中心点最近,所以group-2行置1    
  
          此时应该更新样本点,c1不变,c2更新为((2+4+5)/3,(1+3+4)/3)=(11/3,8/3),更新后的数据中心点如下图红点所示
                                                                        
         第二次迭代,以(11/3,8/3)作为样本中心点,分别计算四个点到样本中心点的距离,如下图
                                                                         
         A,B点距离第一个中心点最近,C,D点距离第二个中心点最近,所以group-1行,A,B置1,group-2行C,D置1
                                                                                          
         此时重新更新样本中心点,c1=((1+2)/2,(1+1)/2)=(3/2,1),c2=((4+5)/2,(3+4)/2)=(9/2,7/2),更新后的数据中心点如下图红点所示
                                                                           
         第三次迭代,计算同上,略过,此时数据的样本中心点不再发生变化,所以可以停止迭代,最终聚类情况如下:
                                                               

4:下边看一个使用sklearn.Kmeans的实例(实例来源)

实例说明:利用sklearn.datasets.make_blobs产生1500条两维的数据集进行不同情况下的聚类示例,代码如下
[python] view plain copy
  1. <span style="font-size:18px;">#coding:utf-8  
  2. ''''' 
  3. Created on 2016/4/25 
  4.  
  5. @author: Gamer Think 
  6. '''  
  7. import numpy as np      #科学计算包  
  8. import matplotlib.pyplot as plt      #python画图包  
  9.   
  10. from sklearn.cluster import KMeans       #导入K-means算法包  
  11. from sklearn.datasets import make_blobs  
  12.   
  13. plt.figure(figsize=(1212))  
  14.   
  15. ''''' 
  16. make_blobs函数是为聚类产生数据集 
  17. 产生一个数据集和相应的标签 
  18. n_samples:表示数据样本点个数,默认值100 
  19. n_features:表示数据的维度,默认值是2 
  20. centers:产生数据的中心点,默认值3 
  21. cluster_std:数据集的标准差,浮点数或者浮点数序列,默认值1.0 
  22. center_box:中心确定之后的数据边界,默认值(-10.0, 10.0) 
  23. shuffle :洗乱,默认值是True 
  24. random_state:官网解释是随机生成器的种子 
  25. 更多参数即使请参考:http://scikit-learn.org/dev/modules/generated/sklearn.datasets.make_blobs.html#sklearn.datasets.make_blobs 
  26. '''  
  27. n_samples = 1500  
  28. random_state = 170  
  29. X, y = make_blobs(n_samples=n_samples, random_state=random_state)  
  30.   
  31.   
  32. # Incorrect number of clusters  
  33. y_pred = KMeans(n_clusters=2, random_state=random_state).fit_predict(X)  
  34.   
  35. plt.subplot(221)  #在2图里添加子图1  
  36. plt.scatter(X[:, 0], X[:, 1], c=y_pred) #scatter绘制散点  
  37. plt.title("Incorrect Number of Blobs")   #加标题  
  38.   
  39. # Anisotropicly distributed data  
  40. transformation = [[ 0.60834549, -0.63667341], [-0.408877180.85253229]]  
  41. X_aniso = np.dot(X, transformation)    #返回的是乘积的形式  
  42. y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_aniso)  
  43.   
  44. plt.subplot(222)#在2图里添加子图2  
  45. plt.scatter(X_aniso[:, 0], X_aniso[:, 1], c=y_pred)  
  46. plt.title("Anisotropicly Distributed Blobs")  
  47.   
  48. # Different variance  
  49. X_varied, y_varied = make_blobs(n_samples=n_samples,  
  50.                                 cluster_std=[1.02.50.5],  
  51.                                 random_state=random_state)  
  52. y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_varied)  
  53.   
  54. plt.subplot(223)#在2图里添加子图3  
  55. plt.scatter(X_varied[:, 0], X_varied[:, 1], c=y_pred)  
  56. plt.title("Unequal Variance")  
  57.   
  58. # Unevenly sized blobs  
  59. X_filtered = np.vstack((X[y == 0][:500], X[y == 1][:100], X[y == 2][:10]))  
  60. y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_filtered)  
  61.   
  62. plt.subplot(224)#在2图里添加子图4  
  63. plt.scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_pred)  
  64. plt.title("Unevenly Sized Blobs")  
  65.   
  66. plt.show() #显示图</span>  

结果图示:


二:Mini Batch K-Means算法

scikit-learn官网上对于Mini Batch K-Means算法的说明如下:

Mini Batch K-Means算法是K-Means算法的变种,采用小批量的数据子集减小计算时间,同时仍试图优化目标函数,这里所谓的小批量是指每次训练算法时所随机抽取的数据子集,采用这些随机产生的子集进行训练算法,大大减小了计算时间,与其他算法相比,减少了k-均值的收敛时间,小批量k-均值产生的结果,一般只略差于标准算法。

该算法的迭代步骤有两步:

1:从数据集中随机抽取一些数据形成小批量,把他们分配给最近的质心

2:更新质心

与K均值算法相比,数据的更新是在每一个小的样本集上。对于每一个小批量,通过计算平均值得到更新质心,并把小批量里的数据分配给该质心,随着迭代次数的增加,这些质心的变化是逐渐减小的,直到质心稳定或者达到指定的迭代次数,停止计算

Mini Batch K-Means比K-Means有更快的 收敛速度,但同时也降低了聚类的效果,但是在实际项目中却表现得不明显

这是一张k-means和mini batch k-means的实际效果对比图


下边给出显示上边这副图的代码,也是对K-Means和Mini Batch K-Means算法的一个比较:

[python] view plain copy
  1. <span style="font-size:18px;">#coding:utf8  
  2. ''''' 
  3. Created on 2016/4/26 
  4.  
  5. @author: Gamer Think 
  6. '''  
  7. import time  
  8.   
  9. import numpy as np  
  10. import matplotlib.pyplot as plt  
  11.   
  12. from sklearn.cluster import MiniBatchKMeans, KMeans  
  13. from sklearn.metrics.pairwise import pairwise_distances_argmin  
  14. from sklearn.datasets.samples_generator import make_blobs  
  15.   
  16. ##############################################################################  
  17. # Generate sample data  
  18. np.random.seed(0)  
  19.   
  20. batch_size = 45  
  21. centers = [[11], [-1, -1], [1, -1]] #初始化三个中心  
  22. n_clusters = len(centers)       #聚类的数目为3  
  23. #产生3000组两维的数据,以上边三个点为中心,以(-10,10)为边界,数据集的标准差是0.7  
  24. X, labels_true = make_blobs(n_samples=3000, centers=centers, cluster_std=0.7)  
  25.   
  26. ##############################################################################  
  27. # Compute clustering with Means  
  28.   
  29. k_means = KMeans(init='k-means++', n_clusters=3, n_init=10)  
  30. t0 = time.time() #当前时间  
  31. k_means.fit(X)  
  32. #使用K-Means 对 3000数据集训练算法的时间消耗  
  33. t_batch = time.time() - t0  
  34.   
  35. ##############################################################################  
  36. # Compute clustering with MiniBatchKMeans  
  37.   
  38. mbk = MiniBatchKMeans(init='k-means++', n_clusters=3, batch_size=batch_size,  
  39.                       n_init=10, max_no_improvement=10, verbose=0)  
  40. t0 = time.time()  
  41. mbk.fit(X)  
  42. #使用MiniBatchKMeans 对 3000数据集训练算法的时间消耗  
  43. t_mini_batch = time.time() - t0  
  44.   
  45. ##############################################################################  
  46. # Plot result  
  47.   
  48. #创建一个绘图对象, 并设置对象的宽度和高度, 如果不创建直接调用plot, Matplotlib会直接创建一个绘图对象  
  49. ''''' 
  50. 当绘图对象中有多个轴的时候,可以通过工具栏中的Configure Subplots按钮, 
  51. 交互式地调节轴之间的间距和轴与边框之间的距离。 
  52. 如果希望在程序中调节的话,可以调用subplots_adjust函数, 
  53. 它有left, right, bottom, top, wspace, hspace等几个关键字参数, 
  54. 这些参数的值都是0到1之间的小数,它们是以绘图区域的宽高为1进行正规化之后的坐标或者长度。 
  55. '''  
  56. fig = plt.figure(figsize=(83))  
  57. fig.subplots_adjust(left=0.02, right=0.98, bottom=0.05, top=0.9)  
  58. colors = ['#4EACC5''#FF9C34''#4E9A06']  
  59.   
  60. # We want to have the same colors for the same cluster from the  
  61. # MiniBatchKMeans and the KMeans algorithm. Let's pair the cluster centers per  
  62. # closest one.  
  63. k_means_cluster_centers = np.sort(k_means.cluster_centers_, axis=0)  
  64. mbk_means_cluster_centers = np.sort(mbk.cluster_centers_, axis=0)  
  65. k_means_labels = pairwise_distances_argmin(X, k_means_cluster_centers)  
  66. mbk_means_labels = pairwise_distances_argmin(X, mbk_means_cluster_centers)  
  67. order = pairwise_distances_argmin(k_means_cluster_centers,  
  68.                                   mbk_means_cluster_centers)  
  69.   
  70. # KMeans  
  71. ax = fig.add_subplot(131#add_subplot  图像分给为 一行三列,第一块  
  72. for k, col in zip(range(n_clusters), colors):  
  73.     my_members = k_means_labels == k  
  74.     cluster_center = k_means_cluster_centers[k]  
  75.     ax.plot(X[my_members, 0], X[my_members, 1], 'w',  
  76.             markerfacecolor=col, marker='.')  
  77.     ax.plot(cluster_center[0], cluster_center[1], 'o', markerfacecolor=col,  
  78.             markeredgecolor='k', markersize=6)  
  79. ax.set_title('KMeans')  
  80. ax.set_xticks(())  
  81. ax.set_yticks(())  
  82. plt.text(-3.51.8,  'train time: %.2fs\ninertia: %f' % (  
  83.     t_batch, k_means.inertia_))  
  84.   
  85. # MiniBatchKMeans  
  86. ax = fig.add_subplot(132)#add_subplot  图像分给为 一行三列,第二块  
  87. for k, col in zip(range(n_clusters), colors):  
  88.     my_members = mbk_means_labels == order[k]  
  89.     cluster_center = mbk_means_cluster_centers[order[k]]  
  90.     ax.plot(X[my_members, 0], X[my_members, 1], 'w',  
  91.             markerfacecolor=col, marker='.')  
  92.     ax.plot(cluster_center[0], cluster_center[1], 'o', markerfacecolor=col,  
  93.             markeredgecolor='k', markersize=6)  
  94. ax.set_title('MiniBatchKMeans')  
  95. ax.set_xticks(())  
  96. ax.set_yticks(())  
  97. plt.text(-3.51.8'train time: %.2fs\ninertia: %f' %  
  98.          (t_mini_batch, mbk.inertia_))  
  99.   
  100. # Initialise the different array to all False  
  101. different = (mbk_means_labels == 4)  
  102. ax = fig.add_subplot(133)#add_subplot  图像分给为 一行三列,第三块  
  103.   
  104. for k in range(n_clusters):  
  105.     different += ((k_means_labels == k) != (mbk_means_labels == order[k]))  
  106.   
  107. identic = np.logical_not(different)  
  108. ax.plot(X[identic, 0], X[identic, 1], 'w',  
  109.         markerfacecolor='#bbbbbb', marker='.')  
  110. ax.plot(X[different, 0], X[different, 1], 'w',  
  111.         markerfacecolor='m', marker='.')  
  112. ax.set_title('Difference')  
  113. ax.set_xticks(())  
  114. ax.set_yticks(())  
  115.   
  116. plt.show()</span>