聚类含义

定义:聚类,也叫做聚类分析,依据对象的属性,将相似的对象归位一类。聚类,就是寻找发生数据之间内在联系的方法。
分类:从聚类的类型来讲,一般有结构性聚类、分散性聚类、密度聚类等。

  • 结构性聚类是指,可以从上至下或者从下至上双向进行计算。从下至上是以单个对象开始,不断与周围相近的对象进行融合,最终将全部数据分成多种类别。而从上至下算法则恰恰相反,它先将全部数据当作一个整体,然后逐渐分小。在结构性聚类中,我们的重要依据为距离。一般情况下,我们会使用欧式距离,或者曼哈顿距离来测量两个对象之间的相似程度。
  • 与结构性聚类不同,分散性聚类会一次性确定所有类别。
  • 度聚类的主要特点为将测算距离改为计算密度。

聚类vs分类:一般来讲,在一个机器学习任务或者数据分析实例中,我们会先采用聚类算法对数据进行处理。使用聚类算法对历史数据处理之后,就可以人为的给每一种类别打上标签。而这些存在标签的数据,就可以被应用到下一步的分类学习中。简而言之、在执行聚类之前,我们的数据没有任何类别可言。但在执行分类之前,我们应该已经有了类别,才能对新数据进行分类。

DNA序列聚类python 聚类算法 python_算法

K-均值聚类

K-均值聚类(又叫 K-Means 聚类)是最常用的聚类方法之一。从它的名字来讲,K 代表最终将全部样本数据集和聚为 K 个类别。而「均值」代表在聚类的过程中,我们计算聚类中心点的特征向量时,需要采用求相邻样本点特征向量均值的方式进行。

例如,我们将 𝑋1=(𝑥1,𝑦1) , 𝑋2=(𝑥2,𝑦2) , 𝑋3=(𝑥3,𝑦3) 聚为一类时,中心点坐标 𝑂(𝑜1,𝑜1) 为: 𝑜1=(𝑥1+𝑥2+𝑥3)/3 , 𝑜2=(𝑦1+𝑦2+𝑦3)/3 。

聚类三步:
第一步:选择聚类数量,也就是 𝑘 值的大小。
第二步:实施聚类算法,k-均值等。
第三步:对聚类结果进行人工标注和分析。

K-均值聚类步骤

1.人为确定 𝑘 值的大小,也就是聚类的数量。然后,我们会使用一种叫 Forgy 的方法初始化聚类,Forgy 也就是随机地从数据集中选择 𝑘 个观测作为初始的均值点。例如,下图中,我们定 𝑘=3 ,然后随机选择 3 个数据点初始化聚类。

DNA序列聚类python 聚类算法 python_算法_02


2.以这三个样本点(红色)为基准,将剩余的数据点按照与其距离最近的标准进行类别划分。

DNA序列聚类python 聚类算法 python_DNA序列聚类python_03


3.就得到了通过绿色线条划分的 A,B,C 三个区域。下面求解各区域中数据点集的中心点,这一步也就是更新。然后得到三个紫色中心点。重复上面的步骤,得到由黄色线条划分的 D, E, F 三个区域。

DNA序列聚类python 聚类算法 python_python_04


4.重复上面的步骤,直到三个区域的中心点变化非常小或没有变化时,终止迭代。最终,就将全部数据划分为 3 了类别。

K值选择
K值不能人为随便确定
K-Means 聚类中,我们一般通过计算轮廓系数,来确定 𝑘 值的大小。轮廓系数(Silhouette Coefficient),是聚类效果好坏的一种评价方式。轮廓系数结合内聚度(Cohesion)和分离度(Separation)两种因素,可以用来在相同原始数据的基础上用来评价不同算法、或者算法不同运行方式对聚类结果所产生的影响。

对于某一点 𝑖 ,我们用 𝑎(𝑖) 表示 𝑖 距离同类中其它点之间的距离的平均值,而 𝑏(𝑖) 表示 𝑖 到所有非同类点的平均距离,然后取最小值。于是, 𝑖 的轮廓系数计算如下:

DNA序列聚类python 聚类算法 python_数据集_05

