[英]Plot confusion matrix in R using ggplot
我有兩個混淆矩陣,其計算值為真陽性 (tp)、假陽性 (fp)、真陰性 (tn) 和假陰性 (fn),對應於兩種不同的方法。 我想將他們表示為
我相信 facet grid 或 facet wrap 可以做到這一點,但我發現很難開始。 這里是method1和method2對應的兩個混淆矩陣的數據
dframe<-structure(list(label = structure(c(4L, 2L, 1L, 3L, 4L, 2L, 1L,
3L), .Label = c("fn", "fp", "tn", "tp"), class = "factor"), value = c(9,
0, 3, 1716, 6, 3, 6, 1713), method = structure(c(1L, 1L, 1L,
1L, 2L, 2L, 2L, 2L), .Label = c("method1", "method2"), class = "factor")), .Names = c("label",
"value", "method"), row.names = c(NA, -8L), class = "data.frame")
這可能是一個好的開始
library(ggplot2)
ggplot(data = dframe, mapping = aes(x = label, y = method)) +
geom_tile(aes(fill = value), colour = "white") +
geom_text(aes(label = sprintf("%1.0f",value)), vjust = 1) +
scale_fill_gradient(low = "white", high = "steelblue")
已編輯
TClass <- factor(c(0, 0, 1, 1))
PClass <- factor(c(0, 1, 0, 1))
Y <- c(2816, 248, 34, 235)
df <- data.frame(TClass, PClass, Y)
library(ggplot2)
ggplot(data = df, mapping = aes(x = TClass, y = PClass)) +
geom_tile(aes(fill = Y), colour = "white") +
geom_text(aes(label = sprintf("%1.0f", Y)), vjust = 1) +
scale_fill_gradient(low = "blue", high = "red") +
theme_bw() + theme(legend.position = "none")
基於 MYaseen208 的答案的稍微模塊化的解決方案。 對於大型數據集/多項分類可能更有效:
confusion_matrix <- as.data.frame(table(predicted_class, actual_class))
ggplot(data = confusion_matrix
mapping = aes(x = Var1,
y = Var2)) +
geom_tile(aes(fill = Freq)) +
geom_text(aes(label = sprintf("%1.0f", Freq)), vjust = 1) +
scale_fill_gradient(low = "blue",
high = "red",
trans = "log") # if your results aren't quite as clear as the above example
這是另一個基於 ggplot2 的選項; 首先是數據(來自插入符號):
library(caret)
# data/code from "2 class example" example courtesy of ?caret::confusionMatrix
lvs <- c("normal", "abnormal")
truth <- factor(rep(lvs, times = c(86, 258)),
levels = rev(lvs))
pred <- factor(
c(
rep(lvs, times = c(54, 32)),
rep(lvs, times = c(27, 231))),
levels = rev(lvs))
confusionMatrix(pred, truth)
並構建圖(在設置“表”時根據需要替換您自己的矩陣):
library(ggplot2)
library(dplyr)
table <- data.frame(confusionMatrix(pred, truth)$table)
plotTable <- table %>%
mutate(goodbad = ifelse(table$Prediction == table$Reference, "good", "bad")) %>%
group_by(Reference) %>%
mutate(prop = Freq/sum(Freq))
# fill alpha relative to sensitivity/specificity by proportional outcomes within reference groups (see dplyr code above as well as original confusion matrix for comparison)
ggplot(data = plotTable, mapping = aes(x = Reference, y = Prediction, fill = goodbad, alpha = prop)) +
geom_tile() +
geom_text(aes(label = Freq), vjust = .5, fontface = "bold", alpha = 1) +
scale_fill_manual(values = c(good = "green", bad = "red")) +
theme_bw() +
xlim(rev(levels(table$Reference)))
# note: for simple alpha shading by frequency across the table at large, simply use "alpha = Freq" in place of "alpha = prop" when setting up the ggplot call above, e.g.,
ggplot(data = plotTable, mapping = aes(x = Reference, y = Prediction, fill = goodbad, alpha = Freq)) +
geom_tile() +
geom_text(aes(label = Freq), vjust = .5, fontface = "bold", alpha = 1) +
scale_fill_manual(values = c(good = "green", bad = "red")) +
theme_bw() +
xlim(rev(levels(table$Reference)))
這是一個非常古老的問題,但似乎仍然有一個非常直接的解決方案來解決使用 ggplot2 的問題,但尚未提及。
希望它可能對某人有幫助:
cm <- confusionMatrix(factor(y.pred), factor(y.test), dnn = c("Prediction", "Reference"))
plt <- as.data.frame(cm$table)
plt$Prediction <- factor(plt$Prediction, levels=rev(levels(plt$Prediction)))
ggplot(plt, aes(Prediction,Reference, fill= Freq)) +
geom_tile() + geom_text(aes(label=Freq)) +
scale_fill_gradient(low="white", high="#009194") +
labs(x = "Reference",y = "Prediction") +
scale_x_discrete(labels=c("Class_1","Class_2","Class_3","Class_4")) +
scale_y_discrete(labels=c("Class_4","Class_3","Class_2","Class_1"))
老問題,但我寫了這個函數,我認為它的答案更漂亮。 導致發散的調色板(或任何你想要的,但默認是發散的):
prettyConfused<-function(Actual,Predict,colors=c("white","red4","dodgerblue3"),text.scl=5){
actual = as.data.frame(table(Actual))
names(actual) = c("Actual","ActualFreq")
#build confusion matrix
confusion = as.data.frame(table(Actual, Predict))
names(confusion) = c("Actual","Predicted","Freq")
#calculate percentage of test cases based on actual frequency
confusion = merge(confusion, actual, by=c('Actual','Actual'))
confusion$Percent = confusion$Freq/confusion$ActualFreq*100
confusion$ColorScale<-confusion$Percent*-1
confusion[which(confusion$Actual==confusion$Predicted),]$ColorScale<-confusion[which(confusion$Actual==confusion$Predicted),]$ColorScale*-1
confusion$Label<-paste(round(confusion$Percent,0),"%, n=",confusion$Freq,sep="")
tile <- ggplot() +
geom_tile(aes(x=Actual, y=Predicted,fill=ColorScale),data=confusion, color="black",size=0.1) +
labs(x="Actual",y="Predicted")
tile = tile +
geom_text(aes(x=Actual,y=Predicted, label=Label),data=confusion, size=text.scl, colour="black") +
scale_fill_gradient2(low=colors[2],high=colors[3],mid=colors[1],midpoint = 0,guide='none')
}
這是一個使用cvms
包的cvms
即cvms
Wrapper 函數來制作混淆矩陣。
library(cvms)
library(broom)
library(tibble)
library(ggimage)
#> Loading required package: ggplot2
library(rsvg)
set.seed(1)
d_multi <- tibble("target" = floor(runif(100) * 3),
"prediction" = floor(runif(100) * 3))
conf_mat <- confusion_matrix(targets = d_multi$target,
predictions = d_multi$prediction)
# plot_confusion_matrix(conf_mat$`Confusion Matrix`[[1]], add_sums = TRUE)
plot_confusion_matrix(
conf_mat$`Confusion Matrix`[[1]],
add_sums = TRUE,
sums_settings = sum_tile_settings(
palette = "Oranges",
label = "Total",
tc_tile_border_color = "black"
)
)
由reprex 包(v0.3.0) 於 2021 年 1 月 19 日創建
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.