返回介绍

第50单元 用k均值聚类实现数据分组

发布于 2024-01-28 22:01:16 字数 2802 浏览 0 评论 0 收藏 0

聚类是一种无监督的机器学习技术。你不需要(也不能)对模型进行训练。

聚类的目标是将样本(每个样本用一个n维实数矢量表示)划分到具有较好内部邻近度的不相交紧凑组中。要实现聚类,矢量维度必须具有合理的、可兼容的取值范围。如果某一维的取值范围比其他维的取值范围大得多或小得多,就应该在聚类之前对“太大”或“太小”的变量进行缩放。

k均值聚类按照下面的算法将样本聚合成k个类(该算法也因此得名)。

(1) 随机选择k个矢量作为初始质心(矢量不需要是数据集中的样本)。

(2) 将每个样品分配给它最接近的质心。

(3) 重新计算质心位置。

(4) 重复步骤(2)和步骤(3),直到质心不再移动。

sklearn.cluster模块通过KMeans对象实现k均值算法,该对象具有用于实际聚类的fit()函数、用于将新样本分配给预先计算好的聚类的predict()函数,以及用于同时完成聚类和标记的fit_predict()函数。

模块sklearn.preprocessing具有实现变量缩放的scale()函数。该函数将每一维变量减去其最小值,再除以其取值范围,从而将每一维变量都映射到[0…1]的区间内。

cluster_centers_和labels_属性包含描述最终质心的矢量,以及分配给每个样本类的数字标签。其中,标签并不反映类的目的和组成。如果要为类分配有意义的标签,可以执行以下任意一种操作。

使用人的智能(查看样本并提供一个通用标签)。

使用众包(例如亚马逊的MTurk工作人员)。

从数据生成标签(例如将具有主导地位的样本的一个属性指定为类标签)。

在第47单元第2小节中,我们试图对美国在2009年的葡萄酒和啤酒消费情况进行分析,得出的结论是两者并不是线性相关的。现在让我们通过聚类给这些“高贵”饮料另一个机会。分析的流程及结果如下:

clusters.py

import matplotlib, matplotlib.pyplot as plt
import pickle, pandas as pd
import sklearn.cluster, sklearn.preprocessing

# NIAAA frame已完成了pickle操作
alco2009 = pickle.load(open("alco2009.pickle", "rb"))
# 州名缩写
states = pd.read_csv("states.csv",
                     names=("State", "Standard", "Postal", "Capital"))
columns = ["Wine", "Beer"]
# 初始化聚类对象,模型拟合
kmeans = sklearn.cluster.KMeans(n_clusters=9)
kmeans.fit(alco2009[columns])
alco2009["Clusters"] = kmeans.labels_
centers = pd.DataFrame(kmeans.cluster_centers_, columns=columns)

# 选取一种美观的显示样式
matplotlib.style.use("ggplot")

# 绘制州和聚类中心
ax = alco2009.plot.scatter(columns[0], columns[1], c="Clusters",
                           cmap=plt.cm.Accent, s=100)
centers.plot.scatter(columns[0], columns[1], color="red", marker="+",
                     s=200, ax=ax)

# 将州的缩写作为注释加入图中
def add_abbr(state):
    _ = ax.annotate(state["Postal"], state[columns], xytext=(1, 5),
                    textcoords="offset points", size=8,
                    color="darkslategrey")
alco2009withStates = pd.concat([alco2009, states.set_index("State")],
                                axis=1)
alco2009withStates.apply(add_abbr, axis=1)

# 加入标题,并保存绘图结果
plt.title("US States Clustered by Alcohol Consumption")
plt.savefig("../images/clusters.pdf")

请注意,除非传递了n_clusters参数,否则KMeans()函数总是生成八个类。如何选择类的数量取决于你和你的直觉。

我们将原始数据(实心圆圈,用州名缩写标记)和类的质心(十字符号)绘制在同一个图表中,如下所示:

KMeans()函数在类的识别方面做了很好的工作(比如葡萄酒和啤酒的饮用量处于中等水平的东北部)。标签的放置存在许多不足之处,但该主题不在本书的讨论范围之内。

 Voronoi单元

k均值聚类算法将自变量空间分为Voronoi单元——由与一个种子(数据点)的距离小于任何其他种子的点组成的区域。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文