Cómo validar la clasificación de coberturas en R con matrices de confusión

0.32. Ese fue el número que me devolvió la consola después de correr confusionMatrix() sobre mi primera clasificación de coberturas que de verdad quería mostrarle a alguien, y por un buen rato no supe si alegrarme o cerrar la laptop para siempre. Llevaba varias semanas metida en esto de la teledetección con R, armando un mapa —bosque nativo, matorral, plantación, agua— convencida de que por fin tenía algo sólido, hasta que el índice Kappa me aterrizó de un empujón. Porque una cosa es que la clasificación de coberturas se vea ordenada en pantalla, con sus cuadraditos verdes y cafés bien puestitos, y otra muy distinta es que la matriz de confusión confirme que ese orden es real.

Antes de llegar a ese número intenté hacer las cosas "como se debe", o sea, leyendo artículos científicos sobre teledetección para entender de una vez qué significaba validar un modelo. Grave error: el vocabulario técnico me bloqueó completamente, cada párrafo tenía tres palabras que no conocía y terminé más perdida que al principio, con varias pestañas abiertas y ninguna respuesta clara. Isidora, una compañera que conocí comentando los mismos tutoriales en YouTube sin entender del todo (las dos preguntándonos lo mismo en inglés), me escribió por esos días para avisarme de un video en español que por fin explicaba la matriz de confusión sin dar por sentado que una es ingeniera.

¿Por qué un mapa bonito no significa un mapa correcto?

Tabla de matriz de confusión en la consola de RStudio durante la validación de una clasificación de coberturas

Un mapa puede verse precioso y estar completamente equivocado, y ese fue justo mi problema durante varias tardes de invierno clasificando imágenes Landsat 8. No hace falta entender cada banda del sensor para partir. Eso lo dejo para cuando escriba sobre cómo se bajan las imágenes de satélite. Pero sí hace falta algo que a mí nadie me explicó al principio: separar los datos que usas para enseñarle a R qué es bosque de los datos que usas después para preguntarle si aprendió bien. Es como si el profesor te pasara las respuestas del examen antes de tomarlo.

Separar los puntos antes de confiar en la clasificación de coberturas

Separar los puntos antes de confiar en el resultado también significa aceptar que una parte de tu trabajo de campo —o de tus horas mirando Google Earth— tiene que quedar guardada bajo llave. En R, el paquete caret hace ese trabajo sucio: tomas todos los puntos que recolectaste, le pasas una porción grande al modelo para que aprenda (el set de entrenamiento) y escondes el resto (el set de validación) hasta que la clasificación esté terminada. Ahí recién sacas esos puntos guardados y le preguntas, punto por punto, si el modelo acertó o no.

Si te interesa cómo llegué a tener esas imágenes listas para clasificar, hace un tiempo escribí sobre cómo hacer un análisis multiespectral en R usando imágenes de satélite, que es básicamente el paso anterior a todo este enredo de la validación. Si la imagen de entrada viene mal, la matriz de confusión solo te va a confirmar el desastre con números.

Cuaderno con anotaciones a mano comparando árboles reales y píxeles de un mapa de teledetección en R

Lo raro es que una vez que entiendes la función confusionMatrix(), deja de dar miedo. No es solo un número: es una tabla que te dice exactamente dónde te equivocas. En mi caso, el modelo era bastante bueno reconociendo agua —se nota a leguas incluso con poca experiencia— pero se hacía bolsa apenas tenía que distinguir entre bosque nativo y una plantación forestal joven.

El Kappa que me bajó los humos

La precisión global —eso que en los tutoriales llaman "Overall Accuracy"— se veía decente, algo así como un 0.85, y por un segundo pensé que ya estaba. Pero el índice Kappa, que va de 0 a 1 y castiga los aciertos que podrían deberse solo al azar, marcó 0.32, y ese fue el número que me hizo sentir que mi clasificación de coberturas era casi una moneda al aire.

Ese resultado me obligó a mirar la matriz completa en vez de quedarme con el número resumen: la precisión del productor y la precisión del usuario, calculadas por separado para cada clase. Ahí quedó claro que el modelo decía "esto es bosque" casi siempre, aunque fueran matorrales, simple y llanamente porque yo le había dado muchísimos puntos de entrenamiento de bosque y casi ninguno de matorral. El número resumen escondía ese problema; la tabla completa no.

También me pasó que las nubes —tan típicas acá en el sur— dejaban compuestas que yo creía limpias pero no lo estaban del todo. Si alguna vez probaste visualizar series temporales de satélite en R para ver cambios forestales, sabrás que una nube mal descartada arruina cualquier matriz de validación en cosa de segundos.

Las clases desequilibradas explican más que el número final

Gráfico del índice Kappa junto a la matriz de confusión revisado una tarde lluviosa en Valdivia

Muchos tutoriales tratan el índice Kappa como la palabra final, pero confiar ciegamente en él es un error que he visto mencionado más de una vez: tiende a inflar o castigar la precisión cuando las clases están desequilibradas —mucho bosque, poca ciudad, por ejemplo— y cuando hay autocorrelación espacial, o sea, cuando los píxeles vecinos se parecen tanto entre sí que engañan a la estadística. No hace falta ser especialista para aplicarlo, pero sí para no creerle todo a ese número solo.

El sábado en la tarde salí a caminar un rato por el Mercado Fluvial, más que nada para despejarme antes de volver a mirar la pantalla. Ahí me acordé de Raimundo, un conocido del grupo de senderismo que fue quien me habló por primera vez de eso del NDVI, hace ya un tiempo, mientras bajábamos de un cerro. Si él me preguntara ahora si esto sirve para saber si el bosque donde anda buscando hongos está cambiando, creo que por fin le podría contestar con algo más que una corazonada.

Ese 0.32 no era una nota reprobatoria: era más bien un mapa de ruta, algo que me decía dejar de juntar tantos puntos de bosque nativo y salir a buscar más matorral y zonas agrícolas para que el modelo tuviera con qué comparar. Dolió un poco verlo tan bajo, lo reconozco, pero fue más útil que un 0.85 solitario y sin contexto.

Para la semana ocho de estar metida en esto de validar clasificaciones, ya no me ponía nerviosa cada vez que corría confusionMatrix(). Un domingo particularmente lluvioso corrí el script completo, de principio a fin, sin que apareciera ni una sola línea roja en la consola. Por primera vez el silencio en la pantalla se sintió como una buena señal, no como que algo se me había olvidado. En el escritorio de mi pieza, con la ventana empañada por el frío y la taza de té ya fría al lado del trackpad, guardé esa corrida en la carpeta de anotaciones donde llevo los errores que ya resolví, para no tener que pelear con lo mismo dos veces.

Si estás empezando a validar tus propios mapas, no le tengas miedo a los números bajos: el problema real llega si te sale todo perfecto a la primera, porque casi seguro significa que mezclaste los datos de entrenamiento con los de validación sin darte cuenta. Un Kappa modesto que te obliga a revisar tus clases vale más que una precisión alta en la que no confías del todo —esa es la diferencia entre un mapa que se ve bien y un mapa del que puedes hablar con seguridad.

Artículos relacionados