Kmeans算法及相关优化

Kmeans算法及相关优化

  • Kmeans算法简介
  • 初始类簇中心点的选取
  • K值的选取
  • 算法流程
  • 相关优化
  • 补充
    • 优点
    • 缺点
    • LOF离群点检测算法
    • Kmeans的K值自适应优化算法
    • KNN邻近算法
    • 交叉验证

本文主要参考https://www.cnblogs.com/pinard/p/6164214.html
和https://www.cnblogs.com/jojo123/p/6822908.html,百度百科

Kmeans算法简介

(1)Kmeans算法是一种无监督聚类算法。
(2)算法的目标:给定样本集,根据样本之间的距离大小,将样本划分为K个簇,让簇内的点之间的距离尽可能近,让簇间的点的距离尽可能的远。
(3)算法的思路:在给定K值和K个初始类簇中心点的情况下,把每个点(样本数据)分到距离最近的类簇中心点代表的类簇中。分配完毕后,根据一个类簇中的所有点重新计算类簇中心点,然后再迭代的进行分配点和更新类簇中心点的过程,直到没有(或者是预期要求)点被分配到其它类簇中,没有(或达到预期要求)类簇中心点再发生更新,误差平方和最小(或达到某一条件)。
假设簇划分为( C 1 C_{1} C1 C k C_{k} Ck),误差平方和E表示为
E = ∑ i = 1 k ∑ x ∈ C i ∣ x − u i ∣ 2 E = \sum_{i=1}^k\sum_{x\in C_{i}}|x - u_{i}|^2 E=i=1kxCixui2
上面的公式不太准确,但对于理解问题足够了。其中, x x x为某个样本数据, u i u_{i} ui C i C_{i} Ci的质心,表示为
u i = 1 ∣ C i ∣ ∑ x ∈ C i x u_{i} = \frac{1}{|C_{i}|}\sum_{x\in C_{i}}x ui=Ci1xCix
我们的目的是使让E尽可能小,但直接求解E很困难,通常采用上面说的启发式迭代求解。

初始类簇中心点的选取

