Imputación de valores faltantes, explicación: una guía visual con ejemplos de código para principiantes | por Samy Baladram | agosto, 2024

PREPROCESAMIENTO DE DATOS

¿Un (pequeño) conjunto de datos, seis métodos de imputación?

Hablemos de algo con lo que todo científico de datos, analista o curioso que analiza números tiene que lidiar tarde o temprano: los valores faltantes. Ahora, sé lo que estás pensando: “Oh, genial, otra guía sobre valores faltantes”. Pero escúchame. Te mostraré cómo abordar este problema utilizando no uno, ni dos, sino seis métodos de imputación diferentes, todos en un único conjunto de datos (¡con útiles elementos visuales también!). Al final de esto, verás por qué el conocimiento del dominio vale su peso en oro (algo que incluso nuestros amigos de la IA podrían tener dificultades para replicar).

Todas las imágenes fueron creadas por el autor con Canva Pro. Optimizadas para dispositivos móviles; pueden verse demasiado grandes en computadoras de escritorio.

Antes de adentrarnos en nuestro conjunto de datos y métodos de imputación, tomémonos un momento para comprender qué son los valores faltantes y por qué son un dolor de cabeza tan común en la ciencia de datos.

¿Qué son los valores faltantes?

Los valores faltantes, a menudo representados como NaN (no es un número) en pandas o NULL en bases de datos, son esencialmente agujeros en su conjunto de datosSon las celdas vacías de su hoja de cálculo, los espacios en blanco en las respuestas de su encuesta, los puntos de datos que se escaparon. En el mundo de los datos, no todas las ausencias son iguales, y comprender la naturaleza de los valores faltantes es crucial para decidir cómo manejarlos.

Imagen del autor.

¿Por qué ocurren valores faltantes?

Los valores faltantes pueden aparecer en sus datos por diversos motivos. A continuación, se indican algunos motivos habituales:

  1. Errores de ingreso de datos:A veces, se trata simplemente de un error humano. Alguien puede olvidar ingresar un valor o eliminar uno por accidente.
  2. Averías del sensor:En IoT o en experimentos científicos, un sensor defectuoso podría no registrar datos en determinados momentos.
  3. Encuesta sin respuesta:En las encuestas, los encuestados pueden omitir preguntas que no se sienten cómodos respondiendo o que no entienden.
  4. Conjuntos de datos fusionados:Al combinar datos de múltiples fuentes, es posible que algunas entradas no tengan valores correspondientes en todos los conjuntos de datos.
  5. Corrupción de datos:Durante la transferencia o el almacenamiento de datos, algunos valores podrían dañarse y volverse ilegibles.
  6. Omisiones intencionales:Es posible que se omitan algunos datos intencionalmente por cuestiones de privacidad o por ser irrelevantes.
  7. Problemas de muestreo:El método de recopilación de datos podría omitir sistemáticamente ciertos tipos de datos.
  8. Datos sensibles al tiempo:En los datos de series de tiempo, es posible que falten valores correspondientes a períodos en los que no se recopilaron datos (por ejemplo, fines de semana, feriados).

Tipos de datos faltantes

Comprender el tipo de datos faltantes con el que está tratando puede ayudarlo a elegir el método de imputación más adecuado. Los estadísticos generalmente clasifican los datos faltantes en tres tipos:

  1. Desaparecido completamente al azar (MCAR):La falta es totalmente aleatorio y no depende de ninguna otra variable. Por ejemplo, si una muestra de laboratorio se cayó accidentalmente.
  2. Desaparecido al azar (MAR):La probabilidad de que falten datos depende de otras variables observadas Pero no en los datos faltantes en sí. Por ejemplo, los hombres podrían ser menos propensos a responder preguntas sobre emociones en una encuesta.
  3. Perdido, no al azar (MNAR):La falta Depende del valor de los datos faltantes en sí.Por ejemplo, las personas con ingresos altos podrían tener menos probabilidades de informar sus ingresos en una encuesta.

¿Por qué preocuparse por los valores faltantes?

