Какие методы обработки пропущенных значений (missing values) вы используете?

«Какие методы обработки пропущенных значений (missing values) вы используете?» — вопрос из категории Предобработка данных, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Стратегия обработки пропусков зависит от природы данных, доли пропусков и типа признака. Я выбираю метод исходя из этого анализа.

1. Удаление (Deletion):

  • Удаление строк: Применимо, если пропусков мало (<5%) и они случайны (MCAR). Риск — потеря данных.
    df_dropped_rows = df.dropna(axis=0)
  • Удаление столбцов: Если признак имеет очень высокий процент пропусков (>40-50%) и не является критически важным.
    df_dropped_cols = df.dropna(axis=1, thresh=len(df)*0.5) # Удаляем колонки, где >50% NaN

2. Замена константами (Imputation with Constants):

  • Для числовых признаков: 0, -1, или крайнее значение (например, 999).
  • Для категориальных признаков: отдельная категория 'Missing' или 'Unknown'.
    df_filled = df.copy()
    df_filled['age'].fillna(-1, inplace=True)
    df_filled['education'].fillna('Unknown', inplace=True)

3. Замена статистическими метриками (Statistical Imputation):

  • Среднее (Mean) или Медиана (Median): Для числовых признаков. Медиана более устойчива к выбросам.
    median_age = df['age'].median()
    df['age'].fillna(median_age, inplace=True)
  • Мода (Mode): Для категориальных признаков.
    most_frequent_city = df['city'].mode()[0]
    df['city'].fillna(most_frequent_city, inplace=True)

4. Импутация с использованием моделей (Model-Based Imputation): Более продвинутый подход, где пропуски предсказываются на основе других признаков.

  • K-Nearest Neighbors (KNNImputer): Заменяет пропуск средним значением от k наиболее похожих наблюдений.
    from sklearn.impute import KNNImputer
    imputer = KNNImputer(n_neighbors=5, weights='uniform')
    df_imputed = pd.DataFrame(imputer.fit_transform(df_numeric), columns=df_numeric.columns)
  • Итеративная импутация (IterativeImputer): Моделирует каждый признак с пропусками как функцию других признаков (часто на основе регрессии).
    from sklearn.experimental import enable_iterative_imputer
    from sklearn.impute import IterativeImputer
    from sklearn.ensemble import RandomForestRegressor
    imputer = IterativeImputer(estimator=RandomForestRegressor(), random_state=42)
    df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)

5. Интерполяция (Interpolation): В основном для временных рядов, где есть естественный порядок.

df['temperature'] = df['temperature'].interpolate(method='time') # Учитывает временные интервалы
# или линейная интерполяция
df['value'] = df['value'].interpolate(method='linear')

Важное правило: Метод импутации, рассчитанный на трейновой выборке (например, медиана), должен быть сохранен и применен к валидационной и тестовой выборкам для корректной оценки модели. Я всегда создаю флаги is_missing для важных признаков, чтобы модель знала, что значение было пропущено.