En una tabla de ventas como BigMart, Item_Weight puede faltar porque falló la captura del proveedor. En cambio, si Outlet_Size falta sobre todo en tiendas de cierto tipo, la ausencia contiene información sobre la tienda. Antes de elegir un método, pregunta qué filas faltan, en qué grupos y desde cuándo. NaN1 indica que no se registró un valor; no explica la causa.

1 NaN significa Not a Number. En pandas, también pueden aparecer otros marcadores de ausencia como None o pd.NA, según el tipo de columna.

40.1 Un primer ejemplo visual

Supongamos que conocemos el peso de todos los productos de una población simulada y ocultamos algunos a propósito. Podemos comparar la distribución completa con la que quedaría disponible para analizar. En datos reales, la curva completa normalmente no está disponible: aquí la conocemos porque hemos simulado los datos.

Media verdadera: 12.043
Media observada: 11.119
Proporción missing: 28.650%

En este ejemplo, los pesos altos tienen más probabilidad de desaparecer y la media observada queda por debajo de la verdadera. Los histogramas tienen tamaños de muestra distintos; compara sobre todo su forma y las medias impresas, no solo la altura de las barras.

40.2 Ejemplo: tres mecanismos de ausencia

Usaremos \(R_i=1\) cuando el peso del producto \(i\) está ausente. Los nombres MCAR, MAR y MNAR describen supuestos sobre el proceso que generó la ausencia, no etiquetas que podamos deducir con certeza de una tabla incompleta2.

2 MCAR significa Missing Completely At Random; MAR, Missing At Random; MNAR, Missing Not At Random. MAR es una independencia condicional respecto al valor ausente.

40.2.1 MCAR: pérdida independiente de los datos

Un fallo aleatorio del sistema elimina algunas filas sin tener en cuenta pesos ni características de las tiendas. En la simulación, cada registro tiene la misma probabilidad de perderse.

Proporción missing: 20.57%
Media verdadera:    12.0425
Media observada:    12.0411
Desv. estándar verdadera: 2.1935
Desv. estándar observada: 2.1811

La similitud de las medias es esperable en promedio, pero no garantiza que una muestra concreta no tenga error de muestreo. Eliminar filas MCAR también reduce la cantidad de información.

40.2.2 MAR: pérdida explicada por variables observadas

La probabilidad de que falte Item_Weight depende de Outlet_Type, que sí conocemos. Dentro de cada tipo de tienda, el mecanismo simulado ya no depende del peso. Como los pesos también varían por tipo, analizar solo los valores observados cambia la composición de la muestra.

Proporción missing por grupo:
     Outlet_Type  missing
0  Grocery Store    0.763
1    Mini Market    0.173
2    Supermarket    0.031

Media verdadera: 12.177 Media observada: 13.693

La primera gráfica muestra dónde se concentran los faltantes; la segunda muestra el efecto sobre la distribución agregada. La variable auxiliar Outlet_Type permite estudiar y modelar ese patrón. MAR no significa que la falta sea aleatoria sin condiciones.

40.2.3 MNAR: pérdida ligada al valor ausente

Imaginemos que un proceso de captura omite con más frecuencia pesos grandes y que esa causa no queda explicada por ninguna columna observada. El mecanismo depende del propio peso que falta.

Media verdadera: 12.012
Media observada: 10.716
Proporción missing: 62.44%

No podemos confirmar MNAR solo mirando los pesos registrados. Necesitamos conocimiento del proceso de captura, una muestra de seguimiento o un análisis de sensibilidad3.

3 Un análisis de sensibilidad repite el cálculo bajo varios supuestos plausibles sobre los valores no observados para ver cuánto cambia la conclusión.

40.2.4 Laboratorio: tres mecanismos, un mismo promedio

Las tres simulaciones anteriores usan datos distintos. Aquí los comparamos sobre la misma población de 1 500 productos: las tiendas Grocery venden productos más ligeros (media 10 kg) que los Supermarket (media 14 kg). Tú eliges cómo se pierden los pesos y el laboratorio compara tres estimadores de la media: casos completos, imputación por la media global e imputación por la media de cada tipo de tienda.

Laboratorio · Mecanismos de ausencia

¿Cuándo sesga la media observada y cuándo lo corrige una variable auxiliar?

La población completa es conocida porque la simulamos; en un proyecto real solo verías las barras azules.

Mecanismo

Distribución completa frente a observada

población completapesos observadosmedia verdaderamedia observada

Tasa de faltantes por tipo de tienda

