当前位置: 首页 > article >正文

层次聚类构建层次结构的簇

层次聚类(Hierarchical Clustering)可以通过自定义函数来完成。层次聚类可以分为两种方法:凝聚型(Agglomerative)和分裂型(Divisive)。这里主要介绍一种常用的凝聚型方法,它是自底向上的方法,逐步合并最近的簇,直到达到预定的簇数量或者所有数据点合并成一个簇。

可以使用距离度量来衡量不同簇之间的相似性(例如欧氏距离),并通过最短距离来决定哪些簇合并。最终,我们将通过构建一个层次结构树(Dendrogram)来表示这种簇的合并过程。

层次聚类的步骤:

  1. 初始化:将每个数据点视为一个单独的簇。
  2. 计算距离矩阵:计算各簇之间的距离。
  3. 合并簇:选择最相似(最小距离)的簇进行合并。
  4. 更新距离矩阵:合并簇后重新计算距离矩阵。
  5. 重复步骤 3 和 4,直到只剩下一个簇或达到预定的簇数量。

例子代码:

import torch
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, squareform
from scipy.cluster.hierarchy import dendrogram, linkage


# 计算簇之间的距离(欧氏距离)
def compute_distance_matrix(X):
    return squareform(pdist(X, 'euclidean'))


# 凝聚型层次聚类
def agglomerative_clustering(X, num_clusters=1):
    # 初始每个点为一个簇
    clusters = [[i] for i in range(X.shape[0])]

    # 计算初始距离矩阵
    dist_matrix = compute_distance_matrix(X)

    # 逐步合并簇直到达到预定的簇数
    while len(clusters) > num_clusters:
        # 找到距离最小的簇对
        min_dist_idx = np.unravel_index(np.argmin(dist_matrix + np.eye(len(dist_matrix)) * np.inf), dist_matrix.shape)
        i, j = min_dist_idx

        # 合并这两个簇
        new_cluster = clusters[i] + clusters[j]

        # 删除旧簇
        if i > j:
            clusters.pop(i)
            clusters.pop(j)
        else:
            clusters.pop(j)
            clusters.pop(i)

        # 更新距离矩阵
        # 计算新簇与所有其他簇的距离
        new_distances = []
        for k in range(len(dist_matrix)):
            if k != i and k != j:
                dist_i = dist_matrix[k][i] if k < i else dist_matrix[k][i - 1]
                dist_j = dist_matrix[k][j] if k < j else dist_matrix[k][j - 1]
                new_distances.append(min(dist_i, dist_j))

        new_distances = np.array(new_distances)

        # 生成新的距离矩阵
        dist_matrix = np.delete(dist_matrix, [i, j], axis=0)
        dist_matrix = np.delete(dist_matrix, [i, j], axis=1)

        # 在 dist_matrix 的末尾添加新簇的距离
        dist_matrix = np.vstack([dist_matrix, new_distances])  # 添加新行
        new_distances = np.append(new_distances, 0)  # 为了和列对齐,添加最后一列
        dist_matrix = np.column_stack([dist_matrix, new_distances])  # 添加新列

        # 打印当前簇的数量
        print(f'当前簇数量:{len(clusters)}')
        print(f'簇结构:{clusters}')

    return clusters


# 生成更多的示例数据:50个二维数据点
np.random.seed(42)
X_np = np.random.rand(50, 2) * 10  # 50个数据点,数据范围在[0, 10]

# 聚类成5个簇
num_clusters = 5
clusters = agglomerative_clustering(X_np, num_clusters=num_clusters)

# 将每个数据点分配到对应的簇
labels = np.zeros(X_np.shape[0])
for idx, cluster in enumerate(clusters):
    for i in cluster:
        labels[i] = idx

# 可视化结果
plt.figure(figsize=(8, 6))

# 按照簇分配颜色
for cluster_idx in range(num_clusters):
    cluster_points = X_np[labels == cluster_idx]  # 使用 NumPy 数组进行索引
    plt.scatter(cluster_points[:, 0], cluster_points[:, 1], label=f"Cluster {cluster_idx + 1}")

plt.title(f'Agglomerative Clustering with {num_clusters} Clusters')
plt.xlabel('X1')
plt.ylabel('X2')
plt.legend()
plt.show()

# 画出层次聚类树状图
linked = linkage(X_np, 'ward')

plt.figure(figsize=(10, 7))
dendrogram(linked)
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('Sample Index')
plt.ylabel('Distance')
plt.show()


http://www.kler.cn/a/525435.html

相关文章:

  • 基于Python的人工智能患者风险评估预测模型构建与应用研究(下)
  • Git图形化工具【lazygit】
  • Vuex中的getter和mutation有什么区别
  • 大一计算机的自学总结:异或运算
  • 分享| RL-GPT 框架通过慢agent和快agent结合提高AI解决复杂任务的能力-Arxiv
  • 项目部署(springboot项目)
  • 智能工厂能耗管理:Python助力节能增效
  • 真正的智能与那只蝴蝶
  • 后盾人JS--闭包明明白白
  • 人工智能 - 1
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.21 索引宗师:布尔索引的七重境界
  • sem_init的概念和使用案例
  • ollama的setup.exe和ollama-windows-amd64.zip区别
  • 网易有道开源 “子曰 - o1” 推理模型
  • Python动量策略实战:大幅跑赢市场的底层逻辑
  • 跑腿小程序/智能派单/系统派单/同城配送/校园跑腿/预约取件/用户端+骑手端【全开源】
  • 多线程进阶(一命通关)
  • 抠图神器,全离线使用,支持win和mac
  • github制作静态网页
  • 高精度算法:高精度减法
  • 【C++动态规划 状态压缩】2597. 美丽子集的数目|2033
  • 单细胞-第五节 多样本数据分析,打分R包AUCell
  • 简单聊聊“DeepSeek”
  • 【设计测试用例自动化测试性能测试 实战篇】
  • 2.3.1 基本数据类型
  • 获取snmp oid的小方法1(随手记)