Transformación de funciones para el aprendizaje automático, una guía para principiantes

Cuando comencé a aprender cómo optimizar los modelos de aprendizaje automático, a menudo me encontraba, después de llegar a la etapa de construcción del modelo, que tenía que volver a revisar los datos para manejar mejor los tipos de características presentes en el conjunto de datos. Con el tiempo, descubrí que uno de los primeros pasos a seguir antes de construir los modelos es revisar cuidadosamente los tipos de variables presentes en los datos y tratar de determinar por adelantado el mejor proceso de transformación que se debe seguir para lograr el rendimiento óptimo del modelo.

En la siguiente publicación voy a describir el proceso que tomo para identificar y transformar cuatro tipos de variables comunes. Voy a utilizar un conjunto de datos tomado de la competencia de calentamiento "aprendizaje automático con corazón" alojada en el sitio web https://www.drivendata.org/. El conjunto de datos completo se puede descargar aquí https://www.drivendata.org/competitions/54/machine-learning-with-a-heart/data/. DrivenData presenta desafíos en línea regulares que se basan en la resolución de problemas sociales. Recientemente comencé a participar en algunas de estas competencias en un esfuerzo por usar algunas de mis habilidades para una buena causa, y también para ganar experiencia con conjuntos de datos y problemas que generalmente no encuentro en mi trabajo diario.

Identificación de tipos de variables

En estadística, las variables numéricas se pueden caracterizar en cuatro tipos principales. Al comenzar un proyecto de aprendizaje automático, es importante determinar el tipo de datos que se encuentra en cada una de sus funciones, ya que esto puede tener un impacto significativo en el rendimiento de los modelos. He tratado de dar una descripción simple de los cuatro tipos a continuación.

  • Las variables continuas son variables que pueden tener un número infinito de valores posibles, a diferencia de las variables discretas que solo pueden tener un rango específico de valores. Un ejemplo de una variable continua sería la cantidad de millas que un automóvil ha recorrido en su vida útil.
  • Las variables nominales son valores categóricos que tienen 2 o más valores posibles, pero en el que el orden de esos valores no tiene significado. Por ejemplo, podríamos usar una representación numérica para interpretar tipos de automóviles, digamos que el compacto tiene un valor de 1, MPV tiene un valor de 2 y el convertible tiene un valor de 3. Sin embargo, el hecho de que el automóvil compacto tiene un valor de 1 y el convertible tiene un valor de 2 no significa que matemáticamente el grupo convertible sea de alguna manera más grande que el MPV. Es simplemente una representación numérica de la categoría.
  • Las variables dicotómicas son nuevamente categóricas, pero solo tienen 2 valores posibles, generalmente 0 y 1. Por ejemplo, podríamos clasificar la propiedad del automóvil como 1 (lo que significa sí) o 0 (lo que significa no). Cuando convertimos variables en columnas ficticias (que haremos más adelante en esta publicación), las nuevas características producidas también se vuelven dicotómicas.
  • Las variables ordinales son similares a las nominales en que tienen 2 o más valores posibles, la diferencia principal es que estos valores tienen un orden o rango significativo. Entonces, en nuestro ejemplo de automóvil, esto podría ser algo así como el tamaño del motor, donde estas categorías podrían ordenarse en términos de potencia, 1.2, 1.6, 1.8.

Preparando los datos

Voy a utilizar nuestro aprendizaje automático con un conjunto de datos del corazón para recorrer el proceso de identificación y transformación de los tipos de variables. He descargado y leído los archivos csv en un cuaderno Jupyter. A continuación, ejecuto la siguiente función para obtener una instantánea de la composición de los datos.

importar pandas como pd
def_análisis rápido (df):
 print ("Tipos de datos:")
 print (df.dtypes)
 print ("Filas y columnas:")
 print (df.shape)
 print ("Nombres de columna:")
 imprimir (df.columns)
 print ("Valores nulos:")
 print (df.apply (lambda x: sum (x.isnull ()) / len (df)))
análisis rápido (tren)

Esto produce la siguiente salida.

Esto me dice que tengo un pequeño conjunto de datos de solo 180 filas y que hay 15 columnas. Una de las características no es numérica y, por lo tanto, deberá transformarse antes de aplicar la mayoría de las bibliotecas de aprendizaje automático. No hay valores nulos, así que no necesito preocuparme por tratarlos. Antes de procesar el conjunto de datos, también dejo caer la columna "patient_id" por ahora, ya que no es numérica y no se usará en ninguna de las etapas de entrenamiento o predicción.

Luego ejecuto la función de descripción de pandas para producir algunas estadísticas descriptivas rápidas.

train.describe ()

Para clasificar los tipos de variables en el conjunto de datos, ejecuto el siguiente código que produce histogramas de todas las características numéricas. Puede ver fácilmente en el resultado resultante qué características son continuas y dicotómicas. Las características continuas muestran un patrón de distribución continua, mientras que las características dicotómicas tienen solo dos barras. Las variables nominales y ordinales a veces pueden ser más difíciles de determinar, y pueden requerir algún conocimiento adicional del conjunto de datos o algún conocimiento de dominio específico. En el caso de una competencia de aprendizaje automático como esta, sugeriría referirse a cualquier diccionario de datos que pueda suministrarse, si no hay uno (como es el caso aquí), entonces puede ser necesaria una combinación de intuición y prueba y error.

