$k-means$ 算法是无监督的聚类算法。
$k-means$ 算法的思想:对于给定的 $n$ 个样本,按照样本之间的距离大小,将样本集划分为 $k$ 个簇。让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。
假设簇划分为 $(C_{1}, C_{2},..., C_{k})$,$|C_{i}|$ 表示簇中的向量个数,为每个簇选择一个代表向量 $mu_{i}$,我们的目标是最小化平方误差:
$$L = sum_{i = 1}^{k}sum_{x in C_{i}}^{}|x - mu_{i}|^{2}$$
计算每个簇中的所有向量到其代表向量欧氏距离的平方和,然后将所有的误差平方和累加就得到上面的误差函数。
怎么求这个函数的最优值呢?
可以观察到函数中每个向量所属的类和每个簇的代表向量都不知道,采用的思路是先固定 $A$,调整 $B$ 来使 $L$ 降低,降到最低之后再固定 $B$ 来调整 $A$。
首先假设已知每个向量所属的类别,如何求解最优的代表向量?
$n$ 个样本,$k$ 个类,将每个样本所属的类构成一个 $n imes k$ 矩阵 $r_{n imes k}$,形如
$$r_{5 imes 4} = egin{bmatrix}
0 & 0 & 0 & 1 \
0 & 1 & 0 & 0 \
1 & 0 & 0 & 0 \
1 & 0 & 0 & 0 \
0 & 1 & 0 & 0
end{bmatrix}$$
每行对应的那个 $1$ 代表样本所属的类别,一共 $5$ 行即 $5$ 个样本,每个样本属于唯一的一个类别,即
$$r_{nk} = left{egin{matrix}
1 & if ; k = arg min_{j} | x_{n} - mu_{j} |^{2} \
0 & otherwise
end{matrix}
ight.$$
现在将目标函数写为
$$L = sum_{i = 1}^{n}sum_{j = 1}^{k}r_{ij}left ( x_{i} - u_{j} ight )^{2}$$
设矩阵 $r_{nk}$ 已知,即样本都已经被分类好,$mu_{j},j = 1,2,...,k$ 为未知数,对 $u_{j}$ 求导数得
$$frac{dL}{dmu_{j}} = -2sum_{i = 1}^{n}r_{ij}left (x_{i} - mu_{j} ight )$$
令上式为 $0$ 可得
$$mu_{j} = frac{sum_{i = 1}^{n}r_{ij}x_{i}}{sum_{i = 1}^{n}r_{ij}}$$
所以代表向量为均值向量时,簇内所有元素到其距离平方和最小,即
$$mu_{i} = frac{1}{|C_{i}|}sum_{x in C_{i}}^{}x$$
在已知每个样本所属类别的情况下,只要将均值向量作为代表向量,$L$ 就会被调整到当前最低值。
那接下来固定代表向量,重新按照样本到代表向量距离最小的原则调整每个样本所属的簇,调整之后会使目标函数 $L$ 继续减小。
$k-means$ 算法就是这样交替调整,逐步降低误差,步骤如下:
1)首先要注意的是 $k$ 值的选择,一般来说,我们会根据对数据的先验经验选择一个合适的 $k$ 值。
2)在确定了最终所要分出的类别 $k$ 后,接着随机选择 $k$ 个向量构成 $k$ 个簇,因为最开始每个簇内都只有一个点,所以
这个点本身就是均值向量。
3)对数据集内的每一点 $x$,计算它到 $k$ 个均值向量 $mu_{i},i=1,2...,k$ 的欧氏距离,将它归入距离最小的那个簇,即
$$i = arg ; min_{i}|x - mu_{i}| \
C_{i} = C_{i} cup {x_{i}}$$
4)按下面方法重新计算每个簇的均值向量,如果所有的 $k$ 个质心向量都没有发生变化,则停止迭代,输出结果; 否则转到第 3)步。
$$mu_{i} = frac{1}{|C_{i}|}sum_{x in C_{i}}^{}x$$