Plot A Confusion Matrix with Color and Frequency in R

久未见 提交于 2020-07-05 10:57:07

问题


I want to plot a confusion matrix, but, I don't want to just use a heatmap, because I think they give poor numerical resolution. Instead, I want to also plot the frequency in the middle of the square. For instance, I like the output of this:

library(mlearning);
data("Glass", package = "mlbench")
Glass$Type <- as.factor(paste("Glass", Glass$Type))

summary(glassLvq <- mlLvq(Type ~ ., data = Glass));
(glassConf <- confusion(predict(glassLvq, Glass, type = "class"), Glass$Type))

plot(glassConf) # Image by default

However, 1.) I don't understand that the "01, 02, etc" means along each axis. How can we get rid of that? 2.) I would like 'Predicted' to be as the label of the 'y' dimension, and 'Actual' to be as the label for the 'x' dimension 3.) I would like to replace absolute counts by frequency / probability.

Alternatively, is there another package that will do this?

In essence, I want this in R:

http://www.mathworks.com/help/releases/R2013b/nnet/gs/gettingstarted_nprtool_07.gif

OR:

http://c431376.r76.cf2.rackcdn.com/8805/fnhum-05-00189-HTML/image_m/fnhum-05-00189-g009.jpg


回答1:


The mlearning package seems quite inflexible with plotting confusion matrices.

Starting with your glassConf object, you probably want to do something like this:

prior(glassConf) <- 100 
# The above rescales the confusion matrix such that columns sum to 100.
opar <- par(mar=c(5.1, 6.1, 2, 2))
x <- x.orig <- unclass(glassConf)
x <- log(x + 0.5) * 2.33
x[x < 0] <- NA
x[x > 10] <- 10
diag(x) <- -diag(x)
image(1:ncol(x), 1:ncol(x),
      -(x[, nrow(x):1]), xlab='Actual', ylab='',
      col=colorRampPalette(c(hsv(h = 0, s = 0.9, v = 0.9, alpha = 1), 
                             hsv(h = 0, s = 0, v = 0.9, alpha = 1), 
                             hsv(h = 2/6, s = 0.9, v = 0.9, alpha = 1)))(41), 
      xaxt='n', yaxt='n', zlim=c(-10, 10))
axis(1, at=1:ncol(x), labels=colnames(x), cex.axis=0.8)
axis(2, at=ncol(x):1, labels=colnames(x), las=1, cex.axis=0.8)
title(ylab='Predicted', line=4.5)
abline(h = 0:ncol(x) + 0.5, col = 'gray')
abline(v = 0:ncol(x) + 0.5, col = 'gray')
text(1:6, rep(6:1, each=6), 
     labels = sub('^0$', '', round(c(x.orig), 0)))
box(lwd=2)
par(opar) # reset par

The above code uses bits and pieces of the confusionImage function called by plot.confusion.

Confusion matrix




回答2:


Here is a function for plotting confusion matrices I developed from jbaums excellent answer.
It is similar, but looks a bit nicer (IMO), and does not transpose the confusion matrix you feed it, which might be helpful.

### Function for plotting confusion matrices
confMatPlot = function(confMat, titleMy, shouldPlot = T) {
  #' Function for plotting confusion matrice
  #' 
  #' @param confMat: confusion matrix with counts, ie integers. 
  #' Fractions won't work
  #' @param titleMy: String containing plot title
  #' @return Nothing: It only plots

  ## Prepare data
  x.orig = confMat; rm(confMat)  # Lazy conversion to function internal variable name
  n = nrow(x.orig)  # conf mat is square by definition, so nrow(x) == ncol(x)
  opar <- par(mar = c(5.1, 8, 3, 2))
  x <- x.orig
  x <- log(x + 0.5)  # x<1 -> x<0 ,  x>=1 -> x>0
  x[x < 0] <- NA
  diag(x) <- -diag(x)  # change sign to give diagonal different color
  ## Plot confusion matrix
  image(1:n, 1:n,  # grid of coloured boxes
        # matrix giving color values for the boxes
        # t() and [,ncol(x):1] since image puts [1,1] in bottom left by default
        -t(x)[, n:1],  
        # ylab added later to avoid overlap with tick labels
        xlab = 'Actual', ylab = '',
        col = colorRampPalette(c("darkorange3", "white", "steelblue"), 
                               bias = 1.65)(100),
        xaxt = 'n', yaxt = 'n'
        )
  # Plot counts
  text(rep(1:n, each = n), rep(n:1, times = n), 
       labels = sub('^0$', '', round(c(x.orig), 0)))
  # Axis ticks but no lables
  axis(1, at = 1:n, labels = rep("", n), cex.axis = 0.8)
  axis(2, at = n:1, labels = rep("", n), cex.axis = 0.8)
  # Tilted axis lables
  text(cex = 0.8, x = (1:n), y = -0.1, colnames(x), xpd = T, srt = 30, adj = 1)
  text(cex = 0.8, y = (n:1), x = +0.1, colnames(x), xpd = T, srt = 30, adj = 1)
  title(main = titleMy)
  title(ylab = 'Predicted', line = 6)
  # Grid and box
  abline(h = 0:n + 0.5, col = 'gray')
  abline(v = 0:n + 0.5, col = 'gray')
  box(lwd = 1, col = 'gray')
  par(opar)
}

Example of output:



来源:https://stackoverflow.com/questions/21589991/plot-a-confusion-matrix-with-color-and-frequency-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!