然后,我们计算数据集中所有点的轮廓系数,最终以平均值作为当前聚类的整体轮廓系数。整体轮廓系数介于 [−1,1] ,越趋近于 1 代表聚类的效果越好。

案例实现:数据用数据源里的three_class_data.csv

import pandas as pd
# 导入数据
data = pd.read_csv(
    "http://labfile.oss.aliyuncs.com/courses/764/three_class_data.csv", header=0)
data.head()

#计算k取2-12的轮廓系数
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from matplotlib import pyplot as plt
%matplotlib inline

X = data[["x", "y"]]
score = []
for i in range(10):
    model = KMeans(n_clusters=i+2)
    model.fit(X)
    score.append(silhouette_score(X, model.labels_))  #计算轮廓系数
    
plt.figure(figsize=(11, 5))
plt.subplot(1, 2, 1)
plt.scatter(data['x'], data['y'])  #原数据散点图
plt.subplot(1, 2, 2)
plt.plot(range(2, 12, 1), score)

DNA序列聚类python 聚类算法 python_算法_06


右图说明,当 𝑘 取 3 时,轮廓系数最大。也就是推荐将原数据聚合为三类

#选定k为3类后,进行聚合
model = KMeans(n_clusters=3)
model.fit(X)
plt.scatter(data['x'], data['y'], c=model.labels_)

#绘制出 k-均值聚类的决策边界
import numpy as np

# 计算聚类过程中的决策边界
x_min, x_max = data['x'].min() - 0.1, data['x'].max() + 0.1
y_min, y_max = data['y'].min() - 0.1, data['y'].max() + 0.1
xx, yy = np.meshgrid(np.arange(x_min, x_max, .01),
                     np.arange(y_min, y_max, .01))

result = model.predict(np.c_[xx.ravel(), yy.ravel()])

# 将决策边界绘制绘制出来
result = result.reshape(xx.shape)
plt.contourf(xx, yy, result, cmap=plt.cm.Greens)
plt.scatter(data['x'], data['y'], c=model.labels_, s=15)
# 绘制聚类中心点
center = model.cluster_centers_
plt.scatter(center[:, 0], center[:, 1], marker='p',
            linewidths=2, color='b', edgecolors='w', zorder=20)

其他聚类算法

Mini Batch K-Means
Mini Batch K-Means 整体上和 K-Means 很相似,它是 K-Means 的一个变种形式。与 K-Means 不同的地方在于,其每次从全部数据集中抽样小数据集进行迭代。Mini Batch K-Means 算法在不对聚类效果造成较大影响的前提下,大大缩短了计算时间。

Affinity Propagation
Affinity Propagation 又被称为亲和传播聚类。Affinity Propagation 是基于数据点进行消息传递的理念设计的。与 K-Means 等聚类算法不同的地方在于,亲和传播聚类不需要提前确定聚类的数量,即 𝑘 值。但是运行效率较低。

Mean Shift
MeanShift 又被称为均值漂移聚类。Mean Shift 聚类的目的是找出最密集的区域, 同样也是一个迭代过程。在聚类过程中,首先算出初始中心点的偏移均值,将该点移动到此偏移均值,然后以此为新的起始点,继续移动,直到满足最终的条件。Mean Shift 也引入了核函数,用于改善聚类效果。除此之外,Mean Shift 在图像分割,视频跟踪等领域也有较好的应用。

Spectral Clustering
Spectral Clustering 又被称为谱聚类。谱聚类同样也是一种比较常见的聚类方法,它是从图论中演化而来的。谱聚类一开始将特征空间中的点用边连接起来。其中,两个点距离越远,那么边所对应的权值越低。同样,距离越近,那么边对应的权值越高。最后,通过对所有特征点组成的网络进行切分,让切分后的子图互相连接的边权重之和尽可能的低,而各子图内部边组成的权值和经可能高,从而达到聚类的效果。谱聚类的好处是能够识别任意形状的样本空间,并且可以得到全局最优解。

