BIRCH聚类算法(平衡迭代规约层次聚类)
- 目的及用途
- 聚类(Clustering)是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。也即聚类后同一类的数据尽可能聚集到一起,不同类数据尽量分离。
- 聚类算法的分类:基于层次、基于划分、基于密度、基于网格、基于模型
- 用途:分类、异常检测、数据压缩
- 算法概述
- 算法原理
算法利用聚类特征树(CF Tree)来进行聚类,聚类特征树类似于平衡B+树,主要通过计算数据点间的相似度来创建一棵有层次的嵌套聚类树(如图1所示),它试图在不同层次对数据集进行划分,从而形成树形的聚类结构。
图1 嵌套聚类树示意图
算法主要分为两个阶段:
阶段一对整个数据集进行扫描,建立一棵初始化的聚集特征树(CF-tree)尽可能地包含所有属性的信息;
阶段二用聚集特征代替原有数据集进行聚类.在第一阶段聚集特征树是随着对象一个一个地加入而自动形成的:一个对象被放入那个离它最近的叶子节点(簇)中去.如果放入以后这个簇的半径大于阈值 T 的话,那么这个叶节点就会被分割(Split).新对象插入以后关于这个对象的信息向根节点传递.插入过程类似于 B+树构建中的插入和节点分裂.聚集特征树的大小可以通过调节参数来改变,如果存储树需要的内存超过了主存,可以定义一个较小的阈值,然后通过提升阈值重新建立一棵聚类特征树,这个重建过程并不需要将整个记录扫描一次,而是建立在原有树的叶子节点的基础之上的。因此,建立一个树,数据记录只需要被扫描一次.当树建好以后可以在第二阶段用其他的聚类算法对聚类特征进行聚类.
- 聚类特征CF的定义
每一个CF是一个三元组,可以用(N,LS,SS)表示。其中N代表了这个CF中拥有的样本点的数量;LS
代表了这个CF中拥有的样本点各特征维度的和向量,SS代表了这个CF中拥有的样本点各特征维度的平方和。
例如,在CF Tree中的某一个节点的某一个CF中,有5个样本(3,4), (2,6), (4,5), (4,7), (3,8)。则其对应的CF三元组如下所示:
N=5
LS=3+2+4+4+3,4+6+5+7+8=16,30
SS=32+22+42+42+32+42+62+52+72+82=54+190=244
- 算法输入、输出
- 输入:一组样本点(一个数据库)
- 输出:一个聚类特征树CF Tree
- 预备知识
- 叶子节点:一棵树当中没有子结点的结点称为叶子结点(上图中的sc1、sc2、……、sc8);
- 枝节点:有子结点的结点称为枝节点,即树中的非叶子节点
- 算法参数
- 分枝因子(B、L):B为允许叶子节点包含的CF三元组的最大个数(上图中为2),L为允许枝节点(非叶子节点)包含的CF三元组的最大个数,默认值均为50。
- 最大样本半径阈值(T):决定了每个聚类特征所有样本形成的超球体( 超球面和超球体 - gkm0120 - 博客园 (cnblogs.com))的半径值域,也就是说,在这个CF中的所有样本点一定要在半径小于T的一个超球体内。值越小,说明CF树在建立的时候规模会比较大,默认值0.5。
簇半径(相当于全局标准差)为:
R=SSN-LS2N2
任意两个簇之间的距离为:
D=i=1N1j=1N2xi-xj2N1N2=SS1N1+SS2N2-2LS1∙LS2N1N2
- 聚类类别数(可选参数K):如果不输入K值,则最后的CF三元组的组数即为最终的K,否则会按输入的K值对CF三元组按距离大小进行合并。
图
![]() |
2 聚类特征树(CF Tree)示意图
- 算法步骤
参考数据挖掘入门笔记——BIRCH聚类(一拍即合) - 知乎 (zhihu.com)
BIRCH聚类算法原理 - 刘建平Pinard - 博客园 (cnblogs.com)
- 主要步骤
- 根据经验值确定参数分枝因子(B、L)和最大样本半径阈值(T)
- 从数据库中逐个加入新样本,将新样本插入到CF树上:
①从根节点向下寻找和新样本距离最近的叶子节点和叶子节点里最近的CF节点
②如果新样本加入后,这个CF节点对应的超球体半径仍然满足小于阈值T,则更新路径上所有的CF三元组,插入结束。否则转入3
③如果当前叶子节点的CF节点个数小于阈值L,则创建一个新的CF节点,放入新样本,将新的CF节点放入这个叶子节点,更新路径上所有的CF三元组,插入结束。否则转入4。
④将当前叶子节点划分为两个新叶子节点,选择旧叶子节点中所有CF元组里超球体距离最远的两个CF元组,分布作为两个新叶子节点的第一个CF节点。将其他元组和新样本元组按照距离远近原则放入对应的叶子节点。依次向上检查父节点是否也要分裂,如果需要按照叶子节点分裂方式进行分裂。
- 样本点插入CF树的具体示范
- 确定参数分枝因子(B=L=2)和最大样本半径阈值(T),初始CF树为空,设置根节点的CF信息为CF1
- 读入第一个样本点 A,构造根节点的一个叶子节点和一个子簇。
- 读入第二个样本点B,判断样本点A和样本点B是否在以最大样本半径阈值T为半径的超球体范围内
①如果在,也就是说他们属于同一个CF,根据 CF 可加性,更新CF
②如果不在,需要一个新的CF三元组,来容纳这个新的样本点
- 读入第三个样本点C,离CF3最近,但不属于A,B两个超球体范围内,本应该将它单独设一个分支,但是CF1的分枝数已经达到最大值(设置分枝因子B=L=2),此时,我们只能选择继续向下分裂。
- 实例
参考(182条消息) 机器学习笔记(九)聚类算法Birch和层次聚类Hierarchical clustering_birch算法流程图_大白兔黑又黑的博客-CSDN博客
假设已有数据集为:{[0, 1], [0.3, 1], [-0.3, 1], [0, -1], [0.3, -1], [-0.3, -1], [-0.3,-1.1],[1,2]},构建 CF Tree 每个分支节点的最大CF数B和每个叶子节点的最大CF数L都取2,叶节点每个CF的最大样本半径阈值T为0.2。CF Tree的构建过程如下:
为了方便表述,将数据集用样本点描述,即
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
数据集 | [0,1] | [0.3,1] | [-0.3,1] | [0,-1] | [0.3,-1] | [-0.3,-1] | [-0.3,-1.1] | [1,2] |
样本点 | A | B | C | D | E | F | G | H |
- 初始化CF树为空树,读入样本点A[0,1]:
将样本点A放入根节点
- 读入样本点B[0.3,1]:
尝试将样本点B加入CF1,则CF1三元组变为(2,(0.3,2),2.09),CF1的簇半径RCF1=2.092-0.32+2222=0.15<T,所以可以将样本点B加入CF1,并更新已有三元组:
- 读入样本点C[-0.3,1]:
尝试将样本点C加入CF1,则CF1三元组变为(3,(0,3),3.18),CF1的簇半径RCF1=3.183-02+3232=0.24>T,所以不可以将样本点C入CF1;
需要创建一个新的三元组CF2(1,( -0.3,1),1.09),与三元组CF1一同放在根节点中,并更新已有三元组:
- 读入样本点D[0,-1]:
将样本点D看作一个单独的三元组(1,(0,-1),1), 分别计算样本点D和CF三元组CF1、CF2之间的距离,D(D,CF1)=11+2.092-2×(0-2)1×2=2.01,D(D,CF2)=11+1.091-2×(0-1)1×1=2.02
,距离三元组CF1最近;
尝试把样本点D加入三元组CF1,则三元组CF1变为(3,(0.3,1),3.09),CF1的簇半径RCF1=3.093-0.32+1232=0.95>T,因此不可以将样本点D加入三元组CF1;
为样本点D分配新的三元组CF3(1,(0,-1),1),挂在与其距离最近的三元组CF1上,但是三元组CF1中已经有两个样本点,达到最大值L,因此需要将三元组CF0进行分裂,以分层容纳CF1、CF2、CF3三个三元组,计算CF1和CF2之间的距离
D(CF1,CF2)=2.092+1.091-2×(-0.09+2)2×1=0.47
CF2和CF3(此时仅包含样本点D)距离最远,将其作为种子继续向下分裂,由于三元组CF1距离CF3最近,将其分配到同一个叶子节点中。
- 读入样本点E[0.3,-1]:
分别计算样本点E到叶子节点L1、L2之间的距离,可以发现距离叶子节点L2更近,应该将其挂在L2上,尝试将样本点E加入三元组CF3,加入后三元组CF3的簇半径为0.15,小于T,因此可以加入三元组CF3,并更新已有三元组。
- 读入样本点F[-0.3,-1]:
分别计算样本点F到叶子节点L1、L2之间的距离,可以发现距离叶子节点L2更近,应该将其挂在L2上,尝试将样本点F加入三元组CF3,加入后三元组CF3的簇半径大于T,因此在L2中为样本点F分配新的三元组,并更新已有三元组。
- 读入样本点G[-0.3,-1.1]:
- 读入样本点H[1,2]:
分别计算样本点H到叶子节点L1、L2之间的距离,可以发现距离叶子节点L1更近,应该将其挂在L1上;
由于叶子节点L1中有两个三元组CF1、CF2,继续计算样本点H和CF1、CF2之间的距离,发现距离三元组CF1更近,尝试将样本点H加入三元组CF1,加入后三元组CF1的簇半径大于T,因此不能直接加入三元组CF1;
为样本点H分配新的三元组CF5(1,(1,2),5),计算CF1、CF2、CF5之间的簇间距,三元组CF2和CF5之间距离最大,将其作为种子继续向下分裂,由于三元组CF1距离CF2最近,将其分配到同一个叶子节点中。
- 输出聚类结果:AB、C、H、DE、FG
- 算法优缺点
- 优点:BIRCH算法聚类速度快,只需要单遍扫描数据集就能进行聚类;
- 缺点:
- 对高维、非凸数据效果不好
- 由于CF Tree对每个节点的CF个数有限制,导致聚类的结果可能和真实的类别分布不同
- 只考虑到簇内各数据对象之间的关系,为叶子节点中的簇设定统一阈值,在数据对象插入时,根据数据对象与簇之间的距离而决定数据对象的插入位置,这种方式具有极大的局限性,它忽略了簇与簇之间的关系,对体积相差较大的簇的聚类结果较差。
- 聚类的结果依赖于数据的读入顺序
- 适用场景
BIRCH算法比较适合于数据量大,类别数K也比较多的情况。
- 改进方向
- 数据的读入顺序:可以先读入区别较大的或者具有代表性的数据,后续在进行聚类时可以将不同的类别的数据尽可能划分到已有类别中。
- 簇间距离的度量准则:可以改进为根据实际场景中数据的特点获取指标的相似度
- 改进分枝因子(B、L):决定每个聚类内样本点的最大个数
- 改进最大样本半径阈值(T):如果threshold越小,说明CF树在建立的时候规模会比较大。如果数据方差比较大的时候,一般需要增大threshold的值。因为样本大意味着数据比较离散,如果设置threshold特别小的话,每个聚类特征中将只有很少的元素,CF树会产生很多新的聚类特征CF。
(参考论文《一种改进的 BIRCH 聚类分析算法及其应用研究》)
主要思想:为每个簇设立一个阈值S
引入分裂因子 S 定义为叶子节点离差平方和的上限,当有新的节点加入到叶结点时,如果新的叶节点的离差平方和大于 S ,无论原来节点是否有存储空间(节点的条目小于L )都将要产生一个新的叶结点.