Главная
#Математика и ML #Data Science #Missing Values

Что такое Missing data patterns в Data Science и почему пропуски в данных несут больше смысла, чем кажется в 2026 году?

Missing data patterns — это взгляд на пропуски не как на технический мусор, а как на структуру поведения данных. Именно здесь у многих студентов происходит важный интеллектуальный перелом. Пока пропуск воспринимается как пустая ячейка, кажется, что задача сводится к imputation. Но как только мы начинаем смотреть на паттерн пропусков, становится видно: отсутствие значения тоже является наблюдением. Иногда оно даже говорит о процессе больше, чем само число.

Содержание
  1. Почему пропуск сам по себе может быть признаком
  2. Первая полезная идея: отделить значение от факта его наличия
  3. Как увидеть паттерн, а не только долю пропусков
  4. Три механизма missingness, которые нельзя путать
  5. Геометрический смысл missing data patterns
  6. Почему пропуски напрямую связаны с оптимизацией модели
  7. Когда простая imputation полезна, а когда опасна
  8. Python: как увидеть структуру пропусков на практике
  9. Какие ошибки здесь делают чаще всего
  10. Что важно вынести из темы
  11. Kaggle notebook по теме:

Представьте медицинскую таблицу, где дорогой анализ отсутствует именно у легких пациентов. Или e-commerce-датасет, где поле “доход” чаще пустое у пользователей, которые не завершили анкету. Или банковский скоринг, где часть документов не загружается именно в рискованных кейсах. В этих примерах пропуск уже не является нейтральной дырой. Он связан с механизмом отбора, поведением пользователя, стоимостью измерения или устройством бизнес-процесса.

Эту тему лучше рассматривать как часть взрослой работы с данными целиком. Тогда пропуски перестают выглядеть как локальная неприятность перед моделью и начинают восприниматься как сигнал о том, как именно система собирает, теряет и искажает наблюдения.

Поэтому в 2026 году сильная работа с пропусками начинается не с вопроса “чем заменить NaN?”, а с вопроса “почему это значение исчезло именно здесь?”. Это уже не косметика перед моделью. Это исследование того, как система порождает неполноту.

Почему пропуск сам по себе может быть признаком

В Data Science мы привыкли думать о признаке как о числе, категории или векторе. Но отсутствие значения тоже может отделять одни объекты от других. Если у клиента не заполнен доход, это может означать одно поведение. Если у пациента нет результата обследования, это может означать другое. Если сенсор не передал сигнал, это может говорить не о “нуле”, а о сбое, перегрузке или особом режиме работы.

Интуитивно это похоже на молчание в диалоге. Иногда молчание ничего не значит. Иногда оно случайно. А иногда именно в нем и спрятан главный смысл. С пропусками происходит то же самое: одни появляются случайно, другие систематически, третьи отражают сам скрытый target-механизм.

Из-за этого слепая замена всех пропусков медианой часто оказывается слишком грубой. Мы как будто закрашиваем картину ровным серым цветом и теряем узор, который как раз и был важен.

Дата сайнс комикс о том, что пропуск может быть отдельным сигналом для модели

Первая полезная идея: отделить значение от факта его наличия

Очень сильный практический прием состоит в том, чтобы мыслить в двух слоях. Первый слой — это само значение признака. Второй — индикатор того, было ли значение наблюдено вообще. Тогда таблица начинает выглядеть честнее: мы больше не путаем “число отсутствует” и “число равно нулю”.

(R_{ij}=\mathbb{I}(X_{ij}\neq \mathrm{NA}))

Раздел математики: математическая статистика и теория индикаторных функций.

Что означает каждый символ:

(R_{ij}) — индикатор наблюдаемости признака (j) у объекта (i).

(\mathbb{I}(\cdot)) — индикаторная функция, которая возвращает (1), если условие выполнено, и (0) в противном случае.

(X_{ij}) — значение признака (j) у объекта (i).

(\mathrm{NA}) — отсутствие наблюдаемого значения.

Формула появляется из очень практической идеи: отсутствие значения тоже нужно превратить в наблюдаемый объект, иначе модель и аналитик потеряют часть информации.

Численный пример: пусть у клиента номер (i=7) поле дохода заполнено, тогда (R_{7,\mathrm{income}}=1). Если у клиента номер (i=12) это поле пустое, то (R_{12,\mathrm{income}}=0). Уже этот бинарный признак может оказаться полезным для модели.

