Ответ
Стратегия обработки пропусков зависит от природы данных, доли пропусков и типа признака. Я выбираю метод исходя из этого анализа.
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 для важных признаков, чтобы модель знала, что значение было пропущено.