当前位置:   article > 正文

K-means聚类模型(超详细,含案例代码)_kmeans聚类

kmeans聚类

什么是K-means ?

        K-means是一种常用的聚类算法,用于将数据集中的观测点分为不同的群组或簇。聚类是一种无监督学习方法,其目标是发现数据中隐藏的结构,将相似的数据点划分为同一组,同时将不相似的数据点划分为不同的组。

e1a0144f5aea42d3b95d5076b64243a1.png

K-means聚类的工作原理

  1.         1、选择簇的数量(K): 首先,用户需要指定要将数据分成多少个簇。这通常是在算法应用之前由用户提供的一个参数。
  2.         2、初始化聚类中心: 随机选择K个数据点作为初始聚类中心(centroid)。这些中心点代表了每个簇的中心。
  3.         3、分配数据点到最近的聚类中心: 对于每个数据点,计算其与每个聚类中心的距离,将其分配给距离最近的聚类中心所在的簇。
  4.         4、更新聚类中心: 对于每个簇,计算该簇中所有数据点的平均值,将这个平均值作为新的聚类中心。
  5.         5、重复步骤3和步骤4: 重复这个过程,直到聚类中心不再发生显著变化,或者达到预定的迭代次数。

        K-means的目标是最小化簇内的平方误差,即最小化每个数据点到其簇内聚类中心的距离的平方和。虽然K-means在处理大型数据集时效果良好,但它对于初始聚类中心的选择敏感,并且可能陷入局部最小值。因此,通常会多次运行算法,并选择效果最好的一组聚类结果。

 

79ef893489314fdd9de651074027caac.png

什么时候用K-means聚类算法?

b5e60c4c863f449f9dc34c1a3ef6e8fc.png

        数据集中存在自然的群集结构: K-means假设数据可以被分为若干个紧密聚集的群集,适用于数据集中存在簇结构的情况。

        对计算效率要求较高: K-means是一种计算效率较高的算法,特别是对于大型数据集。它通常是大规模数据集聚类的首选算法之一。

        簇的形状近似为球形: K-means对于各向同性(球形)簇的效果较好。如果簇的形状非常复杂或者簇之间有重叠,K-means的性能可能会下降。

        对于划分性质的问题: K-means适用于将数据点划分为互不重叠的簇的问题,每个数据点只属于一个簇。

        对于初始聚类中心的选择不敏感时: 尽管K-means对于初始聚类中心的选择较为敏感,但在某些情况下,算法的性能可能对初始值不太敏感,或者可以通过多次运行算法以获取不同初始值的结果。

        注意:K-means并不适用于所有类型的数据和问题。在一些情况下,数据可能不满足K-means的假设,或者聚类的数量不容易确定。在这些情况下,其他聚类算法或深度学习方法可能更为合适。在应用K-means之前,最好先对数据进行探索性分析,确保它满足算法的假设。

案例代码1

        当使用Python实现K-means聚类时,可以使用一些流行的机器学习库,例如scikit-learn。以下是一个简单的K-means聚类案例代码:

  1. # 导入必要的库
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from sklearn.cluster import KMeans
  5. from sklearn.datasets import make_blobs
  6. # 生成模拟数据
  7. n_samples = 300
  8. n_features = 2
  9. n_clusters = 3
  10. # 使用make_blobs生成聚类数据
  11. X, y = make_blobs(n_samples=n_samples, n_features=n_features, centers=n_clusters, random_state=42)
  12. # 使用KMeans算法进行聚类
  13. kmeans = KMeans(n_clusters=n_clusters)
  14. kmeans.fit(X)
  15. # 获取聚类结果和聚类中心
  16. labels = kmeans.labels_
  17. centers = kmeans.cluster_centers_
  18. # 绘制原始数据和聚类结果
  19. plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', edgecolor='k')
  20. plt.scatter(centers[:, 0], centers[:, 1], c='red', marker='X', s=200, label='Centroids')
  21. plt.title('K-means Clustering')
  22. plt.xlabel('Feature 1')
  23. plt.ylabel('Feature 2')
  24. plt.legend()
  25. plt.show()

        在这个例子中,使用make_blobs生成包含三个簇的模拟数据,然后使用KMeans类进行聚类。最后,我们绘制原始数据和聚类结果,标记出聚类中心。请注意,实际数据可能需要更复杂的预处理和调整参数,具体取决于数据集和应用场景。

案例代码2

        1.便于理解,首先创建一个明显分为2类20*2的例子(每一列为一个变量共2个变量,每一行为一个样本共20个样本):

  1. import numpy as np
  2. c1x=np.random.uniform(0.5,1.5,(1,10))
  3. c1y=np.random.uniform(0.5,1.5,(1,10))
  4. c2x=np.random.uniform(3.5,4.5,(1,10))
  5. c2y=np.random.uniform(3.5,4.5,(1,10))
  6. x=np.hstack((c1x,c2x))
  7. y=np.hstack((c2y,c2y))
  8. X=np.vstack((x,y)).T
  9. print(X)

        2.引用Python库将样本分为两类(k=2),并绘制散点图:

