2. Análisis de concordancia en variables categóricas

Clasificaciones binomiales

Casos donde la prueba diagnóstica solo presenta dos resultados distintos.

Analizamos si dos agentes que clasifican a los individuos según el resultado de la p.d. concuerdan en sus opiniones. También me sirve la discordancia completa. (sé que un agente siempre clasifica lo contrario al otro agente)

Como la p.d. depende del agente que me da la medida, tengo una variable aleatoria por cada agente.

X = “clasificación dada por el observador A.”
Y = “clasificación dada por el observador B.”

Dado un individuo este es analizado por el agente A y por el agente B.

\[ \displaylines{ & \text {Medidas para cada inidividuo} \\ &\begin{array}{ccc} \hline \text{individuo k} & X_k & Y_k \end{array} } \]

Resumen de la información del modelo teórico.

Suponemos distribución de probabilidad conjunta.

\[ \begin{array}{c|c c c c} & & \textbf{Y} & & \\ & \textbf{Categoría} & \textbf{1} & \textbf{2} & \textbf{Total} \\ \hline \textbf{X} & \textbf{1} & \pi_{11} & \pi_{12} & \pi_{1\cdot} \\ & \textbf{2} & \pi_{21} & \pi_{22} & \pi_{2\cdot} \\ \hline & \textbf{Total} & \pi_{\cdot1} & \pi_{\cdot2} & 1 \\ \end{array} \]

\[ \begin{array}{} &\pi_{.j} = (X,Y) \epsilon {(1,1),(1,2),(2,1),(2,2)} \\ \pi_{ij} = \text{p({X=i, Y=j})} & \pi_{i.} = \text{p({Y=j})} & \pi_{.j} = \text{p({X=i})} \\ \end{array} \]

Acuerdo observado o Índice de concordancia global

Es la aproximación a la concordancia más intuitiva. Expresa el porcentaje de coincidencia en la clasificación de ambos agentes.

El problema que plantea este índice básico es que una parte de ese acuerdo puede deberse exclusivamente al azar.

Medir la concordancia es saber la probabilidad con la que los dos dan la misma clasificación.

Medida de concordancia global: \(\Pi_0 = \pi_{11} + \pi_{22} = \sum_{i=j} \pi_{ij}\)

Ejemplo 1.0.

Se recogen las respuestas a las entrevistas 1 y 2 de manera independiente.

Entrevista 1: ¿Consume usted suplementos vitamínicos?
Entrevista 2: Responda si consume vitaminas sin contar sus aportes alimentarios

  • Caso 1. Concordancia perfecta. {X=Y} o {X\(\neq\)Y}
    p({X=Y})=1

\[ \begin{array}{c|c c c c} & & \textbf{Entervista 1} \\ & & \textbf{No} & \textbf{Sí} & \textbf{Total} \\ \hline \textbf{Entrevista 2} & \textbf{No} & 0.6 & 0 & 0.6 \\ & \textbf{Sí} & 0 & 0.4 & 0.4 \\ \hline & \textbf{Total} & 0.6 & 0.4 & 1 \\ \end{array} \]

La probabilidad de que un individuo conteste lo mismo en ambos cuestionarios es 1.

  • Caso 2. Concordancia.

\[ \begin{array}{c|c c c c} & & \textbf{Entervista 1} \\ & & \textbf{No} & \textbf{2} & \textbf{Sí} \\ \hline \textbf{Entrevista 2} & \textbf{No} & 0.4 & 0.2 & 0.6 \\ & \textbf{Sí} & 0.2 & 0.2 & 0.4 \\ \hline & \textbf{Total} & 0.6 & 0.4 & 1 \\ \end{array} \]

La probabilidad de dar la misma respuesta es 0.8.

  • Caso 3. Sin concordancia.

Las dos entrevistas concuerdan el 40 % de las ocasiones. Puede no haber asociación real entre las dos entrevistas porque toda la concordancia puede atribuirse al azar.

\[ \begin{array}{c|c c c c} & & \textbf{Entervista 1} \\ & & \textbf{No} & \textbf{Sí} & \textbf{Total} \\ \hline \textbf{Entrevista 2} & \textbf{No} & 0.3 & 0.3 & 0.6 \\ & \textbf{Sí} & 0.3 & 0.1 & 0.4 \\ \hline & \textbf{Total} & 0.6 & 0.4 & 1 \\ \end{array} \]

¿Cuál sería la distribución de las respuestas si los individuos responden tirando una moneda? (cara: no, cruz: sí)

p(X=“no”, Y=“sí”) = p(“sale cara primera moneda”, “sale cara segunda moneda”) = 0.5 * 0.5 = 0.25

p(X=“sí”, Y=“no”) = p(X=“no”, Y=“no”) = p(X=“sí”, Y=“sí”) = 0.25

\(\pi_{0}\) = 0.25 + 0.25 = 0.5
\(\pi_{i} = \pi_{1.} * \pi_{.1} + \pi_{2.} * \pi_{.2}\) = 0.5 * 0.5 + 0.5 * 0.5 (concordancia debida al azar)

