最强聚类模型,层次聚类 !!

最强聚类模型,层次聚类 !!哈喽 我是小白 咱们今天聊聊层次聚类 这种聚类方法在后面的使用 也是非常频繁的 首先 聚类很好理解 聚类 Clustering 就是把一堆 东西 自动分组 这些 东西 可以是人 物品 图像 文本 客户等等

大家好,欢迎来到IT知识分享网。

哈喽,我是小白~

咱们今天聊聊层次聚类,这种聚类方法在后面的使用,也是非常频繁的~

首先,聚类很好理解, 聚类(Clustering)就是把一堆“东西”自动分组

这些“东西”可以是人、物品、图像、文本、客户等等。

分组是 让相似的归在一组,不相似的分开

核心干货,文末领取


层次聚类

层次聚类就是: 一步一步地合并(或拆分)小组,最后形成一个“层次结构” ,像一棵树一样。

有两种方式:

  1. 自底向上(常见)
    :一开始每个点都是一个小组,然后
    两两合并最像的组
    ,一直合并,直到只剩一个大组。
  2. 自顶向下(不常用)
    :一开始是一个大组,不断拆分。

类比解释

假设有 6 个小朋友,他们身高如下(单位:cm):

小朋友
身高
A
100
B
102
C
105
D
160
E
162
F
165

你不知道他们属于哪个年级,但你怀疑:他们应该可以分成“低年级”和“高年级”。

怎么做层次聚类?

第一步:先把他们看成 6 个独立的组:

A   B   C   D   E   F

第二步:找“最像”的两个小朋友(距离最小的)

他们的“相似度”可以用“身高差”来表示:

最小的是 AB 和 DE,都是距离 2。

我们先合并 AB,变成一个新组(叫 AB),然后重新计算“组与其他人”的距离。

第三步:继续合并(演示部分)

现在的组是:

[AB]  C   D   E   F

我们假设用“组的平均值”代表组的身高:

再计算距离:

现在是:

[AB]   C   [DE]   F

继续:

我们可以任选一个合并,比如 AB 和 C → ABC,平均身高 = (100+102+105)/3 = 102.3

最后也会合并 DE 和 F → DEF,平均身高 = (160+162+165)/3 ≈ 162.3

最终变成:

[ABC]   [DEF]

你看到没有?我们 成功把6个小朋友分成了两组:一个是100多身高,一个是160多身高的!

公式解析

我们有一个数据集 ,其中每个数据点 是一个 -维向量。

聚类的目标是把这 个样本划分成 个组(簇,cluster),使得:

这种“相似”通常用 距离函数 衡量。

核心思想:从每个点一个簇开始(共有 个簇),找出两个“最近”的簇,合并成一个新簇;重复,直到只剩一个簇(或满足停止条件)

这个过程会生成一个 嵌套的层级结构(树) ,称为 树状图

常用的距离度量公式

数据点之间的距离(欧几里得距离):

对于两个点


也可以用曼哈顿距离、余弦相似度等。

簇之间的距离计算

层次聚类中,两个簇之间的“距离”可以有不同的定义方式。

最重要最常见的是 4种经典的 Linkage 方法

1. 单链接(Single Linkage)

定义两个簇 之间的距离为:


也就是两个簇中 最近的两个点 之间的距离。

2. 全链接(Complete Linkage)

定义两个簇 之间的距离为:


两个簇中 最远的两个点 之间的距离。

3. 平均链接(Average Linkage)


两个簇中 所有点对的平均距离

4. 重心法(Centroid Linkage)

先计算簇的 重心(中心) ,再比较两个重心之间的距离:

是簇 的重心:


那么:


推导例子

让我们再用前面的数据:

样本
身高(1D)
A
100
B
102
C
105
D
160
E
162
F
165

欧几里得距离为:

( 因 是 )


初始簇:


使用单链接(Single Linkage)

计算最小距离:

最小是 ,合并成

现在:


再计算所有距离,使用 single linkage:

再继续……直到你达到目标簇数。

完整案例

基于上面的小朋友身高示例,生成一个稍微复杂的合成数据集,模拟两类人群(儿童与成年人)在四个维度(身高 Height、体重 Weight、年龄 Age、收入 Income)上的分布,使用平均链接的层次聚类方法进行分析~

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import linkage, dendrogram, fcluster
from scipy.spatial.distance import pdist, squareform
from sklearn.metrics import silhouette_samples, silhouette_score

