请选择 进入手机版 | 继续访问电脑版
楼主: CDA网校
1420 2

使用k均值聚类对数据点进行分组 [推广有奖]

  • 4关注
  • 96粉丝

管理员

大师

60%

还不是VIP/贵宾

-

威望
3
论坛币
27973 个
通用积分
2983.4549
学术水平
259 点
热心指数
267 点
信用等级
234 点
经验
193571 点
帖子
5034
精华
19
在线时间
3670 小时
注册时间
2019-9-13
最后登录
2024-3-29

初级热心勋章

CDA网校 学生认证  发表于 2020-9-17 14:28:29 |显示全部楼层 |坛友微信交流群
相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

K-均值聚类是一种简单的分区方法 ķķ 组或群集。

本质上,该过程如下:

  • 选择 ķķ重心。这些将是每个线段的中心点。
  • 将数据点分配给最近的质心。
  • 将质心值重新分配为每个群集的计算平均值。
  • 将数据点重新分配到最近的质心。
  • 重复直到数据点停留在同一群集中。

这是一个很好的GIF,可以使过程可视化的XX的是质心,彩色的点是分配给群集的数据点。

kmeans.gif

现在,让我们更详细地了解每个步骤。

选择初始质心值

在讨论如何为k均值聚类初始化质心之前,我们必须首先确定将数据划分为多少个聚类。作为人类,看上面的例子,答案显然是三个。但是,如何在算法上做出决定呢?

肘法

一种方法是尝试许多不同的ķķ 并绘制出数据点距其各自质心的平均距离(群集内平均平方和),作为 ķķ。这将为您提供如下所示的内容。注意如何增加ķķ 值从1到2会大大降低每个数据点与其各自质心的平均距离,但是随着您继续增加ķķ改进开始逐渐减少。理想ķķ 值可以在该图的肘部找到。

BzwBY.png

不幸的是,这并不是一种精确的算法方法,因为它仍然取决于人工决定肘部的位置。此外,当无法明确区分肘部时(例如,曲线非常平滑时),此方法并不总是能很好地工作。

轮廓分析

另一种更自动化的方法是构建具有一系列取值范围的k-means聚类模型的集合。 ķķ 然后评估每个模型以确定最佳聚类数。

我们可以使用Silhouette分析来评估每个模型。计算用于观察的Silhouette系数,然后将其平均以确定Silhouette得分。

该系数将平均集群内距离与平均最近集群距离相结合,以分配一个介于-1和1之间的值。零以下的值表示观测值可能在错误的集群中,而接近1的值表示观测值是错误的。非常适合该集群,并且与其他集群明显分开。该系数实质上测量的是观测值与相邻簇之间的接近程度,在这种情况下,期望与相邻簇之间的最大距离是可能的。


我们可以自动确定最佳的群集数量,ķķ,通过选择产生最高轮廓得分的模型。

  1. from sklearn.cluster import KMeans
  2. from sklearn.metrics import silhouette_score
  3. import numpy as np

  4. # Use silhouette score to find optimal number of clusters to segment the data
  5. num_clusters = np.arange(2,10)
  6. results = {}
  7. for size in num_clusters:
  8.     model = KMeans(n_clusters = size).fit(data)
  9.     predictions = model.predict(data)
  10.     results[size] = silhouette_score(data, predictions)

  11. best_size = max(results, key=results.get)
复制代码
重心初始化

一旦选择了要将数据分区到的组,就有几个选择初始质心值的选项。最简单的方法?选择ķķ从您的数据集中随机点,并称之为一天。但是,重要的是要记住,k均值聚类会导致近似解收敛到局部最优值-因此,从质心选择不当开始可能会打乱您的聚类(即,选择离群值作为质心)。常见的解决方案是多次运行聚类算法,然后选择以最佳聚类性能结束的初始值(通过与质心的最小平均距离进行度量-通常使用聚类内平方和)。您可以使用n_init参数在sci-kit learning中指定要对K-means聚类模型执行的随机初始化的次数。