\[ \begin{array}{c|c c c c} & & \textbf{Entervista 1} \\ & & \textbf{No} & \textbf{Sí} & \textbf{Total} \\ \hline \textbf{Entrevista 2} & \textbf{No} & 0.25 & 0.25 & 0.5 \\ & \textbf{Sí} & 0.25 & 0.25 & 0.5 \\ \hline & \textbf{Total} & 0.5 & 0.5 & 1 \\ \end{array} \]

Esta sería la máxima no concordancia, ya que si la diagonal principal acumula menos de la mitad de los casos podríamos medir una concordancia inversa.

El problema de \(\Pi_{0}\) es que incluye concordancia que puede atribuirse al azar. Y concordar por azar no es concordar.

Y bailar de lejos no es bailar.

Si los dos observadores clasificasen de forma independiente y, por tanto, totalmente al azar entre las dos categorías, la probabilidad de la concordancia \(p(X=Y)\) sería:

Medida de concordancia debida al azar: \(\Pi_c = \pi_{1.}\pi_{.1} + \pi_{2.}\pi_{.2} = \sum_{k=1,2} \pi_{k.}\pi_{.k}\)

A la concordancia global debo restarle la concordancia del azar.

Índice kappa (de Cohen)

Este índice es una medida basada en resultados teóricos.

\[k = \frac{\Pi_0-\Pi_c}{1-\Pi_c}\] tal que \[\Pi_0 = \pi_{11} + \pi_{22} \quad \text{y} \quad \Pi_c = \pi_{1.}\pi_{.1} + \pi_{2.}\pi_{.2}\]

A la concordancia le quita la concordancia debida al azar y lo compara con la concordancia perfecto sin contar la concordancia al azar. Es decir, a la concordancia y a la concordancia perfecta les substrae la concordancia debida al azar y compara la concordancia sin el azar obtenida contra la máxima concordancia sin el azar posible.

Podemos tener resultados negativos: el intervalor [-1,0) es sin corcondancia.

Ejemplo 1.0.

  • Caso 1. Concordancia perfecta.

\[ \begin{array}{c|c c c c} & & \textbf{Entervista 1} \\ & & \textbf{No} & \textbf{Sí} & \textbf{Total} \\ \hline \textbf{Entrevista 2} & \textbf{No} & 0.6 & 0 & 0.6 \\ & \textbf{Sí} & 0 & 0.4 & 0.4 \\ \hline & \textbf{Total} & 0.6 & 0.4 & 1 \\ \end{array} \]

Cuando tengo una concordancia perfecta, la concordancia debido al azar es 0.5.

\(\Pi_c = \pi_{1.}\pi_{.1} + \pi_{2.}\pi_{.2} = 0.36 + 0.24 = 0.5\)

Y POR EEEEEEEEEEEESO, usamos el índice kappa del señor Cohen.

  • Caso 3. Sin corcondancia.

Si la concordancia observada \(\Pi_0\) coincide con la concordancia esperada por el azar \(\Pi_1\) el índice kappa toma el valor 0.

\[ \begin{array}{c|c c c c} & & \textbf{Entervista 1} \\ & & \textbf{No} & \textbf{Sí} & \textbf{Total} \\ \hline \textbf{Entrevista 2} & \textbf{No} & 0.25 & 0.25 & 0.5 \\ & \textbf{Sí} & 0.25 & 0.25 & 0.5 \\ \hline & \textbf{Total} & 0.5 & 0.5 & 1 \\ \end{array} \] \(\Pi_0 = \pi_{11} + \pi_{22} = 0.5\) y \(\Pi_c = \pi_{1.}\pi_{.1} + \pi_{2.}\pi_{.2} = 0.5*0.5 + 0.5*0.5 = 0.5\)

\(k = \frac{0.5-0.5}{1-0.5} = 0\)

\[ \begin{array}{c|c c c c} & & \textbf{Entervista 1} \\ & & \textbf{No} & \textbf{Sí} & \textbf{Total} \\ \hline \textbf{Entrevista 2} & \textbf{No} & 0.3 & 0.3 & 0.6 \\ & \textbf{Sí} & 0.3 & 0.1 & 0.4 \\ \hline & \textbf{Total} & 0.6 & 0.4 & 1 \\ \end{array} \]

\(\Pi_0 = \pi_{11} + \pi_{22} = 0.4\) y \(\Pi_c = \pi_{1.}\pi_{.1} + \pi_{2.}\pi_{.2} = 0.6*0.6 + 0.4*0.4 = 0.52\)

\(k = \frac{0.4-0.52}{1-0.52} = -0.25\)

Interpretación del índice kappa (si \(k\)>0)

Los datos observados son un caso particular.

La probabilidad de acuerdo observado es una media ponderada del máximo acuerdo y del acuerdo debido al azar \(\Pi_c\), siendo \(k\) el peso del máximo acuerdo.

\[ \displaylines{ k = \frac{\Pi_0-\Pi_c}{1-\Pi_c} \\ \\ k * (1-\Pi_{i}) = (\Pi_{0} - \Pi_{c}) \\ \\ \Pi_{0} = k + (1-k)*\Pi_{c} } \]

El acuerdo observado es una combinación de la concordania perfecta y concordania debida al azar. El ínidce kappa da más peso a uno u otro.

