最强聚类算法,层次聚类!!

文摘   2024-11-25 11:26   北京  

哈喽,我是小白~

今儿和大家来聊聊层次聚类的内容~

首先来说,聚类算法是一种无监督学习算法,用于将一组数据按照它们的相似性划分成不同的组(称为“簇”)。它不会依赖预先定义的标签,而是自动根据数据本身的特性发现这些组。

聚类就像把一堆东西分类整理,比如按照颜色、大小、形状把玩具分成不同的篮子。

如果需要本文PDF版本的同学,文末获取~

另外,文末有总结性的干货~

一起来看下具体细化内容~

层次聚类是聚类算法的一种,它会一步步地将数据点聚合到一起,形成一棵“聚类树”(称为树状图,dendrogram)。根据需求,可以在不同的层级选择划分结果。

层次聚类 是什么?

层次聚类有两种主要方式:

1. 凝聚式(自底向上):每个数据点开始作为一个独立的簇,逐步将最近的簇合并,直到只剩一个大簇。 2. 分裂式(自顶向下):从一个大簇开始,将其逐步拆分成更小的簇。

通俗案例:聚餐座位分配

场景:假设你是一家餐馆老板,餐厅里来了6位顾客,他们互相认识的程度(即亲密关系)如下:

  • A和B非常熟(距离=1)
  • A和C有点熟(距离=3)
  • B和C也有点熟(距离=3)
  • A和D不太熟(距离=6)
  • B和D完全不熟(距离=9)
  • 其他两两之间关系如下表:
ABCDEF
A013699
B103999
C330999
D699023
E999201
F999310

目标:把这些人分成若干组,关系更近的坐在一起。

手动示例

1. 初始状态

每个人都是一个独立的簇:

2. 找最近的两个人

从距离矩阵中,找到最近的两个人:

  • A和B之间的距离是1,是最小的。

于是合并成一个簇:

3. 更新距离矩阵

更新簇和其他人的距离。常见方法是最小距离法,即取簇中任意两点的最小距离:

  • 到C:最小距离是3。
  • 到D:最小距离是6。
  • 到E和F:最小距离是9。

更新后的距离矩阵:

{A,B}CDEF
{A,B}03699
C30999
D69023
E99201
F99310

4. 重复步骤

再次寻找最近的两个:

  • E和F的距离是1。

合并成一个簇:

更新距离矩阵:

  • 到D:最小距离是2。

继续:

  • 和C的距离是3。
  • 和D的距离是2。

最终可构造树状图,将人群分成更大的簇直到合并成一个。

总结

层次聚类像是搭积木,根据“距离”逐步合并,最终形成一个分类树。你可以在任何层级“剪开”,得到需要的簇。例如:

  • 剪成2簇:
  • 剪成3簇:

公式解析

层次聚类的核心在于定义簇之间的相似性(或距离),并逐步合并最近的簇。以下是具体推导过程。

1. 问题定义

给定数据集 ,其中 ,我们需要将数据划分成  个簇,使得:

  1. 同簇的数据点尽可能相似。
  2. 不同簇的数据点尽可能不同。

基本目标:通过一系列的合并操作生成一个树状结构(树状图,dendrogram)。

2. 距离的定义

在聚类中,核心是定义两点或两簇之间的距离。常见的距离计算方法包括:

点之间的距离:

  • 欧几里得距离
  • 曼哈顿距离

簇之间的距离:

假设  和  是两个簇,簇中的点集合分别是  和 。常见定义方式有: 1. 最小距离法(Single Linkage)

适合找“紧密连接”的簇。

2. 最大距离法(Complete Linkage)

更强调“整体分离”。

3. 平均距离法(Average Linkage)

考虑两簇之间所有点的平均距离。

4. 质心距离法(Centroid Linkage)

