R中有哪些技术可以用来可视化“距离矩阵”?

66

我希望在我写的一篇文章中展示一个距离矩阵,我正在寻找一个好的可视化方式。

到目前为止,我发现了气球图(我在这里使用了它, 但我认为在这种情况下它不起作用),热力图(这是一个很好的例子,但它们不允许在表格中呈现数字,如果我错了请纠正我。也许将一半的表格着色,另一半显示数字会很酷),最后是相关椭圆图(这里是一些代码和示例- 使用形状很酷,但我不确定如何在这里使用它)。

还有各种聚类方法,但它们会聚合数据(这不是我想要的),而我想呈现所有数据。

数据示例:

nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
dist(nba[1:20, -1], )

我愿意接受任何想法。


请提供一些虚拟数据,很难理解您尝试获取的内容... 经过非常短暂的头脑风暴会话后,我发现自相关图可能是适当的?在 lower.tri 上,您可以放置散点图,在 upper.tri 上,您可以放置相关系数... 但您已经知道了,对吧... O_o - aL3xa
热力图和图例有什么问题吗?你真的必须注释距离矩阵中的所有值吗?难道你不能在绘图后仅叠加关键值吗? - nico
嗨aL3xa - correlograms将聚合数据 - 我尽可能想避免这种情况(但感谢您的建议 :))。亲爱的Nico - 这是一个好问题。如果我有只覆盖部分数据的选项,我可能会使用它。再次感谢,但我需要一些帮助来编写这样的代码 :) - Tal Galili
2
这里不需要“虚拟”数据——OP已经选择了正确的抽象层次来提出这个问题。数据不会以任何有意义的方式澄清问题(除非有人不知道距离矩阵是什么,也不知道如何计算它)。这个问题涉及到任何距离矩阵,我们在R中生成一个距离矩阵比从OP复制更快。 - doug
1
不是距离本身,而是多维尺度缩放(MDS)方面有何想法? - catastrophic-failure
7个回答

29

您也可以使用力导向图绘制算法可视化距离矩阵,例如:

nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
dist_m <- as.matrix(dist(nba[1:20, -1]))
dist_mi <- 1/dist_m # one over, as qgraph takes similarity matrices as input
library(qgraph)
jpeg('example_forcedraw.jpg', width=1000, height=1000, unit='px')
qgraph(dist_mi, layout='spring', vsize=3)
dev.off()


5
我非常喜欢这个解决方案,因为它实际上代表了距离。你真的想要倒数1/距离吗?为什么不用1-距离呢?据我所见,距离永远不会大于1。 - Johannes Titz
1
“dist_mi <- 1/dist_m” 这行代码实际上是做什么的?它不像 rescale 函数一样分配逆矩阵或标准化矩阵。那个操作的意义是什么? - Kora K
1
这里的线条粗细代表什么? - bob
dist_mi <- 1/dist_m 应该改为 dist_mi <- 1/(dist_m + 1) 吗? - DuckPyjamas
这个库已经不可用了,任何安装过程都会以“'RcppExports.o' 不存在”结束。还有其他类似的库吗? - undefined

24

Tal,这是一种快速将文本重叠在热图上的方法。请注意,这取决于使用image而不是heatmap,因为后者会偏移图形,使得在正确位置添加文本更加困难。

说实话,我认为这张图展示了太多的信息,使得它有点难以阅读... 你可能只想写出具体的值。

此外,另一个更快的选项是将图形保存为PDF格式,导入Inkscape(或类似软件),并在需要时手动添加文本。

希望这可以帮助到你。

nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")

dst <- dist(nba[1:20, -1],)
dst <- data.matrix(dst)

dim <- ncol(dst)

image(1:dim, 1:dim, dst, axes = FALSE, xlab="", ylab="")

axis(1, 1:dim, nba[1:20,1], cex.axis = 0.5, las=3)
axis(2, 1:dim, nba[1:20,1], cex.axis = 0.5, las=1)

text(expand.grid(1:dim, 1:dim), sprintf("%0.1f", dst), cex=0.6)

在这里输入图像描述


23

一个沃罗诺伊图(Voronoi Diagram)是一种可视化表示距离矩阵(Distance Matrix,DM)的方法。它也很容易用R语言创建和绘制--你只需要一行代码就能完成。

如果你不熟悉这方面的计算几何知识,VD和DM之间的关系是直观的,但简要的概括可能有帮助。

距离矩阵--即显示点与其他每个点之间距离的2D矩阵,在kNN计算过程中产生(即k最近邻算法,根据其k个最近邻居的加权平均值,距离上,预测给定数据点的值,其中'k'为某个整数,通常在3到5之间。)

kNN的概念非常简单--训练集中的每个数据点本质上都是n维空间中的'位置',因此下一步是使用某些距离度量(例如欧几里得距离、曼哈顿距离等)计算每个点与所有其他点之间的距离。虽然训练步骤--即构建距离矩阵--很简单,但将其用于预测新数据点的值实际上受到数据检索的限制--从几千或几百万个分散在n维空间中的点中找出最接近的3或4个点。

通常使用两种数据结构来解决这个问题:kd树和沃罗诺伊分解(也称"狄利克雷镶嵌")。

