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

如何在R中使用热图绘制混淆矩阵?,r,heatmap,confusion-matrix,R,Heatmap,Confusion Matrix,我有一个混淆矩阵,以便: 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

我有一个混淆矩阵,以便:

  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一无所知,所以很难对样本进行更改。如果有人能很快帮我画画,我将不胜感激。或任何其他建议,而不是热图也欢迎。
我知道这方面有很多示例,但我仍然无法使用自己的数据进行绘制。

R中的
image
函数将获取一个矩阵,并根据矩阵中的值绘制一个带有颜色的规则网格。您可以设置许多选项,但只需使用矩阵作为唯一参数调用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(t(z)[ncol(z):1,], Rowv=NA,
               Colv=NA, col = heat.colors(256))

使用
ggplot2
可以获得很好的结果,但为此需要一个data.frame,其中包含3列x、y和要打印的值

使用
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

好的,不算太糟,但我们可以做得更好。首先,我们可能要反转y轴。诀窍是提供x和y作为因子,并按照我们想要的级别进行排序

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

画龙点睛:在瓷砖顶部打印值并删除图例,因为它不再有用。显然,这都是可选的,但它为您提供了构建材料。注
geom_text
继承了
x
y
美学,因为它们被传递到
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
以在tile周围绘制(黑色)线。带有
RdYlBu
配色方案的最终绘图(有关可用调色板的列表,请参见
RColorBrewer::display.brewer.all()


不幸的是,在另一个答案中建议的
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")


下一步,您可以添加一些轴标签,自定义它,等等。

是的,它可以工作,而且非常简单,正如您所说的。非常感谢。图像还可以绘制直线网格。非常感谢!还有一个简单的问题,如何将列名和行名而不是0到1的值放在绘图上?@agenis我刚刚运行了所有程序,没有任何错误。可能是错误的复制/粘贴?好吧,你是对的,可能是浏览器破坏了数据的复制/粘贴。无论如何,我删除了我的评论
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
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")