Связь с Machine Learning здесь прямая. Во многих табличных задачах missing indicator действительно добавляют в feature space. Это особенно полезно тогда, когда сам факт отсутствия значения коррелирует с target.

Именно поэтому тема очень естественно продолжается в сторону feature lineage: как только пропуск начинает нести смысл, становится важно понимать не только само поле, но и путь его появления в данных.

Как увидеть паттерн, а не только долю пропусков

Доля пропусков по столбцу — это только первый взгляд. Она отвечает на вопрос “сколько отсутствует?”, но не отвечает на вопрос “как именно отсутствует?”. А именно второй вопрос чаще оказывается содержательным. Может быть так, что два признака по отдельности теряют по 20 процентов значений, но почти всегда пропадают вместе. Или наоборот: у них одинаковая доля пропусков, но механизмы полностью разные.

Поэтому полезно смотреть на missingness mask как на отдельную бинарную матрицу. Каждая строка этой матрицы — это профиль наблюдаемости объекта. Два объекта могут иметь очень разные численные значения, но одинаковый профиль пропусков. Иногда именно этот профиль и формирует скрытую сегментацию данных.

(m_j=\frac{1}{n}\sum_{i=1}^{n}(1-R_{ij}))

Раздел математики: математическая статистика.

Что означает каждый символ:

(m_j) — доля пропусков в признаке (j).

(n) — число объектов в выборке.

(R_{ij}) — индикатор наблюдаемости из предыдущей формулы.

(1-R_{ij}) — индикатор пропуска: он равен (1), если значение отсутствует.

Формула показывает, как из бинарной матрицы наблюдаемости получить стандартную missing rate. Но важно помнить: это только агрегат. Он удобен, но скрывает структуру совместных пропусков.

Численный пример: если в столбце из (1000) строк пропущены (150) значений, то (m_j=150/1000=0.15). Это означает, что 15 процентов наблюдений отсутствуют, но пока ничего не говорит о том, случайны ли эти 15 процентов.

Дата сайнс комикс о том, что одинаковая доля пропусков не означает одинаковый паттерн

Три механизма missingness, которые нельзя путать

Здесь начинается самая важная математика темы. Одни пропуски возникают независимо от данных. Другие зависят от уже наблюдаемой части объекта. Третьи связаны с самими ненаблюдаемыми значениями. Именно эта классификация определяет, насколько честно будут работать imputation, статистические выводы и ML-модель.

Дата сайнс комикс про различие MCAR, MAR и MNAR

MCAR означает, что пропуск не зависит ни от наблюдаемых, ни от ненаблюдаемых переменных. Это почти идеальная ситуация. Таблица как будто теряет значения случайным шумом. MAR означает, что механизм пропуска можно объяснить уже доступными наблюдаемыми признаками. Это гораздо реалистичнее: например, доход пропускается чаще у молодых пользователей, но возраст у нас наблюдается. MNAR означает, что пропуск зависит от самого скрытого значения. Например, люди с очень высоким или очень низким доходом реже сообщают его в анкете. Это самый сложный случай, потому что в механизме missingness участвует как раз то, чего мы не видим.

(P(R \mid X_{\mathrm{obs}}, X_{\mathrm{mis}})=P(R))

Раздел математики: теория вероятностей.

Что означает каждый символ:

(R) — весь механизм пропусков или missingness pattern.

(X_{\mathrm{obs}}) — наблюдаемая часть данных.

(X_{\mathrm{mis}}) — ненаблюдаемая часть данных, то есть сами пропущенные значения.

(P(R \mid X_{\mathrm{obs}}, X_{\mathrm{mis}})) — вероятность конкретного паттерна пропусков при фиксированных данных.

Эта формула описывает режим MCAR: вероятность пропуска не зависит ни от чего содержательного в таблице.

Численный пример: если часть значений потерялась из-за случайного технического сбоя сети на этапе передачи, то для конкретного признака можно думать о пропуске как о почти независимом шуме. Тогда missingness не несет содержательного сигнала о пользователе или объекте.

(P(R \mid X_{\mathrm{obs}}, X_{\mathrm{mis}})=P(R \mid X_{\mathrm{obs}}))

Раздел математики: теория вероятностей и статистическое моделирование.

Что означает каждый символ:

(R) — механизм пропусков.

