一、聚类算法简介
聚类的基本思想:对于给定的M个样本的数据集,给定聚类(簇)的个数K(K<M),初始化每个样本所属的类别,再根据一定的规则不断地迭代并重新划分数据集的类别(改变样本与簇的类别关系),使得每一次的划分都比上一次的划分要好。
聚类是一种无监督的算法。
距离的常用度量方法:欧氏距离(P=2)
二、聚类算法分类
聚类算法有很多种,主要分为划分聚类、密度聚类和谱聚类等三种聚类。
2.1 划分聚类
1)KMeans聚类(KMeans、二分KMeans、KMeans++、KMeansll、Canopy、Mini Batch KMeans)
2)层次聚类(AGNES(凝聚的层次聚类)、DIANA(分裂的层次聚类)、BIRCH(平衡迭代削减聚类法)、CURE(使用代表点的聚类法))
2.2 密度聚类
1)DBSCAN(基于密度的聚类算法)
2)MDCA(密度最大值聚类算法)
2.3 谱聚类–通过对样本数据的拉普拉斯矩阵的特征向量进行聚类
三、划分聚类
1 kMeans算法及其衍生算法
1.1 KMeans算法
sklearn.cluster.
KMeans
(n_clusters=8,init=’k_means++’, n_init=10, max_iter=300, tol=0.0001, precompute_distances=’auto’, verbose=0, random_state=None, copy_x=True, n_jobs=1, algorithm=’auto’)
KMeans算法的思想:对于给定的M个样本的数据集(无标签),给定聚类(簇)的个数K(K<M),初始化每个样本所属的类别,再根据距离的不同,将每个样本分配到距离最近的中心点的簇中,然后再对迭代完成的每个簇更新中心点位置(改变样本与簇的类别关系),直到达到终止条件为止。
KMeans算法的终止条件:1)迭代次数 2)簇中心点变化率 3)最小平方误差值
KMeans算法的优点:理解简单容易,凸聚类的效果不错,效率高;对于服从高斯分布的数据集效果相当好。
KMeans算法的缺点:中心点数量K的确定,初始化的中心点位置敏感,对于环形等非凸的数据集的聚类效果不好。
KMeans算法的伪代码:
初始化K个中心点(一般随机选择):
当中心点变化大于给定值或者小于迭代次数时:
对于数据集中的每个点:
对于每个中心点:
计算数据点到中心点的距离
将数据点分配到距离最近的簇中
对于每个簇,计算簇中所有数据点的平均值,更新簇中心点的位置
返回最终的簇中心点和对应的簇
1.2 二分KMeans算法(一次选择两个点进行KMeans划分)
二分KMeans主要是为了解决KMeans的初值敏感的问题对KMeans算法做出的改进算法。二分KMeans每次选择两个聚类点进行KMeans算法聚类,然后再根据一定的标准(计算SSE值或者簇中的样本点的个数,选择值较大的簇进行划分)对分类后的类进行二分,直到达到终止条件为止。
1.3 KMeans++算法(就是选择距离最远的两个数据点作为聚类初始点)
KMeans++也是解决解决KMeans的初值敏感的问题,它与二分KMeans不同的是:在选择两个聚类点的时候不是随机选择,而是先随机选择一个点,第二个选择距离该点最远的点,再进行划分。当然,为了避免异常点的存在,第二个点的选择会选择距离较远的几个点并进行加权选择最终的第二个点。
1.4 KMeansll(其实就是根据数据集的随机采样的离散性,更方便找出数据集的聚类中心点)
KMeansll主要是KMeans的一个变种算法。它是通过随机采样的方法选择K个数据点,进行M次这样的选择得到M个样本,将这些样本合在一起进行KMeans算法得到初始的中心点,再用这些初始的中心点进行数据集的聚类操作。
1.5 Canopy
Canopy是一种‘粗’的聚类方法,这种聚类方法主要是为了找到聚类的个数K及聚类中心点,一般我们使用时将这个结果传递给KMeans算法,克服了KMeans存在的聚类中心点个数不确定及初始敏感的问题。
1.6 Mini Batch KMeans(适合大数据集使用的算法)—效果略差于KMeans算法
Mini Batch KMeans主要是KMeans的一个变种算法,它的算法计算步骤如下:
1)它是对于较大的数据集,随机抽取一部分数据集,使用KMeans算法构建出K个聚簇点的模型;
2)再次抽取部分数据,将这些数据添加到上面得到的K个聚类中;
3)更新中心点位置;
4)循环上述的步骤2和步骤3,直到达到终止条件(中心点位置不发生变化或者达到迭代次数),停止操作。
2 层次聚类及其优化算法
2.1 AGNES算法(凝聚的层次聚类,自底向上)
2.2 DIANA算法(分裂的层次聚类,自顶而下)
2.3 BIRCH算法(平衡迭代削减法)—适合大数据集使用的算法
sklearn.cluster.
Birch
(threshold=0.5, branching_factor=50, n_clusters=3, compute_labels=True, copy=True)
BRICH使用三元组保存簇的相关信息,通过构建满足两个参数分支因子和类直径的聚类特征树(底层为CF-Tree实现的)来求聚类。
三元组:(数据点个数,数据点特征之和,数据点特征的平方和)–这种方式可以有效地提高计算距离的速度(就是三元组的线性组合求距离)
分支因子:分支因子规定了树的每个节点的样本个数。
类直径:体现这一类点的距离范围。
BIRCH算法中聚类特征树的构建过程是一个动态的过程,可以随时接受数据点并对树进行重新构建,这也是它适用于大规模数据集的主要原因。
四、密度聚类
4.1 密度聚类简介:
简单点说,密度聚类就是通过计算给定样本点附近的邻域内地数据点的个数,如果个数大于给定的阈值,那么就判定该样本点属于这个簇。
密度聚类能够很好的克服前面所讲的划分聚类的缺点(只能发现凸聚类的数据),它可以发现任意形状的聚类,并且对于噪声数据不敏感。
密度聚类将簇的概念重新定义为:密度相连的点的最大集合。
4.2 DBSCAN(基于密度的聚类方法–常用的密度聚类方法)
sklearn.cluster.
DBSCAN
(eps=0.5, min_samples=5, metric=’euclidean’, metric_params=None, algorithm=’auto’, leaf_size=30, p=None, n_jobs=1)
1)DBSCAN的算法思想:用一个点附近的邻域内的数据点的个数来衡量该点所在空间的密度。
2)基本概念
1. 邻域— 给定点的半径为内的区域。
2. 密度— 就是数据点邻域内的样本点的个数。
3. 阈值— 给定的值M。
4. 核心点— 如果数据点的邻域内的样本点数大于等于阈值M,则该点为核心点。
5. 边界点— 如果非核心点的邻域内存在核心点。
6. 噪音点— 既不是核心点也不是边界点的数据点。
7. 直接密度可达— 对于核心点X,其附近的邻域内的样本点对X都叫做直接密度可达。
8. 密度可达— 对于核心点X,Y为其邻域内的又一个核心点,则Y的邻域内的所有数据点对X均为密度可达。
9. 密度相连— 对于核心点X,Y,如果有点Z与X、Y都密度可达,则X、Y密度相连。
10. 簇— 在DBSCAN中,簇就是最大密度相连的数据点的集合。
3)DBSCAN算法伪代码
摘自:https://www.cnblogs.com/chaosimple/archive/2013/07/01/3164775.html
算法描述:
算法: DBSCAN
输入: ——半径
MinPts——给定点在邻域内成为核心对象的最小邻域点数。
D——集合。
输出: 目标类簇集合
方法: Repeat
1) 判断输入点是否为核心对象
2) 找出核心对象的邻域中的所有直接密度可达点。
Until 所有输入点都判断完毕
Repeat
针对所有核心对象的邻域内所有直接密度可达点找到最大密度相连对象集合,中间涉及到一些密度可达对象的合并。
Until 所有核心对象的领域都遍历完毕
4.3 MDCA(密度最大值聚类算法)— 密度和层次结合的算法
MDCA的基本思路是寻找最高密度的对象和它所在的稠密区域。
最大密度点:对于数据集中的点X,如果X的邻域内的数据点的个数大于等于任意其它数据点的邻域内的数据点的个数,则点X为最大密度点。
有序序列S:将所有的数据点到的距离从小到大排序,得到的距离对应的点的集合。
MDCA聚类的一般过程:
1)基本簇划分(就是找到最大的密度点及其周边的密度最大的几个点作为核心点的数据点的集合)
步骤1. 对于数据集上的数据点,找到最大密度点,形成以为核心的新簇,再找到对应的有序序列S,选取前m个数据点,计算这些数据点的密度。如果密度值大于density0(给定值),则将这个数据点添加到新簇中。
步骤2. 对于上一步剩余的数据点,循环第一步骤的操作,构建不同的簇,直到剩余的所有数据点密度值均小于density0的值。
2)使用AGNES的算法思想,合并簇,得到最终的划分
对于划分好的基本簇,运用AGNES的算法思想,将距离较近的簇进行合并。
3)将剩余的数据点划分到距离较近的簇中
五、谱聚类
class sklearn.cluster.
SpectralClustering
(n_clusters=8, eigen_solver=None, random_state=None, n_init=10, gamma=1.0, affinity=’rbf’, n_neighbors=10, eigen_tol=0.0, assign_labels=’kmeans’, degree=3, coef0=1, kernel_params=None, n_jobs=1)