另一种方法是在数据集的样本上使用另一种聚类技术,例如层次聚类,并使用结果聚类质心作为初始k均值质心。此方法通常为大型数据集上的k均值聚类应用保留。您也可以以最分散的方式(使质心之间的距离最大)选择初始值,以防止发生不必要的局部收敛。

将数据点分配给集群

选择初始质心后,下一步就是将每个数据点分配给一个群集。从数学上讲,您可以这样做:

S(t)i={xp:∥∥xp−m(t)i∥∥2≤∥∥xp−m(t)j∥∥2∀j,1≤j≤k}

集群表示为集合
表示质心值(在第一个步骤之后的所有后续步骤中为平均值)。

将此翻译成英文,我们得到以下信息:

集合i包含从数据点(xp)到i(mi)平均值的距离小于从数据点到所有其他质心平均值(mj)的距离的所有数据点(x)。

计算新的质心值

将每个数据点分配给一个群集后,将每个群集的质心值重新分配为该群集内所有数据点的平均值。

m(t+1)i=1∣∣S(t)i∣∣∑xj∈ S(t)ixj

处理大型数据集,是否不想对数据执行多次迭代?看看Bradley-Fayyad-Reina算法,该算法执行k均值的功能与k均值类似,仅对数据进行一次传递。

范例程式码

让我们看一下k均值对Iris数据集中的花朵进行分组的实现。首先,我们将导入一些库并加载数据集。

  1. from sklearn import datasets
  2. from sklearn.cluster import KMeans
  3. from scipy.spatial.distance import cdist, pdist
  4. import numpy as np

  5. iris = datasets.load_iris()      
  6. # attributes of iris are ['target_names', 'data', 'target', 'DESCR', 'feature_names']
复制代码

由此可见,我们将基于以下功能对数据库进行聚类:

  • 萼片长度(厘米)
  • 萼片宽度(厘米)
  • 花瓣长度(厘米)
  • 花瓣宽度(厘米)

接下来,我们必须选择要将数据分成多少组。

  1. # Choosing the optimal k
  2. k_range = range(1,10)
  3. # Try clustering the data for k values ranging 1 to 10
  4. k_means_var = [KMeans(n_clusters = k).fit(iris.data) for k in k_range]
  5. centroids = [X.cluster_centers_ for X in k_means_var]

  6. k_euclid = [cdist(iris.data, cent, 'euclidean') for cent in centroids]
  7. dist = [np.min(ke, axis=1) for ke in k_euclid]

  8. # Calculate within-cluster sum of squares
  9. wcss = [sum(d**2) for d in dist]

  10. # Visualize the elbow method for determining k
  11. import matplotlib.pyplot as plt
  12. plt.plot(k_range, wcss)
  13. plt.show()
复制代码

检查此图,k = 3似乎是最佳选择。

  1. kmeans = KMeans(n_clusters = 3)
  2. kmeans.fit(iris.data)
  3. kmeans.labels_
复制代码

让我们看看我们是如何做到的。k-means算法返回的标签是:

  1. >> kmeans.labels_

  2. array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 0, 2, 0, 2, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 0])
复制代码

原始数据集中的标签是:

  1. >> iris.target

  2. array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
复制代码

由此可见,我们的算法在对第一朵和第二朵花类型进行聚类方面做得不错,但有时却混淆了第二朵和第三朵花。注意,我们的算法对与数据相关的任何标签都是盲目的;只是将数据点分组。这就是为什么标签与我们的结果和提供的标签不一致的原因。


想要在k均值聚类中玩得


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Predictions Determining Prediction Clustering Matplotlib

qqpaalmmz 在职认证  学生认证  发表于 2020-9-25 20:31:46 |显示全部楼层 |坛友微信交流群
666666666666

使用道具

三江鸿 发表于 2022-10-29 17:05:41 来自手机 |显示全部楼层 |坛友微信交流群
点个赞加点人气
感谢分享

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加JingGuanBbs
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-3-29 18:00