(X_{\mathrm{obs}}) — наблюдаемая часть данных.

(X_{\mathrm{mis}}) — ненаблюдаемая часть данных.

Эта формула описывает режим MAR: механизм пропуска можно объяснить тем, что уже наблюдается в таблице.

Численный пример: если поле “доход” чаще пустое у студентов, но возраст и статус занятости у нас есть, то missingness уже не случайна, но все еще может быть описана через доступные признаки. Это типичный сценарий, где missing indicator и разумный imputation часто работают полезно.

MNAR формально ещё сложнее: там missingness зависит от самого скрытого значения. Геометрически это особенно неприятно, потому что в пространстве признаков вы видите не просто разреженность, а систематически вырезанные области. В таких задачах среднее или медиана могут вносить сильное смещение, а простая imputation создает иллюзию восстановленной информации.

Ровно здесь особенно опасно недооценить утечку из будущего или из побочных источников: статья про data leakage в фичах времени хорошо показывает, как “удобное” восстановление данных может незаметно превратить пропуск в ложное знание о target.

Геометрический смысл missing data patterns

Если смотреть на пропуски геометрически, каждый объект можно описать не только числовым вектором признаков, но и бинарным вектором наблюдаемости. Тогда все объекты живут сразу в двух пространствах: пространстве значений и пространстве паттернов missingness. Иногда эти пространства почти независимы. А иногда второе пространство объясняет структуру данных даже лучше первого.

Это особенно хорошо видно в табличных задачах, где клиенты, пациенты или устройства естественно распадаются на режимы заполнения данных. Одни всегда приходят с полным набором полей. Другие регулярно теряют конкретные признаки. Третьи образуют редкие “маски пропусков”, которые сами по себе выглядят аномально. В такой картине пропуски перестают быть шумом и становятся координатой.

В длинных пользовательских сценариях такие паттерны часто заметнее всего проявляются именно на временной оси, поэтому рядом полезно держать и материал о time-based validation, где хорошо видно, как структура данных меняется вместе с возрастом наблюдений.

Именно отсюда возникает связь с кластеризацией, anomaly detection и feature engineering. Missingness mask можно кластеризовать, по ней можно искать сегменты, а индикаторы пропусков можно использовать как вход в модель.

Почему пропуски напрямую связаны с оптимизацией модели

Это место часто недооценивают. Любая модель оптимизирует loss по тем данным, которые мы ей дали. Если missingness pattern несет сигнал, а мы не сохранили этот сигнал, то оптимизация идет по обедненному представлению объекта. Мы заставляем модель минимизировать ошибку на искусственно уплощенной версии реальности.

Если же пропуски действительно случайны, слишком агрессивное добавление missing indicators может, наоборот, привести к лишнему шуму. Поэтому missing data patterns — это не только вопрос предобработки, но и вопрос того, какую геометрию объекта мы даем алгоритму в оптимизации.

На практике это почти всегда упирается и в инфраструктуру данных: статья про data contracts полезна здесь как продолжение мысли о том, что часть пропусков надо не “лечить” постфактум, а предотвращать на уровне договоренностей между системами.

В деревьях решений и бустингах часть этой проблемы часто решается нативно: модель умеет работать с отсутствующими значениями как с отдельным маршрутом. В линейных моделях и нейросетях вопрос о том, как представить missingness, становится особенно чувствительным. Там отсутствие значения нужно либо осмысленно кодировать, либо явно отделять через индикатор, либо моделировать отдельно.

Когда простая imputation полезна, а когда опасна

Заполнение медианой или наиболее частым значением полезно как baseline, особенно если пропусков мало и они близки к MCAR. Но как только missingness pattern становится информативным, простая imputation начинает скрывать важный механизм. Медиана не рассказывает, почему поле отсутствовало. Она лишь делает таблицу удобной для алгоритма.

Поэтому сильная практика обычно такая: сначала исследовать mask и pattern counts, затем проверить, связаны ли пропуски с target или сегментами, потом уже решать, нужен ли indicator, отдельный режим imputation, модель с native missing support или вообще переосмысление источника данных.

Python: как увидеть структуру пропусков на практике

import pandas as pd  # Подключаем pandas для работы с таблицей.
import numpy as np  # Numpy понадобится для численных операций.
from sklearn.impute import SimpleImputer  # Берем простой baseline-импьютер.
from sklearn.linear_model import LogisticRegression  # Используем логистическую регрессию как понятную модель.
from sklearn.model_selection import cross_val_score  # Подключаем кросс-валидацию для проверки идеи.

