Python:层次聚类(凝聚型-----自下而上)手工实现

目标:获取数据集的 关联矩阵

获取关联矩阵是 层次聚类算法 的核心内容

配有调包对比       

中文网站  找不到一个像样的 层次聚类 手写代码。给大家做个开头!

使用了两个字典存储聚类结果

 

from itertools import combinations,product
from scipy.spatial.distance import pdist,squareform
from scipy.cluster.hierarchy import linkage
from collections import OrderedDict
import numpy as np
'''构造数据'''
np.random.seed(100)
data = np.random.random_sample((5,3))*10  #生成数据
# print(data)
'''获取距离矩阵'''
dist_Matrix = squareform(pdist(data,metric='euclidean'))  #原始数据的距离矩阵
'''获取距离矩阵的距离矩阵'''                              #不要问为什么,我也不知道。只知道这么干样本之间的距离度量值更大。
dist_Matrix_Vector = pdist(dist_Matrix,metric='euclidean')  #距离矩阵的压缩距离矩阵,其实是个距离列表
dist_Matrix_Matrix = squareform(dist_Matrix_Vector)
n = int(np.ceil((dist_Matrix_Vector.size * 2)**0.5))   #获取样本个数
indexes = combinations(range(n),2)      #获取样本之间的两两组合,其实是压缩距离矩阵的索引
##################------------------##############################
'''初始化一个有序字典,用于存储类簇对和类簇对之间的距离'''
clusters = OrderedDict()   #用于存储类簇索引和类簇对应的样本子集,key 为int类型是类簇标号,value是list类型来存储类簇样本
initial_clusters = OrderedDict() #初始距离矩阵
for idx,ids in zip(indexes,dist_Matrix_Vector):      #初始化时每个样本形成一个类簇
    clusters[idx] = ids   #字典repository的key是类簇的name,随着算法迭代的更新会不断增加
    # initial_clusters[idx] = ids
'''初始化一个有序字典,用于存储类簇索引和类簇对应的样本子集'''
repository = OrderedDict() # 用于存储类簇对和类簇对之间的距离,key为元组类簇组合,value是相应类簇对儿的距离single linkage
for idx in range(n):  #每个类簇对儿对应一个距离值
    repository[idx] = [idx]
#################-----------------###############################
output = []
while len(clusters)>0:
    #获取最小类簇对儿
    mini_cluster_pairs = min(clusters.items(),key=lambda x:x[1])
    a,b = mini_cluster_pairs[0]
    d = mini_cluster_pairs[1]
    length = len(repository[a] + repository[b])
    output.append([a,b,d,length])
    #然后就是更新repository,需要添加一个新类簇,删除两个旧类簇
    idx,ids = max(repository.items(),key= lambda x:x[0])
    idx += 1
    # print(idx)
    repository[idx] = repository[a] + repository[b]
    repository.pop(a)
    repository.pop(b)
    #然后是更新类簇对儿距离字典
    current_clusters_Comb = combinations(repository.keys(), 2)
    clusters.clear()
    for ele in current_clusters_Comb:
        dikarji = product(repository[ele[0]], repository[ele[1]])  # 类簇对儿ele中的样本组合
        sub_cluster = OrderedDict()
        for item in dikarji:
            a,b = item
            sub_cluster[item] = dist_Matrix_Matrix[a,b]
        mini_dist_cluster, mini_dist_cluster_value = min(sub_cluster.items(), key=lambda x: x[1])
        clusters[ele] = mini_dist_cluster_value

print('手工结果:\n',np.array(output))
print('调包结果:\n',linkage(dist_Matrix,method='single',metric='euclidean'))

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeniuHe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值