【知识】Kmeans聚类算法

Kmeans算法是一个重复移动类中心点的过程,把类的中心点,也称重心(centroids),移动到其包含成员的平均位置,然后重新划分其内部成员。
k是算法计算出的超参数,表示类的数量;Kmeans可以自动分配样本到不同的类,但是不能决定究竟要分几个类。k必须是一个比训练集样本数小的正整数。有时,类的数量是由问题内容指定的。例如,一个鞋厂有三种新款式,它想知道每种新款式都有哪些潜在客户,于是它调研客户,然后从数据里找出三类。也有一些问题没有指定聚类的数量,最优的聚类数量是不确定的,可以由一些方法得到。
Kmeans的参数是类的重心位置和其内部观测值的位置。与广义线性模型和决策树类似,Kmeans参数的最优解也是以成本函数最小化为目标。Kmeans成本函数公式如下:

\[J = \sum_{i=1}^{k}\sum_{j \in c_k}(x^{(j)}-\mu_i)^2 \]

\(\mu_i\)是第i个类的重心位置。成本函数是各个类畸变程度(distortions)之和。每个类的畸变程度等于该类重心与其内部成员位置距离的平方和。若类内部的成员彼此间越紧凑则类的畸变程度越小,反之,若类内部的成员彼此间越分散则类的畸变程度越大。求解成本函数最小化的参数就是一个重复配置每个类包含的观测值,并不断移动类重心的过程。首先,类的重心是随机确定的位置。实际上,重心位置等于随机选择的观测值的位置。每次迭代的时候,Kmeans会把观测值分配到离它们最近的类,然后把重心移动到该类全部成员位置的平均值那里。

Kmeans算法流程

输入:聚类个数k,数据集\(X_{m*n}\)
输出:满足方差最小标准的k个聚类。
(1) 选择k个初始中心点,例如c[0]=X[0] , … , c[k-1]=X[k-1];
(2) 对于X[0]….X[n],分别与c[0]…c[k-1]比较,假定与c[i]差值最少,就标记为i;
(3) 对于所有标记为i点,重新计算c[i]={ 所有标记为i的样本的每个特征的均值};
(4) 重复(2)(3),直到所有c[i]值的变化小于给定阈值或者达到最大迭代次数。
Kmeans的时间复杂度:O(tkmn),空间复杂度:O((m+k)n)。其中,t为迭代次数,k为簇的数目,m为样本数,n为特征数。

距离的度量

欧几里得度量(euclidean metric)(也称欧氏距离)是一个通常采用的距离定义,指在m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。在二维和三维空间中的欧氏距离就是两点之间的实际距离。

\[EuclideanDistance(x,y) = \sqrt{\sum\limits_i^n (x_i-y_i)^2} \]

闵可夫斯基距离

\[MinkovskiDistance(x,y) =(\sum\limits_i^n (x_i-y_i)^p)^\frac{1}{2} \]

闵可夫斯基距离公式中,当p=2时,即为欧氏距离;当p=1时,即为曼哈顿距离;当p→∞时,即为切比雪夫距离。
余弦相似度(Cosine Similarity)

\[Cosine(x,y) = \frac{x\dot y}{||x||*||y||}=\frac{\sum_i (x_i*y_i)}{\sqrt{\sum x_i^2}*\sqrt{\sum y_i^2}} \]

一个余弦相似度的例子

K值的确定方法

1 问题给定K值

2 肘部法则

如果问题中没有指定k的值,可以通过肘部法则这一技术来估计聚类数量。肘部法则会把不同k值的成本函数值画出来。随着k值的增大,平均畸变程度会减小;每个类包含的样本数会减少,于是样本离其重心会更近。但是,随着k值继续增大,平均畸变程度的改善效果会不断减低。k值增大过程中,畸变程度的改善效果下降幅度最大的位置对应的k值就是肘部。为了让读者看的更加明白,下面让我们通过一张图用肘部法则来确定最佳的k值。下图数据明显可分成两类:

从图中可以看出,k值从1到2时,平均畸变程度变化最大。超过2以后,平均畸变程度变化显著降低。因此最佳的k是2。

3 稳定性方法

稳定性方法对一个数据集进行2次重采样产生2个数据子集,再用相同的聚类算法对2个数据子集进行聚类,产生2个具有k个聚类的聚类结果,计算2个聚类结果的相似度的分布情况。2个聚类结果具有高的相似度说明k个聚类反映了稳定的聚类结构,其相似度可以用来估计聚类个数。采用次方法试探多个k,找到合适的k值。

