所有文章 > AI驱动 > 讲透一个强大算法模型,层次聚类!!

讲透一个强大算法模型,层次聚类!!

基本概念

首先,层次聚类是一种常用的聚类方法,用于将数据分成不同的组或簇。

这个方法的核心思想是:根据数据之间的相似度来构建一个“层次结构”,逐步将数据进行合并或拆分,直到得到最终的聚类结果。

下面,看看基本的步骤:

  1. 起点:开始时,把每一个数据点当作一个独立的簇,每个簇里面只有一个数据点。
  2. 计算相似度:计算每对簇之间的相似度或距离。相似度可以通过各种方法计算,比如欧几里得距离、曼哈顿距离等。
  3. 合并最近的簇:找到距离最近的两个簇,把它们合并成一个新的簇。
  4. 更新相似度矩阵:更新簇之间的相似度或距离,因为合并了新的簇,所以需要重新计算新簇与其他簇之间的相似度。
  5. 重复步骤3和4:不断重复合并最近的簇,直到所有数据点最终合并成一个大簇,或者达到预定的停止条件(比如得到指定数量的簇)。

层次聚类主要分为两种类型:

  1. 自底向上(凝聚层次聚类):从每个数据点开始,每一步合并两个最相似的簇,直到所有数据点被合并到一个簇中。
  2. 自顶向下(分裂层次聚类):从所有数据点开始,每一步拆分一个簇成两个最不相似的簇,直到每个数据点成为一个独立的簇。

理论基础

层次聚类是一种无监督学习方法,其目的是根据数据点之间的相似性将数据划分成层次结构的簇。

基本概念

距离度量:计算数据点之间的相似性,常用的度量有欧几里得距离、曼哈顿距离等。

对于两个数据点  和  ,欧几里得距离为:

其中,  是数据的维度。

簇之间的距离:常用的簇间距离度量方法有单链法、全链法、平均链法和中心点法等。

  • 单链法(最小距离)

全链法(最大距离)

平均链法(平均距离)

中心点法(簇中心距离)

其中,  和  分别是簇  和  的中心点。

算法流程

层次聚类的过程可以分为自底向上(凝聚层次聚类)和自顶向下(分裂层次聚类)两种。

下面,咱们主要介绍凝聚层次聚类的算法流程。

  1. 初始化
  • 将每个数据点视为一个独立的簇,形成  个簇, 。
  1. 计算距离矩阵
  • 计算所有簇之间的距离,形成距离矩阵 ,其中  表示簇  和  之间的距离。
  1. 合并最近的簇
  • 找到距离最近的两个簇  和 ,即找到  使得 。
  • 合并  和  成为一个新的簇 ,更新簇集合 。
  1. 更新距离矩阵
  • 计算新簇  与其他所有簇之间的距离,更新距离矩阵 。
  • 对于中心点法,更新公式为:
  • 对于平均链法,更新公式为:
  • 对于全链法,更新公式为:
  • 对于单链法,更新公式为:
  • 然后计算  与其他簇中心点的距离。
  1. 重复步骤3和4
  • 重复合并最近的簇并更新距离矩阵的过程,直到簇的数量减少到预定的值 ,或者所有数据点合并成一个簇。

数学推理

为了保证层次聚类算法能够有效地进行,需要证明以下几点:

  1. 距离矩阵的对称性:距离矩阵  是对称的,即 。这是因为距离度量满足对称性。
  2. 距离的非负性:距离矩阵  中的所有值都是非负的,即 。这是因为距离度量满足非负性。
  3. 合并操作的单调性:每次合并操作后,新簇的距离不会小于之前的最小距离。以单链法为例,合并操作后的新簇与其他簇之间的距离为:

因此,新簇的距离不会比原来的最小距离更小。

通过以上数学推理和算法流程,层次聚类算法能够有效地将数据点分成层次结构的簇,可以帮助大家理解数据的内在结构和分布。

Python案例

下面的案例,咱们使用一个真实的数据集,大家可以直接使用api获取。

使用来自 UCI 机器学习库的“葡萄酒数据集”(Wine Dataset),该数据集包含了 178 种葡萄酒的 13 个化学特征,目标是通过层次聚类来分析这些葡萄酒的分组情况。

我们将包括以下步骤:

  1. 数据集导入和预处理
  2. 使用层次聚类进行聚类分析
  3. 聚类结果的可视化
  4. 算法优化

1. 数据集导入和预处理

首先,我们需要导入数据集并做一定的预处理。

import pandas as pd
from sklearn.datasets import load_wine
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import seaborn as sns

# 加载数据集
data = load_wine()
df = pd.DataFrame(data.data, columns=data.feature_names)

# 数据标准化
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df)

2. 使用层次聚类进行聚类分析

我们使用 scipy 库中的 linkage 和 dendrogram 函数进行层次聚类分析,并绘制树状图。

from scipy.cluster.hierarchy import linkage, dendrogram

# 使用欧几里得距离和沃德方法进行层次聚类
Z = linkage(df_scaled, method='ward')

# 绘制树状图
plt.figure(figsize=(12, 8))
dendrogram(Z, labels=data.target, leaf_rotation=90, leaf_font_size=10)
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('Sample index')
plt.ylabel('Distance')
plt.show()

