机器学习(聚类七)——层次聚类的优化算法

上篇博客介绍的层次聚类,尤其是AGNES这一传统的层次聚类算法。这篇博客介绍层次聚类的优化算法。

优化算法

BIRCH算法
BIRCH算法(平衡迭代削减聚类法):聚类特征使用3元组进行一个簇的相关信息,通过构建满足分枝因子和簇直径限制的聚类特征树来求聚类,聚类特征树其实是一个具有两个参数分枝因子和类直径的高度平衡树;分枝因子规定了树的每个节点的子女的最多个数,而类直径体现了对这一类点的距离范围;非叶子节点为它子女的最大特征值;聚类特征树的构建可以是动态过程的,可以随时根据数据对模型进行更新操作。

优缺点:

  • 适合大规模数据集,线性效率;
  • 只适合分布呈凸形或者球形的数据集、需要给定聚类个数和簇之间的相关参数;

CURE算法
CURE(对BIRCH的优化,但很少有人用。因为不如后面讲的密度聚类方法)
CURE算法(使用代表点的聚类法):该算法先把每个数据点看成一类,然后合并距离最近的类直至类个数为所要求的个数为止。但是和AGNES算法的区别是:取消了使用所有点或用中心点+距离来表示一个类,而是从每个类中抽取固定数量、分布较好的点作为此类的代表点,并将这些代表点乘以一个适当的收缩因子,使它们更加靠近类中心点。代表点的收缩特性可以调整模型可以匹配那些非球形的场景,而且收缩因子的使用可以减少噪音对聚类的影响。

优缺点:

  • 能够处理非球形分布的应用场景
  • 采用随机抽样和分区的方式可以提高算法的执行效率

代码实现

基于scikit的API创建模拟数据,使用BRICH算法对数据进行聚类操作,并比较n_clusters参数的作用。
API

class sklearn.cluster.Birch(threshold=0.5, branching_factor=50, n_clusters=3, compute_labels=True, copy=True)

代码

from itertools import cycle
from time import time
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.colors as colors

from sklearn.preprocessing import StandardScaler
from sklearn.cluster import Birch
from sklearn.datasets.samples_generator import make_blobs

## 设置属性防止中文乱码
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False

## 产生模拟数据
xx = np.linspace(-22, 22, 10)
yy = np.linspace(-22, 22, 10)
xx, yy = np.meshgrid(xx, yy)
n_centres = np.hstack((np.ravel(xx)[:, np.newaxis],
                       np.ravel(yy)[:, np.newaxis]))
#产生10万条特征属性是2,类别是100,符合高斯分布的数据集
X, y = make_blobs(n_samples=100000,n_features=2, centers=n_centres, random_state=28)

#创建不同的参数(簇直径)Birch层次聚类
birch_models = [
    Birch(threshold=1.7, n_clusters=None),
    Birch(threshold=0.5, n_clusters=None),
    Birch(threshold=1.7, n_clusters=100)
]
#threshold:簇直径的阈值,    branching_factor:大叶子个数
#我们也可以加参数来试一下效果,比如加入分支因子branching_factor,给定不同的参数值,看聚类的结果 

## 画图
final_step = [u'直径=1.7;n_lusters=None',u'直径=0.5;n_clusters=None',u'直径=1.7;n_lusters=100']

plt.figure(figsize=(12,8),facecolor='w')
plt.subplots_adjust(left = 0.02, right = 0.98, bottom = 0.1,top = 0.9)
colors_ = cycle(colors.cnames.keys())
cm = mpl.colors.ListedColormap(colors.cnames.keys())

for ind, (birch_model, info) in enumerate(zip(birch_models, final_step)):
    t = time()
    birch_model.fit(X)
    time_ = time() - t
#获取模型结果(label和中心点)    
    labels = birch_model.labels_
    centroids = birch_model.subcluster_centers_
    n_clusters = len(np.unique(centroids))
    print ("Birch算法,参数信息为:%s;模型构建消耗时间为:%.3f秒;聚类中心数目:%d" % (info, time_, len(np.unique(labels))))
    
    ## 画图
    subinx = 221 + ind
    plt.subplot(subinx)
    for this_centroid, k, col in zip(centroids, range(n_clusters), colors_):
        mask = labels == k
        plt.plot(X[mask, 0], X[mask, 1], 'w', markerfacecolor=col, marker='.')
        if birch_model.n_clusters is None:
            plt.plot(this_centroid[0], this_centroid[1], '*', markerfacecolor=col, markeredgecolor='k', markersize=2)
    plt.ylim([-25, 25])
    plt.xlim([-25, 25])
    plt.title(u'Birch算法%s,耗时%.3fs' % (info, time_))
    plt.grid(False)

## 原始数据集显示
plt.subplot(224)
plt.scatter(X[:, 0], X[:, 1], c=y, s=1, cmap=cm, edgecolors='none')
plt.ylim([-25, 25])
plt.xlim([-25, 25])
plt.title(u'原始数据')
plt.grid(False)
    
plt.show()

Birch算法,参数信息为:直径=1.7;n_lusters=None;模型构建消耗时间为:12.264秒;聚类中心数目:158
Birch算法,参数信息为:直径=0.5;n_clusters=None;模型构建消耗时间为:21.004秒;聚类中心数目:3205
Birch算法,参数信息为:直径=1.7;n_lusters=100;模型构建消耗时间为:10.647秒;聚类中心数目:100

看一下最后的效果:
机器学习(聚类七)——层次聚类的优化算法

上一篇:TZOJ 5113: Starry Night


下一篇:《机器学习》周志华note3