La prueba de McNemar es una prueba para proporciones emparejadas, no veo cómo se aplica a una matriz de confusión multiclase. Normalmente, se aplica para validar modelos logísticos. No se puede pretender agregar toda la matriz de confusión en una matriz de contingencia 2x2 y esperar una prueba de hipótesis válida.
Supongo que podría iterar a través de las clases, derivando una matriz 2x2 apropiada para cada clase, pero esto sólo le daría una medida de la precisión por clase y no el rendimiento del modelo, lo que llevaría a una evaluación sesgada del rendimiento. Se podría considerar la prueba de Bowker, que es una extensión asintótica de la prueba de McNemar que permite múltiples clases.
Sin embargo, no creo que la prueba de Bowker sea adecuada en este caso, ya que comprueba si las celdas no diagonales son iguales a la celda simétrica a ella. Un test que compare la diagonal, como el Kappa, sería mucho más informativo para un modelo multiclase.
Si realmente quiere hacerlo, puede calcular el porcentaje de clasificación correcta de cada modelo y comparar estas proporciones. Sin embargo, esto le dirá muy poco sobre el rendimiento del modelo, porque el modelo global (pcc) podría estar muy sesgado hacia una única clase con un rendimiento muy alto, mientras que las demás clases tienen un rendimiento bajo. En cambio, el otro modelo puede tener una precisión global más baja, pero una distribución de errores más uniforme, lo que lo hace más deseable.
He aquí un ejemplo en R. En primer lugar, crear matriz de confusión para cada modelo.
classes = c("crop","water","pasture","fallow","forest","urban")
crop=c(34,4,5,3,1,1); water=c(23,29,5,6,0,4); pasture=c(7,2,22,9,0,0)
fallow=c(23,4,5,75,1,0); forest=c(1,0,1,2,77,0); urban=c(1,2,0,0,0,10)
( A <- matrix(c(crop, water, pasture,fallow,forest,urban), nrow = 6,
ncol = 6, byrow=TRUE, dimnames=list(classes,classes) ) )
crop2=c(73,0,0,4,3,2); water2=c(9,36,2,11,0,6); pasture2=c(2,2,30,19,0,0);
fallow2=c(5,2,5,59,1,0); forest2=c(0,0,1,2,74,0); urban2=c(0,1,0,0,1,7)
( B <- matrix(c(crop2, water2, pasture2,fallow2,forest2,urban2), nrow = 6,
ncol = 6, byrow=TRUE, dimnames=list(classes,classes) ) )
Calcular el porcentaje de clasificación correcta de cada modelo
( pcc1 <- sum(diag(A))/sum(A) )
( pcc2 <- sum(diag(B))/sum(B) )
Coordine en una matriz de proporciones 2x2 apropiada y ejecute la prueba de McNemar.
( m <- matrix( c(pcc1, (1-pcc1), pcc2, (1-pcc2)),
nrow = 2, ncol = 2, byrow=TRUE) )
mcnemar.test(m)
Prueba Chi-cuadrado de McNemar con corrección de continuidad: Chi-cuadrado de McNemar = 0,25451, df = 1, p-valor = 0,6139
Para crear específicamente la matriz de comparación cruzada detallada por el OP, puede utilizar la diagonal de la matriz para construir los valores.
# f11 - number of cases with correct classification in both A and B
f11 <- sum(diag(A)) + sum(diag(B))
# f12 - number of cases wrongly classified by A but correctly classified by B
f12 <- sum(diag(B)) - ( sum(A) - sum(diag(A)) )
# f21 - number of cases correctly classified by A but wrongly classified by B
f21 <- sum(diag(A)) - ( sum(B) - sum(diag(B)) )
# f22 - number of cases wrongly classified in both A and B
f22 <- ( sum(B) - sum(diag(B)) ) + ( sum(A) - sum(diag(A)) )
# Build matrix
( cm <- matrix( c(f11,f12,f21,f22), nrow=2, byrow=TRUE,
dimnames=list( c("correct","incorrect"),
c("correct","incorrect"))) )
Alternativamente, calculamos matrices de confusión binomiales (verdadero/falso) para cada clase, sobre los valores acumulados de las dos matrices. El resultado es una lista que contiene una matriz de confusión para cada clase con todas las demás clases tratadas acumulativamente.
( cm <- A + B )
agg_mat <- list()
for (i in 1:nrow(cm) ) {
agg_mat[[i]] <- t( matrix(c(cm[i,i], sum(cm[i,]) - cm[i,i], sum(cm[,i]) - cm[i,i],
sum(cm) - sum(cm[i,]) - sum(cm[,i]) + cm[i,i]), ncol=2) )
}
names(agg_mat) <- rownames(cm)
agg_mat
Ahora podemos calcular la prueba chi-cuadrado de McNemar para cada clase.
for(i in 1:length(agg_mat)) {
cat(paste0("McNemar's chi-squared for ", rownames(cm)[i]),
round(mcnemar.test(agg_mat[[i]])$statistic,digits=3), "\n")
}
Aquí podemos sumar las matrices de confusión a nivel de clase en una única matriz. Puede promediar las matrices sumadas, sin embargo, los resultados de precisión no diferirán, por lo que es un paso innecesario.
binomial_cm <- agg_mat[[1]]
for(i in 2:length(agg_mat)) binomial_cm <- binomial_cm + agg_mat[[i]]
rownames(binomial_cm) <- c("correct", "incorrect")
colnames(binomial_cm) <- c("correct", "incorrect")
binomial_cm
# average matrices
( binomial_cm.ave <- round(binomial_cm / nrow(cm), digits=0) )