Ejemplo 1.1.

\[ \begin{array}{cc|ccc} & & \textbf{Radiólogo A} \\ & & \textbf{Pulmonía} & \textbf{No pulmonía} & \textbf{Total} \\ \hline \textbf{Radiólogo B} & \textbf{Pulmonía} & 0.04 & 0.06 & 0.10 \\ & \textbf{No pulmonía} & 0.10 & 0.80 & 0.90 \\ \hline & \textbf{Total} & 0.14 & 0.86 & 1 \\ \end{array} \]

data <- matrix(c(0.04, 0.06, 0.10, 0.80), nrow = 2, byrow = TRUE,
               dimnames = list(c("Pulmonía B", "No pulmonía B"),
                               c("Pulmonía A", "No pulmonía A")))
data
              Pulmonía A No pulmonía A
Pulmonía B          0.04          0.06
No pulmonía B       0.10          0.80
df <- data.frame(col1 = c(0.04, 0.10),
                 col2 = c(0.06, 0.80)
)
colnames(df) <- c("Pulmonía A", "No pulmonía A")
rownames(df) <- c("Pulmonía B", "No pulmonía B")
df
              Pulmonía A No pulmonía A
Pulmonía B          0.04          0.06
No pulmonía B       0.10          0.80

\(\Pi_{0} = \text{"concordancia absoluta"} = 0.04 + 0.80 = 0.84\)

(pi_0 <- data[1,1] + data[2,2])
[1] 0.84
(pi_0 <- df[1,1] + df[2,2])
[1] 0.84
(pi_0 <- df["Pulmonía B","Pulmonía A"] + df["No pulmonía B","No pulmonía A"])
[1] 0.84

\(\Pi_{1} = \text{"concordancia debida al azar"} = 0.10*0.14 + 0.86*0.90 = 0.788\)

(pi_1 <- sum(df["Pulmonía A"]) * sum(df["Pulmonía B",])  + sum(df["No pulmonía A"]) * sum(df["No pulmonía B",]))
[1] 0.788
(pi_1 <- sum(df[1]) * sum(df[1,])  + sum(df[2]) * sum(df[2,]))
[1] 0.788
(pi_1 <- sum(data[1,])*sum(data[,1]) + sum(data[2,])*sum(data[,2]))
[1] 0.788

Interpretación.]{underline}
La concordancia observada en los informes (84%) está compuesta por un 24,5% de la concordancia máxima y un 78,8% de la esperada al azar.

Clasificaciones multinomiales

\[ \begin{array}{c|c c c c} & & \textbf{Y} & & \\ & \textbf{Categoría} & \textbf{1} & \textbf{...} & \textbf{t} & \textbf{Total} \\ \hline \textbf{X} & \textbf{1} & \pi_{11} & ... & \pi_{1t} & \pi_{1\cdot} \\ & \textbf{2} & \pi_{21} & ... & \pi_{2t} & \pi_{2\cdot} \\ & \textbf{...} & ... & ... & ... & ... \\ & \textbf{t} & \pi_{2t} & ... & \pi_{tt} & \pi_{t\cdot} \\ \hline & \textbf{Total} & \pi_{\cdot1} & ... & \pi_{\cdot t} & 1 \\ \end{array} \]

Medida de concordancia global: \(\Pi_0 = \sum_{i=1}^{t} \pi_{ii}\)

Medida de concordancia debida al azar: \(\Pi_c = \sum_{i=1}^{t} \pi_{i.}\pi_{.i}\)

Índice kappa: \(k = \frac{\Pi_0-\Pi_c}{1-\Pi_c}\)

Hay veces que nos interesa saber si la concordancia es mayor en unas categorías o en otras. Por ejemplo, en la categoría grave hay muchas concordancia pero en las categorías leve y media no. En este caso se suele estandarizar para tener dos categorías y medir concordancia para cada categoría.

Ejemplo 1.2.

df <- data.frame(rbind(c(0.1125, 0.1, 0.0375),
                       c(0.1125, 0.3625, 0.0625),
                       c(0, 0.0375, 0.175))
)
colnames(df) <- c("Leve", "Moderada", "Grave")
rownames(df) <- c("Leve", "Moderada", "Grave")
df
           Leve Moderada  Grave
Leve     0.1125   0.1000 0.0375
Moderada 0.1125   0.3625 0.0625
Grave    0.0000   0.0375 0.1750
df_extended <- rbind(df, "Total" = colSums(df))
df_extended
           Leve Moderada  Grave
Leve     0.1125   0.1000 0.0375
Moderada 0.1125   0.3625 0.0625
Grave    0.0000   0.0375 0.1750
Total    0.2250   0.5000 0.2750
df_extended <- df_extended |> mutate("Total" = rowSums(df_extended)) # arreglar lo de las librerías
df_extended
           Leve Moderada  Grave  Total
Leve     0.1125   0.1000 0.0375 0.2500
Moderada 0.1125   0.3625 0.0625 0.5375
Grave    0.0000   0.0375 0.1750 0.2125
Total    0.2250   0.5000 0.2750 1.0000

Medida de concordancia global

(pi_0 <- sum(diag(as.matrix(df))))
[1] 0.65