#只需将X修改即可进行其他聚类分析

  1. import matplotlib.pyplot as plt
  2. from sklearn.cluster import KMeans
  3. kemans=KMeans(n_clusters=2)
  4. result=kemans.fit_predict(X) #训练及预测
  5. print(result) #分类结果
  6. plt.rcParams['font.family'] = ['sans-serif']
  7. plt.rcParams['font.sans-serif'] = ['SimHei'] #散点图标签可以显示中文
  8. x=[i[0] for i in X]
  9. y=[i[1] for i in X]
  10. plt.scatter(x,y,c=result,marker='o')
  11. plt.xlabel('x')
  12. plt.ylabel('y')
  13. plt.show()
  1. 结果:
  2. [0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1]

        3.如果K值未知,可采用肘部法选择K值(假设最大分类数为9类,分别计算分类结果为1-9类的平均离差,离差的提升变化下降最抖时的值为最优聚类数K)

  1. import matplotlib.pyplot as plt
  2. from sklearn.cluster import KMeans
  3. from scipy.spatial.distance import cdist
  4. K=range(1,10)
  5. meanDispersions=[]
  6. for k in K:
  7. kemans=KMeans(n_clusters=k)
  8. kemans.fit(X)
  9. #计算平均离差
  10. m_Disp=sum(np.min(cdist(X,kemans.cluster_centers_,'euclidean'),axis=1))/X.shape[0]
  11. meanDispersions.append(m_Disp)
  12. plt.rcParams['font.family'] = ['sans-serif']
  13. plt.rcParams['font.sans-serif'] = ['SimHei'] #使折线图显示中文
  14. plt.plot(K,meanDispersions,'bx-')
  15. plt.xlabel('k')
  16. plt.ylabel('平均离差')
  17. plt.title('用肘部方法选择K值')
  18. plt.show()

案例分析

对某网站500家饭店价格及评论进行聚类

  1. import numpy as np
  2. from sklearn.cluster import KMeans
  3. from scipy.spatial.distance import cdist
  4. import matplotlib.pyplot as plt
  5. import pandas as pd
  6. data=pd.read_excel('data.xlsx',header=0).iloc[:501,3:5]
  7. per_25=data.describe().iloc[4,1]
  8. per_75=data.describe().iloc[6,1]
  9. data=data[(data.iloc[:,1]>=per_25)&(data.iloc[:,1]<=per_75)] #选择位于四分位数之内的数
  10. X=np.array(data)
  11. K=range(1,10)
  12. meanDispersions=[]
  13. for k in K:
  14. kemans=KMeans(n_clusters=k)
  15. kemans.fit(X)
  16. meanDispersions.append(sum(np.min(cdist(X,kemans.cluster_centers_,'euclidean'),axis=1))/X.shape[0])
  17. plt.rcParams['font.family'] = ['sans-serif']
  18. plt.rcParams['font.sans-serif'] = ['SimHei']
  19. plt.plot(K,meanDispersions,'bx-')
  20. plt.xlabel('k')
  21. plt.ylabel('平均离差')
  22. plt.title('用肘部方法选择K值')
  23. plt.show()

        具体聚类过程:

  1. from sklearn.cluster import KMeans
  2. import matplotlib.pyplot as plt
  3. kemans=KMeans(n_clusters=3)
  4. result=kemans.fit_predict(X)
  5. print(result)
  6. x=[i[0] for i in X]
  7. y=[i[1] for i in X]
  8. plt.scatter(x,y,c=result,marker='o')
  9. plt.xlabel('avgPrice')
  10. plt.ylabel('llCommentNum')
  11. plt.title('对500家饭店价格与评论数进行聚类')

        聚类结果:

  1. [2 0 0 0 0 1 0 0 2 0 0 2 1 2 0 1 2 0 2 2 2 0 0 0 0 1 2 0 1 0 0 2 2 2 2 2 2
  2. 2 2 0 1 0 0 0 1 0 2 2 0 2 2 0 0 2 2 2 1 0 1 1 1 0 0 0 0 1 2 1 2 0 2 1 0 0
  3. 2 1 1 0 0 1 2 2 0 2 2 1 0 2 1 0 2 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 2 1 2 1
  4. 1 0 0 1 0 1 2 1 0 1 1 0 1 1 0 1 0 2 1 1 0 1 0 2 0 2 1 2 1 1 0 0 1 0 1 0 1
  5. 0 2 0 1 1 0 1 0 0 1 1 1 1 0 0 0 0 1 0 0 0 2 0 1 1 0 1 0 1 0 0 0 0 1 1 0 1
  6. 2 0 1 1 2 0 1 0 0 1 1 1 1 1 0 0 0 1 1 1 2 0 1 1 1 2 2 0 0 2 1 1 2 1 1 1 0
  7. 1 1 0 1 2 2 0 2 2 2 0 1 0 1 1 2 1 1 1 0 1 1 1 1 0 0 0 0 1]

 

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/494510
推荐阅读
相关标签
  

闽ICP备14008679号