其中,质心 $ \mu_1 = \frac1}{C_1| \sum_{x_i \in C_1} x_i $,质心距离计算较快,但可能不适合非凸形状。

3. 层次聚类算法步骤

输入

数据点集合 ,距离度量 ,簇间距离定义(如最小距离)。

输出

生成的树状图或任意层次的簇划分。

算法流程

1. 初始化: 每个点单独成为一个簇,记为 

2. 计算距离矩阵: 计算所有簇之间的初始距离,构造距离矩阵 ,其中 

3. 合并簇:

  • 找到距离矩阵中最小值对应的簇 
  • 合并  成新簇 
  • 更新距离矩阵:
    • 根据选择的距离度量方式(如最小距离),重新计算 

4. 重复步骤3: 直到簇数量减少到1或达到预期层次。

5. 输出: 生成一棵树状图。

4. 数学公式推导

(1) 距离矩阵更新公式

假设当前簇为 ,合并  后形成新簇 ,剩下的簇为 

新簇  到其他簇  的距离  更新公式取决于距离度量:

  • 最小距离法:
  • 最大距离法:
  • 平均距离法:

(加权平均)。

(2) 复杂度分析

1. 初始距离矩阵计算:

需要计算两两点之间的距离。

2. 合并操作: 在每次合并中更新距离矩阵,涉及  次操作,共  次合并:

因此,层次聚类的时间复杂度为 ,对大规模数据集计算效率较低。

5. 示例推导

输入数据: 

步骤:

1. 初始化距离矩阵(欧几里得距离):

2. 合并最近的点:

  • 合并  和 ,生成新簇 
  • 更新距离矩阵,重复。
  1. 最终生成的树状图可根据需要划分层次。

优缺点和适用场景

优点

1. 可解释性强:层次聚类通过生成树状图(Dendrogram)展现数据的分层结构,直观显示数据的分组关系。便于分析簇的形成过程和相似性。

2. 无需预设簇数量:与 -均值聚类等方法不同,不需要事先指定簇的数量,适用于对未知数据的探索。

3. 适合发现分层结构:如果数据具有自然的层次或嵌套关系(如家族谱系、生物分类),层次聚类可以很好地捕捉这种结构。

4. 对噪声点更鲁棒:相比密度聚类,层次聚类对小规模的噪声点影响较小,尤其是“单链”或“全链”方法。

5. 灵活的距离定义:支持多种簇间距离计算方式(单链、全链、平均等),能够根据任务需求调整方法。

缺点

1. 时间复杂度高:典型的时间复杂度为 ,存储复杂度为 ,对大规模数据不适用。

2. 合并不可逆:一旦将两个点或簇合并,无法撤回。初始合并错误可能影响最终结果。

3. 对距离度量敏感:不同的距离度量方法会显著影响结果,选择不当可能导致误差。

4. 无法处理非凸簇:由于基于距离,层次聚类难以处理非凸形状的簇(如环形、蛇形)。

5. 缺乏中心:层次聚类无法提供簇的“中心”点或代表性样本,不适合用来直接生成摘要信息。

适用场景

  1. 数据量较小(通常 )。
  2. 对数据分层结构或嵌套关系感兴趣。
  3. 无需明确的簇数量,或者簇数量未知。
  4. 数据的特性适合距离度量(如空间分布、生物特性等)。

完整案例

基于市场细分(消费者行为聚类),我们下面来实现具体细节:

1. 生成模拟消费者数据:包含年龄、收入、购买频率等。 2. 应用层次聚类算法:生成聚类结果。 3. 生成两个图形

  • 聚类结果的二维投影(使用PCA降维):通过颜色区分不同的簇。
  • 树状图(Dendrogram):展示层次聚类的分层结构。

代码:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

# 设置随机种子,生成消费者数据
np.random.seed(42)
n_samples = 10000

# 模拟消费者数据:年龄、收入、购买频率
age = np.random.randint(1870, n_samples)
income = np.random.normal(5000015000, n_samples).astype(int)
purchase_frequency = np.random.randint(120, n_samples)

# 创建数据框
data = pd.DataFrame({
    'Age': age,
    'Income': income,
    'PurchaseFrequency': purchase_frequency
})

# 数据标准化
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

# 层次聚类
linkage_matrix = linkage(data_scaled, method='ward')  # Ward方法最常用

# 从层次聚类中提取实际的聚类标签
n_clusters = 5  # 假设分为5个聚类
labels = fcluster(linkage_matrix, t=n_clusters, criterion='maxclust')  # 提取聚类标签

# 图形1: 聚类结果的二维投影
# 使用PCA将数据降维至2D
pca = PCA(n_components=2)
data_pca = pca.fit_transform(data_scaled)

plt.figure(figsize=(128))
plt.scatter(data_pca[:, 0], data_pca[:, 1], c=labels, cmap='Spectral', s=50, alpha=0.7)
plt.title('Cluster Visualization (PCA Projection)', fontsize=18)
plt.xlabel('PCA Component 1', fontsize=12)
plt.ylabel('PCA Component 2', fontsize=12)
plt.colorbar(label='Cluster ID', shrink=0.8)
plt.grid(True)
plt.show()

# 图形2: 树状图(Dendrogram)
plt.figure(figsize=(1610))
dendrogram(linkage_matrix, truncate_mode='lastp', p=10, leaf_rotation=90, leaf_font_size=12, show_contracted=True)
plt.title('Dendrogram for Hierarchical Clustering', fontsize=18)
plt.xlabel('Cluster Size', fontsize=12)
plt.ylabel('Distance (Ward\'s Method)', fontsize=12)
plt.show()

PCA投影后的聚类结果:数据被降维至二维平面,使用颜色标识不同簇。图中展示了层次聚类的分组效果。

树状图(Dendrogram):展示了层次聚类的分层结构,显示不同簇的合并过程。可以通过剪切树状图来决定分组数量。


最后

以上就是今天所有的内容了。
获取本文PDF,点击名片回复「基础算法模型」即可~
 
另外, 我们整理了机器学习算法册子,总共16大块的内容,124个问题的总结点击领取!
如果对你来说比较有用,记得点赞、转发,收藏起来慢慢学习~
下期会有更多干货等着你!~

Python和机器学习初学者
Python和机器学习分享,只写干货,一起学习~
 最新文章