Medida de concordancia debida al azar

pi_1 <- 0
t <- dim(df_extended)[1]
for (i in seq(1:(t-1))){
  pi_1 <- pi_1 + df_extended[i,t]*df_extended[t,i]
}
(pi_1 <- pi_1 |> unname())
[1] 0.3834375

Índice kappa

(k <- ((pi_0 - pi_1) / (1 - pi_1)) |> unname())
[1] 0.4323365

El índice kappa no mide la distancia entre las discordancias. No es lo mismo decir (X=7, Y=8) que (X=7, Y=2).

Comparando cada categoría con el resto

df
           Leve Moderada  Grave
Leve     0.1125   0.1000 0.0375
Moderada 0.1125   0.3625 0.0625
Grave    0.0000   0.0375 0.1750
Código
cat <- "Leve"
print(paste("Categoría de referencia:", cat))

df_new <- df |> mutate("Otras" = df[,names(df)[!names(df) %in% cat]] |> rowSums()) |> select(-c( names(df)[!names(df) %in% cat]))

df_new["Otras",] <- df_new %>% filter(!row.names(df_new) %in% c(cat)) |> colSums()
df_new <- df_new |> filter(rownames(df_new) %in% c(cat,"Otras"))

df_extended <- rbind(df_new, "Total" = colSums(df_new))
df_new_extended <- df_extended |> mutate("Total" = rowSums(df_extended)) # arreglar lo de las librerías
(df_new_extended)

print("Medida de concordancia global:")
(pi_0 <- sum(diag(as.matrix(df_new))))

print("Medida de concordancia debida al azar:")
pi_1 <- 0
t <- dim(df_new_extended)[1]
for (i in seq(1:(t-1))){
  pi_1 <- pi_1 + df_new_extended[i,t]*df_new_extended[t,i]
}
(pi_1 <- pi_1 |> unname())

print("Índice kappa:")
(k <- ((pi_0 - pi_1) / (1 - pi_1)) |> unname())
[1] "Categoría de referencia: Leve"
        Leve  Otras Total
Leve  0.1125 0.1375  0.25
Otras 0.1125 0.6375  0.75
Total 0.2250 0.7750  1.00
[1] "Medida de concordancia global:"
[1] 0.75
[1] "Medida de concordancia debida al azar:"
[1] 0.6375
[1] "Índice kappa:"
[1] 0.3103448
Código
cat <- "Moderada"
print(paste("Categoría de referencia:", cat))

df_new <- df |> mutate("Otras" = df[,names(df)[!names(df) %in% cat]] |> rowSums()) |> select(-c( names(df)[!names(df) %in% cat]))

df_new["Otras",] <- df_new %>% filter(!row.names(df_new) %in% c(cat)) |> colSums()
df_new <- df_new |> filter(rownames(df_new) %in% c(cat,"Otras"))

df_extended <- rbind(df_new, "Total" = colSums(df_new))
df_new_extended <- df_extended |> mutate("Total" = rowSums(df_extended)) # arreglar lo de las librerías
(df_new_extended)

print("Medida de concordancia global:")
(pi_0 <- sum(diag(as.matrix(df_new))))

print("Medida de concordancia debida al azar:")
pi_1 <- 0
t <- dim(df_new_extended)[1]
for (i in seq(1:(t-1))){
  pi_1 <- pi_1 + df_new_extended[i,t]*df_new_extended[t,i]
}
(pi_1 <- pi_1 |> unname())

print("Índice kappa:")
(k <- ((pi_0 - pi_1) / (1 - pi_1)) |> unname())
[1] "Categoría de referencia: Moderada"
         Moderada Otras  Total
Moderada   0.3625 0.175 0.5375
Otras      0.1375 0.325 0.4625
Total      0.5000 0.500 1.0000
[1] "Medida de concordancia global:"
[1] 0.6875
[1] "Medida de concordancia debida al azar:"
[1] 0.5
[1] "Índice kappa:"
[1] 0.375
Código
cat <- "Grave"
print(paste("Categoría de referencia:", cat))

df_new <- df |> mutate("Otras" = df[,names(df)[!names(df) %in% cat]] |> rowSums()) |> select(-c( names(df)[!names(df) %in% cat]))

df_new["Otras",] <- df_new %>% filter(!row.names(df_new) %in% c(cat)) |> colSums()
df_new <- df_new |> filter(rownames(df_new) %in% c(cat,"Otras"))

df_extended <- rbind(df_new, "Total" = colSums(df_new))
df_new_extended <- df_extended |> mutate("Total" = rowSums(df_extended)) # arreglar lo de las librerías
(df_new_extended)

print("Medida de concordancia global:")
(pi_0 <- sum(diag(as.matrix(df_new))))

print("Medida de concordancia debida al azar:")
pi_1 <- 0
t <- dim(df_new_extended)[1]
for (i in seq(1:(t-1))){
  pi_1 <- pi_1 + df_new_extended[i,t]*df_new_extended[t,i]
}
(pi_1 <- pi_1 |> unname())

print("Índice kappa:")
(k <- ((pi_0 - pi_1) / (1 - pi_1)) |> unname())
[1] "Categoría de referencia: Grave"
      Grave  Otras  Total
