基于质心的聚类中,该聚类可以使用聚类的中心向量来表示,这个中心向量不一定是该聚类下数据集的成员。当聚类的数量固定为k时,k-means聚类给出了优化问题的正式定义:找到聚类中心并将对象分配给最近的聚类中心,以使与聚类的平方距离最小化。
该优化问题它本身是一个NP-hard(non-deterministic polynomial-time hardness)问题。 Lloyd’s algorithm 是一种近似方法,通常被称为“k-means algorithm”。但是,它只能找到局部最优值,并且通常需要使用不同的随机初始化进行多次运行。K-means的变体通常包括:k-medoids; k-medians; k-means++。
大部分k-means 类型的算法需要提前指定聚类的数量k,这也是这类算法最大的缺点之一。此外,由于算法总是将对象分配给最近的质心,因此它们倾向于使用近似大小的集群。这经常会导致错误地切割集群地边界。
K-means 算法分配一个样本量为N的样本X 到K个不相互连接的聚类C,每个聚类使用该聚类中的样本均值来描述。这个均值通常称为该聚类的“质心”;需要注意的是,这个质心虽然和样本X是在同一个区域内,但是却不是X中的点。
基本而言,该算法有三个步骤,第一步选择初始的质心,最基本的方法是从数据集X中选择k个样本。在初始化之后,k-means包含两个其他步骤之间的循环。第一步是将每个样本分配给最接近的质心。第二步通过所有的分配到之前该质心的样本计算得到均值来作为一个新的质心。计算老的和新的质心的差,该算法重复那最后两步,直到这个差值小于一个临界点。换句话说,一直重复它直到质心没有明显地移动。
集群分配的可能组合数量和数据点的数量成指数关系–一个详尽的搜索花销是非常大的。然而这样详尽的搜索是不必要的;k-means典型的方法涉及一个直观的迭代方法(称为expectation-maximization期望最大化)。
EM 方法由下面的步骤组成:
1. 猜测一些聚类中心
2. 重复下面步骤直到收敛:
A. 把点分配到最近的聚类中心。
B. 将聚类中心设置为被分配到该聚类的所有点的均值。
只要给够足够的时间,k-means 将会收敛,然而这也可能是一个局部最小。这高度依赖于质心的初始值。因此,不同的初始化质心下,这个计算通常进行多次。一个用来排除这个问题的方法为k-means++初始化方案,这个已在scikit-learn中实现(使用init=’k-means++’参数)。这样通常可以将质心初始化为彼此远离,从而产生比随机初始化明显更好的结果。
下面的五个动态图中,展示了k-means计算聚类中心并移动聚类中心的过程。五个图中分别展示了五种不同的初始聚类中心位置,上下左右四个初始位置,及一个随机初始位置。
left:
right:
top:
bottom:
random:
通过代码使用K-means给一些点进行分类:
产生一个包含四个不同片区的二维数据表,先不看标签,将它们画在同一个图上面,如下图所示:
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns; sns.set() # for plot styling
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
X, y_true = make_blobs(n_samples=300, centers=4,
cluster_std=0.60, random_state=0)
plt.scatter(X[:, 0], X[:, 1], s=50)
肉眼是可以很清楚地看到四个明显的区域在上图。下面使用k-means算法来自动区分它:
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=4,init='random')
kmeans