zl程序教程

您现在的位置是:首页 >  .Net

当前栏目

聚类:主要聚类算法

2023-02-18 16:34:35 时间

1 前言


  如下图有各种各样的虫子,试将它们分成不同的组别。

  

   一般来说可将这些虫子分成四组:蜘蛛、蜗牛、蝴蝶/飞蛾、蜜蜂/黄蜂(不唯一解)。对于人来说很容易?即使虫子数量再多一倍也能把它们分清楚。只需一点时间以及对昆虫学的热情,其实就算有成千上万只虫子你也能将它们分开。但对于一台机器而言,将这 10 个对象分类成几个有意义的分组却并不简单,对这 10 只虫子,可以有 115975 种不同的分组方式。如果虫子数量增加到 20,那它们可能的分组方法将超过 50 万亿种。其中大多数分组方案都无意义,在浩如烟海的分组选择中,只能找到少量有用分组。

1.1 聚类概念

  类是一种机器学习技术,涉及数据点的分组。聚类就是按照某个特定标准(如距离准则)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。即聚类后同一类的数据尽可能聚集到一起,不同数据尽量分离。聚类是一种无监督学习的方法,是许多领域中常用的统计数据分析技术。在数据科学中,可以使用聚类分析从数据中获得一些有价值的见解。

1.2 聚类目标

  使同一类对象的相似度尽可能地大;不同类对象之间的相似度尽可能地小。

1.3 聚类和分类的区别

  聚类技术是无监督学习,与监督学习不同的是在聚类中无表示数据类别的分类或分组信息。 
  聚类:就是把相似的东西分到一组,聚类的时候,并不关心某一类是什么,需要实现的目标是把相似的东西聚到一起。因此,一个聚类算法通常只需要知道如何计算相似度就可以开始工作,因此聚类通常并不需要使用训练数据进行学习,这在$ML$中被称作$Unsupervised learning$ (无监督学习)。 
  分类:对于一个分类器,通常需要告诉它类别信息。理想情况下,一个分类器会从训练集中进行学习,从而具备对未知数据进行分类的能力,这种提供训练数据的过程通常叫做$Supervised learning$ (监督学习)。

2 聚类算法


  任务:将数据集中的样本划分成若干个通常不相交的子集,对特征空间的一种划分。
  性能度量:类内相似度高,类间相似度低。两大类:1、有参考标签,外部指标;2、无参照,内部指标。
  距离计算:非负性,同一性(与自身距离为0),对称性,直递性(三角不等式)。包括欧式距离(二范数),曼哈顿距离(一范数)等等。

 

3 聚类算法的分类


3.1 基于划分

3.1.1 基本思想

  基于划分的方法:想象有一堆散点需要聚类,聚类效果是“类内的点都足够近,类间的点都足够远”。首先要确定散点聚类数,然后挑选部分(几个)点作为初始中心点,再给数据点做迭代重置,直到最后到达聚类效果。这就是所谓的“启发式算法”,也形成了$k-means$算法及其变体包括$k-medoids$、$k-modes$、$k-medians$、$kernel k-means$等算法。

3.1.2 特点

  计算量大,适合发现中小规模的数据库中的球状簇。

3.1.3 主要算法

  $k-medoids$、$k-modes$、$k-medians$、$kernel k-means$等算法。

3.1.4 KNN算法回顾

  $KNN$是一种基本分类与回归方法。

  思路:给一个训练数据集和一个新实例,在训练数据集中找出与这个新实例最近的 $k$ 个训练实例,然后统计得出最近的 $k$ 个训练实例中所属类别计数最多的类,就是新实例的类。

  流程如下所示

  1、计算训练样本和测试样本中每个样本点的距离;
  2、对上面所有的距离值进行排序;
  3、选前 $k$ 个最小距离的样本;
  4、根据这 $k$ 个样本的标签进行投票,得到最后的分类类别;

  KNN的特殊情况是 $k =1$ 的情况,称为最近邻算法。对输入的实例点 $x$ ,最近邻法将训练数据集中与 $x$ 最近邻点的类作为其类别。

  注意事项

  1、一般 $k$ 会取一个较小的值,然后用过交叉验证来确定;
  2、距离度量:一般是欧式距离,或曼哈顿距离;
  3、回归问题:取 $k$ 个最近样本的平均,或者使用加权平均;

  算法的优点

  1、思想简单,理论成熟,既可以用来做分类也可以用来做回归;  
  2、可用于非线性分类;
  3、训练时间复杂度为 $O(n)$;
  4、准确度高,对数据没有假设,对outlier不敏感。

  算法的缺点

  1、计算量大;
  2、样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少);
  3、需要大量的内存;

   需要考虑问题:

  1、$KNN$的计算成本很高;
  2、所有特征应该标准化数量级,否则数量级大的特征在计算距离上会有偏移;
  3、在进行$KNN$前预处理数据,例如去除异常值,噪音等。

