学习数据mining算法收集(1)聚类算法:K-means算法

————————非原创,用来学习,转载https://zhuanlan.zhihu.com/p/77040610——————

 

 

1.定义

K-means 算法中的 代表类簇个数, means 代表类簇内数据对象的均值(当有部分异常点时,求均值是不合理的,即一个特大都值,或者极小的值,会影响均值的数值),因此,K-means算法又称为k-均值算法,k-means算法是一种基于划分的聚类算法,以距离作为数据对象间相似性度量的标准,即数据对象间的距离越小,则它们的相似性越高,则它们越有可能在同一个类簇。数据对象间距离的计算有很多种,k-means算法通常采用欧氏距离来计算数据对象间的距离。

2.算法思想

  1. 初始化 K 个簇集中心,然后计算各个数据对象到簇集中心的距离,把数据对象划分至距离其最近的聚类中心所在簇集中,并求距离和 J1 ,跳转到2
  2. 根据所得簇集,得到新的簇集中心;同时计算新的距离和 2 ,跳转到3
  3. 计算 ΔJ ,判断 ΔJ是否小于阈值或者循环次数是否大于 T ,如果小于阈值或者循环次数大于 T,跳出循环,结束聚类。否则跳转到4
  4. 根据所得簇集,得到新的簇集中心;同时计算新的距离和 J1

  流程:

  

 

 

 3.算法实现

  numpy实现K-means算法

 1 import numpy as np
 2 import random
 3 import time
 4 import matplotlib.pyplot as plt
 5 from scipy.spatial.distance import cdist
 6 # 计算两个矩阵的距离矩阵
 7 def compute_distances_no_loops(A, B):
 8     return cdist(A,B,metric='euclidean')
 9     
10 # 显示簇集,如果簇集类别大于6类,需要增加colorMark的内容
11 def plotFeature(data, labels_):
12     clusterNum=len(set(labels_))
13     fig = plt.figure()
14     scatterColors = ['black', 'blue', 'green', 'yellow', 'red', 'purple', 'orange', 'brown','#BC8F8F','#8B4513','#FFF5EE']
15     ax = fig.add_subplot(111)
16     for i in range(-1,clusterNum):
17         colorSytle = scatterColors[i % len(scatterColors)]
18         subCluster = data[np.where(labels_==i)]
19         ax.scatter(subCluster[:,0], subCluster[:,1], c=colorSytle, s=20)
20     plt.show()
21 
22 # 聚类算法的实现
23 # 需要聚类的数据data
24 # K 聚类的个数
25 # tol 聚类的容差,即ΔJ
26 # 聚类迭代都最大次数N
27 def K_means(data,K,tol,N):
28     #一共有多少条数据
29     n = np.shape(data)[0]
30     # 从n条数据中随机选择K条,作为初始中心向量
31     # centerId是初始中心向量的索引坐标
32     centerId = random.sample(range(0, n), K)
33     # 获得初始中心向量,k个
34     centerPoints = data[centerId]
35     # 计算data到centerPoints的距离矩阵
36     # dist[i][:],是i个点到三个中心点的距离
37     dist = compute_distances_no_loops(data, centerPoints)
38     # axis=1寻找每一行中最小值都索引
39     # squeeze()是将label压缩成一个列表
40     labels = np.argmin(dist, axis=1).squeeze()
41     # 初始化old J
42     oldVar = -0.0001
43     # data - centerPoint[labels],获得每个向量与中心向量之差
44     # np.sqrt(np.sum(np.power(data - centerPoint[labels], 2),获得每个向量与中心向量距离
45     # 计算new J
46     newVar = np.sum(np.sqrt(np.sum(np.power(data - centerPoints[labels], 2), axis=1)))
47     # 迭代次数
48     count=0
49     # 当ΔJ大于容差且循环次数小于迭代次数,一直迭代。负责结束聚类
50     # abs(newVar - oldVar) >= tol:
51     while count<N and abs(newVar - oldVar) > tol:
52         oldVar = newVar
53         for i in range(K):
54             # 重新计算每一个类别都中心向量
55             centerPoints[i] = np.mean(data[np.where(labels == i)], 0)
56         # 重新计算距离矩阵
57         dist = compute_distances_no_loops(data, centerPoints)
58         # 重新分类
59         labels = np.argmin(dist, axis=1).squeeze()
60         # 重新计算new J
61         newVar = np.sum(np.sqrt(np.sum(np.power(data - centerPoints[labels], 2), axis=1)))
62         # 迭代次数加1
63         count+=1
64     # 返回类别标识,中心坐标
65     return labels,centerPoints
66 starttime = time.clock()
67 data = np.loadtxt("cluster.csv", delimiter=",")
68 labels,_=K_means(data,3,0.01,100)
69 endtime = time.clock()
70 print(endtime - starttime)
71 plotFeature(data, labels)

  使用scikit-learn实现K-means算法

 1 import numpy as np
 2 from sklearn.cluster import KMeans
 3 # 加载数据
 4 data = np.loadtxt("cluster.csv", delimiter=",")
 5 # 构造一个聚类数为3的聚类器
 6 estimator = KMeans(n_clusters=3,max_iter=100,tol=0.001)
 7 # 实现聚类结果
 8 estimator.fit(data)
 9 # 获取聚类标签
10 label_pred = estimator.labels_
11 # 获取聚类中心
12 centroids = estimator.cluster_centers_
13 # 获取聚类准则的总和
14 inertia = estimator.inertia_

5.K-means优缺点

   优点:

    算法简单易实现;

   缺点:

    需要用户事先指定类簇个数K;

    **对异常点敏感,一个特大都值,或者极小的值,会影响均值的数值**

    聚类结果对初始类簇中心的选取较为敏感;

    容易陷入局部最优;

    只能发现球型类簇;

 

 

posted @ 2023-03-22 19:43  SophiaShen1114  阅读(180)  评论(0)    收藏  举报