3. 聚类结果的可视化

为了更好地理解聚类结果,我们可以将数据降维至二维,并用不同的颜色表示不同的簇。

from sklearn.decomposition import PCA
from scipy.cluster.hierarchy import fcluster

# 使用PCA将数据降维到二维
pca = PCA(n_components=2)
df_pca = pca.fit_transform(df_scaled)

# 从树状图中选择一个合适的阈值,划分簇
max_d = 7.0 # 这个阈值需要根据树状图手动调整
clusters = fcluster(Z, max_d, criterion='distance')

# 绘制二维降维后的聚类结果
plt.figure(figsize=(10, 8))
plt.scatter(df_pca[:, 0], df_pca[:, 1], c=clusters, cmap='rainbow', alpha=0.7)
plt.title('Hierarchical Clustering of Wine Dataset (2D PCA)')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.show()

4. 算法优化

我们可以通过调整距离度量方法、合并策略等来优化算法。这里我们展示如何使用不同的合并策略进行层次聚类。

# 使用不同的合并策略进行层次聚类
methods = ['single', 'complete', 'average', 'ward']
plt.figure(figsize=(20, 15))

for i, method in enumerate(methods, 1):
Z = linkage(df_scaled, method=method)
plt.subplot(2, 2, i)
dendrogram(Z, labels=data.target, leaf_rotation=90, leaf_font_size=10)
plt.title(f'Linkage Method: {method.capitalize()}')
plt.xlabel('Sample index')
plt.ylabel('Distance')

plt.tight_layout()
plt.show()

通过比较不同的合并策略的树状图,我们可以选择最适合当前数据集的策略。

总结如下:

  1. 数据标准化:在聚类前标准化数据有助于消除不同特征量纲之间的影响。
  2. 降维:使用PCA将数据降维至二维,有助于可视化和理解高维数据的聚类结果。
  3. 树状图(Dendrogram):通过观察树状图,可以确定合适的阈值来划分簇。
  4. 合并策略比较:通过比较不同的合并策略,可以选择最适合的数据集的策略,提高聚类效果。

整个的这些步骤展示了如何使用层次聚类进行数据分析,大家可以通过可视化和算法优化提升结果的理解和效果。

模型分析

层次聚类模型的优缺点

优点

  1. 直观易懂:层次聚类生成的树状图(dendrogram)可以清晰地展示数据的层次结构,直观且易于理解。
  2. 无需预先指定簇的数量:与K均值聚类不同,层次聚类不需要预先指定簇的数量,适合于不确定簇数的情况。
  3. 适用于任意形状的簇:层次聚类可以处理形状复杂的簇,而K均值聚类更适合球形簇。
  4. 数据处理能力:层次聚类能处理小到中等规模的数据集,适用于一些小样本但高维的数据集。

缺点

  1. 计算复杂度高:层次聚类的计算复杂度较高,通常为 ,对大规模数据集不太适用。
  2. 对噪声和离群点敏感:噪声和离群点可能会影响聚类结果,导致聚类质量下降。
  3. 一旦合并无法撤销:层次聚类一旦合并两个簇,无法进行拆分,容易在早期步骤中产生错误。

与相似算法的对比

K均值聚类(K-means Clustering)

  • 优点
    • 计算速度快,适用于大规模数据集。
    • 算法简单,容易实现和理解。
  • 缺点
    • 需要预先指定簇的数量 。
    • 对初始中心点选择敏感,容易陷入局部最优。
    • 适用于球形簇,不适合复杂形状的簇。

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)

  • 优点
    • 可以发现任意形状的簇。
    • 自动识别噪声点,不需要预先指定簇的数量。
  • 缺点
    • 对参数敏感(如eps和min_samples)。
    • 不适合高维数据集,计算复杂度较高。

适用场景

层次聚类的优选场景

  1. 数据规模适中:适用于小到中等规模的数据集,数据点数量在几百到几千之间。
  2. 簇数不确定:适用于不确定簇的数量,需要通过观察树状图来确定聚类结构。
  3. 数据结构层次化:适用于数据具有明显的层次结构的场景,如生物分类、社会网络分析等。

其他算法的优选场景

  1. 大规模数据集:对于大规模数据集,K均值聚类和MiniBatch K均值聚类更为适用,因为它们计算速度快且效率高。
  2. 复杂形状的簇:当数据集中的簇形状复杂且包含噪声点时,DBSCAN算法更为适用,因为它能够识别任意形状的簇并自动处理噪声点。
  3. 高维数据集:对于高维数据集,谱聚类(Spectral Clustering)可能更为适用,因为它通过图论方法处理数据,能更好地捕捉高维空间中的数据结构。

最后

层次聚类在处理中小规模且具有层次结构的数据集时非常有效,特别是当不确定簇的数量时。然而,在大规模数据集或具有复杂形状簇的情况下,其他算法如K均值聚类或DBSCAN可能更为适用。通过根据数据集的特性和具体需求选择合适的聚类算法,可以更好地实现数据聚类和分析目标。

本文章转载微信公众号@深夜努力写Python