本篇结构
本篇介绍了聚类算法的种类,重点关注K-Means和DBSCAN两类聚类算法,并给出具体实现。
聚类是数据挖掘中的概念,就是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。也即聚类后同一类的数据尽可能聚集到一起,不同类数据尽量分离。
分类简单来说,就是根据文本的特征或属性,划分到已有的类别中。也就是说,这些类别是已知的,通过对已知分类的数据进行训练和学习,找到这些不同类的特征,再对未分类的数据进行分类。
Clustering (聚类),是把相似的东西分到一组。聚类的时候,并不关心某一类是什么,需要实现的目标只是把相似的东西聚到一起。因此,一个聚类算法通常只需要知道如何计算相似度就可以开始工作了,因此 clustering 通常并不需要使用训练数据进行学习,这在Machine Learning中被称作unsupervised learning (无监督学习)。
Classification (分类),对于一个classifier,通常需要告诉它“这个东西被分为某某类”这样一些例子,理想情况下,一个 classifier 会从它得到的训练集中进行“学习”,从而具备对未知数据进行分类的能力,这种提供训练数据的过程通常叫做supervised learning (监督学习)。
来自博文:聚类(clustering)与分类(Classification)的区别。
假设有一批人的年龄的数据,大致知道其中有一堆少年儿童,一堆青年人,一堆老年人。
聚类就是自动发现这三堆数据,并把相似的数据聚合到同一堆中。所以对于这个例子,如果要聚成3堆的话,那么输入就是一堆年龄数据,注意,此时的年龄数据并不带有类标号,也就是说我只知道里面大致有三堆人,至于谁是哪一堆,现在是不知道的,而输出就是每个数据所属的类标号,聚类完成之后,就知道谁和谁是一堆了。
而分类就是,事先告诉你,少年儿童、青年人及老年人的年龄是什么样的,现在新来了一个年龄,输出它的类标号,就是它是属于少年儿童、青年人、老年人的哪个类。一般来说,分类器是需要训练的,也就是要告诉你的算法,每个类的特征是什么样子,它才能识别新的数据。
下面再举一个实际的例子。
对于聚类,比如有些搜索引擎有“查看相似网页”的功能,这个就可以用聚类来做,把网页就行聚类,在聚类的结果中,每一个类中的网页看成是相似的。
对于分类,比如手写识别就可以看到是分类问题,比如我写了10个“我”字,然后对这10个“我”字进行特征提取,就可以告诉算法,“我”字具有什么样的特征,于是来了一个新的“我”字,虽然笔画和之前的10个“我”字不完全一样,但是特征高度相似,于是就把这个手写的字分类到“我”这个类,就识别出来了。
总结一下,数据分类是分析已有的数据,寻找其共同的属性,并根据分类模型将这些数据划分成不同的类别,这些数据赋予类标号。这些类别是事先定义好的,并且类别数是已知的。相反,数据聚类则是将本没有类别参考的数据进行分析并划分为不同的组,即从这些数据导出类标号。聚类分析本身则是根据数据来发掘数据对象及其关系信息,并将这些数据分组。每个组内的对象之间是相似的,而各个组间的对象是不相关的。不难理解,组内相似性越高,组间相异性越高,则聚类越好。
来自博文:常用聚类算法有哪些?
主要分为层次化聚类算法,划分式聚类算法,基于密度的聚类算法,基于网格的聚类算法,基于模型的聚类算法等。
给定一个有N个元组或者记录的数据集,分裂法将构造K个分组,每一个分组就代表一个聚类,K《N。而且这K个分组满足下列条件:
对于给定的K,算法首先给出一个初始的分组方法,以后通过反复迭代的方法改变分组,使得每一次改进之后的分组方案都较前一次好,而所谓好的标准就是:同一分组中的记录越近越好,而不同分组中的纪录越远越好。
大部分划分方法是基于距离的。给定要构建的分区数k,划分方法首先创建一个初始化划分。然后,它采用一种迭代的重定位技术,通过把对象从一个组移动到另一个组来进行划分。一个好的划分的一般准备是:同一个簇中的对象尽可能相互接近或相关,而不同的簇中的对象尽可能远离或不同。
代表算法有:K-means,K-medoids,CLARANS。
这种方法对给定的数据集进行层次似的分解,直到某种条件满足为止。具体又可分为“自底向上”和“自顶向下”两种方案。
例如:在“自底向上”方案中,初始时每个数据点组成一个单独的组,在接下来的迭代中,按一定的距离度量将相互邻近的组合并成一个组,直至所有的记录组成一个分组或者满足某个条件为止。代表算法有:BIRCH,CURE,CHAMELEON等。
基于密度的方法的特点是不依赖于距离,而是依赖于密度,从而克服基于距离的算法只能发现“球形”聚簇的缺点。其核心思想在于只要一个区域中点的密度大于某个阈值,就把它加到与之相近的聚类中去。代表算法有:DBSCAN,OPTICS,DENCLUE,WaveCluster。
这种方法通常将数据空间划分成有限个单元的网格结构,所有的处理都是以单个的单元为对象。这样做起来处理速度很快,因为这与数据点的个数无关,而只与单元个数有关。代表算法有:STING,CLIQUE,WaveCluster。
基于模型的方法给每一个聚类假定一个模型,然后去寻找能很好的拟合模型的数据集。模型可能是数据点在空间中的密度分布函数或者其它。这样的方法通常包含的潜在假设是:数据集是由一系列的潜在概率分布生成的。通常有两种尝试思路:统计学方法和神经网络方法。其中,统计学方法有COBWEB算法、GMM(Gaussian Mixture Model),神经网络算法有SOM(Self Organized Maps)算法。
k-means算法中的k代表类簇个数,means代表类簇内数据对象的均值(这种均值是一种对类簇中心的描述),因此,k-means算法又称为k-均值算法。k-means算法是一种基于划分的聚类算法,以距离作为数据对象间相似性度量的标准,即数据对象间的距离越小,则它们的相似性越高,则它们越有可能在同一个类簇。
数据对象间距离的计算有很多种,k-means算法通常采用欧氏距离来计算数据对象间的距离,计算公式如下(如果是多维也可以进行扩展):
k-means算法聚类过程中,每次迭代,对应的类簇中心需要重新计算(更新):对应类簇中所有数据对象的均值,即为更新后该类簇的类簇中心。
k-means算法需要不断地迭代来重新划分类簇,并更新类簇中心,那么迭代终止的条件是什么呢?一般情况,有两种方法来终止迭代:一种方法是设定迭代次数T,当到达第T次迭代,则终止迭代,此时所得类簇即为最终聚类结果;另一种方法是采用误差平方和准则函数。
k-means算法思想可描述为:
网上有很多实现,可以参考一下下面的博文:
C#下实现的基础K-MEANS多维聚类
k-means聚类算法
也可以参考我的github:
https://github.com/w1992wishes/daily-summary/blob/master/algorithm/cluster/src/main/java/me/w1992wishes/algorithm/cluster/kmeans/KMeans.java
k-means算法优缺点分析
来自博文:从DBSCAN算法谈谈聚类算法
DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种基于密度的空间聚类算法。该算法将具有足够密度的区域划分为簇,并在具有噪声的空间数据库中发现任意形状的簇,它将簇定义为密度相连的点的最大集合。
DBSCAN一些关键概念的定义:
根据上图,分别解释这五条定义。
由以上概念,DBSCAN算法中将数据点分为一下三类:
DBSCAN算法描述:
具体算法描述如下:
其伪代码描述如下:
输入:数据对象集合D,半径Eps,密度阈值MinPts
输出:聚类C
**DBSCAN(D, Eps, MinPts)
Begin
init C=0; //初始化簇的个数为0
for each unvisited point p in D
mark p as visited; //将p标记为已访问
N = getNeighbours (p, Eps);
//如果满足sizeOf(N) < MinPts,则将p标记为噪声
if sizeOf(N) < MinPts then
mark p as Noise;
else
C= next cluster; //建立新簇C
ExpandCluster (p, N, C, Eps, MinPts);
end if
end for
End**
ExpandCluster(p, N, C, Eps, MinPts)
add p to cluster C; //首先将核心点加入C
for each point p’ in N
mark p' as visited;
N’ = getNeighbours (p’, Eps); //对N邻域内的所有点在进行半径检查
if sizeOf(N’) >= MinPts then
N = N+N’; //如果大于MinPts,就扩展N的数目
end if
if p’ is not member of any cluster
add p’ to cluster C; //将p' 加入簇C
end if
end for
End ExpandCluster
如果没有讲清楚,可以参考下面的博文:
聚类分析常用算法原理:KMeans,DBSCAN
DBSCAN 算法介绍以及C++实现
可以参考博文:
聚类算法——python实现密度聚类(DBSCAN)
也可以访问我的github:
https://github.com/w1992wishes/spark-learning/tree/master/clustering-algorithm/src/main/java/me/w1992wishes/learning/dbscan_algorithm
DBSCAN算法优缺点: