前面我们说过,聚类是将数据划分成组的任务,这些组叫做簇,其目标是划分数据,使得一个簇内的数据点非常相似且不同簇内的数据点非常不同。与分类算法类似,聚类算法为每一个数据点分配(或预测)一个数字,表示这个点属于哪个簇。
K均值聚类:K均值聚类是最简单也是最常用的聚类算法之一。它试图找到代表数据特征区域的簇中心。算法交替执行以下两个步骤:将每个数据点分配给最近的簇中心,然后将每个簇中心设置为所分配的数据点的平均值。如果簇的分配不再发生变化,那么算法结束。下面我们现将其算法的三个步骤可视化出来。
mglearn.plots.plot_kmeans_algorithm()
运行后其结果如下图:
![c32f56bd9da1a3522dfc323ecb887210.png](https://i-blog.csdnimg.cn/blog_migrate/174977d43d6c53cdf1d52a748b2e8afe.jpeg)
输入数据与K均值的三个步骤
簇中心用三角形表示,而数据点用圆表示,颜色表示簇成员,我们要寻找三个簇,所以通过申明三个随机数据点为簇中心将其初始化。然后开始迭代算法。首先,每个数据点分配给距离中心最近的簇。接下来,将簇中心修改为所分配点的平均值。然后再将这一过程重复两次,经过第三次迭代后,为簇中心分配的数据点保持不变,算法结束。
给定新的数据点,K均值会将其分配给最近的簇中心,下面我们来看看簇中心的边界:
![190463ca9da2687f0aa4ea6fce22f1e0.png](https://i-blog.csdnimg.cn/blog_migrate/034ebb82c6b9dc53699709cca01737cc.jpeg)
K均值算法找到簇中心的边界
用scikit-learn应用K均值算法相当简单,下面我们将其应用于上图中的模拟数据。我们将Kmeans类实例化,并设置我们要寻找的粗个数,然后对数据进行fit,其代码如下:
mglearn.plots.plot_kmeans_boundaries()
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
#生成模拟的二维数据
x, y = make_blobs()
#构建聚类模型
kmeans = KMeans(n_clusters=3)
kmeans.fit(x)
#算法在运行时,为x的每个训练集数据点分配一个标签,可以通过kmeans.labels_属性中找到这些标签
print("cluster memberships:{}".format(kmeans.labels_))
运行结果如下:
cluster memberships:
[2 1 1 0 2 2 2 2 0 2 0 2 1 2 1 2 2 2 1 1 1 1 2 2 1 1 1 2 1 1 0 0 0 0 0 0 1
1 2 0 0 1 0 0 1 0 2 2 1 1 2 0 0 1 0 1 0 1 0 0 1 1 1 1 1 2 2 1 2 1 2 2 0 0
0 0 1 1 0 2 1 2 2 1 2 2 0 2 1 1 0 0 2 2 1 1 2 2 0 2]
因为我们要找三个簇,所以簇的编号是0、1、2。也可以用predict方法为新数据点分配簇标签,与测试会将最近的簇中心分配给每个新的数据点,但是现有规模不会改变。
print("predict result:{}".format(kmeans.predict(x)))
运行后结果如下:
predict result:
[2 1 2 1 2 0 1 2 2 2 1 0 2 1 1 2 2 0 2 1 2 0 2 2 2 0 1 1 1 0 1 0 1 1 2 0 1
1 2 0 0 1 1 2 2 0 2 2 0 0 0 2 0 2 0 0 1 2 1 2 2 0 2 0 0 0 2 0 2 2 2 1 1 0
0 1 1 0 1 1 2 0 2 0 1 1 0 1 2 0 0 0 1 1 1 0 2 1 1 1]
可以看到,聚类算法和分类算法有些类似,每个元素都有一个标签。但并不存在真是的标签,所以该标签本身并没有先验意义。
我们回到之前讨论的人脸图像聚类的例子,聚类的结果可能是,算法找到第三个簇包含bela的面孔,但只有在查看图片之后才能知道这一点,而且数字3是任意的,算法给你唯一的信息就是所有标签为3的人脸都是相似的。
所以聚类的初始化是随机的,给出的标签是没有预先给其赋予任何意义的。簇中心被保存在了cluster_center_属性中,当然,我们可以根据自己的需要使用更多或更少的簇中心。
from sklearn.cluster import KMeans
#生成模拟的二维数据
x, y = make_blobs()
#构建聚类模型
kmeans = KMeans(n_clusters=3)
kmeans.fit(x)
#算法在运行时,为x的每个训练集数据点分配一个标签,可以通过kmeans.labels_属性中找到这些标签
print("cluster memberships:{}".format(kmeans.labels_))
print("predict result:{}".format(kmeans.predict(x)))
mglearn.discrete_scatter(x[:, 0], x[:, 1], kmeans.labels_, markers='o')
mglearn.discrete_scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],
[0,1,2], markers='^', markeredgewidth=2)
运行后结果为:
![db087faee77db6901a258976e58a69b2.png](https://i-blog.csdnimg.cn/blog_migrate/44537579c1c5bd8f7aeb6f089331cf8a.jpeg)
3个簇的K均值算法找到的分配簇中心
下面是分别使用两个和五个簇中心的代码:
#使用两个簇中心:
kmeans = KMeans(n_clusters=2)
kmeans.fit(x)
assignments = kmeans.labels_
mglearn.discrete_scatter(x[:, 0], x[:, 1], assignments, ax=axes[0])
#使用5个簇中心
kmeans = KMeans(n_clusters=5)
kmeans.fit(x)
assignments = kmeans.labels_
mglearn.discrete_scatter(x[:, 0], x[:, 1], assignments, ax=axes[1])
运行后结果为:
![ea9639d625aa19f056d246710f06dfdc.png](https://i-blog.csdnimg.cn/blog_migrate/fc3300c7ce90b5caa80d0f1b1832c5d7.jpeg)
使用2个(左)和5个簇中心的K均值算法找到的源分配
今天我们暂时分享到这里,明天继续分享K均值失败案例和K均值用于人脸识别。
如果觉得我写的不错,那就多多关注我吧,多谢大家的支持,祝大家生活愉快