geo*_*ncl 34 python dendrogram scipy
我已经编写了自己的聚类程序,并希望生成一个树形图.最简单的方法是使用scipy树形图函数.但是,这要求输入的格式与scipy linkage函数产生的格式相同.我找不到如何格式化输出的示例.我想知道是否有人可以启发我.
dka*_*kar 35
这是来自scipy.cluster.hierarchy.linkage()函数文档,我认为这是对输出格式的一个非常清晰的描述:
返回A(n -1)×4矩阵Z. 在第i次迭代中,具有索引Z [i,0]和Z [i,1]的聚类被组合以形成聚类n + i.索引小于n的聚类对应于原始观察之一.簇Z [i,0]和Z [i,1]之间的距离由Z [i,2]给出.第四个值Z [i,3]表示新形成的簇中的原始观察的数量.
你还需要更多东西吗?
use*_*472 23
我同意/sf/users/81723281/该文件并不能完全解释中间簇索引,虽然我与同意/sf/users/94839111/的否则精确解释格式.
使用此问题的示例数据: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]])
Run Code Online (Sandbox Code Playgroud)
可以使用单个(即,最接近的匹配点)构建链接矩阵:
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. ]])
Run Code Online (Sandbox Code Playgroud)
正如文档解释的那样,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
Run Code Online (Sandbox Code Playgroud)
该集群现在应该是中间集群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
Run Code Online (Sandbox Code Playgroud)
其中,可以看出也检查出来,并解释了新集群的中间格式.
小智 10
dkar指出,scipy文档准确无误......但将返回的数据转换为可用于进一步分析的内容有点困难.
在我看来,它们应该包括在数据结构树中返回数据的能力.下面的代码将遍历矩阵并构建一个树:
from scipy.cluster.hierarchy import linkage
import numpy as np
a = np.random.multivariate_normal([10, 0], [[3, 1], [1, 4]], size=[100,])
b = np.random.multivariate_normal([0, 20], [[3, 1], [1, 4]], size=[50,])
centers = np.concatenate((a, b),)
def create_tree(centers):
clusters = {}
to_merge = linkage(centers, method='single')
for i, merge in enumerate(to_merge):
if merge[0] <= len(to_merge):
# if it is an original point read it from the centers array
a = centers[int(merge[0]) - 1]
else:
# other wise read the cluster that has been created
a = clusters[int(merge[0])]
if merge[1] <= len(to_merge):
b = centers[int(merge[1]) - 1]
else:
b = clusters[int(merge[1])]
# the clusters are 1-indexed by scipy
clusters[1 + i + len(to_merge)] = {
'children' : [a, b]
}
# ^ you could optionally store other info here (e.g distances)
return clusters
print create_tree(centers)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18881 次 |
| 最近记录: |