Grave 0.175 0.0375 0.2125
Otras 0.100 0.6875 0.7875
Total 0.275 0.7250 1.0000
[1] "Medida de concordancia global:"
[1] 0.8625
[1] "Medida de concordancia debida al azar:"
[1] 0.629375
[1] "Índice kappa:"
[1] 0.6290051

Hasta ahora hemos hablado de probabilidades ya que estamos con el modelo teórico. Cuando trabajamos con datos de una muestra hablaremos de porcentajes. \(\Rightarrow\) “Este % es consecuencia de un acuerdo de xx y un azar de xx”

El índice kappa tiene una distribución teórica y lo estimo según una muestra. Con una poca información (la muestra) doy un intervalo. No doy intervalos de confianza para valores desconocidos sino para las estimaciones.

Inconvenientes del índice kappa

Ejemplo 1.1.

\[ \begin{array}{cc|ccc} & & \textbf{Radiólogo A} \\ & & \textbf{Pulmonía} & \textbf{No pulmonía} & \textbf{Total} \\ \hline \textbf{Radiólogo B} & \textbf{Pulmonía} & 0.04 & 0.06 & 0.10 \\ & \textbf{No pulmonía} & 0.10 & 0.80 & 0.90 \\ \hline & \textbf{Total} & 0.14 & 0.86 & 1 \\ \end{array} \]

La prevalencia de pulmonía es baja: 014 para el radiólogo A y 0.1 para el rediólogo B.

Ambas marginales desequilibradas: la prevalencia observada dista mucho de 0.5 (a favor de los diagnósticos negativos)

El bajo valor del índice kappa se explica porque nos encontramos en el peor de los escenarios: baja prevalencia y marginales desequilibradas.

(pi_0 <- data[1,1] + data[2,2])
## [1] 0.84
(pi_1 <- sum(df["Pulmonía A"]) * sum(df["Pulmonía B",])  + sum(df["No pulmonía A"]) * sum(df["No pulmonía B",]))
## [1] 0.788
(k <- ((pi_0 - pi_1) / (1 - pi_1)) |> unname())
## [1] 0.245283

El valor del índice kappa depende de la prevalencia de la característica observada.

Ejemplo 1.1.a.

\[ \begin{array}{cc|ccc} & & \textbf{Radiólogo A} \\ & & \textbf{Pulmonía} & \textbf{No pulmonía} & \textbf{Total} \\ \hline \textbf{Radiólogo B} & \textbf{Pulmonía} & 0.30 & 0.06 & 0.36 \\ & \textbf{No pulmonía} & 0.10 & 0.54 & 0.64 \\ \hline & \textbf{Total} & 0.40 & 0.60 & 1 \\ \end{array} \]

Aumentamos la prevalencia: 0.40 para el radiólogo A y 0.36 para el rediólogo B.

(pi_0 <- data[1,1] + data[2,2])
## [1] 0.84
(pi_1 <- sum(df["Pulmonía A"]) * sum(df["Pulmonía B",])  + sum(df["No pulmonía A"]) * sum(df["No pulmonía B",]))
## [1] 0.528
(k <- ((pi_0 - pi_1) / (1 - pi_1)) |> unname())
## [1] 0.6610169

Cuanto más cercana a 0,5 sea la prevalencia (más equilibradas estén las marginales) mayor es el índice kappa, para igual probabilidad de acuerdos observados.

\[\Downarrow\]

Prevalencias muy altas o muy bajas penalizan el índice kappa.

El valor del índice kappa depende de la simetría y homogeneidad de las marginales.

En el primer caso el comportamiento de los agentes es homogéneo: pues ambos emiten informes positivos con mayor frecuencia.

En el segundo caso el comportamiento de los agentes es heterogéneo y asimétrico.

En ambos casos los diagnósticos del agente A distan 0.2 de 0.5.

\[ \begin{array}{cc|ccc} & & \textbf{Radiólogo A} \\ & & \textbf{Pulmonía} & \textbf{No pulmonía} & \textbf{Total} \\ \hline \textbf{Radiólogo B} & \textbf{Pulmonía} & 0.45 & 0.15 & 0.60 \\ & \textbf{No pulmonía} & 0.25 & 0.15 & 0.40 \\ \hline & \textbf{Total} & 0.70 & 0.30 & 1 \\ & & 0.50+0.20 & 0.50-0.20 & \\ \end{array} \]

(pi_0 <- data[1,1] + data[2,2])
## [1] 0.84
(pi_1 <- sum(df["Pulmonía A"]) * sum(df["Pulmonía B",])  + sum(df["No pulmonía A"]) * sum(df["No pulmonía B",]))
## [1] 0.54
(k <- ((pi_0 - pi_1) / (1 - pi_1)) |> unname())
## [1] 0.6521739

\[ \begin{array}{cc|ccc} & & \textbf{Radiólogo A} \\ & & \textbf{Pulmonía} & \textbf{No pulmonía} & \textbf{Total} \\ \hline \textbf{Radiólogo B} & \textbf{Pulmonía} & 0.25 & 0.35 & 0.60 \\ & \textbf{No pulmonía} & 0.05 & 0.35 & 0.40 \\ \hline & \textbf{Total} & 0.30 & 0.70 & 1 \\ & & 0.50-0.20 & 0.50+0.20 & \\ \end{array} \]