# 1. 生成合成数据:基于“小朋友”和“成年人”两个簇
np.random.seed(42)
# “小朋友”簇
children_height = np.random.normal(120525)
children_weight = children_height * 0.45 + np.random.normal(0325)
children_age = np.random.normal(10225)
children_income = np.random.normal(501025)
# “成年人”簇
adult_height = np.random.normal(170525)
adult_weight = adult_height * 0.5 + np.random.normal(0525)
adult_age = np.random.normal(35525)
adult_income = np.random.normal(2005025)

# 合并到 DataFrame
data = pd.DataFrame({
    'Height': np.concatenate([children_height, adult_height]),
    'Weight': np.concatenate([children_weight, adult_weight]),
    'Age': np.concatenate([children_age, adult_age]),
    'Income': np.concatenate([children_income, adult_income])
})

# 2. 计算欧氏距离矩阵
dist_matrix = pdist(data.values, metric='euclidean')

# 3. 进行层次聚类(平均链接)
Z = linkage(dist_matrix, method='average')

# 4. 绘制树状图(Dendrogram)
plt.figure(figsize=(105))
dendrogram(Z, leaf_rotation=90)
plt.title('Figure 1: Hierarchical Clustering Dendrogram')
plt.xlabel('Sample Index')
plt.ylabel('Distance')
plt.tight_layout()

# 5. 绘制距离矩阵热图
plt.figure(figsize=(86))
dm = squareform(dist_matrix)
plt.imshow(dm, aspect='auto', origin='lower')
plt.title('Figure 2: Distance Matrix Heatmap')
plt.xlabel('Sample Index')
plt.ylabel('Sample Index')
plt.colorbar(label='Euclidean Distance')
plt.tight_layout()

# 6. 根据距离阈值截断,获取簇标签
max_d = 30  # 根据树状图设定
clusters = fcluster(Z, max_d, criterion='distance')

# 7. 绘制 Height vs Weight 散点图,标记簇
plt.figure(figsize=(86))
plt.scatter(data['Height'], data['Weight'], c=clusters)
plt.title('Figure 3: Height vs Weight Clustering')
plt.xlabel('Height (cm)')
plt.ylabel('Weight (kg)')
plt.tight_layout()

# 8. 轮廓系数(Silhouette)分析
sil_score = silhouette_score(data.values, clusters)
sil_samples = silhouette_samples(data.values, clusters)
plt.figure(figsize=(86))
y_lower = 10
for i in np.unique(clusters):
    ith_silhouette = sil_samples[clusters == i]
    ith_silhouette.sort()
    y_upper = y_lower + len(ith_silhouette)
    plt.fill_betweenx(np.arange(y_lower, y_upper),
                      0, ith_silhouette)
    plt.text(-0.05, y_lower + 0.5 * len(ith_silhouette), str(i))
    y_lower = y_upper + 10
plt.title(f'Figure 4: Silhouette Plot (Score = {sil_score:.2f})')
plt.xlabel('Silhouette Coefficient Values')
plt.ylabel('Cluster Label')
plt.tight_layout()

# 9. 各簇特征分布箱线图
data['Cluster'] = clusters
plt.figure(figsize=(108))
data.boxplot(by='Cluster', layout=(22))
plt.suptitle('Figure 5: Feature Distribution by Cluster')
plt.tight_layout(rect=[00.0310.95])

# 显示所有图形
plt.show()


























































































Figure 1 – Dendrogram(树状图)

最强聚类模型,层次聚类 !!

可以清晰看到:

此图告诉我们左右两侧分别代表两大类群体——高度、体重、年龄、收入都近似的儿童簇与成年人簇。

Figure 2 – Distance Matrix Heatmap(距离矩阵热图)

最强聚类模型,层次聚类 !!

热图以视觉形式强化:跨两大簇的距离远超簇内距离,聚类分界明显。

Figure 3 – Height vs Weight Clustering(身高-体重散点图)

最强聚类模型,层次聚类 !!

二维投影依旧能显著区分簇的分布,并验证 平均链接 在主要特征上表现优秀。

Figure 4 – Silhouette Plot(轮廓系数图)

最强聚类模型,层次聚类 !!

该图量化了簇的内部凝聚力与群间分离度,平均 0.67 属于比较理想的聚类结果。

Figure 5 – Feature Distribution by Cluster(按簇分组特征箱线图)

最强聚类模型,层次聚类 !!

四个子图分别展示 Age、Height、Income、Weight 在不同簇(1/2)下的箱线分布

箱线图直观展现每个特征在两簇间的中位数、四分位距与异常值情况。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/186425.html

(0)
上一篇 2025-08-23 09:10
下一篇 2025-08-23 09:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信