K-means聚类算法

k-means聚类算法

一、介绍

K-means聚类算法是先随机选取K个对象作为初始的聚类中心。然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。

二、简化实例

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

import numpy as np
c1x=np.random.uniform(0.5,1.5,(1,10))
c1y=np.random.uniform(0.5,1.5,(1,10))
c2x=np.random.uniform(3.5,4.5,(1,10))
c2y=np.random.uniform(3.5,4.5,(1,10))
x=np.hstack((c1x,c2x))
y=np.hstack((c2y,c2y))
X=np.vstack((x,y)).T
print(X)

结果如下:

[[1.4889993  4.18741329]
 [0.73017615 4.07842216]
 [1.15522846 4.05744838]
 [1.40768457 3.76674812]
 [1.376212   3.95063903]
 [1.20821055 4.34138767]
 [0.73898392 3.55026013]
 [0.97116627 3.65432314]
 [0.98267302 4.16731561]
 [1.06346541 4.44383585]
 [4.10945954 4.18741329]
 [3.75288064 4.07842216]
 [4.29638229 4.05744838]
 [3.95221785 3.76674812]
 [4.09826192 3.95063903]
 [4.04840874 4.34138767]
 [4.29594009 3.55026013]
 [3.56931245 3.65432314]
 [3.57962941 4.16731561]
 [3.65208848 4.44383585]]

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

#只需将X修改即可进行其他聚类分析
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
 
kemans=KMeans(n_clusters=2)
result=kemans.fit_predict(X) #训练及预测
print(result)   #分类结果
 
plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei'] #散点图标签可以显示中文
 
x=[i[0] for i in X]
y=[i[1] for i in X]
plt.scatter(x,y,c=result,marker='o')
plt.xlabel('x')
plt.ylabel('y')
plt.show()

结果如下:

[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):

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

三、实例分析(对某网站500家饭店价格及评论进行聚类)

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

具体聚类过程:

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

kemans=KMeans(n_clusters=3)
result=kemans.fit_predict(X)
print(result)
x=[i[0] for i in X]
y=[i[1] for i in X]
plt.scatter(x,y,c=result,marker='o')
plt.xlabel('avgPrice')
plt.ylabel('llCommentNum')
plt.title('对500家饭店价格与评论数进行聚类')

聚类结果:

[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 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
 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
 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
 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
 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
 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] 

K-means聚类是一种非常流行的聚类算法,它基于中心点的迭代优化来将数据点划分到不同的簇中。以下是对K-means聚类算法的总结:

四、最佳K值的确定

在实际应用中确定K-means聚类算法的最佳K值是一个关键问题,以下是几种常用的方法:

  1. 肘部法则(Elbow Method):这是一种直观的方法,通过绘制WCSS(误差平方和)与K值的关系图来确定最优K值。随着K值的增加,WCSS通常会下降,然后在某个点之后下降速度显著减慢,形成一个“肘部”,这个点通常被认为是最优K值 。

  2. 轮廓系数法:轮廓系数结合了内聚度和分离度两个因素,S值介于-1到1之间,越接近1表示聚类效果越好。该方法适用于评价聚类效果,但需要确定K值后再进行评估 。

  3. Gap统计量:Gap统计量基于实际数据集与随机数据集WCSS的期望值之间的差异。如果聚类是有意义的,那么实际数据集的样本点应该比随机数据更紧密地聚集在一起,从而产生更大的Gap值 。

  4. 交叉验证方法:将数据集分成多个部分,在部分数据上进行聚类,同时在其他部分上评估聚类的质量。这可以通过轮廓系数或其他聚类质量指标来实现 。

  5. Canopy算法:这是一种预聚类方法,通过设置两个距离阈值T1和T2(T1 > T2),快速将数据分为多个“canopy”,然后对每个canopy使用K-means算法进行更细致的聚类。这种方法不需要事先指定K值,并且可以作为确定K值的初步步骤 。

  6. 拍脑袋法:一个非正式的方法是将样本量除以2再开方,得到的值作为K值的初始估计 。

  7. 间隔统计量:该方法通过计算聚类数据的WCSS与随机生成数据的WCSS之间的差异来确定K值。Gap值最大的K被认为是最优的聚类数 。

每种方法都有其优缺点,选择哪种方法取决于具体问题和数据集的特性。在实践中,可能需要尝试多种方法并结合领域知识来确定最佳的K值。

五、总结

1. 算法原理

K-means算法的基本思想是将数据点划分到K个簇中,使得每个数据点属于与其最近的聚类中心对应的簇。算法的步骤如下:

  1. 初始化:随机选择K个数据点作为初始聚类中心。
  2. 分配:计算每个数据点与各个聚类中心的距离,将数据点分配到最近的聚类中心,形成K个簇。
  3. 更新:重新计算每个簇的聚类中心,通常是取簇内所有点的均值。
  4. 迭代:重复步骤2和3,直到满足终止条件,如聚类中心不再变化或达到最大迭代次数。

2. 算法特点

  • 简单高效:算法逻辑简单,易于实现,计算复杂度较低。
  • 易于理解:直观地将数据点划分到最近的聚类中心。
  • 适用范围广:适用于各种类型的数据集,尤其是数值型数据。

3. 算法参数

  • K值:需要预先指定的簇的数量。选择合适的K值是算法的关键。
  • 终止条件:可以是聚类中心的变化小于某个阈值,或者达到最大迭代次数。

4. 算法优缺点

  • 优点
    • 实现简单,计算效率高。
    • 对于大数据集表现良好。
    • 可以很容易地并行化处理。
  • 缺点
    • 需要预先指定K值,选择不当会影响聚类效果。
    • 对初始聚类中心敏感,可能导致局部最优解。
    • 不适合非球形簇或大小不一的簇。

5. 应用场景

K-means聚类广泛应用于各种领域,如:

  • 市场细分:根据消费者的购买行为将他们分为不同的市场细分。
  • 图像分割:将图像分割成不同的区域。
  • 社交网络分析:根据用户的兴趣或行为将用户分组。
  • 基因表达分析:将基因表达数据聚类以发现基因表达模式。

6. 改进方法

为了克服K-means的一些局限性,研究者们提出了一些改进方法:

  • K-means++:改进的初始化方法,减少局部最优解的可能性。
  • 模糊C均值聚类:允许数据点属于多个簇,增加聚类的灵活性。
  • 谱聚类:基于数据的相似性矩阵,使用图论的方法进行聚类。

7. 实现工具

K-means聚类可以通过多种编程语言和工具实现,如:

  • Python:使用scikit-learn库中的KMeans类。
  • R:使用stats包中的kmeans函数。
  • MATLAB:内置的kmeans函数。

8. 可视化

聚类结果可以通过散点图进行可视化,使用不同的颜色或标记表示不同的簇,直观地展示聚类效果。

通过以上总结,可以更好地理解K-means聚类算法的基本原理、特点、应用场景以及如何实现和改进。

  • 18
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值