Los valores faltantes pueden afectar significativamente su análisis:

  1. Pueden introducir sesgos si no se manejan adecuadamente.
  2. Muchos algoritmos de aprendizaje automático no pueden manejar valores faltantes de forma inmediata.
  3. Pueden provocar la pérdida de información importante si las instancias con valores faltantes simplemente se descartan.
  4. Los valores faltantes manejados incorrectamente pueden llevar a conclusiones o predicciones incorrectas.

Por eso es fundamental contar con una estrategia sólida para abordar los valores faltantes. ¡Y eso es exactamente lo que vamos a explorar en este artículo!

Primero lo primero, vamos a presentar nuestro conjunto de datos. Trabajaremos con un conjunto de datos de campos de golf que rastrea varios factores que afectan la afluencia de público en el campo. Este conjunto de datos tiene un poco de todo: datos numéricos, datos categóricos y, sí, muchos valores faltantes.

Este conjunto de datos fue creado artificialmente por el autor (inspirado en [1]) para promover el aprendizaje.
import pandas as pd
import numpy as np

# Create the dataset as a dictionary
data = {
'Date': ['08-01', '08-02', '08-03', '08-04', '08-05', '08-06', '08-07', '08-08', '08-09', '08-10',
'08-11', '08-12', '08-13', '08-14', '08-15', '08-16', '08-17', '08-18', '08-19', '08-20'],
'Weekday': [0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5],
'Holiday': [0.0, 0.0, 0.0, 0.0, np.nan, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, np.nan, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
'Temp': [25.1, 26.4, np.nan, 24.1, 24.7, 26.5, 27.6, 28.2, 27.1, 26.7, np.nan, 24.3, 23.1, 22.4, np.nan, 26.5, 28.6, np.nan, 27.0, 26.9],
'Humidity': [99.0, np.nan, 96.0, 68.0, 98.0, 98.0, 78.0, np.nan, 70.0, 75.0, np.nan, 77.0, 77.0, 89.0, 80.0, 88.0, 76.0, np.nan, 73.0, 73.0],
'Wind': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, np.nan, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, np.nan, 1.0, 0.0],
'Outlook': ['rainy', 'sunny', 'rainy', 'overcast', 'rainy', np.nan, 'rainy', 'rainy', 'overcast', 'sunny', np.nan, 'overcast', 'sunny', 'rainy', 'sunny', 'rainy', np.nan, 'rainy', 'overcast', 'sunny'],
'Crowdedness': [0.14, np.nan, 0.21, 0.68, 0.20, 0.32, 0.72, 0.61, np.nan, 0.54, np.nan, 0.67, 0.66, 0.38, 0.46, np.nan, 0.52, np.nan, 0.62, 0.81]
}

# Create a DataFrame from the dictionary
df = pd.DataFrame(data)

# Display basic information about the dataset
print(df.info())

# Display the first few rows of the dataset
print(df.head())

# Display the count of missing values in each column
print(df.isnull().sum())

Producción:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Date 20 non-null object
1 Weekday 20 non-null int64
2 Holiday 19 non-null float64
3 Temp 16 non-null float64
4 Humidity 17 non-null float64
5 Wind 19 non-null float64
6 Outlook 17 non-null object
7 Crowdedness 15 non-null float64
dtypes: float64(5), int64(1), object(2)
memory usage: 1.3+ KB

Date Weekday Holiday Temp Humidity Wind Outlook Crowdedness
0 08-01 0 0.0 25.1 99.0 0.0 rainy 0.14
1 08-02 1 0.0 26.4 NaN 0.0 sunny NaN
2 08-03 2 0.0 NaN 96.0 0.0 rainy 0.21
3 08-04 3 0.0 24.1 68.0 0.0 overcast 0.68
4 08-05 4 NaN 24.7 98.0 0.0 rainy 0.20

Date 0
Weekday 0
Holiday 1
Temp 4
Humidity 3
Wind 1
Outlook 3
Crowdedness 5
dtype: int64

Como podemos ver, nuestro conjunto de datos contiene 20 filas y 8 columnas:

  • Fecha: La fecha de la observación.
  • Día de la semana: Día de la semana (0–6, donde 0 es lunes)
  • Vacaciones: Booleano que indica si es feriado (0 o 1)
  • Temp: Temperatura en grados Celsius
  • Humedad: Porcentaje de humedad
  • Viento: Condición del viento (0 o 1, posiblemente indicando calma o viento)
  • Perspectiva: Perspectiva meteorológica (soleado, nublado o lluvioso)
  • Aglomeración: Porcentaje de ocupación del campo