(pi_0 <- data[1,1] + data[2,2])
## [1] 0.84
(pi_1 <- sum(df["Pulmonía A"]) * sum(df["Pulmonía B",])  + sum(df["No pulmonía A"]) * sum(df["No pulmonía B",]))
## [1] 0.46
(k <- ((pi_0 - pi_1) / (1 - pi_1)) |> unname())
## [1] 0.7037037

El valor del índice kappa depende del equilibrio de las marginales.

Cuanto mayor sea la diferencia de la prevalencia observada de cada agente respecto de 0.5 mayor es el índice kappa. (incluso para un mismo valor de acuerdos observados).

Índice kappa ponderado.

Sólo tiene sentido para variables ordinales.

Está diseñado para recoger la idea de que algunas discordancias son más severas que otras y, por tanto, asigna pesos que representan la importancia entre los desacuerdos. El máximo peso se da a la concordancia perfecta y pesos proporcionalmente menores según la importancia del desacuerdo.

No tiene la misma importancia un desacuerdo en la clasificación entre las categorías leve y moderada que entre leve y grave, obviamente la última representa un mayor desacuerdo que la primera.

Medida de concordancia global: \(\Pi_0 = \sum_{i=1}^{t} \sum_{j=1}^{t} w_{ij} \pi_{ij}\)

Medida de concordancia debida al azar: \(\Pi_c = \sum_{i=1}^{t} \sum_{j=1}^{t} w_{ij} \pi_{i.}\pi_{.j}\)

Índice kappa: \(k_{w} = \frac{\Pi_0-\Pi_c}{1-\Pi_c}\)

Los pesos satisfacen:

\[ w_{ij} = \begin{cases} w_{ii} = 1 \\ 0 \le w_{ij} \le 1 \\ w_{ij} = w_{ji} \end{cases} \]

\[ w_{ij} = \begin{cases} 1, \hspace{1em} i = j \\ 0, \hspace{1em} i \neq j \\ \end{cases} \hspace{1em} \text{sii} \hspace{1em} k_{w} = k \\ \] \[ \text{si t = 2} \Rightarrow k_{w} = k \]

Ponderaciones.

  • Cicchetti-Allison (1971) \(w_{ij} = 1 - \frac{|i-j|}{t-1}\)

  • Fleiss-Cohen (1973) \(w_{ij} = 1 - \frac{(i-j)^2}{(t-1)^2}\)

Tratamiento muestral de los índices kappa

Sea:

  • n el número de individuos en la muestra.
  • \(p_ij\) la proporción de individuos asignados a la categoría i por el observador X y a la categoría j por el observador Y, donde i, j =1,2,…,t.
  • \(p_{i.}\) la proporción marginal de que un sujeto sea asignado a la clase i por el observador X (análogo para \(p_{.j}\), la clase j y el observador Y), donde i, j =1,2,…,t.
    • \(p_{i.}\) = \(p_{i1}\) + … + \(p_{it}\)
    • \(p_{.j}\) = \(p_{1j}\) + … + \(p_{tj}\)

Tenemos:

\[E(p_{ij}) = \pi_{ij}, \quad E(p_{i.}) = \pi_{i.}, \quad E(p_{.j}) = \pi_{.j}\]

El estimador del índice de kappa ponderado es:

\[ \kappa_w = \frac{P_0 - P_c}{1 - P_c}, \quad P_0 = \sum_{i=1}^{t}\sum_{j=1}^{t} w_{ij}p_{ij}, \quad P_c = \sum_{i=1}^{t}\sum_{j=1}^{t} w_{ij}p_{i.}p_{.j} \]

Es un estimador con una distribución asintótica normal.

\[ \kappa_w ~ N(\kappa_w, \sigma_{\kappa_w})\]

Tengo una distribucion normal centrada en k y al elegir un dato al azar (o sea, de la muestra aleatoria) puede tener un valor muy cercano o muy lejano de la media.

La varianza también es una estimación hecha con lo que yo he visto. Es otra estimación más. Esto hace que vayamos arrastrando aproximaciones AKA posibles errores.

\[ \displaylines{ \sigma^2_{\kappa_w} = \frac{\sum_i \sum_j \pi_{ij} \left[ w_{ij} - (\overline{w}_{i \cdot} + \overline{w}_{\cdot j})(1 - \kappa_w) \right]^2 - \left[ \kappa_w - \Pi_c (1 - \kappa_w) \right]^2}{n (1 - \Pi_c)^2} \\ \overline{w}_{i \cdot} = \sum_{j=1}^t \pi_{\cdot j} w_{ij} \\ \overline{w}_{\cdot j} = \sum_{i=1}^t \pi_{i \cdot} w_{ij} } \]

El estimador de esta varianza su contrapartida muestral, sustituyendo probabilidades por proporciones y el índice kappa por su estimador.

