Otros artículos en esta sección

No hay entradas relacionadas

Machine Learning: El camino del dato hasta el modelo

Want create site? Find Free WordPress Themes and plugins.

Resumen del Meetup de Machine Learning

Alejandro Arranz de datahack labs, el 9 de enero impartió un meetup sobre Machine Learning en el auditorio del Campus Madrid que fue todo un éxito. En este wiki os traemos un resumen de lo que se vio en la sesión que esperamos que os resulte muy interesante.

El camino del dato hasta el modelo

A la hora de emprender un proyecto de Machine Learning, estamos acostumbrados a que sea un enfrentamiento entre nosotros y el conjunto de datos del cual hay que sacar algún tipo de valor. Una vez que el score de nuestro modelo contra el subconjunto de test es lo suficientemente satisfactorio, consideramos que nuestra labor está hecha.

La cosa cambia en un contexto laboral real, de repente somos parte de un flujo de datos donde es muy importante conocer nuestra ubicación. Es decir, quién nos provee los datos que utilizaremos para alimentar nuestro modelo y quien utilizará las predicciones del mismo.

 

Wiki de Machine Learning: el camino del dato hasta el modelo

Asimismo habrá que monitorizar nuestro modelo controlando su rendimiento y detectando si se deteriora y las posibles causas de ese deterioro.

Obtención de los datos y análisis preliminar

Una vez establezcamos el contexto, empezaremos a pensar en obtener los datos. En este caso se tratarán de datos un poco de juguete que descargaremos desde una URL a nuestro ordenador. Python nos ofrece varias librerías que pueden sernos útiles tanto para gestionar nuestros directorios locales (la librería os que proporciona distintas funcionalidades para interactuar con nuestro sistema operativo); como para realizar peticiones HTTP (la librería requests ofrece una manera fácil y efectiva para ello) y desempaquetar el contenido que nos descarguemos (la librería tarfile no solo nos permite gestionar el des/empaquetado de ficheros, sino también la des/compresión con gzip y bz2)

Una vez tengamos nuestro conjunto de datos en formato CSV (comma separated values), será muy sencillo cargarlo dentro de una estructura tabular conocida como DataFrame (similar a las hojas de cálculo de Excel) que en Python nos viene dada a través de la librería pandas y que facilita tremendamente el  manejo de nuestros datos. Parte de esta sencillez incluye el inferir los tipos de datos de las features de nuestro conjunto de datos, aunque dependiendo del tamaño del mismo, puede ser muy interesante especificar nosotros mismos dichos tipos, de lo contrario Python tenderá a reservar tipos más “amplios” para evitar pillarse los dedos con el tamaño de los datos. Por ejemplo, asignará a la feature edad un tipo FLOAT64, cuando con un UINT8 sobraría.

Una vez tenemos nuestro DataFrame de Pandas, podremos beneficiarnos de los métodos propios de esta estructura. Por ejemplo head() para tener una noción de como lucen los datos, info() para hacernos una idea de cuantos “huecos” o valores missing tenemos o describe() que nos permitirá obtener una serie de datos numéricos y estadísticos para hacernos una idea de cómo se distribuyen aquellas features numéricas.

Wiki de Machine Learning: el camino del dato hasta el modelo

El poder visualizar gráficamente la distribución de las features, permite complementar los estadísticos obtenidos mediante describe(). Para esto contamos con la librería matplotlib y el método de pandas, hist().

Wiki de Machine Learning: el camino del dato hasta el modelo

Separación en conjuntos de training y test

El conjunto de test es nuestra vía principal para saber cómo de bien va a ser nuestro modelo capaz de generalizar. Es decir, una vez entrenado con un conjunto de datos, ¿será capaz nuestro modelo de realizar predicciones correctas sobre datos que no haya visto antes?

Para asegurarnos de que la separación de nuestro dataset en training y test es constante independientemente de cuantas veces ejecutemos nuestro código. Scikit-learn (librería que cubre para nosotros funcionalidades que van desde el preproceso de datos hasta la construcción de modelos y scoring de los mismos) nos ofrece una manera efectiva y rápida de conseguir esto mediante la clase train_test_split. Aunque en ocasiones no es suficiente con garantizar que los datos de training y test no se van a mezclar. Sino que necesitamos también que la división respete las proporciones que existan para determinados estratos ocultos en nuestros datos. Por ejemplo, si en nuestro conjunto de datos tenemos un 5% de personas ricas, un 60% de clase media y un 35% de personas pobres, es muy posible que queramos que esta proporción se mantenga también en nuestro conjunto de entrenamiento y de test, para ello utilizaremos otra clase de scikit-learn llamada StratifiedShuffleSplit. A partir de aquí, las operaciones a realizar sobre los datos las haremos exclusivamente en el conjunto de training resultante de la división.

Correlaciones y combinación de features

Las correlaciones entre las distintas variables numéricas (dadas por el coeficiente de correlación de Pearson) ofrecen una manera de encontrar relaciones lineales entre ellas. No obstante hay que tener en cuenta varias cosas:

  • El coeficiente de Pearson permite descubrir relaciones lineales entre las variables.
  • El hecho de que dicho coeficiente sea 0 signifique que entre dos variables no hay correlación, esto no quita de que puedan existir relaciones no lineales entre ellas.
  • ¿Correlación y causalidad? Este es un tema espinoso, que dos variables presenten correlación, no significa necesariamente que una sea causa de la otra. Podría darse la circunstancia de que exista/n una o varias variables que no tengamos controladas y que estén ejerciendo su influencia en la sombra (estas se denominan factores de confusión).

