Buscar este blog

domingo, 2 de septiembre de 2018

Conjuntos de datos multi-etiquetas y multi-clases (multilabel and multiclass datasets)

De vez en cuando en nuestro trabajo del dia a dia como analistas de datos nos encontramos cosas curiosas, cosas que nos pueden llegar a dar un dolor de cabeza, y ¿cómo no?, pensar que siempre que nos enseñan algun algoritmo clasificador  es con datasets sencillos en donde todo sale bien, pero cuando recopilamos los datos en nuestro trabajo,¡Oh sorpresa! las cosas no son tan fáciles.

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:

  1. - Binary Relevance
  2. - Classifier Chains
  3. - Label Powerset
y basicamente hacen esto:

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