3.1.5 K-Means算法

   $K-Means$算法是无监督的聚类算法。

   基本思想:对于给定的样本集,按照样本之间的距离大小,将样本集划分为$K$个簇。让簇内的点尽量紧密相连,让簇间的距离尽量大。

   算法步骤

  1、随机选择$K$个样本作为初始均值向量;
  2、计算样本到各均值向量的距离,把它划到距离最小的簇;
  3、计算新的均值向量;
  4、迭代,直至均值向量未更新或到达最大次数。

  时间复杂度:$O(tkmn)$,其中,$t$ 为迭代次数,$k$ 为簇的数目,$m$ 为记录数,$n$为维数。

  空间复杂度:$O((m+k)n)$,其中,$k$ 为簇的数目,$m$ 为记录数,$n$ 为维数。

  算法优点

  1、原理比较简单,实现也是很容易,收敛速度快;
  2、聚类效果较优;
  3、算法的可解释度比较强;
  4、主要需要调参的参数仅仅是簇数$k$。

  算法缺点:

  1、聚类中心的个数$K$需要事先给定,这个 $K$ 值的选定是非常难以估计的。很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适;一般通过交叉验证确定;
  2、不同的初始聚类中心可能导致完全不同的聚类结果。算法速度依赖于初始化的好坏,初始质点距离不能太近;
  3、如果各隐含类别的数据不平衡,比如各隐含类别的数据量严重失衡,或者各隐含类别的方差不同,则聚类效果不佳;
  4、该方法不适于发现非凸面形状的簇或大小差别很大的簇,对于不是凸的数据集比较难收敛;
  5、对噪音和异常点比较的敏感;
  6、需样本存在均值(限定数据种类);
  7、采用迭代方法,得到的结果只是局部最优;

3.1.6 常见的算法及改进

  $k-means$对初始值的设置很敏感,所以有了$k-means++$、$intelligent k-means$、$genetic k-means$。 
  $k-means$对噪声和离群值非常敏感,所以有了$k-medoids$和$k-medians$。 
  $k-means$只用于$numerical$类型数据,不适用于$categorical$类型数据,所以$k-modes$。 
  $k-means$不能解决非凸数据,所以有了$kernel k-means$。 
  另外,很多教程都告诉我们$Partition-based methods$聚类多适用于中等体量的数据集,但我们也不知道“中等”到底有多“中”,所以不妨理解成,数据集越大,越有可能陷入局部最小。

3.1.7 K-Means++算法

  $K-Means++$算法就是对$K-Means$随机初始化质心的方法的优化。

  $K-Means++$的对于初始化质心的优化策略也很简单,如下:
  1、从输入的数据点集合中随机选择一个点作为第一个聚类中心
  2、对于数据集中的每一个点,计算它与已选择的聚类中心中最近聚类中心的距离
  3、选择一个新的数据点作为新的聚类中心,选择的原则是:距离较大的点,被选取作为聚类中心的概率较大
  4、重复 $2$ 和 $3$ 直到选择出 $k$ 个聚类质心
  5、利用这 $k$ 个质心来作为初始化质心去运行标准的$K-Means$算法。