¡Y mira eso! Tenemos valores faltantes en todas las columnas excepto Fecha y Día de la semana. Perfecto para nuestra fiesta de imputación.

Ahora que hemos cargado nuestro conjunto de datos, abordemos estos valores faltantes con seis métodos de imputación diferentes. Usaremos una estrategia diferente para cada tipo de datos.

La eliminación por listas, también conocida como análisis de casos completo, implica la eliminación de filas enteras que contienen valores faltantes. Este método es simple y conserva la distribución de los datos, pero puede provocar una pérdida significativa de información si muchas filas contienen valores faltantes.

👍 Uso común:La eliminación por lista se utiliza a menudo cuando la cantidad de valores faltantes es pequeña y los datos faltan de forma completamente aleatoria (MCAR). También es útil cuando se necesita un conjunto de datos completo para determinados análisis que no pueden manejar valores faltantes.

En nuestro caso:Utilizamos la eliminación por lista para las filas que tienen al menos 4 valores faltantes. Es posible que estas filas no proporcionen suficiente información confiable y eliminarlas puede ayudarnos a centrarnos en los puntos de datos más completos. Sin embargo, somos cautelosos y solo eliminamos filas con datos faltantes significativos para preservar la mayor cantidad de información posible.

# Count missing values in each row
missing_count = df.isnull().sum(axis=1)

# Keep only rows with less than 4 missing values
df_clean = df[missing_count < 4].copy()

Hemos eliminado dos filas que tenían demasiados valores faltantes. Ahora, pasemos a imputar los datos faltantes restantes.

La imputación simple implica reemplazar los valores faltantes con una estadística resumida de los valores observados. Los métodos más comunes incluyen el uso de la media, la mediana o la moda de los valores no faltantes en una columna.

👍 Uso común:La imputación de media se utiliza a menudo para variables continuas cuando los datos faltan de forma aleatoria y la distribución es aproximadamente simétrica. La imputación de moda se utiliza normalmente para variables categóricas.

En nuestro caso:Utilizamos la imputación media para la humedad y la imputación modal para las vacaciones. Para la humedad, suponiendo que los valores faltantes son aleatorios, la media proporciona una estimación razonable de la humedad típica. Para las vacaciones, dado que es una variable binaria (feriado o no), la moda nos da el estado más común, que es una estimación sensata para los valores faltantes.

# Mean imputation for Humidity
df_clean['Humidity'] = df_clean['Humidity'].fillna(df_clean['Humidity'].mean())

# Mode imputation for Holiday
df_clean['Holiday'] = df_clean['Holiday'].fillna(df_clean['Holiday'].mode()[0])

La interpolación lineal estima los valores faltantes al suponer una relación lineal entre puntos de datos conocidos. Es especialmente útil para datos de series temporales o datos con un orden natural.

👍 Uso común:La interpolación lineal se utiliza a menudo para datos de series temporales, en los que los valores faltantes se pueden estimar en función de los valores anteriores y posteriores a ellos. También es útil para cualquier dato en el que se espere que exista una relación aproximadamente lineal entre puntos adyacentes.

En nuestro caso:Utilizamos interpolación lineal para la temperatura. Dado que la temperatura tiende a cambiar gradualmente con el tiempo y nuestros datos están ordenados por fecha, la interpolación lineal puede brindar estimaciones razonables para los valores de temperatura faltantes en función de las temperaturas registradas en días cercanos.

df_clean['Temp'] = df_clean['Temp'].interpolate(method='linear')

El método de relleno hacia adelante (o “última observación trasladada hacia adelante”) propaga el último valor conocido hacia adelante para llenar los espacios vacíos, mientras que el método de relleno hacia atrás hace lo contrario. Este método supone que es probable que el valor faltante sea similar al valor conocido más cercano.

👍 Uso común:El relleno hacia adelante o hacia atrás se utiliza a menudo para datos de series de tiempo, especialmente cuando es probable que el valor permanezca constante hasta que se modifique (como en datos financieros) o cuando el valor conocido más reciente es la mejor estimación para el estado actual.

