Guía Integral para el Preprocesamiento de Datos en Problemas de Clasificación en el Aprendizaje Automático
Tabla de Contenidos
- Introducción a los Problemas de Clasificación
- Importación de Datos y Visión General
- Manejo de Datos Faltantes
- Codificación de Variables Categóricas
- Selección de Características
- División Entrenamiento-Prueba
- Escalado de Características
- Conclusión
Introducción a los Problemas de Clasificación
Clasificación es una técnica de aprendizaje supervisado utilizada para predecir etiquetas categóricas. Implica asignar datos de entrada a categorías predefinidas basadas en datos históricos. Los modelos de clasificación varían desde algoritmos simples como la Regresión Logística hasta otros más complejos como los Bosques Aleatorios y las Redes Neuronales. El éxito de estos modelos no depende únicamente del algoritmo elegido, sino significativamente de cómo se prepara y preprocesa los datos.
Importación de Datos y Visión General
Antes de sumergirse en el preprocesamiento, es esencial comprender e importar el conjunto de datos. Para esta guía, utilizaremos el conjunto de datos WeatherAUS de Kaggle, que contiene observaciones diarias del clima en Australia.
1 2 3 4 5 6 7 8 9 |
# Importando las bibliotecas necesarias import pandas as pd import seaborn as sns # Cargando el conjunto de datos data = pd.read_csv('weatherAUS.csv') # Mostrando las últimas cinco filas del conjunto de datos data.tail() |
Salida:
1 2 3 4 5 6 7 8 |
Date Location MinTemp MaxTemp Rainfall Evaporation Sunshine WindGustDir WindGustSpeed WindDir9am ... Humidity3pm Pressure9am Pressure3pm Cloud9am Cloud3pm Temp9am Temp3pm RainToday RISK_MM RainTomorrow 142188 2017-06-20 Uluru 3.5 21.8 0.0 NaN NaN E 31.0 ESE ... 27.0 1024.7 1021.2 NaN NaN 9.4 20.9 No 0.0 No 142189 2017-06-21 Uluru 2.8 23.4 0.0 NaN NaN E 31.0 SE ... 24.0 1024.6 1020.3 NaN NaN 10.1 22.4 No 0.0 No 142190 2017-06-22 Uluru 3.6 25.3 0.0 NaN NaN NNW 22.0 SE ... 21.0 1023.5 1019.1 NaN NaN 10.9 24.5 No 0.0 No 142191 2017-06-23 Uluru 5.4 26.9 0.0 NaN NaN N 37.0 SE ... 24.0 1021.0 1016.8 NaN NaN 12.5 26.1 No 0.0 No 142192 2017-06-24 Uluru 7.8 27.0 0.0 NaN NaN SE 28.0 SSE ... 24.0 1019.4 1016.5 3.0 2.0 15.1 26.0 No 0.0 No [5 filas x 24 columnas] |
El conjunto de datos comprende diversas características como temperatura, precipitación, humedad, velocidad del viento y más, que son vitales para predecir si lloverá mañana (RainTomorrow).
Manejo de Datos Faltantes
Los conjuntos de datos del mundo real a menudo vienen con datos faltantes o incompletos. Manejar estas brechas es crucial para asegurar la confiabilidad del modelo. Abordaremos los datos faltantes en dos categorías: Numéricos y Categóricos.
A. Datos Numéricos
Para las características numéricas, una estrategia común es reemplazar los valores faltantes con medidas estadísticas como la media, mediana o moda. Aquí, utilizaremos la media para imputar los valores faltantes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import numpy as np from sklearn.impute import SimpleImputer # Identificando columnas numéricas numerical_cols = list(np.where((X.dtypes == np.int64) | (X.dtypes == np.float64))[0]) # Inicializando el imputador con la estrategia de media imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean') # Ajustando el imputador en las columnas numéricas imp_mean.fit(X.iloc[:, numerical_cols]) # Transformando los datos X.iloc[:, numerical_cols] = imp_mean.transform(X.iloc[:, numerical_cols]) |
B. Datos Categóricos
Para las características categóricas, el valor más frecuente (moda) es un reemplazo adecuado para los datos faltantes.
1 2 3 4 5 6 7 8 9 10 11 |
# Identificando columnas categóricas string_cols = list(np.where((X.dtypes == np.object))[0]) # Inicializando el imputador con la estrategia de valor más frecuente imp_mean = SimpleImputer(missing_values=np.nan, strategy='most_frequent') # Ajustando el imputador en las columnas categóricas imp_mean.fit(X.iloc[:, string_cols]) # Transformando los datos X.iloc[:, string_cols] = imp_mean.transform(X.iloc[:, string_cols]) |
Codificación de Variables Categóricas
Los modelos de aprendizaje automático requieren entradas numéricas. Por lo tanto, es esencial convertir las variables categóricas en formatos numéricos. Podemos lograr esto utilizando Codificación de Etiquetas y Codificación One-Hot.
A. Codificación de Etiquetas
Codificación de Etiquetas asigna un entero único a cada categoría única en una característica. Es simple pero puede introducir relaciones ordinales donde no las hay.
1 2 3 4 5 6 7 8 |
from sklearn import preprocessing def LabelEncoderMethod(series): le = preprocessing.LabelEncoder() return le.fit_transform(series) # Codificando la variable objetivo y = LabelEncoderMethod(y) |
B. Codificación One-Hot
Codificación One-Hot crea columnas binarias para cada categoría, eliminando las relaciones ordinales y asegurando que cada categoría se trate de manera distinta.
1 2 3 4 5 6 |
from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder def OneHotEncoderMethod(indices, data): columnTransformer = ColumnTransformer([('encoder', OneHotEncoder(), indices)], remainder='passthrough') return columnTransformer.fit_transform(data) |
Selección de Codificación para Características
Dependiendo del número de categorías únicas, es eficiente elegir entre Codificación de Etiquetas y Codificación One-Hot.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
def EncodingSelection(X, threshold=10): # Paso 1: Seleccionar las columnas string string_cols = list(np.where((X.dtypes == np.object))[0]) one_hot_encoding_indices = [] # Paso 2: Aplicar Codificación de Etiquetas o marcar para Codificación One-Hot basado en la cantidad de categorías for col in string_cols: length = len(pd.unique(X[X.columns[col]])) if length == 2 or length > threshold: X[X.columns[col]] = LabelEncoderMethod(X[X.columns[col]]) else: one_hot_encoding_indices.append(col) # Paso 3: Aplicar Codificación One-Hot donde sea necesario X = OneHotEncoderMethod(one_hot_encoding_indices, X) return X # Aplicando la selección de codificación X = EncodingSelection(X) |
Salida:
1 |
(142193, 23) |
Este paso reduce el espacio de características seleccionando solo las características codificadas más relevantes.
Selección de Características
No todas las características contribuyen por igual a la tarea de predicción. La selección de características ayuda a identificar y retener las características más informativas, mejorando el rendimiento del modelo y reduciendo la sobrecarga computacional.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from sklearn.feature_selection import SelectKBest, chi2 from sklearn import preprocessing # Inicializando SelectKBest con la estadística chi-cuadrado kbest = SelectKBest(score_func=chi2, k=10) # Escalando características usando MinMaxScaler antes de la selección de características MMS = preprocessing.MinMaxScaler() x_temp = MMS.fit_transform(X) # Ajustando SelectKBest x_temp = kbest.fit(x_temp, y) # Seleccionando las mejores características basadas en las puntuaciones best_features = np.argsort(x_temp.scores_)[-13:] features_to_delete = np.argsort(x_temp.scores_)[:-13] # Eliminando las características menos importantes X = np.delete(X, features_to_delete, axis=1) # Verificando la nueva forma print(X.shape) |
Salida:
1 |
(142193, 13) |
Este proceso reduce el conjunto de características de 23 a 13, enfocándose en las características más impactantes para nuestra tarea de clasificación.
División Entrenamiento-Prueba
Para evaluar el rendimiento de nuestro modelo de clasificación, necesitamos dividir el conjunto de datos en subconjuntos de entrenamiento y prueba.
1 2 3 4 5 6 7 |
from sklearn.model_selection import train_test_split # Dividiendo los datos: 80% entrenamiento y 20% prueba X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=1) # Mostrando la forma de los datos de entrenamiento print(X_train.shape) |
Salida:
1 |
(113754, 13) |
Escalado de Características
El escalado de características asegura que todas las características contribuyan de manera equitativa al resultado, especialmente importante para algoritmos sensibles a las magnitudes de las características como las Máquinas de Vectores de Soporte o los K-Vecinos Más Cercanos.
Estandarización
La estandarización reescala los datos para que tengan una media de cero y una desviación estándar de uno.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from sklearn import preprocessing # Inicializando el StandardScaler sc = preprocessing.StandardScaler(with_mean=False) # Ajustando el escalador en los datos de entrenamiento sc.fit(X_train) # Transformando tanto los datos de entrenamiento como los de prueba X_train = sc.transform(X_train) X_test = sc.transform(X_test) # Verificando la forma después del escalado print(X_train.shape) print(X_test.shape) |
Salida:
1 2 |
(113754, 13) (28439, 13) |
Nota: El parámetro with_mean=False
se utiliza para evitar problemas con las matrices de datos dispersos resultantes de la Codificación One-Hot.
Conclusión
El preprocesamiento de datos es un paso crítico en la construcción de modelos de clasificación robustos y precisos. Al manejar metódicamente los datos faltantes, codificar variables categóricas, seleccionar características relevantes y escalar, establecemos una base sólida para cualquier modelo de aprendizaje automático. Esta guía proporcionó un enfoque práctico utilizando Python y sus poderosas bibliotecas, asegurando que tus problemas de clasificación estén bien preparados para el entrenamiento y la evaluación del modelo. Recuerda, el adagio «basura entra, basura sale» se aplica en el aprendizaje automático; por lo tanto, invertir tiempo en el preprocesamiento de datos rinde dividendos en el rendimiento del modelo.
Palabras Clave: Problemas de Clasificación, Preprocesamiento de Datos, Aprendizaje Automático, Limpieza de Datos, Selección de Características, Codificación de Etiquetas, Codificación One-Hot, Escalado de Características, Python, Pandas, Scikit-learn, Modelos de Clasificación