【问题标题】:How to plot a confusion matrix using heatmaps in R?如何使用 R 中的热图绘制混淆矩阵?
【发布时间】:2020-01-08 05:27:45
【问题描述】:

我有一个混淆矩阵:

  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 heatmap confusion-matrix


    【解决方案1】:

    您可以使用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())。

    【讨论】:

    • @agenis 我刚刚运行了所有内容,没有任何错误。也许是错误的复制/粘贴?
    • 好吧,你是对的,也许是浏览器破坏了数据复制/粘贴。无论如何我删除我的评论
    【解决方案2】:

    正如 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))
    

    【讨论】:

    • 非常感谢!还有一个快速的问题,如何将列名和行名放在绘图上,而不是从 0 到 1 的值?
    【解决方案3】:

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

    【讨论】:

    • 是的,它可以工作,而且也很简单,就像你说的那样。非常感谢。
    • 图像也可以绘制直线网格
    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2016-10-20
      • 2016-01-31
      • 2016-06-04
      • 2019-08-09
      • 2021-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多