如何在 R 中使用热图绘制混淆矩阵?

发布于 2024-12-04 08:52:44 字数 452 浏览 0 评论 0原文

我有一个混淆矩阵:

  a b c d e f g h i j
a 5 4 0 0 0 0 0 0 0 0
b 0 0 0 0 0 0 0 0 0 0
c 0 0 4 0 0 0 0 0 0 0
d 0 0 0 0 0 0 0 0 0 0
e 2 0 0 0 2 0 0 0 0 0
f 1 0 0 0 0 2 0 0 0 0
g 0 0 0 0 0 0 0 0 0 0
h 0 0 0 0 0 0 0 0 0 0 
i 0 0 0 0 0 0 0 0 0 0 
j 0 0 0 0 0 0 0 0 0 0 

其中字母表示类标签。

我只需要绘制混淆矩阵。我搜索了几个工具。 R 中的热图看起来正是我所需要的。由于我对R一无所知,因此很难对样本进行更改。如果有人能很快帮助我如何画画,我将不胜感激。或者除热图之外的任何其他建议也是受欢迎的。 我知道有很多关于这方面的样本,但我仍然无法用自己的数据进行绘制。

I have a confusion matrix such that:

  a b c d e f g h i j
a 5 4 0 0 0 0 0 0 0 0
b 0 0 0 0 0 0 0 0 0 0
c 0 0 4 0 0 0 0 0 0 0
d 0 0 0 0 0 0 0 0 0 0
e 2 0 0 0 2 0 0 0 0 0
f 1 0 0 0 0 2 0 0 0 0
g 0 0 0 0 0 0 0 0 0 0
h 0 0 0 0 0 0 0 0 0 0 
i 0 0 0 0 0 0 0 0 0 0 
j 0 0 0 0 0 0 0 0 0 0 

where the letters denote the class labels.

I just need to plot the confusion matrix. I searched a couple of tools. Heatmaps in R looks like what I need. As I don't know anything about R, it is really hard to do changes on the samples. If anybody could help me shortly how to draw, I will be really appreciated. Or any other suggestion rather than heatmaps are welcome as well.
I know there is plenty of samples about this, but still I cannot manage to draw with my own data.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

软糯酥胸 2024-12-11 08:52:44

您可以使用 ggplot2 获得不错的结果,但为此您需要一个包含 3 列 x、y 和要绘制的值的 data.frame。

使用 tidyr 工具中的 gather 可以非常轻松地重新格式化数据:

library("dplyr")
library("tidyr")