\[ \displaylines{ \hat{\sigma}^2_{\kappa_w} = s^2_{\kappa_w} = \frac{\sum_i \sum_j p_{ij} \left[ w_{ij} - (\hat{w}_{i \cdot} + \hat{w}_{\cdot j})(1 - \hat{\kappa}_w) \right]^2 - \left[ \hat{\kappa}_w - P_c (1 - \hat{\kappa}_w) \right]^2}{n (1 - P_c)^2} \\ \hat{w}_{i \cdot} = \sum_{j=1}^t p_{\cdot j} w_{ij} \\ \hat{w}_{\cdot j} = \sum_{i=1}^t p_{i \cdot} w_{ij} } \] Límites de confianza para el índice kappa con nivel de confianza \(\alpha\):

\[ \hat{\kappa}_w +- z_\alpha s_{\hat{\kappa}_w}\]

Escala de valoración del índice Kappa.

\[ \begin{array}{c|c} \textbf{Kappa} & \textbf{Grado de concordancia} \\ \hline < 0.00 & \text{Sin concordancia} \\ 0.00 - 0.20 & \text{Insignificante} \\ 0.20 - 0.40 & \text{Discreta} \\ 0.40 - 0.60 & \text{Moderada} \\ 0.60 - 0.80 & \text{Sustancial} \\ 0.80 - 1 & \text{Casi perfecta} \\ \end{array} \]

Ejemplo 1.3.

Dos radiólogos independientes informan de la presencia o ausencia de neumonía en 100 radiografías, siendo los resultados los siguientes.

\[ \begin{array}{cc|ccc} & & \textbf{Radiólogo A} \\ & & \textbf{Neumonía} & \textbf{No neumonía} & \textbf{Total} \\ \hline \textbf{Radiólogo B} & \textbf{Neumonía} & 4 & 6 & 10 \\ & \textbf{No neumonía} & 10 & 80 & 90 \\ \hline & \textbf{Total} & 14 & 86 & 100 \\ \end{array} \]

\(P_0 = \frac{4+80}{100} = 0.84 \quad \quad P_c = \frac{10*14 + 90*86}{100^2} = 0.788\)
\(\hat{\kappa_w} = \frac{0.84 - 0.788}{1 - 0.788} = 0.245\)
\(s^2_{\kappa_w} = 0.018 \quad \quad z_{0.05}s_{\kappa_w} = 1.65 \sqrt{0.018} = 0.22\)

Se podría hacer también un aproximación asintótica pero conlleva arrastrar una simulacion más.

La estimación puntual la tengo. Como no tengo una muestra más grande puedo remuestrear.

Los estimadores por intervalo miden la precision de la estimación puntual. Cómo de buena es esa estimación puntual para representar otra posible muestra que podríamos haber obtenido.

Una estimación puntual que se encuentra en alguno de los intervalos de Landis y Koch.

La validez de la estimacion hay que refrentarla con un IC. La estimación puntual de 0.245 se considera discreta y el \(IC_90 = (0.025, 0.465)\) abarca varios niveles, desde discreta hasta sustancial. Si el IC estuviera solo en el mismo intervalo que la estimación puntual diríamos que el IC respalda/valida la estimacion puntual. Al abarcar más de un nivel deberemos explicarlo.

En el 90 % de estudios similares a este tenemos una concordancia que iría desde insignificante a moderada. La validaz de nuestra estimación no es super cool, es cuestionable, ya que hay otros estudios donde podemos encontrar una concordancia diferente a la que hemos calculado en esta muestra.

H0: las opiniones son independientes (que no hay relación entre las opiniones) (si hay una concordancia que sea casual) AKA \(\rho\) = 0.

Para poder admitir \(\rho\) = 0 el IC tendría que darlo como un valor posible y en este caso no lo da. Rechazamos que haya un criterio diferente. (juzgamos que los dos puntúen por igual)

Ejemplo 1.4.

Dos psiquiatras evaluaron a 129 pacientes que habían sido diagnosticados previamente como clínicamente deprimidos. Las categorías de clasificación fueron: 0 para no deprimido, 1 para moderadamente deprimido y 2 para clínicamente deprimido. La tabla siguiente muestra los resultados de la clasificación realizada por los dos psiquiatras.

\[ \begin{array}{cc|ccc} & & \textbf{Psiquiatra 1} \\ & & \textbf{0} & \textbf{1} & \textbf{2} & \textbf{Total} \\ \hline \textbf{Psiquiatra 2} & \textbf{0} & 11 & 2 & 19 & 32 \\ & \textbf{1} & 1 & 3 & 3 & 7 \\ & \textbf{2} & 0 & 8 & 82 & 90 \\ \hline & \textbf{Total} & 12 & 13 & 104 & 129 \\ \end{array} \]

Datos.

Código
library(psych)
(A <- matrix(c(11,2,19,1,3,3,0,8,82),ncol=3,byrow=TRUE))
     [,1] [,2] [,3]
[1,]   11    2   19
[2,]    1    3    3
[3,]    0    8   82

Índice kappa en R por defecto.

En la diagonal pone peso 0 (yo quiero que en la diagonal tiene 1 y conforme me alejo lo voy bajando).

Índice kappa sin ponderar.

Le damos importancia a todo lo que coincide pero no le damos peso a la cercanía entre dos diagnósticos. La elección por el kappa ponderado es crucial cuando los niveles de clasificación son mayores a dos niveles.