3.1.8 二分-K均值

  二分-K均值是为了解决k-均值的用户自定义输入簇值k所延伸出来的自己判断k数目,针对初始聚类中心选择问题
  基本思路:为了得到 $k$ 个簇,将所有点的集合分裂成两个簇,从这些簇中选取一个继续分裂,如此下去,直到产生 $k$ 个簇。

  具体描述:比如要分成5个组,第一次分裂产生2个组,然后从这2个组中选一个目标函数产生的误差比较大的,分裂这个组产生2个,这样加上开始那1个就有3个组了,然后再从这3个组里选一个分裂,产生4个组,重复此过程,产生5个组。这算是一中基本求精的思想。

  二分k均值不太受初始化的困扰,因为它执行了多次二分试验并选取具有最小误差的试验结果,还因为每步只有两个质心。

 3.1.9 大样本优化Mini Batch K-Means

  用样本集中部分样本来做传统的K-Means,可以避免样本量太大时的计算难题,算法收敛速度大大加快。此时的代价就是聚类的精确度会有一些降低。一般来说这个降低的幅度在可以接受的范围之内。

  在$Mini Batch K-Means$中,选择一个合适的批样本大小$batch size$,仅仅用$batch size$个样本来做我们K-Means我们聚类。那么这我们batch size我们个样本怎么来的?一般是通过无放回的随机采样得到的。为增加算法的准确性,一般会多跑几次Mini Batch K-Means算法,用得到不同的随机采样集来得到聚类簇,选择其中最优的聚类簇。

3.2 基于层次

  层次聚类主要有两种类型:合并的层次聚类分裂的层次聚类

  合并的层次聚类:是一种自底向上的层次聚类算法,从最底层开始,每一次通过合并最相似的聚类来形成上一层次中的聚类,当全部数据点都合并到一个聚类的时候停止或者达到某个终止条件而结束,大部分层次聚类都是采用这种方法处理。
  分裂的层次聚类:采用自顶向下的方法,从一个包含全部数据点的聚类开始,然后把根节点分裂为一些子聚类,每个子聚类再递归地继续往下分裂,直到出现只包含一个数据点的单节点聚类出现,即每个聚类中仅包含一个数据点。

3.2.1 层次聚类基本思想

  处理速度很快,通常这是与目标数据库中记录的个数无关的,只与把数据空间分为多少个单元有关。

3.2.2 层次聚类主要算法

  BIRCH算法、CURE算法、CHAMELEON算法

3.2.3 层次聚类算法流程

  以自下向上为例。 
  1、将每个对象看作一类,计算两两之间的最小距离; 
  2、将距离最小的两个类合并成一个新类; 
  3、重新计算新类与所有类之间的距离; 
  4、重复2、3,直到所有类最后合并成一类

3.2.4 层次聚类算法优缺点

  优点:无需目标函数,没有局部极小问题或是选择初始点的问题。
  缺点:计算代价大,时间复杂度高$O(m^{3})$,改进后的算法也有$O(m^{2}logm)$,$m$为点的个数。

3.3 密度聚类

  DBSCAN既可以适用于凸样本集,也可以适用于非凸样本集。找到几个由密度可达关系导出的最大的密度相连样本集合。即为我们最终聚类的一个类别,或者说一个簇。

3.3.1 密度聚类基本思想

   它任意选择一个没有类别的核心对象作为种子,然后找到所有这个核心对象能够密度可达的样本集合,即为一个聚类簇。继续选择另一个没有类别的核心对象去寻找密度可达的样本集合,得到另一个聚类簇。一直运行到所有核心对象都有类别为止。

3.3.2 密度聚类步骤

  1、找到任意一个核心点,对该核心点进行扩充;
  2、扩充方法是寻找从该核心点出发的所有密度相连的数据点;
  3、遍历该核心的邻域内所有核心点,寻找与这些数据点密度相连的点。

3.3.3 密度聚类优缺点

  优点

  1、不需要确定要划分的聚类个数,聚类结果没有偏倚;
  2、抗噪声,在聚类的同时发现异常点对数据集中的异常点不敏感;
  3、处理任意形状和大小的簇,相对的,K-Means之类的聚类算法一般只适用于凸数据集。

  缺点

  1、数据量大时内存消耗大,相比K-Means参数多一些;
  2、样本集的密度不均匀、聚类间距差相差很大时,聚类质量较差,这时用DBSCAN聚类一般不适合;如果数据集是稠密的,并且数据集不是凸的,那么用DBSCAN会比K-Means聚类效果好很多。如果数据集不是稠密的,则不推荐用DBSCAN来聚类。

参考文献

1.聚类及聚类算法的分类

2.机器学习(十)—聚类算法(KNN、Kmeans、密度聚类、层次聚类)