Es sencillo calcular la matriz de correlaciones asociada a nuestras features y a nuestro target mediante el método corr() de nuestro DataFrame de pandas.

Wiki de Machine Learning: el camino del dato hasta el modelo

A partir de aquí, se nos pueden venir a la cabeza nuevas posibles features obtenidas a partir de las dadas. Para añadir una nueva feature a nuestro dataframe, simplemente nos referiremos a ella como si ya existiera y le asignaremos el valor que corresponda. Por ejemplo, una nueva feature podría resultar de la división entre sí de dos ya existentes. Hay que pensar que esto es un proceso iterativo y tampoco volverse loco combinando todas las features posibles.

Es interesante también utilizar funciones como scatter_matrix (contenido en el módulo pandas.plotting) para poder ver plasmadas las correlaciones a través de gráficos de dispersión.

Preparación de los datos

A la hora de preparar los datos, si las bibliotecas mencionadas (junto con numpy que nos permite gestionar estructuras matriciales n dimensionales) no nos resultan suficientes, implementaremos la funcionalidad necesaria normalmente a través de una clase a partir de BaseEstimator y TransformerMixing (localizadas en sklearn.base).

Una de las primeras cosas que tendremos que hacer es gestionar los valores ausentes. Para lo cual no existe una única manera: podemos eliminar aquellos registros que tengan valor ausente para cierta feature, podemos eliminar la feature entera si vemos que tiene demasiados missing o (lo que suele ser más razonable) imputar algún valor para rellenar los missing, esto puede ser la moda de la feature, la mediana, la media… ¡incluso cero! Realmente no existe una regla de oro, solamente se aconseja no ignorarlos.

Si se opta por la última y más frecuente de las opciones, imputar algún valor. Scikit-learn nos brinda la clase Imputer, que nos permitirá utilizar fácilmente distintas estrategias de imputación.

Otra parte de la preparación, es la gestión de variables categóricas ya que pocos  modelos trabajan bien con ellas. En este caso la aproximación que se toma es transformar los posibles valores de una variable categórica a números enteros o bien a notación one-hot. Lo que significa representar cada posible valor mediante una cadena de bits (tantos como valores posibles tenga la variable categórica). De manera que todos los bits sean 0 y solo uno (diferente para cada valor) sea 1 (de ahí lo de one hot).

De  nuevo scikit-learn nos provee de distintas clases para conseguir esto, por ejemplo de cara a las features tenemos LabelEncoder y OneHotEncoder:

  • El primero transforma las categorías en números enteros, hay que tener cuidado con esto ya que los números más próximos entre si indican que las categorías que representan son más similares entre sí.
  • El segundo permite realmente convertir features categóricas presentadas como números enteros a la codificación one hot.

En el caso de que lo nuestra label o target sea categórica, podemos utilizar LabelBinarizer que directamente transformará los valores de la variable a notación one hot.

Finalmente no hay que perder de vista la cuestión del escalado: nuestras features numéricas pueden presentarse en dimensiones de lo más variopintas. Desde las que van de 0 a 0.5 hasta aquellas que empiezan en 10000 y pueden ir hasta millones. El problema es que los modelos suelen ser bastante susceptibles a esta disparidad de dimensiones y para ello existe el escalado ó scaling.

Son múltiples los métodos que nos proporciona scikit-learn para realizar el escalado de variables. Aunque los más conocidos son el MinMaxScaler que restringe los rangos de valores de nuestras features numéricas a un límite dado (por defecto 0 y 1 aunque puede modificarse). Y también StandardScaler, que busca centrar la media de cada feature de manera que sea 0 y su desviación estándar de manera que sea 1, buscando así que la feature siga una distribución más simétrica. Ambos son muy sensibles a outliers (el primero más que el segundo) así que es mejor que nos hayamos preocupados de aquellos antes del escalado.

Lo juntamos todo

Al final del proceso uno termina juntándose con largas cadenas de procesamiento. En las que los diversos transformadores que hemos ido invocando (Imputer, Scaler…) se tienen que ejecutar uno después de otro. E incluso, las features numéricas se tienen que tratar independientemente de las categóricas ya que pasarán por un preprocesamiento distinto.

Para ello, contamos con dos estructuras principales Pipeline y FeatureUnion contenidas en el módulo sklearn.pipeline.

  • Pipeline nos permite construir una estructura tipo lista en la que cada elemento representará un paso del procesamiento porque el que pasarán secuencialmente los datos con los que se la invoque.
  • FeatureUnion responde a la necesidad de que en ciertas ocasiones no tiene porqué ser necesario un procesamiento secuencial. Sino que puede ser paralelo (¿qué necesidad hay de esperar a que terminen de procesarse las features categóricas para que empiecen las numéricas si pueden ocurrir en paralelo?).

Wiki de Machine Learning: el camino del dato hasta el modelo

A partir de aquí se puede seguir incluyendo más preprocesamiento. O, si creemos que ya ha llegado el momento, podemos empezar a probar con los distintos modelos que ofrece scikit-learn según nuestro tipo de problema, incorporándolo a nuestro Pipeline como un bloque más.

Esperamos que este pequeño viaje por la vida de los datos hasta que llegan al modelo os haya sido de utilidad. ¡Hasta la próxima!

Did you find apk for android? You can find new Free Android Games and apps.

¿Te ha parecido de ayuda este artículo?

Si
No
0
de
0
lo encontró de ayuda

Deja tu comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

d

datahack

91 091 28 42
Iniciar sesión