Guía del laboratorio.

  1. Con MCAR, mueve la proporción de faltantes de 5 % a 70 %. Comprueba que la media observada se mantiene cerca de la verdadera mientras la desviación estándar tras imputar con la media disminuye. ¿Por qué ocurre lo segundo aunque no haya sesgo?
  2. Cambia a MAR con intensidad 1.2. Identifica en el panel derecho qué grupo pierde más pesos y explica el signo del sesgo de la media observada. Verifica que el estimador por grupo lo corrige.
  3. Cambia a MNAR. Observa que las tasas por tipo de tienda casi no se distinguen, pero las tasas por peso sí. ¿Qué implica que la evidencia de MNAR esté precisamente en la columna que no observamos?
NotaAntes de imputar

Cuenta los faltantes por columna, por tipo de tienda y por periodo. Verifica si un código especial como 0 o "sin dato" representa ausencia. Documenta la definición de cada campo y el momento en que estará disponible durante la predicción.

40.3 De la intuición al cálculo: imputar un peso

En esta muestra pequeña conocemos Item_Outlet_Sales solo como variable auxiliar de demostración. Si las ventas son el objetivo de un modelo predictivo, no debemos usarlas para imputar predictores que estarán disponibles antes de la venta4.

4 La variable objetivo es el resultado que se desea predecir. Usarla para construir un predictor crea fuga de información si ese resultado todavía no existe al hacer la predicción.

Producto Item_Weight (kg) Ventas observadas
FDA15 9.30 3735.13
DRC01 5.92 1200.00
FDN15 — 1098.56
FDX07 19.20 4138.61

Media observada. Para FDN15, la media de los tres pesos registrados es \((9.30+5.92+19.20)/3\approx 11.47\) kg. Es sencilla, pero todas las filas incompletas reciben el mismo número y la dispersión se contrae.

Cuánto se contrae. La varianza muestral5 de los tres pesos observados es \[ s^2_{\mathrm{obs}}=\frac{(9.30-11.47)^2+(5.92-11.47)^2+(19.20-11.47)^2}{3-1}\approx\frac{4.72+30.82+59.72}{2}\approx 47.63 . \] Al añadir el valor imputado \(11.47\), el numerador no cambia (esa fila está exactamente en la media, así que aporta cero), pero el divisor pasa de \(2\) a \(3\): \(s^2_{\mathrm{imp}}=95.26/3\approx31.75\). La desviación estándar cae de \(6.90\) a \(5.64\) kg sin que hayamos aprendido nada nuevo sobre los pesos. Un modelo entrenado con esa columna verá los datos más concentrados de lo que son.

5 Varianza muestral: \(s^2=\frac{1}{n-1}\sum_i (y_i-\bar y)^2\). Se divide entre \(n-1\) porque las desviaciones se miden respecto a \(\bar y\), calculada con los mismos datos; así \(s^2\) es un estimador insesgado de la varianza poblacional.

6 Por defecto, KNNImputer usa la distancia nan_euclidean y weights="uniform"; también admite ponderar vecinos por distancia. Documentación de KNNImputer.

Vecino más cercano. Si comparamos únicamente las ventas disponibles, DRC01 es el más cercano a FDN15: \(|1200-1098.56|=101.44\). Con \(k=1\) y ese único atributo auxiliar, imputaríamos 5.92 kg. La distancia y el resultado cambian si añadimos otras variables o las escalamos; KNNImputer usa por defecto vecinos con peso uniforme6.

Pregunta para discutir. ¿Cuál de los dos valores parece más razonable? No podemos saberlo para FDN15 sin una observación verdadera. Por eso evaluaremos métodos ocultando temporalmente valores que sí conocemos.

40.4 Qué muestran las imputaciones

40.4.1 Imputación simple y distribución

Esta gráfica de Plotly del capítulo original compara la distribución simulada completa con varias imputaciones simples. La modalidad se calcula después de redondear el peso a una décima; esa discretización solo sirve para ilustrar el método.

Observa el pico que produce reemplazar muchos faltantes por un mismo número. Mantener aproximadamente la media no implica conservar la varianza ni las relaciones con otras columnas.

40.4.2 KNN: los vecinos importan

En el siguiente ejemplo original se ocultan valores conocidos de una simulación. El panel derecho permite ver los vecinos y comparar una imputación con el valor ocultado. Los puntos rojos son una referencia didáctica, no información disponible al imputar datos reales.

Al usar KNN, escala las variables numéricas pertinentes y revisa qué columnas entran en la distancia. El vecino más cercano en una dimensión puede ser muy distinto del vecino en varias dimensiones.