importar matplotlib.pyplot como plt
train [train.dtypes [(train.dtypes == "float64") | (train.dtypes == "int64")]
                        .index.values] .hist (figsize = [11,11])

He caracterizado las características en los cuatro tipos de la tabla a continuación. Ahora puedo tomar algunas decisiones sobre los pasos de transformación que tomaré para preparar los datos para el entrenamiento y la predicción.

Variables ficticias

Como se mencionó anteriormente en esta publicación, cualquier valor no numérico debe convertirse a números enteros o flotantes para poder utilizarse en la mayoría de las bibliotecas de aprendizaje automático. Para las variables de baja cardinalidad, el mejor enfoque suele ser convertir la entidad en una columna por valor único, con un 0 donde el valor no está presente y un 1 donde está. Estos se conocen como variables ficticias.

Esta técnica también suele aplicarse mejor a cualquier variable nominal. Como no tienen un orden intrínseco, si no aplicamos esto primero, el algoritmo de aprendizaje automático puede buscar incorrectamente una relación en el orden de estos valores.

Pandas tiene una buena función para esto llamada get_dummies (). En el siguiente código, he usado esto para convertir todas las características nominales y no numéricas en nuevas columnas. Puede ver en el resultado que se han creado varias columnas nuevas y que las columnas originales se han eliminado.

dummy_cols = ['thal', 'chest_pain_type', 'num_major_vessels',
              'exercise_induced_angina', 'fasting_blood_sugar_gt_120_mg_per_dl',
              'resting_ekg_results', 'inclin_of_peak_exercise_st_segment']
train = pd.get_dummies (train, columnas = dummy_cols)

Escalado de características

Las variables continuas en nuestro conjunto de datos están en escalas variables. Por ejemplo, si vuelve a consultar los histogramas anteriores, puede ver que la variable "oldpeak_eq_st_depression" varía de 0 a 6, mientras que "max_heart_rate_achieved" varía de 100 a 200. Esto plantea un problema para muchos algoritmos populares de aprendizaje automático que a menudo usan la distancia euclidiana. entre puntos de datos para hacer las predicciones finales. La estandarización de la escala para todas las variables continuas a menudo puede resultar en un aumento en el rendimiento de los modelos de aprendizaje automático.

Existen varios métodos para realizar el escalado de características en python. Mi método preferido es usar la función Sci-Kit Learn MinMaxScaler. Lo que transforma la escala de modo que todos los valores en las características varían de 0 a 1. He incluido un código que hace esto a continuación.

desde el preprocesamiento de importación sklearn
n_test = train [['serum_cholesterol_mg_per_dl', 'max_heart_rate_achieved',
                'oldpeak_eq_st_depression', 'resting_blood_pressure']]
cols_to_norm = ['serum_cholesterol_mg_per_dl', 'max_heart_rate_achieved',
                'oldpeak_eq_st_depression', 'resting_blood_pressure']
x = n_test.values
min_max_scaler = preprocesamiento.MinMaxScaler ()
x_scaled = min_max_scaler.fit_transform (x)
n_test = pd.DataFrame (x_scaled, columnas = cols_to_norm)
l_test = train.drop (['serum_cholesterol_mg_per_dl', 'max_heart_rate_achieved',
                'oldpeak_eq_st_depression', 'resting_blood_pressure'], axis = 1)
train = pd.concat ([n_test, l_test], axis = 1)
tren.columnas

Binning

Notará en el código anterior que no incluí la variable continua "edad" en la transformación de escalado de características. La razón de esto es que la edad es un ejemplo de un tipo de característica que podría beneficiarse de la transformación en una variable discreta. En este ejemplo, podemos usar el uso de bucketing o binning para transformar la característica en una lista de categorías significativas.

En el siguiente código, he especificado categorías intuitivas basadas en la distribución en los datos. Esto utiliza la función de corte de pandas que toma una lista de contenedores, nombres de grupo y el marco de datos. Esta función devuelve el marco de datos original con una nueva función "age_categories". Esta columna se puede convertir en varias columnas ficticias utilizando el método descrito anteriormente.

contenedores = [30, 40, 50, 60, 70, 80]
group_names = ['30 -39 ', '40 -49', '50 -59 ', '60 -69', '70 -79 ']
age_categories = pd.cut (train ['age'], bins, labels = group_names)
train ['age_categories'] = pd.cut (train ['age'], bins, labels = group_names)
age_categories
pd.value_counts (train ['age_categories'])

Lo que tenemos ahora es un conjunto de datos donde todas las columnas no son numéricas. Hemos creado varias funciones nuevas y transformado las funciones existentes en formatos que deberían ayudar a mejorar el rendimiento de cualquier modelo de aprendizaje automático que ahora podamos usar. La transformación de características es un primer paso importante en el proceso de aprendizaje automático y esto a menudo puede tener un impacto significativo en el rendimiento del modelo. He esbozado aquí los primeros pasos que tomaría en el proceso para pensar lógicamente cómo tratar las diferentes variables que tengo. Una vez en la fase de construcción del modelo, casi siempre regresaré y modificaré los datos utilizando diferentes métodos para tratar de aumentar la precisión de los modelos. Sin embargo, encuentro que al seguir estos pasos al principio, esto a menudo reduce el tiempo que paso volviendo a las etapas de transformación.