df = pd.read_csv("data.csv")  # Загружаем таблицу, в которой хотим изучить пропуски.

target = "churn"  # Предполагаем, что в задаче есть целевая переменная churn.
X = df.drop(columns=[target])  # Отделяем признаки от target.
y = df[target]  # Сохраняем целевую переменную отдельно.

missing_mask = X.isna().astype(int)  # Превращаем факт пропуска в бинарную матрицу из нулей и единиц.
print("Missing rate by column:")  # Печатаем заголовок для долей пропусков.
print(missing_mask.mean().sort_values(ascending=False))  # Смотрим, какие столбцы теряются чаще всего.

print("Top missingness patterns:")  # Печатаем заголовок для самых частых паттернов.
print(missing_mask.value_counts().head(10))  # Считаем, какие бинарные маски пропусков встречаются чаще всего.

co_missing = missing_mask.T.dot(missing_mask) / len(missing_mask)  # Считаем долю совместных пропусков между признаками.
print("Co-missingness matrix:")  # Печатаем заголовок для матрицы совместных пропусков.
print(co_missing)  # Смотрим, какие поля часто пропадают вместе.

X_with_flags = X.copy()  # Создаем копию признаков, чтобы добавить missing indicators.
for column in X.columns:  # Проходим по всем исходным признакам.
    X_with_flags[f"{column}_is_missing"] = X[column].isna().astype(int)  # Добавляем бинарный индикатор пропуска.

imputer = SimpleImputer(strategy="median")  # Заполняем числовые пропуски медианой как baseline.
X_imputed = pd.DataFrame(imputer.fit_transform(X_with_flags), columns=X_with_flags.columns)  # Получаем таблицу без NaN.

model = LogisticRegression(max_iter=1000)  # Создаем простую линейную модель.
scores = cross_val_score(model, X_imputed, y, cv=5, scoring="roc_auc")  # Проверяем, помогает ли такое представление объекту.

print("ROC-AUC mean:", scores.mean())  # Смотрим среднее качество по фолдам.
print("ROC-AUC std:", scores.std())  # Смотрим устойчивость качества.

Этот код не утверждает, что так нужно делать всегда. Он показывает правильную исследовательскую логику: сначала мы смотрим на карту пропусков, затем на совместные паттерны, потом пробуем добавить missing indicators и только после этого оцениваем, помогает ли такое представление модели. То есть пропуски становятся частью feature engineering, а не только проблемой очистки.

А если источник признаков уже дошел до продовой аналитики или ML-пайплайна, следующим шагом почти неизбежно становится и вопрос производительности извлечения: материал про SQL performance полезен как напоминание, что плохие запросы могут не только тормозить систему, но и искажать структуру доступных данных.

Какие ошибки здесь делают чаще всего

Первая ошибка — считать, что пропуски являются чисто технической неприятностью. Вторая — смотреть только на missing rate и не изучать совместные маски. Третья — заполнять всё одной схемой без вопроса о механизме missingness. Четвертая — забывать, что отсутствие значения может быть predictive signal.

Есть и обратная ошибка: романтизировать любой пропуск как “скрытый смысл”. Иногда дырка в данных действительно просто случайна. Поэтому сильная работа с missing data patterns — это не мистификация, а аккуратная проверка гипотезы: несет ли механизм пропуска информацию или нет.

Что важно вынести из темы

Missing data patterns — это способ увидеть в пропусках структуру. Они помогают понять, случайно ли данные теряются, зависит ли пропуск от наблюдаемой части объекта и можно ли использовать missingness как самостоятельный сигнал. В этом смысле пропуск — не просто отсутствие числа, а событие в жизненном цикле данных.

Если сформулировать совсем коротко, сильный специалист по Data Science не просто заполняет NaN, а сначала спрашивает, что именно система пытается рассказать через эти пустые места. Именно с этого и начинается взрослая работа с неполными данными.

Kaggle notebook по теме:

https://www.kaggle.com/code/alexisbcook/missing-values

Что читать дальше

Связанные статьи по этой теме

Инструменты Python в 2026 году: современный стек для профессиональной разработки Что должен знать Junior Data Scientist в 2026 году? Как собрать GitHub-портфолио для Data Science
Вернуться в блог