40.4.3 Imputación múltiple: representar incertidumbre

Una sola tabla completada trata cada valor imputado como si fuese conocido. Para inferencia estadística, podemos crear varias tablas plausibles, ajustar el análisis en cada una y combinar estimaciones y varianzas7. La figura original usa IterativeImputer(sample_posterior=True) para generar cinco realizaciones; el valor predeterminado sample_posterior=False genera una imputación determinista y no equivale por sí solo a imputación múltiple.

7 La imputación múltiple considera incertidumbre entre tablas imputadas. IterativeImputer puede producir realizaciones con sample_posterior=True, pero el análisis y la combinación de estimaciones quedan a cargo del usuario. Documentación de IterativeImputer.

Las cinco nubes muestran incertidumbre entre imputaciones; ninguna recupera necesariamente cada valor individual. Esta simulación visualiza el principio. Un análisis inferencial completo también necesita combinar los resultados de los modelos ajustados en cada tabla.

40.5 Formalización breve

Sea \(Y=(Y_{\mathrm{obs}},Y_{\mathrm{mis}})\) el conjunto completo, \(R\) el indicador de ausencia y \(X\) las variables auxiliares observadas. De manera esquemática:

  • MCAR: \(P(R\mid Y,X)=P(R)\). La ausencia es independiente de los valores.
  • MAR: \(P(R\mid Y_{\mathrm{obs}},Y_{\mathrm{mis}},X)=P(R\mid Y_{\mathrm{obs}},X)\). Una vez condicionamos8 en lo observado, el valor ausente no añade información sobre \(R\).
  • MNAR: la probabilidad de ausencia todavía depende de \(Y_{\mathrm{mis}}\) después de condicionar en lo observado.

8 Independencia condicional: \(R\) y \(Y_{\mathrm{mis}}\) pueden estar relacionadas en general y, aun así, ser independientes dentro de cada grupo definido por las variables observadas. Es la diferencia entre «la ausencia depende del peso» y «la ausencia depende del tipo de tienda, que a su vez se relaciona con el peso».

9 Esperanza condicional: \(E[Y\mid R=0]\) es el valor promedio de \(Y\) restringido a la subpoblación donde \(R=0\) (valor observado). Si las subpoblaciones \(R=0\) y \(R=1\) tienen promedios distintos, mirar solo una de ellas da una imagen distorsionada del total.

10 Sesgo de un estimador: diferencia entre el valor que el estimador da en promedio, sobre muchas muestras posibles, y el parámetro que pretende estimar. Un estimador sesgado no mejora al aumentar el tamaño de muestra: converge al valor equivocado.

La media de casos completos estima \(E[Y\mid R=0]\)9. Por la ley de la probabilidad total, \[ E[Y]=P(R=0)\,E[Y\mid R=0]+P(R=1)\,E[Y\mid R=1], \] así que el sesgo10 de usar solo los casos completos es \(E[Y\mid R=0]-E[Y]=P(R=1)\,\big(E[Y\mid R=0]-E[Y\mid R=1]\big)\): crece con la proporción de faltantes y con la diferencia entre quienes responden y quienes no. Bajo MCAR esa diferencia es cero. Bajo MAR puede no serlo, pero dentro de cada valor de \(X\) sí lo es, por lo que promediar primero dentro de los grupos de \(X\) y luego ponderar por su tamaño elimina el sesgo: \[ \hat\mu_{\mathrm{MAR}}=\sum_{x}\hat P(X=x)\,\bar y_{\mathrm{obs}}(x). \] Es exactamente el estimador «por tipo de tienda» del laboratorio de mecanismos. Bajo MNAR no existe una corrección que use solo lo observado.

Para una columna numérica, la imputación por media usa \(\hat y_i=\bar y_{\mathrm{obs}}\) cuando \(R_i=1\). Con \(n_{\mathrm{obs}}\) valores observados de \(n\), la varianza de la columna imputada es \[ s^2_{\mathrm{imp}}=\frac{n_{\mathrm{obs}}-1}{n-1}\,s^2_{\mathrm{obs}}, \] porque los valores imputados no aportan desviaciones respecto a la media. En el ejemplo, \(\frac{2}{3}\cdot47.63=31.75\). En KNN, \(\hat y_i=k^{-1}\sum_{j\in N_k(i)}y_j\), donde \(N_k(i)\) reúne vecinos con el valor observado. Ambas producen estimaciones, no recuperaciones seguras del dato original.