Agglomerative Clustering
Agglomerative Clustering 又被称为层次聚类。层次聚类算法是将所有的样本点自下而上合并组成一棵树的过程,它不再产生单一聚类,而是产生一个聚类层次。层次聚类通过计算各样本数据之间的距离来确定它们的相似性关系,一般情况下,距离越小九代表相似度越高。最后,将相似度越高的样本归为一类,依次迭代,直到生成一棵树。由于层次聚类涉及到循环计算,所以时间复杂度比较高,运行速度较慢。

BIRCH
BIRCH 是英文 Balanced Iterative Reducing and Clustering Using Hierarchies 的简称,它的中文译名为「基于层次方法的平衡迭代规约和聚类」,名字实在太长。BIRCH 引入了聚类特征树(CF 树),先通过其他的聚类方法将其聚类成小的簇,然后再在簇间采用 CF 树对簇聚类。BIRCH 的优点是,只需要单次扫描数据集即可完成聚类,运行速度较快,特别适合大数据集。

DBSCAN
DBSCAN 是英文 Density-based spatial clustering of applications with noise 的简称,它的中文译名为「基于空间密度与噪声应用的聚类方法」,名字同样很长。DBSCAN 基于密度概念,要求聚类空间中的一定区域内所包含的样本数目不小于某一给定阈值。算法运行速度快,且能够有效处理特征空间中存在的噪声点。但是对于密度分布不均匀的样本集合,DBSCAN 的表现较差。

用代码实现上述8种聚类方法

from sklearn import cluster
import time

# 对聚类方法依次命名
cluster_names = ['KMeans', 'MiniBatchKMeans', 'AffinityPropagation', 'MeanShift',
                 'SpectralClustering', 'AgglomerativeClustering', 'Birch', 'DBSCAN']

# 确定聚类方法相应参数
cluster_estimators = [
    cluster.KMeans(n_clusters=3),
    cluster.MiniBatchKMeans(n_clusters=3),
    cluster.AffinityPropagation(),
    cluster.MeanShift(),
    cluster.SpectralClustering(n_clusters=3),
    cluster.AgglomerativeClustering(n_clusters=3),
    cluster.Birch(n_clusters=3, threshold=0.1),
    cluster.DBSCAN()
]

# 为绘制子图准备
plot_num = 1
plt.figure(figsize=(14, 7))
# 依次运行不同的聚类方法
for name, model in zip(cluster_names, cluster_estimators):
    tic = time.time()
    # 建立模型
    model.fit(X)
    # 绘制子图
    plt.subplot(2, len(cluster_estimators) / 2, plot_num)
    # 计算聚类过程中的决策边界
    x_min, x_max = data['x'].min() - 0.1, data['x'].max() + 0.1
    y_min, y_max = data['y'].min() - 0.1, data['y'].max() + 0.1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, .01),
                         np.arange(y_min, y_max, .01))
    if hasattr(model, 'predict'):
        result = model.predict(np.c_[xx.ravel(), yy.ravel()])
        # 将决策边界绘制绘制出来
        result = result.reshape(xx.shape)
        plt.contourf(xx, yy, result, cmap=plt.cm.Greens)

    plt.scatter(data['x'], data['y'], c=model.labels_, s=15)
    # 判断方法中是否由 cluster_centers_ 聚类中心参数,并执行不同的命令
    if hasattr(model, 'cluster_centers_'):
        center = model.cluster_centers_
        plt.scatter(center[:, 0], center[:, 1], marker='p',
                    linewidths=2, color='b', edgecolors='w', zorder=20)
    # 计算算法运行时间
    toc = time.time()
    cluster_time = (toc - tic)*1000
    # 绘图
    plt.title(str(name) + ", " + str(int(cluster_time)) + "ms")
    plot_num += 1

聚类算法方法的选择

每一种方法的使用情况不同,下面说明一下简易的选择步骤:

如果已知 𝑘 值,即聚类的数量:

  • 样本数量 < 1 万,首选 K-Means,效果不好再选择 Spectral Clustering。
  • 样本数量 > 1 万,首选 MiniBatch K-Means。
    如果 𝑘 值未知:
  • 样本数量 < 1 万,首选 Mean Shift。
  • 样本数量 > 1 万,依靠经验灵活应对了。