Pues bien, recientemente me tope con el siguiente problema, tenia un dataset del cual tenia que predecir su clase, esta clase no era binaria, es decir, era un conjunto de categorias, hasta aqui todo normal, peroooooooooooooo, despues me comentaron que de hecho no solo se tenia que predecir esa clase, si no que habia otras dos columnas que de hecho tambien eran clase y ninguna de ellas binarias, mmmmmmm a ver si lo puedo explicar con este dataset de ejemplo que encontre en el uci repository y que lo pueden descargar aqui.
Básicamente el dataset tiene 22 campos numericos que representan mediciones del sonido que hacen algunas especies de ranas, dicho dataset tiene tres categorias a clasificar : Families, Genus y Species, cada una de estas, asu vez, es una multiclase y sus datos son:
Families
- Bufonidae
- Dendrobatidae
- Hylidae
- Leptodactylidae
Genus
- Adenomera
- Ameerega
- Dendropsophus
- Hypsiboas
- Leptodactylus
- Osteocephalus
- Rhinella
- Scinax
Species
- AdenomeraAndre
- AdenomeraHylaedact
- Ameeregatrivittata
- HylaMinuta
- HypsiboasCinerascens
- HypsiboasCordobae
- LeptodactylusFuscus
- OsteocephalusOopha
- Rhinellagranulosa
- ScinaxRuber
Y es aqui donde las cosas se vuelven interesantes, para una misma entrada tendremos tres etiquetas, a decir : familie, genus y Species las cuales tendremos que clasificar y cada una de esta etiquetas contien varias categorias, entonces ¿Cómo trabajamos con estos datasets?
En esta entrada les explicaré paso a paso como trabajar con estos conjuntos de datos, usaré el lenguaje python por practicidad, sin embargo, explicaré como funcionan los algoritmos para que puedan implementarlos en el lenguaje de su preferencia, asi que, manos a la obra
Primero importamos las librerias que ocuparemos:
Ahora crearemos una función que recibirá un clasificador 'x' , datos de entrenamiento asi como de testeo y nos regresará su desempeño
Ahora cargaremos y estudiaremos nuestro dataset (para los que no sepan python, el método .head() me imprime las primeras 5 filas )
Y bueno, nuestro conjunto de datos consta de 7195 filas y 26 columnas, de las cuales 3 de ellas son nuestras etiquetas y las demas son nuestros datos, todos ellos numericos, podemos ver que no tenemos que realizar mucha limpieza, a decir verdad , solo convertiré las columnas clases en categorias para mejorar un poco el performance.
Bien, el siguiente paso será convertir cada clase en una columna binaria para que los algoritmos puedan funcionar
Y lo mismo con las otras dos clases
Concatenamos los dataframes
Separemos en dos dataframes el dataframe original, a decir, uno que represente los datos y otro las clases
Ahora generamos los conjuntos de entrenamiento y testeo
Listo y ¿ahora qué?, bueno, no podemos usar cualquier algoritmo aqui por que fallaria estrepitosamente, ya que tenemos un problema de multilabel, es decir, tenemos que clasificar aqui tres clases en vez de una, veamos un ejemplo de como fallaria cualquier algoritmo
Entonces ¿Qué hacemos? , bueno tenemos tres formas de enfrentarnos a estos problemas:
- - Binary Relevance
- - Classifier Chains
- - Label Powerset
Binary Relevance:
Este es el divide y vencerás, básicamente toma cada posible clase individualmente y la clasifica, luego concatena todo y obtiene el resultado:
Original:
Lo convierte en:
Classifier Chains
Esta técnica primero toma solo una columna de clase y la clasifica, luego toma otra columna de clase para clasificarla pero la primera formará parte de los datos , luego tomará una tercera y las dos primeras formaran parte de los datos, mmm una imagen muestra mejor este proceso.
Original :
Lo convierte en :
Los datos sombreados en amarillo son los que usariamos para clasificar nuestra clase
Label Powerset
A mi parecer el mas sencillo de entender, aqui intentamos etiquetar las diferentes condiciones en que se generan las clases y creamos clases nuevas
Original :
Lo convierte en :
Este método es el mas simple, sin embargo, cabe mencionar que requeririamos de tener todas las posibles combinaciones para generar todas las clases posibles
¿Qué método es mejor?, bueno sinceramente es mejor experimentar todos los casos para ver cual se acomoda a nuestro problema, para python tenemos que la libreria skmultilearn.problem_transform nos regala estos metodos, entonces manos a la obra
Como observamos , al menos para este dataset, las técnicas que mejor se comportaron fueron Chain y label, ya aqui es cuestión, dependiendo de nuestro problema tomar una desicion.
Espero les haya gustado esta entrada.
por cierto pueden descargar el código completo Aqui