将距离矩阵可视化为图形

Posted

技术标签:

【中文标题】将距离矩阵可视化为图形【英文标题】:Visualize distance matrix as a graph 【发布时间】:2013-09-20 08:21:13 【问题描述】:

我正在做一个聚类任务,我有一个距离矩阵。我希望将此距离矩阵可视化为二维图。请让我知道是否有任何方法可以在线或使用 R 或 python 等编程语言进行操作。 我的距离矩阵如下, 我使用了经典的多维缩放功能(在 R 中)并获得了一个 2D 图,如下所示: 但我正在寻找的是一个带有节点和在它们之间运行的加权边的图。

【问题讨论】:

@Anony-Mousse:我尝试了很多答案中提到的东西(比如vida.io,python 代码 sn-ps - 都是徒劳的)。我希望我能让python代码尽快工作。另外,我正在同时做一些阅读(与我的工作有关),所以如果你想让我这么快更新这篇文章/接受答案,那是不可能的。 嗯,MDS 图是一个好的开始。然后添加 Delauney 三角剖分或使用其他启发式方法添加边。 好的,点,我会更新这个问题,当我能够得到边缘。 【参考方案1】:

可能性 1

我假设您需要一个二维图表,其中节点位置之间的距离与您的表格提供的相同

在 python 中,您可以将networkx 用于此类应用程序。一般来说,有很多方法可以做到这一点,记住,它们都只是近似值(因为一般来说,鉴于它们的成对距离,不可能创建点的二维表示)它们是某种应力最小化(或能量-minimization) 近似,试图找到与提供的距离相似的“合理”表示。

作为示例,您可以考虑一个四点示例(应用了正确的离散度量):

     p1 p2 p3 p4
  ---------------
  p1  0  1  1  1
  p2  1  0  1  1
  p3  1  1  0  1
  p4  1  1  1  0

一般来说,绘制实际的“图形”是多余的,因为您已经完全连接了一个(每对节点都已连接),因此仅绘制点就足够了。

Python example

import networkx as nx
import numpy as np
import string

dt = [('len', float)]
A = np.array([(0, 0.3, 0.4, 0.7),
               (0.3, 0, 0.9, 0.2),
               (0.4, 0.9, 0, 0.1),
               (0.7, 0.2, 0.1, 0)
               ])*10
A = A.view(dt)

G = nx.from_numpy_matrix(A)
G = nx.relabel_nodes(G, dict(zip(range(len(G.nodes())),string.ascii_uppercase)))    

G = nx.to_agraph(G)

G.node_attr.update(color="red", style="filled")
G.edge_attr.update(color="blue", )

G.draw('distances.png', format='png', prog='neato')

在 R 中你可以试试multidimensional scaling

# Classical MDS
# N rows (objects) x p columns (variables)
# each row identified by a unique row name

d <- dist(mydata) # euclidean distances between the rows
fit <- cmdscale(d,eig=TRUE, k=2) # k is the number of dim
fit # view results

# plot solution 
x <- fit$points[,1]
y <- fit$points[,2]
plot(x, y, xlab="Coordinate 1", ylab="Coordinate 2", 
  main="Metric  MDS",    type="n")
text(x, y, labels = row.names(mydata), cex=.7)

可能性 2

您只想绘制带有标签边的图形

同样,networkx 可以提供帮助:

import networkx as nx   

# Create a graph
G = nx.Graph()

# distances
D = [ [0, 1], [1, 0] ]

labels = 
for n in range(len(D)):
    for m in range(len(D)-(n+1)):
        G.add_edge(n,n+m+1)
        labels[ (n,n+m+1) ] = str(D[n][n+m+1])

pos=nx.spring_layout(G)

nx.draw(G, pos)
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels,font_size=30)

import pylab as plt
plt.show()

【讨论】:

networkx 与 python 2.7 不兼容吗?我收到以下错误:(文件“test.py”,第 16 行,在 G = nx.to_agraph(G) 文件“/usr/local/lib/python2.7/dist-packages/networkx/drawing/ nx_agraph.py",第 134 行,在 to_agraph '(不适用于 Python3)') 它适用于 python 2.7。尝试安装此函数使用的pygraphviz.github.io【参考方案2】:

您没有提到是否需要二维图。我想你想在二维上构建一个图表,因为你需要它来进行可视化。考虑到您必须意识到,对于大多数图表来说,这是不可能的。

可以做的可能是以某种方式近似距离矩阵中的值,例如具有相对较小边缘的小值和具有相对大长度的大值。

考虑到所有先前的考虑,一个选项是graphviz。请参阅neato 函数。 一般来说,您感兴趣的是力导向绘图。如需进一步参考,请参阅wikipedia。

【讨论】:

【参考方案3】:

Multidimensional scaling (MDS) 正是您想要的。请参阅here 和here 了解更多信息。

【讨论】:

感谢您的回答,这不是我想要的,但看起来很有趣。我想将该矩阵可视化为具有节点和在节点之间运行的加权边的图。另外,我找到了 MDS here 的 R 示例实现。我会尽快向您更新。【参考方案4】:

您可以使用 d3js Force Directed Graph 并配置节点之间的距离。 d3js 强制布局具有一些聚类能力,可以分离距离相似的节点。这是一个将值作为节点之间距离的示例:

http://vida.io/documents/SyT7DREdQmGSpsBkK

另一种可视化方法是在节点之间使用相同的距离,但线的粗细不同。在这种情况下,您需要根据值计算笔画宽度:

.style("stroke-width", function(d)  return Math.sqrt(d.value / 50); );

【讨论】:

以上是关于将距离矩阵可视化为图形的主要内容,如果未能解决你的问题,请参考以下文章

R中存在哪些技术来可视化“距离矩阵”?

nlp书单

R语言plotly可视化:使用PCA算法进行数据降维使用plotly可视化PCA所有的主成分绘制散点图矩阵降维后的两个(三个)核心主成分的二维三维可视化图形方差解释的量载荷图等

R语言使用psych包的fa函数对指定数据集进行因子分析(输入数据为相关性矩阵)使用rotate参数指定进行斜交旋转提取因子使用fa.diagram函数可视化斜交旋转因子分析并解读可视化图形

将 unsigned char * 数组可视化为位图 [关闭]

将熊猫数据框可视化为热图时出现类型错误