在描述具体算法流程之前,我们先来思考一下初始类簇中心点的选取。(合理的确定K值和K个初始类簇中心点对算法的聚类结果和运行时间(迭代次数)有很大的影响。
(1)最简单的方法确定K个初始类簇中心点的方法是随即选取K个点,但这种方法很明显在某些情况下会很差。
(2)选择彼此距离尽可能远的K个点
首先。随机选择一个点作为第一个初始类簇点,然后选择距离该点最远的那个点作为第二个初始类簇点,然后再选择距离前两个类簇点距离最远的点作为第三个类簇中心点,以此类推,直到选出K个点。
(3)选用层次聚类算法或Canopy算法进行初始聚类,然后利用这些类簇的中心点作为Kmeans算法的初始中心类簇点。本人能力有限,这里只简单介绍一下Canopy算法:
首先,定义两个距离T1、T2,T1 > T2。从样本集S中随机移除一个点P,对与还在样本集S中的每个点,计算其与P的距离,若距离小于T2,则将其从S中移除,并添加到P点代表的簇中,若距离小于T1,而大于T2,依然将其添加到P代表的类簇中,但不将其从S中移除。迭代完一次后,从剩余的S中重新选择一个点作为新的P,重复上述过程。
Canopy算法的特别之处在与样本中的某条数据可能重复出现在不同的类簇中。我们可以使用Canopy计算出来的中心点作为Kmeans算法的初始类簇中心点。

K值的选取

给定一个合适的类簇指标,比如类簇的平均半径或直径,只要我们假设的类簇数目等于或高与真实的类簇数目时,该指标变化的很慢,但若小于真实的类簇数目,该指标会快速变化。

类簇的直径指簇内任意两点之间的最大距离。
类簇的半径指簇内的所有点到类簇中心点的最大距离。
放两张图便于理解
Kmeans算法及相关优化_第1张图片Kmeans算法及相关优化_第2张图片
左图是K取值从2到7时的聚类效果,右图是K取值从2到9时的类簇指标的变化曲线,此处选择类簇指标是K个类簇的平均质心距离的平均值。从上图中可以明显看到,当K取值为5的前后,类簇指标的变化情况,所以K的正确取值应该是5。

算法流程

现在,总结一下Kmeans算法的具体流程
输入:初始样本集D,聚类数K,(最大迭代次数N)
输出:簇的划分C
(1)选则K个初始类簇中心点,每个簇初始为空(或为初始类簇中心点,这个要看中心点的选择)。
(2)对于每个样本,计算其于各个质心的距离,将其划分到距离最小的类簇中。
(3)重新计算每个类簇的质心(中心点)。
(4)若未达到终止条件(所有质心未变,没有点被重新分配,误差平方达到要求)则转到(2)
(5)输出簇的划分。

相关优化

(1)Kmeans算法对噪音和异常点比较敏感,可以使用一些离群点检测算法(比如LOF)进行预处理,去除异常点后进行聚类。
(2)在距离计算上进行优化。
(3)在样本量比较大时,可以随机选择部分进行Kmeans算法,进行多次。

补充

优点

(1)原理比较简单。
(2)聚类效果比较好。

缺点

(1)在K值和初始类簇中心点选择不当时收敛较慢。
(2)对离群点和孤立点敏感。
(3)对于非凸数据集比较难收敛。
(4)采用迭代的方法,只能保证局部最优。

LOF离群点检测算法

在网上看了很多讲解LOF的文章,这里来总结一下自己的思路。
(在平面空间中)假设有一点P,和一个初始设定的K值。以P为圆心,由内向外寻找与P最临近的K个点,把找到的第K个点记为O。此时,以P为圆心,以P点到O点的距离为半径(记为len1)的范围内有至少K个点(因为可能有距离相等的点),我们称这个范围为P的K邻域。然后我们以O点为圆心,以同样的方式寻找O的K邻域以及它的半径(len2)。若len1远大与len2,则说明P为离群点。

Kmeans的K值自适应优化算法

在安徽大学李芳的硕士论文中提到了k-Means算法的k值自适应优化方法。
算法思路为:在开始的时候给定一个合适(也有说法为一个较大的)的K值,通过一次Kmeans算法得到一次聚类中心。根据K个类簇中心点之间的距离,合并距离最近的类簇,并将K值减一。循环使用此方法,直到达到终止条件(整个数据集的误差平方和达到某个值或不变,或则达到迭代次数),最终得到较优聚类数的聚类结果。

KNN邻近算法

(1)kNN,k-NearestNeighbor,所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以由它最邻近的K个值来表示。
(2)KNN算法是监督算法,算法中所选择的邻居都是已经正确分类的样本。KNN算法的核心思想是当某一样本周围最近的K个邻居中大多数属于某一类别,那此样本也属于这个类别。
(3)KNN主要靠周围K个点来确定其类别,而不是通过判断类域的方法,所以对于类域有交叉或重叠的样本集比较合适。
Kmeans算法及相关优化_第3张图片
如上图,当K为3时,绿色节点会被判定为红色三角,若K为5,绿色节点会被判定为蓝色方块。

KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,就可以得到该样本的属性。更有用的方法是将不同距离的邻居对该样本产生的影响给予不同的权值(weight),如权值与距离成反比。

该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。另一个不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。
针对分类效率改进:事先对样本属性进行约简,删除对分类结果影响较小的属性,快速的得出待分类样本的类别。
针对分类效果改进:采用权值的方法(和该样本距离小的邻居权值大)来改进。

交叉验证

(1)在使用训练集对参数进行训练的时候,一般分为:训练集(train_set),评估集(valid_set),测试集(test_set)这三个部分。其中测试集很好理解,其实就是完全不参与训练的数据,仅仅用来观测测试效果的数据。
(2)因为在实际的训练中,训练的结果对于训练集的拟合程度通常还是挺好的(初始条件敏感),但是对于训练集之外的数据的拟合程度通常就不那么令人满意了。因此我们通常并不会把所有的数据集都拿来训练,而是分出一部分来(这一部分不参加训练)对训练集生成的参数进行测试评估,相对客观的判断这些参数对训练集之外的数据的符合程度。这种思想就称为交叉验证。
(3)K折交叉验证,初始采样分割成K个子样本,一个单独的子样本被保留作为验证模型的数据,其他K-1个样本用来训练。交叉验证重复K次,每个子样本验证一次,平均K次的结果或者使用其它结合方式,最终得到一个单一估测。这个方法的优势在于,同时重复运用随机产生的子样本进行训练和验证,每次的结果验证一次,10折交叉验证是最常用的。

你可能感兴趣的:(算法,优化,机器学习)