Python获取聚类数据-层次聚类
我用下面的Python脚本做了层次聚类,并打印出了树状图。请注意,我对数据挖掘还很陌生。
import numpy as np
import distance
import scipy.cluster.hierarchy
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage
mat = np.array([[ 0. , 1. , 3. ,0. ,2. ,3. ,1.],
[ 1. , 0. , 3. , 1., 1. , 2. , 2.],
[ 3., 3. , 0., 3. , 3., 3. , 4.],
[ 0. , 1. , 3., 0. , 2. , 3., 1.],
[ 2. , 1., 3. , 2., 0. , 1., 3.],
[ 3. , 2., 3. , 3. , 1. , 0. , 3.],
[ 1. , 2., 4. , 1. , 3., 3. , 0.]])
linkage_matrix = linkage(mat, "single")
dendrogram(linkage_matrix,
color_threshold=1,
truncate_mode='lastp',
distance_sort='ascending')
plt.show()
下面是我得到的树状图。我想打印出每个聚类以及属于每个聚类的数据,应该怎么做呢?
cluster1 4,5
cluster2 ..,..
cluster3 ..,..
1 个回答
3
根据 scipy.cluster.hierarchy
的文档
(通过运行 linkage...)会返回一个 4 行 (n-1) 列的矩阵 Z。在第 i 次迭代中,索引为 Z[i, 0] 和 Z[i, 1] 的聚类会被合并成一个新的聚类 n + i。索引小于 n 的聚类对应于 n 个原始观测值中的一个。Z[i, 2] 给出了聚类 Z[i, 0] 和 Z[i, 1] 之间的距离。第四个值 Z[i, 3] 表示新形成的聚类中包含的原始观测值的数量。
这意味着,我们可以遍历 linkage_matrix
,找到实际合并形成新聚类的节点。下面是一个简单的 for 循环来实现这个功能
n = len(mat)
cluster_dict = dict()
for i in range(0, 6):
new_cluster_id = n+i
old_cluster_id_0 = linkage_matrix[i, 0]
old_cluster_id_1 = linkage_matrix[i, 1]
combined_ids = list()
if old_cluster_id_0 in cluster_dict:
combined_ids += cluster_dict[old_cluster_id_0]
del cluster_dict[old_cluster_id_0]
else:
combined_ids += [old_cluster_id_0]
if old_cluster_id_1 in cluster_dict:
combined_ids += cluster_dict[old_cluster_id_1]
del cluster_dict[old_cluster_id_1]
else:
combined_ids += [old_cluster_id_1]
cluster_dict[new_cluster_id] = combined_ids
print cluster_dict
这段代码创建了一个字典,用于存储聚类 ID 和该聚类中包含的节点。在每次迭代中,它将 linkage_matrix[i, 0]
和 linkage_matrix[i, 1]
中的两个节点合并成一个新节点。最后,它会打印出每次迭代中正在运行的聚类。输出结果是
{7: [0.0, 3.0]}
{8: [4.0, 5.0], 7: [0.0, 3.0]}
{8: [4.0, 5.0], 9: [6.0, 0.0, 3.0]}
{8: [4.0, 5.0], 10: [1.0, 6.0, 0.0, 3.0]}
{11: [4.0, 5.0, 1.0, 6.0, 0.0, 3.0]}
{12: [2.0, 4.0, 5.0, 1.0, 6.0, 0.0, 3.0]}
(聚类 ID 从 7 开始,原始行的索引是 0 到 6)。注意,字典中没有的 ID 会形成自己的聚类。例如,行 2.0
在第 2 次迭代中形成了自己的聚类。你可以根据自己的停止标准,提前停止,从而得到最终的聚类集合。
我可以在第 3 次迭代时停止(输出的第 3 行),然后我的聚类将是:
cluster 8: {4, 5}
cluster 9: {6, 0, 3}
cluster 1: {1}
cluster 2: {2}