所谓聚类,就是按照某个特定的标准将一个数据集划分成不同的多个类或者簇,使得同一个簇内的数据对象的相似性尽可能大,同时不再一个簇内的数据对象的差异性也尽可能大,聚类算法属于无监督学习算法的一种.
k-均值聚类的目的是:把 n个点(可以是样本的一次观察或一个实例)划分到k个聚类中,使得每个点都属于离他最近的均值(此即聚类中心)对应的聚类,以之作为聚类的标准。
k-均值聚类算法属于最基础的聚类算法,该算法是一种迭代的算法,将规模为n的数据集基于数据间的相似性以及距离簇内中心点的距离划分成k簇.这里的k通常是由用户自己指定的簇的个数,也就是我们聚类的类别个数.
该算法的一般步骤如下:
通过上述描述,我们基本理解了k-means算法工作的原理,但是遗留给我们的问题是这个k值要如何确定呢?由于这个值是算法的输入,需要用户自行指定,当然不可以随便拍脑袋想了.这里介绍一种常用的WCSS方法来进行k值的选择.
WCSS算法是Within-Cluster-Sum-of-Squares的简称,中文翻译为最小簇内节点平方偏差之和.白话就是我们每选择一个k,进行k-means后就可以计算每个样本到簇内中心点的距离偏差之和, 我们希望聚类后的效果是对每个样本距离其簇内中心点的距离最小,基于此我们选择k值的步骤如下:
我们使用python生成我们的数据代码如下:
from clustering__utils import *
x1, y1, x2, y2 = synthData()
X1 = np.array([x1, y1]).T
X2 = np.array([x2, y2]).T
参考上述原理,我们来实现kMeans,我们将其封装成类,代码如下:
class kMeans(Distance):
def __init__(self, K=2, iters=16, seed=1):
super(kMeans, self).__init__()
self._K = K
self._iters = iters
self._seed = seed
self._C = None
def _FNC(self, x, c, n):
# for each point,
# find the nearest center
cmp = np.ndarray(n, dtype=int)
for i, p in enumerate(x):
d = self.distance(p, self._C)
cmp[i] = np.argmin(d)
return cmp
def pred(self, X):
# prediction
n, dim = X.shape
np.random.seed(self._seed)
sel = np.random.randint(0, n, self._K)
self._C = X[sel]
cmp = self._FNC(X, self._C, n)
for _ in range(self._iters):
# adjust position of centroids
# to the mean value
for i in range(sel.size):
P = X[cmp == i]
self._C[i] = np.mean(P, axis=0)
cmp = self._FNC(X, self._C, n)
return cmp, self._C
上述代码中:
我们使用以下代码,计算不同k值下的WCSS的值
# elbow method
Cs = 12
V1 = np.zeros(Cs)
V2 = np.zeros(Cs)
D = Distance()
for k in range(Cs):
kmeans = kMeans(K=k + 1, seed=6)
fnc1, C1 = kmeans.pred(X1)
fnc2, C2 = kmeans.pred(X2)
for i, [c1, c2] in enumerate(zip(C1, C2)):
d1 = D.distance(c1, X1[fnc1 == i])**2
d2 = D.distance(c2, X2[fnc2 == i])**2
V1[k] += np.sum(d1)
V2[k] += np.sum(d2)
结果如下:
这里我们对第一组数据,选择k=3,针对第二组数据选择k=6,示例如上图红色圆圈所示.
我们根据上述选定的k值,可视化两组数据迭代过程,代码如下:
iters = 20; seed = 6
K1 = 3
kmeans1 = kMeans(K1, iters, seed)
fnc1, C1 = kmeans1.pred(X1)
K2 = 6
kmeans2 = kMeans(K2, iters, seed)
fnc2, C2 = kmeans2.pred(X2)
本文介绍了机器学习领域中k-means进行聚类的原理以及相应的代码实现,并给出了完整的代码示例.
您学废了吗?
参考
链接一
链接二
关注公众号《AI算法之道》,获取更多AI算法资讯。
注: 完整代码,关注公众号,后台回复 kMeans , 即可获取。