59

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

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

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

示例数据:

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

我对想法持开放态度。

4

7 回答 7

25

您还可以使用力导向的图形绘制算法来可视化距离矩阵,例如

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()

于 2016-06-15T10:34:38.733 回答
23

Voronoi 图(Voronoi 分解图)是一种直观地表示距离矩阵 (DM) 的方法。

使用 R 创建和绘制它们也很简单——您可以在一行 R 代码中完成这两者。

如果您不熟悉计算几何的这一方面,则两者(VD 和 DM)之间的关系很简单,尽管简要总结可能会有所帮助。

距离矩阵——即显示一个点与其他点之间的距离的 2D 矩阵,是 kNN 计算期间的中间输出(即 k-最近邻,一种机器学习算法,它基于基于它的“k”个最近邻居的加权平均值,距离,其中“k”是某个整数,通常在 3 到 5 之间。)

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

两种数据结构通常用于解决该问题:kd-trees 和 Voroni 分解(又名“Dirichlet tesselation”)。

Voronoi 分解 (VD) 由距离矩阵唯一确定——即,有一个 1:1 的映射;所以它确实是距离矩阵的视觉表示,尽管这又不是他们的目的——他们的主要目的是有效存储用于基于 kNN 的预测的数据。

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

那你怎么做一个?

Voronoi decomp 是通过从训练集中选择(通常是随机的)点的子集来构建的(这个数字因情况而异,但如果我们有 1,000,000 个点,那么 100 是这个子集的合理数字)。这 100 个数据点是 Voronoi 中心(“VC”)。

Voronoi decomp 背后的基本思想是,不必筛选 1,000,000 个数据点来找到最近的邻居,您只需查看这 100 个,然后一旦找到最近的 VC,您对实际最近邻居的搜索是仅限于该 Voronoi 单元内的点。接下来,对于训练集中的每个数据点,计算它最接近的 VC。最后,对于每个 VC 及其关联点,计算凸包——从概念上讲,只是由该 VC 分配的离 VC 最远的点形成的外边界。这个围绕 Voronoi 中心的凸包形成了一个“Voronoi 单元”。完整的 VD 是将这三个步骤应用于训练集中的每个 VC 的结果。这将为您提供完美的曲面镶嵌(参见下图)。

要计算 R 中的 VD,请使用tripack包。关键功能是“voronoi.mosaic”,您只需将 x 和 y 坐标分别传递给它——原始数据,而不是DM——然后你可以将 voronoi.mosaic 传递给“plot”。

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

在此处输入图像描述

于 2010-06-21T08:41:32.087 回答
21

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)

在此处输入图像描述

于 2010-06-21T06:48:33.090 回答
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))))

在此处输入图像描述

于 2010-06-21T03:27:07.923 回答
9
  1. 基于层次聚类分析的树状图可能很有用:http: //www.statmethods.net/advstats/cluster.html

  2. R 中的 2-D 或 3-D 多维缩放分析:http: //www.statmethods.net/advstats/mds.html

  3. 如果你想进入 3+ 维度,你可能想探索 ggobi / rggobi: http ://www.ggobi.org/rggobi/

于 2010-06-21T03:32:59.800 回答
7

在 Borcard 等人的《数值生态学》一书中。2011 他们使用了一个名为 *coldiss.r * 你可以在这里找到它:http: //ichthyology.usm.edu/courses/multivariate/coldiss.R

它对距离进行颜色编码,甚至按不同程度对记录进行排序。

另一个好的包是系列包。

参考文献:Borcard, D.、Gillet, F. 和 Legendre, P. (2011) 与 R. Springer 合作的数值生态学。

在此处输入图像描述

于 2012-09-18T14:07:23.600 回答
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)

在此处输入图像描述

于 2016-07-05T13:28:13.403 回答