沃罗诺伊分解(VD)由距离矩阵唯一确定--即存在一一映射,因此它确实是距离矩阵的可视化表示,虽然再次强调,它们的主要目的是用于基于kNN的预测的高效存储数据。

除此之外,将距离矩阵以这种方式表示是否是一个好主意可能主要取决于你的观众。对大多数人来说,VD和前置的距离矩阵之间的关系并不直观。但这并不意味着它是错误的--如果没有任何统计培训的人想知道两个群体是否具有相似的概率分布,如果你向他们展示了一个Q-Q图,他们可能会认为你没有回答他们的问题。因此,对于那些知道自己在看什么的人来说,VD是DM的紧凑、完整和准确的表示。

那么如何创建一个沃罗诺伊分解呢?

沃罗诺伊分解是通过从训练集中选择(通常是随机选择)一部分点来构造的(这个数量因情况而异,但如果我们有100万个点,则100是这个子集的合理数量)。这100个数据点是沃罗诺伊中心(VC)。

沃罗诺伊分解的基本思想是,不必筛选1,000,000个数据点以查找最近的邻居,只需查看这些100个中心点,然后一旦找到最接近的VC,你的搜索实际上被限制在该沃罗诺伊单元格

library(tripack)
plot(voronoi.mosaic(runif(100), runif(100), duplicate="remove"))

在此输入图像描述


2
你好Doug,如果我理解正确的话,这正是我所希望的 - 谢谢!我看了一下函数,想知道我需要做什么。我需要将距离矩阵转换为长格式,然后在其上运行代码吗?我看了你的解释和维基页面,但仍不确定如何解释距离矩阵的图表。进一步的澄清会很好。再次感谢您提供的线索!最好的问候,Tal。 - Tal Galili
1
Tal - 其实比那更容易(我根据您上面的评论编辑了我的答案)。函数'voronoi.mosaic'接受两个参数,一个x坐标向量和一个y坐标向量。这些是您的Voronoi中心-例如,从初始数据集随机选择的100个数据点。voronoi.mosaic不直接接受DM(尽管它显然是中间步骤的结果)。当您制作此图时,如果需要,可以使用“points”函数将其余的数据点层叠在一起。 - doug
4
嗨,道格,谢谢回信。我打算在其中运行的数据集只有50个数据点(项目)。然而,对于它,我只能生成距离矩阵(我没有一个多维矩阵,其中存在这些项目)。所以我的问题是,如果我只有一个由50个项目组成的距离矩阵,我能否从中生成沃罗诺伊图?感谢您的帮助!塔尔 - Tal Galili

18

你可能希望考虑查看矩阵的二维投影(多维缩放)。这里有一个在R中如何实现它的链接。

否则,我认为你在使用热图方面已经走在了正确的道路上。您可以很容易地添加您的数字。例如,基于Learn R

library(ggplot2)
library(plyr)
library(arm)
library(reshape2)
nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
nba$Name <- with(nba, reorder(Name, PTS))
nba.m <- melt(nba)
nba.m <- ddply(nba.m, .(variable), transform,
rescale = rescale(value))
(p <- ggplot(nba.m, aes(variable, Name)) + geom_tile(aes(fill = rescale),
colour = "white") + scale_fill_gradient(low = "white",
high = "steelblue")+geom_text(aes(label=round(rescale,1))))

这里输入图像描述


谢谢Ian,非常有帮助!你能想到如何更改矩阵上半部分显示的内容吗? - Tal Galili

9

嗨,Jeromy,谢谢回复。我不知道第二部分中的链接,所以很有趣。但是,我正在寻找一种表示数据而不减少维度的方法。无论如何,还是谢谢 :)! - Tal Galili
在MSE意义下,MDS在数学上是最优的解决方案。然而有时结果中会出现非常密集的聚簇,这在数学上是“正确”的,但对于可视化来说并不“合适”。你有任何想法吗? - SolessChong

7
在2011年Borcard等人的《数值生态学》一书中,他们使用了一个名为*coldiss.r*的函数。你可以在这里找到它:http://ichthyology.usm.edu/courses/multivariate/coldiss.R 。它会对距离进行彩色编码,并通过相异性排序记录。另一个好的软件包是seriation软件包。
参考文献:Borcard, D., Gillet, F. & Legendre, P. (2011) Numerical Ecology with R. Springer. enter image description here

4

使用多维缩放的解决方案

data = read.csv("http://datasets.flowingdata.com/ppg2008.csv", sep = ",")
dst = tcrossprod(as.matrix(data[,-1]))
dst = matrix(rep(diag(dst), 50L), ncol = 50L, byrow = TRUE) + 
  matrix(rep(diag(dst), 50L), ncol = 50L, byrow = FALSE) - 2*dst

library(MASS)
mds = isoMDS(dst)
#remove {type = "n"} to see dots
plot(mds$points, type = "n", pch = 20, cex = 3, col = adjustcolor("black", alpha = 0.3), xlab = "X", ylab = "Y") 
text(mds$points, labels = rownames(data), cex = 0.75)

enter image description here


X和Y的含义是什么?它们的测量单位是什么? - FaCoffee
@FaCoffee 距离矩阵的主成分(在MDS的普通公式中)。 - catastrophic-failure

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接