En nuestro caso:Utilizamos una combinación de relleno hacia delante y hacia atrás para Outlook. Las condiciones meteorológicas suelen persistir durante varios días, por lo que es razonable suponer que un valor de Outlook faltante podría ser similar al del día anterior o del día siguiente.

df_clean['Outlook'] = df_clean['Outlook'].fillna(method='ffill').fillna(method='bfill')

Este método implica reemplazar todos los valores faltantes en una variable con un valor constante específico. Esta constante puede elegirse en función del conocimiento del dominio o un valor predeterminado seguro.

👍 Uso comúnLa imputación de valor constante se utiliza a menudo cuando hay un valor predeterminado lógico para los datos faltantes o cuando se desea marcar explícitamente que falta un valor (utilizando un valor fuera del rango normal de los datos).

En nuestro caso:Utilizamos la imputación de valores constantes para la columna Viento y reemplazamos los valores faltantes con -1. Este enfoque marca explícitamente los valores imputados (ya que -1 está fuera del rango normal de 0 a 1 para Viento) y conserva la información de que estos valores faltaban originalmente.

df_clean['Wind'] = df_clean['Wind'].fillna(-1)

K-Vecinos más cercanos La imputación (KNN) estima los valores faltantes al encontrar las K muestras más similares en el conjunto de datos (al igual que KNN como algoritmo de clasificación) y usar sus valores para imputar los datos faltantes. Este método puede capturar relaciones complejas entre variables.

👍 Uso común:La imputación KNN es versátil y se puede utilizar tanto para variables continuas como categóricas. Es particularmente útil cuando se espera que existan relaciones complejas entre variables que los métodos más simples podrían pasar por alto.

En nuestro caso:Utilizamos la imputación KNN para determinar la aglomeración. La aglomeración probablemente dependa de una combinación de factores (como la temperatura, el estado de las vacaciones, etc.) y KNN puede capturar estas relaciones complejas para proporcionar estimaciones más precisas de los valores de aglomeración faltantes.

from sklearn.impute import KNNImputer

# One-hot encode the 'Outlook' column
outlook_encoded = pd.get_dummies(df_clean['Outlook'], prefix='Outlook')

# Prepare features for KNN imputation
features_for_knn = ['Weekday', 'Holiday', 'Temp', 'Humidity', 'Wind']
knn_features = pd.concat([df_clean[features_for_knn], outlook_encoded], axis=1)

# Apply KNN imputation
knn_imputer = KNNImputer(n_neighbors=3)
df_imputed = pd.DataFrame(knn_imputer.fit_transform(pd.concat([knn_features, df_clean[['Crowdedness']]], axis=1)),
columns=list(knn_features.columns) + ['Crowdedness'])

# Update the original dataframe with the imputed Crowdedness values
df_clean['Crowdedness'] = df_imputed['Crowdedness']

¡Y ahí lo tienes! Seis formas diferentes de manejar valores faltantes, todas aplicadas a nuestro conjunto de datos de campos de golf.

¡Ahora, todos los valores faltantes están completos!

Recapitulemos cómo cada método abordó nuestros datos:

  1. Eliminación por lista:Nos ayudó a centrarnos en puntos de datos más completos al eliminar filas con muchos valores faltantes.
  2. Imputación simple:Rellena Humedad con valores medios y Vacaciones con la ocurrencia más común.
  3. Interpolación lineal:Valores de temperatura faltantes estimados según la tendencia de los días circundantes.
  4. Relleno hacia adelante/atrás:Se adivinaron los valores de Outlook faltantes de los días adyacentes, lo que refleja la persistencia de los patrones climáticos.
  5. Imputación de valor constante:Se marcaron los datos de viento faltantes con -1, preservando el hecho de que estos valores eran originalmente desconocidos.
  6. Imputación KNN:Hacinamiento estimado basado en días similares, capturando relaciones complejas entre variables.

Cada método cuenta una historia diferente sobre los datos faltantes, y la elección “correcta” depende de lo que sabemos sobre las operaciones de nuestro campo de golf y las preguntas que estamos tratando de responder.

¿Cuál es la conclusión clave? No aplique métodos de imputación a ciegas. Comprenda los datos, considere el contexto y elija el método que tenga más sentido para su situación específica.