我编写了自己的聚类程序,想要生成树形图。最简单的方法是使用scipy树形图函数。但是,这要求输入的格式与scipy linkage函数产生的格式相同。我找不到如何格式化输出的示例。我想知道是否有人可以启发我。
答案 0 :(得分:30)
这是来自scipy.cluster.hierarchy.linkage()函数文档,我认为这是对输出格式的一个非常清晰的描述:
返回4(矩阵Z)的A( n -1)。在 i -th迭代中,具有索引Z [i,0]和Z [i,1]的聚类被组合以形成聚类 n + i 。索引小于 n 的聚类对应于原始观察之一。簇Z [i,0]和Z [i,1]之间的距离由Z [i,2]给出。第四个值Z [i,3]表示新形成的聚类中的原始观测数。
你还需要更多东西吗?
答案 1 :(得分:17)
我同意https://stackoverflow.com/users/1167475/mortonjt文档没有完全解释中间集群的索引,而我同意https://stackoverflow.com/users/1354844/dkar该格式是否经过精确解释。
使用此问题的示例数据:Tutorial for scipy.cluster.hierarchy
A = np.array([[0.1, 2.5],
[1.5, .4 ],
[0.3, 1 ],
[1 , .8 ],
[0.5, 0 ],
[0 , 0.5],
[0.5, 0.5],
[2.7, 2 ],
[2.2, 3.1],
[3 , 2 ],
[3.2, 1.3]])
可以使用单个(即最接近的匹配点)构建链接矩阵:
z = hac.linkage(a, method="single")
array([[ 7. , 9. , 0.3 , 2. ],
[ 4. , 6. , 0.5 , 2. ],
[ 5. , 12. , 0.5 , 3. ],
[ 2. , 13. , 0.53851648, 4. ],
[ 3. , 14. , 0.58309519, 5. ],
[ 1. , 15. , 0.64031242, 6. ],
[ 10. , 11. , 0.72801099, 3. ],
[ 8. , 17. , 1.2083046 , 4. ],
[ 0. , 16. , 1.5132746 , 7. ],
[ 18. , 19. , 1.92353841, 11. ]])
正如文档解释的那样,n下面的聚类(这里:11)只是原始矩阵A中的数据点。中间聚类前进,连续编入索引。
因此,集群7和9(第一次合并)合并到集群11中,集群4和6合并为12.然后观察第三行,合并集群5(来自A)和12(来自未示出的中间集群12) )群内距离(WCD)为0.5。单一方法需要新的WCS为0.5,即A [5]与簇12中最近点A [4]和A [6]之间的距离。我们来看看:
In [198]: norm([a[5]-a[4]])
Out[198]: 0.70710678118654757
In [199]: norm([a[5]-a[6]])
Out[199]: 0.5
此群集现在应该是中间群集13,随后与A [2]合并。因此,新距离应该是点A [2]和A [4,5,6]之间最接近的。
In [200]: norm([a[2]-a[4]])
Out[200]: 1.019803902718557
In [201]: norm([a[2]-a[5]])
Out[201]: 0.58309518948452999
In [202]: norm([a[2]-a[6]])
Out[202]: 0.53851648071345048
其中,可以看出也检查出来,并解释了新集群的中间格式。
答案 2 :(得分:8)
scipy文档是准确的,因为dkar指出......但是将返回的数据转换为可用于进一步分析的内容有点困难。
在我看来,他们应该包括在数据结构树中返回数据的能力。下面的代码将遍历矩阵并构建一个树:
performUpdatesAnimated
答案 3 :(得分:0)
这是另一段执行相同功能的代码。此版本跟踪每个群集(node_id)的距离(大小),并确认成员数。
这使用了scipy links()函数,该函数与聚合器群集器的基础相同。
from scipy.cluster.hierarchy import linkage
import copy
Z = linkage(data_x, 'ward')
n_points = data_x.shape[0]
clusters = [dict(node_id=i, left=i, right=i, members=[i], distance=0, log_distance=0, n_members=1) for i in range(n_points)]
for z_i in range(Z.shape[0]):
row = Z[z_i]
cluster = dict(node_id=z_i + n_points, left=int(row[0]), right=int(row[1]), members=[], log_distance=np.log(row[2]), distance=row[2], n_members=int(row[3]))
cluster["members"].extend(copy.deepcopy(members[cluster["left"]]))
cluster["members"].extend(copy.deepcopy(members[cluster["right"]]))
clusters.append(cluster)
on_split = {c["node_id"]: [c["left"], c["right"]] for c in clusters}
up_merge = {c["left"]: {"into": c["node_id"], "with": c["right"]} for c in clusters}
up_merge.update({c["right"]: {"into": c["node_id"], "with": c["left"]} for c in clusters})