4 canopy算法

基于Canopy Method的聚类算法将聚类过程分为两个阶段
(1) 聚类最耗费计算的地方是计算对象相似性的时候,Canopy Method在第一阶段选择简单、计算代价较低的方法计算对象相似性,将相似的对象放在一个子集中,这个子集被叫做Canopy,通过一系列计算得到若干Canopy,Canopy之间可以是重叠的,但不会存在某个对象不属于任何Canopy的情况,可以把这一阶段看做数据预处理;
(2) 在各个Canopy内使用传统的聚类方法(如Kmeans),不属于同一Canopy的对象之间不进行相似性计算。
从这个方法起码可以看出两点好处:首先,Canopy不要太大且Canopy之间重叠的不要太多的话会大大减少后续需要计算相似性的对象的个数;其次,类似于Kmeans这样的聚类方法是需要人为指出K的值的,通过(1)得到的Canopy个数完全可以作为这个k值,一定程度上减少了选择k的盲目性。

初始质心的选择

选择适当的初始质心是基本kmeans算法的关键步骤。常见的方法是随机的选取初始中心,但是这样簇的质量常常很差。处理选取初始质心问题的一种常用技术是:多次运行,每次使用一组不同的随机初始质心,然后选取具有最小SSE(误差的平方和)的簇集。这种策略简单,但是效果可能不好,这取决于数据集和寻找的簇的个数。
第二种有效的方法是,取一个样本,并使用层次聚类技术对它聚类。从层次聚类中提取k个簇,并用这些簇的质心作为初始质心。该方法通常很有效,但仅对下列情况有效:(1)样本相对较小,例如数百到数千(层次聚类开销较大);(2) k相对于样本大小较小。
第三种选择初始质心的方法,随机地选择第一个点,或取所有点的质心作为第一个点。然后,对于每个后继初始质心,选择离已经选取过的初始质心最远的点。使用这种方法,确保了选择的初始质心不仅是随机的,而且是散开的。但是,这种方法可能选中离群点。此外,求离当前初始质心集最远的点开销也非常大。为了克服这个问题,通常该方法用于点样本。由于离群点很少(多了就不是离群点了),它们多半不会在随机样本中出现。计算量也大幅减少。
第四种方法就是上面提到的canopy算法。

聚类效果评估(Metrics)

首先就是刚才提到过的畸变程度。
另一种聚类算法效果评估方法称为轮廓系数(Silhouette Coefficient)。轮廓系数是类的密集与分散程度的评价指标。它会随着类的规模增大而增大。彼此相距很远,本身很密集的类,其轮廓系数较大,彼此集中,本身很大的类,其轮廓系数较小。轮廓系数是通过所有样本计算出来的,计算每个样本分数的均值,计算公式如下:

\[s = \frac{a-b}{max(a,b)} \]

a是每一个类中样本彼此距离的均值,b是一个类中样本与其最近的那个类的所有样本的距离的均值。

Kmeans优缺点

优点

1.算法原理简单
2.超参少,只有一个k
3.速度出色,可拓展性好

缺点

1.k需提前选定而且不好定
2.对初始值要求较高
3.受离群点影响较大
4.从数据先验的角度来说,在 Kmeans 中,我们假设各个 cluster 的先验概率是一样的,但是各个 cluster 的数据量可能是不均匀的。举个例子,cluster A 中包含了10000个样本,cluster B 中只包含了100个。那么对于一个新的样本,在不考虑其与A cluster、 B cluster 相似度的情况,其属于 cluster A 的概率肯定是要大于 cluster B的。

代码实现

import numpy as np
class Kmeans:
  def __init__(self,K,epochs=100,epsilon=1e-4):
    '''varepsilon: float
        判断是否收敛, 如果上一次的所有k个聚类中心与本次的所有k个聚类中心的差都小于varepsilon, 
        则说明算法已经收敛'''
  def init_centroids(self,X):
    ''' X 输入'''
        n_samples, n_features = np.shape(X)
        centroids = np.zeros((self.k, n_features))
        for i in range(self.k):
            centroid = X[np.random.choice(range(n_samples))]
            centroids[i] = centroid
        return centroids
  def calculate_distance(self,x):
    pass
  def find_closet_centroid(self,x):
    pass
  def create_centroids(self,X):
    pass
  def train(self,X):
    pass
  def predict(self,X_test):
    pass

具体代码实现参考

其他六大聚类算法

posted @ 2019-03-24 22:28  大胖子球花  阅读(795)  评论(0)    收藏  举报