40.6 Laboratorio: elegir y poner a prueba una imputación

Objetivo. Comparar media, mediana y KNN en el mismo ejemplo de productos. Hipótesis. Un método que use ventas como variable auxiliar debería ganar cuando peso y ventas guarden una relación útil.

  1. Cambia el método y el número de vecinos. Anota la imputación del peso realmente ausente de FDN15.
  2. Ocultamos además el peso conocido de NCD19 solo para validar. Compara la predicción con su valor real y registra el error absoluto.
  3. Cambia entre moda y categoría «Faltante» para Outlet_Size. Comprueba qué celdas cambian y cuáles no.
  4. Explica por qué el menor error en una sola fila no prueba que un método sea mejor para toda la población. Compara después el «error medio (dejar uno fuera)»11, que oculta por turnos cada peso conocido. ¿Cambia el método ganador? Propón cómo repetir esta validación por grupos y periodos en un conjunto real.

11 Validación dejando uno fuera (leave-one-out): se oculta una observación, se estima con las demás y se repite con cada observación. Promediar los errores reduce la dependencia de una sola fila afortunada, aunque con pocos datos la estimación sigue siendo muy variable.

Laboratorio · Imputar y validar

Media, mediana o vecinos: ¿quién estima mejor un peso oculto?

FDN15 no tiene peso. NCD19 sí lo tiene (12.40 kg), pero lo ocultamos para poder medir el error.

Método para el peso

Ventas (auxiliar) frente a peso

donantesestimaciónvalor real de NCD19vecinos usados

Tabla resultante

Estimación FDN15
Error en NCD19
Error medio (dejar uno fuera)

40.7 Implementación sin fuga de información

En un problema supervisado, separamos primero entrenamiento y prueba, y ajustamos cualquier imputador solo con entrenamiento. Aquí Item_Outlet_Sales es la variable objetivo: nunca se usa como predictor para imputar Item_Weight. Las variables auxiliares son un precio y un tipo de tienda simulados.

Código
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LinearRegression

rng = np.random.default_rng(42)
n = 300
outlet = rng.choice(['Supermarket', 'Grocery'], size=n, p=[0.6, 0.4])
weight = rng.normal(12, 2, n)
price = rng.normal(100, 15, n)
sales = 150 + 30 * weight + 4 * price + rng.normal(0, 50, n)
X = pd.DataFrame({'Item_Weight': weight, 'Item_MRP': price, 'Outlet_Type': outlet})
y = pd.Series(sales, name='Item_Outlet_Sales')
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)

# MAR simulado: la ausencia de peso depende del tipo de tienda observado.
for part in (X_train, X_test):
    probability = np.where(part['Outlet_Type'].eq('Grocery'), 0.45, 0.10)
    part.loc[rng.random(len(part)) < probability, 'Item_Weight'] = np.nan

numeric = Pipeline([('imputer', SimpleImputer(strategy='median', add_indicator=True))])
preprocess = ColumnTransformer([
    ('numeric', numeric, ['Item_Weight', 'Item_MRP']),
    ('outlet', OneHotEncoder(handle_unknown='ignore'), ['Outlet_Type'])
])
model = Pipeline([('preprocess', preprocess), ('regression', LinearRegression())])
model.fit(X_train, y_train)
print('R² en prueba:', round(model.score(X_test, y_test), 3))
print('Faltantes en train:', X_train['Item_Weight'].isna().sum())
print('Faltantes en test:', X_test['Item_Weight'].isna().sum())
R² en prueba: 0.623
Faltantes en train: 57
Faltantes en test: 16

La puntuación es solo una comprobación de que el flujo se ejecuta; para elegir estrategia, compara alternativas con validación cruzada dentro del conjunto de entrenamiento y deja la prueba para la evaluación final. Un indicador de ausencia puede ayudar cuando el patrón aporta señal; compruébalo empíricamente12.

12 Un indicador de ausencia es una columna binaria que registra si el valor original faltaba. SimpleImputer(add_indicator=True) la añade para las columnas con faltantes durante el ajuste. Documentación de SimpleImputer.

TipPráctica profesional: documentar y vigilar

Guarda el imputador junto con el modelo, vigila la tasa de faltantes por grupo y periodo, y registra qué campos están disponibles en el momento de inferencia. Compara una línea base simple con métodos más costosos según la métrica, la latencia y el volumen de tu sistema. No existe un umbral universal para descartar columnas ni un método de imputación superior en todos los datos. scikit-learn: errores comunes y fuga de datos · scikit-learn: imputación.