# Loading your example. Row names should get their own column (here `y`).
hm <- readr::read_delim("y a b c d e f g h i j
a 5 4 0 0 0 0 0 0 0 0
b 0 0 0 0 0 0 0 0 0 0
c 0 0 4 0 0 0 0 0 0 0
d 0 0 0 0 0 0 0 0 0 0
e 2 0 0 0 2 0 0 0 0 0
f 1 0 0 0 0 2 0 0 0 0
g 0 0 0 0 0 0 0 0 0 0
h 0 0 0 0 0 0 0 0 0 0
i 0 0 0 0 0 0 0 0 0 0
j 0 0 0 0 0 0 0 0 0 0", delim=" ")

# Gathering columns a to j
hm <- hm %>% gather(x, value, a:j)

# hm now looks like:
# # A tibble: 100 x 3
# y     x     value
# <chr> <chr> <dbl>
# 1 a     a         5
# 2 b     a         0
# 3 c     a         0
# 4 d     a         0
# 5 e     a         2
# # ... with 95 more rows

完美!让我们开始策划吧。 ggplot2 热图的基本几何对象是 geom_tile,我们将为其提供美观的 xyfill

library("ggplot2")
ggplot(hm, aes(x=x, y=y, fill=value)) + geom_tile() 

第一次尝试热图

好吧,还不错,但我们可以做得更好。首先我们可能想要反转 y 轴。诀窍是提供 x 和 y 作为因子,并按照我们想要的顺序排列水平。

hm <- hm %>%
  mutate(x = factor(x), # alphabetical order by default
         y = factor(y, levels = rev(unique(y)))) # force reverse alphabetical order

然后我喜欢黑&白色主题 theme_bw() 摆脱了灰色背景。我还喜欢使用 RColorBrewer 中的调色板(使用 direction = 1 来获得较高值的较暗颜色)。

由于您在 xy 轴上绘制相同的内容,因此您可能需要相等的轴刻度:coord_equal() 会给您一个方形图。

ggplot(hm, aes(x=x, y=y, fill=value)) +
  geom_tile() + theme_bw() + coord_equal() +
  scale_fill_distiller(palette="Greens", direction=1) 
# Other valid palettes: Reds, Blues, Spectral, RdYlBu (red-yellow-blue), ...

更好的热图

最后一步:在图块顶部打印值并删除图例,因为它不再有用。显然,这都是可选的,但它为您提供了构建材料。注意 geom_text 继承了 xy 美学,因为它们被传递给 ggplot

ggplot(hm, aes(x=x, y=y, fill=value)) +
  geom_tile() + theme_bw() + coord_equal() +
  scale_fill_distiller(palette="Greens", direction=1) +
  guides(fill=F) + # removing legend for `fill`
  labs(title = "Value distribution") + # using a title instead
  geom_text(aes(label=value), color="black") # printing values

最终热图

您还可以将 color="black" 传递给 geom_tile 以在图块周围绘制(黑色)线条。使用 RdYlBu 配色方案的最终绘图(有关可用调色板的列表,请参阅 RColorBrewer::display.brewer.all())。

显示更多选项

You can achieve a nice result using ggplot2, but for that you need a data.frame with 3 columns for x, y and the value to plot.

Using gather from the tidyr tool it is very easy to reformat your data:

library("dplyr")
library("tidyr")

# Loading your example. Row names should get their own column (here `y`).
hm <- readr::read_delim("y a b c d e f g h i j
a 5 4 0 0 0 0 0 0 0 0
b 0 0 0 0 0 0 0 0 0 0
c 0 0 4 0 0 0 0 0 0 0
d 0 0 0 0 0 0 0 0 0 0
e 2 0 0 0 2 0 0 0 0 0
f 1 0 0 0 0 2 0 0 0 0
g 0 0 0 0 0 0 0 0 0 0
h 0 0 0 0 0 0 0 0 0 0
i 0 0 0 0 0 0 0 0 0 0
j 0 0 0 0 0 0 0 0 0 0", delim=" ")

# Gathering columns a to j
hm <- hm %>% gather(x, value, a:j)

# hm now looks like:
# # A tibble: 100 x 3
# y     x     value
# <chr> <chr> <dbl>
# 1 a     a         5
# 2 b     a         0
# 3 c     a         0
# 4 d     a         0
# 5 e     a         2
# # ... with 95 more rows

Perfect! Let's get plotting. the basic geom for heatmap with ggplot2 is geom_tile to which we'll provide aesthetic x, y and fill.

library("ggplot2")
ggplot(hm, aes(x=x, y=y, fill=value)) + geom_tile() 

First attempt at a heatmap

OK not too bad but we can do much better. First we probably want to reverse the y axis. The trick is to provide x and y as factors with the levels ordered as we want them.

hm <- hm %>%
  mutate(x = factor(x), # alphabetical order by default
         y = factor(y, levels = rev(unique(y)))) # force reverse alphabetical order

Then I like the black & white theme theme_bw() which gets rid of the grey background. I also like to use a palette from RColorBrewer (with direction = 1 to get the darker colors for higher values).

Since you're plotting the same thing on the x and y axis, you probably want equal axis scales: coord_equal() will give you a square plot.

ggplot(hm, aes(x=x, y=y, fill=value)) +
  geom_tile() + theme_bw() + coord_equal() +
  scale_fill_distiller(palette="Greens", direction=1) 
# Other valid palettes: Reds, Blues, Spectral, RdYlBu (red-yellow-blue), ...

A better heatmap

The finishing touch: printing the values on top of the tiles and removing the legend since it is not longer useful. Obviously this is all optional but it gives you material to build from. Note geom_text inherits the x and y aesthetics since they were passed to ggplot.

ggplot(hm, aes(x=x, y=y, fill=value)) +
  geom_tile() + theme_bw() + coord_equal() +
  scale_fill_distiller(palette="Greens", direction=1) +
  guides(fill=F) + # removing legend for `fill`
  labs(title = "Value distribution") + # using a title instead
  geom_text(aes(label=value), color="black") # printing values

Final heatmap

You could also pass color="black" to geom_tile to draw (black) lines around the tiles. A final plot with the RdYlBu color scheme (see RColorBrewer::display.brewer.all() for a list of available palettes).

Showcasing more options

风筝有风,海豚有海 2024-12-11 08:52:44

正如 Greg 提到的,image 可能是正确的选择:

z = c(5,4,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,4,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
2,0,0,0,2,0,0,0,0,0,
1,0,0,0,0,2,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0)

z = matrix(z, ncol=10)
colnames(z) = c("a","b","c","d","e","f","g","h","i", "j")
rownames(z) = c("a","b","c","d","e","f","g","h","i", "j")

##To get the correct image plot rotation
##We need to flip the plot
image(z[,ncol(z):1], axes=FALSE)

##Add in the y-axis labels. Similar idea for x-axis.
axis(2, at = seq(0, 1, length=length(colnames(z))), labels=colnames(z))

您可能还想查看 heatmap 函数:

heatmap(t(z)[ncol(z):1,], Rowv=NA,
               Colv=NA, col = heat.colors(256))

As Greg mentioned, image is probably the way to go:

z = c(5,4,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,4,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
2,0,0,0,2,0,0,0,0,0,
1,0,0,0,0,2,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0)

z = matrix(z, ncol=10)
colnames(z) = c("a","b","c","d","e","f","g","h","i", "j")
rownames(z) = c("a","b","c","d","e","f","g","h","i", "j")

##To get the correct image plot rotation
##We need to flip the plot
image(z[,ncol(z):1], axes=FALSE)

##Add in the y-axis labels. Similar idea for x-axis.
axis(2, at = seq(0, 1, length=length(colnames(z))), labels=colnames(z))

You may also want to look at the heatmap function:

heatmap(t(z)[ncol(z):1,], Rowv=NA,
               Colv=NA, col = heat.colors(256))
哽咽笑 2024-12-11 08:52:44

R 中的image 函数将采用一个矩阵,并根据矩阵中的值绘制一个带有颜色的规则网格。您可以设置很多选项,但只需使用矩阵作为唯一参数调用 image 即可创建基本绘图。听起来这将是一个很好的起点。

The image function in R will take a matrix and plot a regular grid with colors based on the values in the matrix. You can set a lot of options, but just calling image with your matrix as the only argument will create a basic plot. Sounds like that would be a good place to start.

羁拥 2024-12-11 08:52:44

不幸的是,另一个答案中建议的 image 函数不能这样使用,因为它会反转(镜像)数据,所以您会以错误的方式得到它。通过一点点变换,您可以创建一个能够正确绘制它的函数:

set.seed(1)
d = data.frame(Y_label=rpois(100,1), pred=rpois(100,1))
Show = function(df, ...) {image(t(df[nrow(df):1,]), ...)}
Show(table(d), main="my confusion matrix")

在此处输入图像描述

下一步,您可以添加一些轴标签、对其进行自定义等。

Unfortunately, the image function suggested in another answer cannot be used as such because it reverses (mirror) the data, so you'll get it the wrong way. With a little transform you can coin a function that will plot it right:

set.seed(1)
d = data.frame(Y_label=rpois(100,1), pred=rpois(100,1))
Show = function(df, ...) {image(t(df[nrow(df):1,]), ...)}
Show(table(d), main="my confusion matrix")

enter image description here

Next step you can add some axis labels, customize it, etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文