Pesos Ciccetti y Allison.

Código
(w_CA<- matrix(c( 1,0.5,0, 0.5,1,0.5,0,0.5,1),ncol=3))
     [,1] [,2] [,3]
[1,]  1.0  0.5  0.0
[2,]  0.5  1.0  0.5
[3,]  0.0  0.5  1.0

Estimaciones de kappa.

Código
kappa1 <- cohen.kappa(A, w=w_CA, n.obs=sum(A), alpha=0.1)
str(kappa1)
## List of 11
##  $ kappa         : num 0.375
##  $ weighted.kappa: num 0.402
##  $ n.obs         : num 129
##  $ agree         : num [1:3, 1:3] 0.08527 0.00775 0 0.0155 0.02326 ...
##  $ weight        : num [1:3, 1:3] 1 0.5 0 0.5 1 0.5 0 0.5 1
##  $ var.kappa     : num 0.00622
##  $ var.weighted  : num 0.00688
##  $ confid        : num [1:2, 1:3] 0.245 0.265 0.375 0.402 0.504 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:2] "unweighted kappa" "weighted kappa"
##   .. ..$ : chr [1:3] "lower" "estimate" "upper"
##  $ plevel        : num 0.1
##  $ bad           : logi FALSE
##  $ Call          : language cohen.kappa1(x = x, w = w, n.obs = n.obs, alpha = alpha, levels = levels,      w.exp = w.exp)
##  - attr(*, "class")= chr [1:2] "psych" "kappa"
kappa1$kappa
## [1] 0.3745225
kappa1$weighted.kappa
## [1] 0.4018192
kappa1$var.kappa
## [1] 0.006221038
kappa1$var.weighted
## [1] 0.006884677
kappa1$confid
##                      lower  estimate     upper
## unweighted kappa 0.2447870 0.3745225 0.5042579
## weighted kappa   0.2653391 0.4018192 0.5382992

Pesos de Fleiss y Cohen.

(w_FC<- matrix(c( 1,0.75,0,0.75,1,0.75,0,0.75,1),ncol=3))
     [,1] [,2] [,3]
[1,] 1.00 0.75 0.00
[2,] 0.75 1.00 0.75
[3,] 0.00 0.75 1.00

Estimaciones de kappa.

Código
kappa2 <- cohen.kappa(A, w=w_FC, n.obs=sum(A),alpha=0.1)
str(kappa2)
## List of 11
##  $ kappa         : num 0.375
##  $ weighted.kappa: num 0.42
##  $ n.obs         : num 129
##  $ agree         : num [1:3, 1:3] 0.08527 0.00775 0 0.0155 0.02326 ...
##  $ weight        : num [1:3, 1:3] 1 0.75 0 0.75 1 0.75 0 0.75 1
##  $ var.kappa     : num 0.00622
##  $ var.weighted  : num 0.00796
##  $ confid        : num [1:2, 1:3] 0.245 0.274 0.375 0.42 0.504 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:2] "unweighted kappa" "weighted kappa"
##   .. ..$ : chr [1:3] "lower" "estimate" "upper"
##  $ plevel        : num 0.1
##  $ bad           : logi FALSE
##  $ Call          : language cohen.kappa1(x = x, w = w, n.obs = n.obs, alpha = alpha, levels = levels,      w.exp = w.exp)
##  - attr(*, "class")= chr [1:2] "psych" "kappa"
kappa2$weighted.kappa
## [1] 0.4203694
kappa2$var.weighted
## [1] 0.007955659
kappa2$confid
##                      lower  estimate     upper
## unweighted kappa 0.2447870 0.3745225 0.5042579
## weighted kappa   0.2736575 0.4203694 0.5670813

\[ \begin{array}{c|c} \textbf{Estadístico} & \textbf{Estimación} & \textbf{Varianza estimada} & LI_{90} \\ \hline \text{Kappa sin ponderar} & 0.3745225 & 0.006221038 & 0.2447870 \\ \text{Kappa ponderado (Ciccetti-Allison)} & 0.4018192 & 0.006884677 & 0.2653391 \\ \text{Kappa ponderado (Fleiss-Cohen)} & 04203694 & 0007955659 & 0.2736575 \\ \end{array} \]

Estamos teniendo resultados 0.3, 0.4. Las estimaciones puntuales nos incitan a concordancias moderadas. No podemos decir que no tengan un criterio común. algo tienen.

¿Qué pasha cuando tenemos que analizar la validez de una estimación pero tenemos una muestra pequeña? Po a la metodología booststrap

Nos vamos a Tema 3, página 55.

Depués de remuestrar tengo las 23 radiografías con la clasificación de los dos radiólogos cuando remuestre.

Obtengo muestras bootstrap con 23 radiografias pero la clasificación es la misma para cada radiografía.

Calculo el kappa \(\Rightarrow\) calculo las diferencias \(\Rightarrow\) Despercio las más alejadas \(\Rightarrow\) Me quedo con el 95 % central.

Si hay más de 2 observadores \(\Rightarrow\) Índice de Kappa para múltiples observadores (Fleiss JL Statistical Methods for Rates and Proportions, 2003)