Статистика

Exploratory Data Analysis: смотреть прежде чем считать

Флоренс Найтингейл в 1858 году построила polar area diagram и доказала: солдат убивает антисанитария, не ранения. Одна визуализация изменила политику британской военной медицины. EDA - это детективная работа: 80% критических ошибок ML-проектов обнаруживается до первой строки кода модели.

  • Kaggle победители тратят 60-70% времени именно на EDA перед моделированием
  • Anscombe quartet: 4 датасета с одинаковой статистикой, но кардинально разными паттернами
  • Netflix: EDA рейтингов выявила систематический bias выходного дня
  • Медицина: EDA ЭКГ-данных находит артефакты датчиков до обучения классификатора
  • Финансы: EDA торговых данных обнаруживает look-ahead bias в бэктесте
  • Pandas Profiling и ydata-profiling автоматизируют базовый EDA в один вызов

**1858 год. Крымская война. Флоренс Найтингейл получает доступ к данным британских военных госпиталей.** Данные показывают: солдаты умирают тысячами. Военное командование уверено - гибнут от ранений в бою. Найтингейл берёт те же числа и строит **polar area diagram** - диаграмму-розу, где каждый клин соответствует месяцу, а его площадь - числу погибших. Синий клин (болезни) в 10 раз больше красного (ранения). Не бой убивал солдат - убивала антисанитария в госпиталях. Одна визуализация изменила политику военной медицины Британии. Это и есть EDA: **смотреть на данные прежде чем делать выводы**. До любой модели, до любой формулы, до любой гипотезы.

**Чему этот урок учит на самом деле**: не "как построить гистограмму", а почему **80% критических ошибок ML-проектов возникает до первой строки кода модели**. Плохие типы данных, скрытые пропуски, выбросы, смещения в сборе - всё это EDA обнаруживает за 30 минут там, где модель потом молча выдаёт ерунду. EDA - это детективная работа: данные всегда лгут, пока не доказано обратное.

Tukey 1977: задавать вопросы до того, как считать ответы

**Джон Тьюки** (John Tukey) ввёл термин EDA в 1977 году в одноимённой книге. До него статистика была по большей части **confirmatory** - проверить гипотезу, которую уже сформулировали. Тьюки предложил другой порядок: сначала смотреть на данные без гипотезы, дать данным говорить самим. Его цитата стала манифестом области: *"It is important to understand what you CAN DO before you learn to measure how well you seem to have done it"*. Для ML-инженера это переводится просто: **фитить модель на непонятых данных = измерять качество подгонки к мусору**.

Предварительные знания

  • Sampling: how 1,000 people predict the behavior of a billion
  • Estimation: The $1.5B Mistake of the Hubble Telescope

**Профессиональный приём**: перед любым ML-проектом запускать `df.info()`, `df.describe()`, `df.isnull().sum()` и `df.duplicated().sum()` - четыре команды, две минуты. Это минимальный EDA-скрининг, который спасает от самых дорогих ошибок. По данным Kaggle surveys, дата-сайентисты тратят 60-80% времени именно на EDA и data cleaning - не на моделирование.

Квартет Анскомба: когда summary statistics врут

**Summary statistics** (среднее, дисперсия, корреляция) - первый рефлекс при взгляде на данные. Но в 1973 году статистик Фрэнк Анскомб придумал эксперимент, который навсегда меняет к ним отношение. Он создал **4 датасета** с практически идентичными числовыми характеристиками - но кардинально разными визуальными паттернами. После этого аргумент "у нас одинаковые средние" перестаёт звучать убедительно.

**Datasaurus Dozen (2017)** - современная версия квартета Анскомба: 13 датасетов с идентичными mean, std и correlation до двух знаков, включая изображение динозавра. Созданы для демонстрации того, что числа без визуализации не говорят ничего. Библиотека `datasetsaurus` (Python/R) позволяет воспроизвести это в двух строках кода.

Univariate analysis: одна переменная под микроскопом

Первый шаг EDA - изучить каждую переменную по отдельности. **Распределение** формы важнее, чем среднее. Три инструмента покрывают 90% задач: гистограмма (форма распределения), box plot (выбросы и квартили), QQ-plot (нормальность).

Bivariate и multivariate: как переменные связаны между собой

Одномерный анализ не раскрывает взаимосвязи. **Scatter plot** - базовый инструмент для двух числовых переменных: форма облака рассказывает о линейности, наличии кластеров, гетероскедастичности. **Correlation heatmap** позволяет охватить все пары сразу. **Pair plot** (seaborn.pairplot) - корреляционная матрица + распределения на диагонали - стандарт первичного анализа в Kaggle-соревнованиях.

**Парадокс Симпсона** - классический пример того, почему агрегированная корреляция может обманывать. В 1973 году Калифорнийский университет Беркли обвинили в дискриминации: суммарно в аспирантуру принимали 44% мужчин и 35% женщин. Казалось бы, явная дискриминация. EDA по каждому факультету показала обратное.

**Что показывает EDA**: женщины подавали преимущественно на факультеты C-F с низким acceptance rate (конкурентные гуманитарные), мужчины - на A-B с высоким (менее конкурентные технические). После разбивки по факультетам у женщин acceptance rate выше или равен мужскому на 4 из 6 факультетов. **Переменная-конфаундер (факультет) полностью меняет вывод.** В ML это называется Simpson's paradox - и он регулярно появляется в A/B-тестах при агрегации по неоднородным сегментам.

Missing data: MCAR, MAR, MNAR - три механизма пропусков

Пропущенные значения есть почти в любом реальном датасете. Стандартная реакция - удалить строки или заполнить средним. Но это правильно **только в одном из трёх случаев**, и неправильная обработка пропусков создаёт скрытый bias, который модель тихо впитывает. Рубин (1976) выделил три механизма пропусков, которые требуют разных стратегий обработки.

**Самая дорогая ошибка**: удалять строки с пропусками при MNAR. Пример - кредитный скоринг: заёмщики с высоким риском чаще не заполняют поле 'доход'. Удаление строк систематически убирает плохих заёмщиков из обучающей выборки. Модель обучается на смещённых данных и занижает риск. В 2007-2008 годах похожие паттерны в данных ипотечных заявок не были замечены именно из-за отсутствия EDA по механизму пропусков.

Outlier detection: когда выброс - это не ошибка

**Выброс** (outlier) - наблюдение, которое сильно отличается от остальных. Рефлекс - удалить. Но **outlier не равно error**. История Вальда с бомбардировщиками (урок stat-01) - это outlier-паттерн: именно отсутствие выбросов там, где их ожидают, рассказало всё. В данных о покупках один клиент с чеком $50,000 может быть ошибкой ввода, а может быть ключевым корпоративным покупателем. EDA помогает различить эти случаи.

**Правило расследования выброса**: перед удалением задать три вопроса. Первый - мог ли этот объект физически существовать (pH > 14 в питьевой воде = нет, удалить). Второй - есть ли контекст, объясняющий значение (выручка $1M у одного клиента = корпоративный аккаунт, изучить). Третий - изменятся ли выводы с этим значением и без (если да - документировать и проводить анализ в обоих вариантах). В fraud detection именно выбросы - самое ценное: $50k транзакция среди тысяч по 100 - это сигнал, а не шум.

EDA в production ML pipeline

**EDA в современном MLOps workflow** EDA не разовая активность - в production это автоматизированный слой между ingestion и feature engineering • **Raw Data Ingestion**: Источники: S3, BigQuery, PostgreSQL, Kafka streams - На этом этапе данные приходят как есть - без гарантий качества. Schema drift, missing files, encoding issues - обычная реальность • **Automated EDA / Profiling**: ydata-profiling (ex pandas-profiling): HTML-отчёт за одну строку - from ydata_profiling import ProfileReport; ProfileReport(df).to_file('eda.html') - генерирует полный EDA: distributions, correlations, missing, duplicates, alerts • **Data Quality Report**: Great Expectations: data contracts с автоматической валидацией - Определяет expectations (expect_column_values_to_be_between, expect_no_missing_values) и валидирует каждый batch. Pipeline падает если качество ниже threshold • **Drift Detection**: Evidently AI: мониторинг distribution shift в production - Сравнивает reference distribution (обучение) с current distribution (production). Detects covariate shift до деградации модели • **Feature Engineering**: Трансформации на основе EDA-инсайтов - Log-transform для skewed distributions, outlier capping, missing imputation strategy - всё определяется EDA, не догадками • **Model Training**: Только теперь - baseline модель и эксперименты - MLflow/W&B для tracking. EDA-артефакты хранятся рядом с моделью - для аудита и воспроизводимости

**Netflix experimentation platform**: каждый A/B-тест начинается с автоматического EDA pre-check - проверки баланса ковариат между группами (SRM test), распределений ключевых метрик, наличия outliers. Если pre-check не пройден, тест автоматически останавливается. Это один из примеров EDA, встроенного в production decision-making loop.

Практика: функция eda_summary для любого датафрейма

Tukey 1977: задавать вопросы до того, как считать ответы

**Джон Тьюки** (John Tukey) ввёл термин EDA в 1977 году в одноимённой книге. До него статистика была по большей части **confirmatory** - проверить гипотезу, которую уже сформулировали. Тьюки предло...

Что является ключевой идеей раздела «Tukey 1977: задавать вопросы до того, как считать ответы»?

Квартет Анскомба: когда summary statistics врут

**Summary statistics** (среднее, дисперсия, корреляция) - первый рефлекс при взгляде на данные. Но в 1973 году статистик Фрэнк Анскомб придумал эксперимент, который навсегда меняет к ним отношение....

Что является ключевой идеей раздела «Квартет Анскомба: когда summary statistics врут»?

Univariate analysis: одна переменная под микроскопом

Первый шаг EDA - изучить каждую переменную по отдельности. **Распределение** формы важнее, чем среднее. Три инструмента покрывают 90% задач: гистограмма (форма распределения), box plot (выбросы и к...

Что является ключевой идеей раздела «Univariate analysis: одна переменная под микроскопом»?

ПодходПорядок действийРиск
Confirmatory (традиционный)Гипотеза → Данные → ПроверкаПропустить неожиданные паттерны
EDA-first (Tukey)Данные → Паттерны → Гипотезы → МодельOverfitting к визуальным артефактам
ML без EDA (частая ошибка)Данные → Сразу обучениеGarbage in, garbage out
ML с EDA (правильно)Данные → EDA → Cleaning → Features → МодельМедленнее, но предсказуемо

Все четыре датасета (I, II, III, IV) имеют: mean(X) = 9.0 для всех четырёх mean(Y) = 7.5 для всех четырёх var(X) = 11.0 для всех четырёх var(Y) ≈ 4.12 для всех четырёх corr(X,Y) ≈ 0.816 для всех четырёх reg line: Y = 3.0 + 0.5*X для всех четырёх Но на графике: Dataset I - обычное линейное облако Dataset II - чистая парабола (нелинейная зависимость) Dataset III - прямая с одним мощным выбросом Dataset IV - вертикальный кластер + один outlier Вывод: summary stats ОДИНАКОВЫ, данные ПРИНЦИПИАЛЬНО РАЗНЫЕ. Фитить линейную регрессию - правильно только для I. Для II нужна трансформация. Для III нужно разбираться с выбросом. Для IV данные дефективны по дизайну.

ДатасетВизуальный паттернПравильная модельОшибка без EDA
IЛинейное облако с шумомЛинейная регрессияНет - здесь всё верно
IIГладкая параболаПолиномиальная регрессияRMSE занижен, экстраполяция сломана
IIIПрямая + один мощный выбросРегрессия без выбросаВыброс смещает slope на 30%+
IVОдна X-точка + вертикальный кластерДанные нужно исследоватьМодель fitting к артефакту сбора

Ширина бина влияет на то, что видно в гистограмме. Слишком узко - шум. Слишком широко - структура скрыта. Правило Фридмана-Диакониса: bin_width = 2 * IQR * n^(-1/3) Где: IQR = Q3 - Q1 (межквартильный размах) n = размер выборки Пример: цены на жильё, n = 1000, IQR = $150,000 bin_width = 2 * 150000 * 1000^(-1/3) = 300000 * 0.1 = $30,000 Число бинов ≈ (max - min) / bin_width Почему не sqrt(n) или rule of thumb = 10? FD-правило адаптируется к форме распределения: при большом IQR (широкое распределение) - меньше бинов, при малом IQR (плотное распределение) - больше. stats.iqr() из scipy + np.cbrt() делают это в одну строку.

Box plot кодирует пять чисел: min_whisker Q1 median Q3 max_whisker |--------|====|========|--------| o o Q1 = 25-й перцентиль Q3 = 75-й перцентиль IQR = Q3 - Q1 Тьюки-fence (правило выбросов): Нижний fence = Q1 - 1.5 * IQR Верхний fence = Q3 + 1.5 * IQR Точки за fence = выбросы (plotted individually). Пример: зарплаты [30k, 45k, 50k, 52k, 55k, 60k, 250k] Q1 = 45k, Q3 = 60k, IQR = 15k Верхний fence = 60k + 22.5k = 82.5k 250k > 82.5k → выброс Без box plot средняя = 77k - вводит в заблуждение. С box plot сразу видно: медиана 52k + один outlier.

ФакультетПоданий (М)Принятых (М)Поданий (Ж)Принятых (Ж)
A82562%10882%
B56063%2568%
C32537%59334%
D41733%37535%
E19128%39324%
F3736%3417%
Итого269144%183535%
МеханизмРасшифровкаПримерСтратегия
MCARMissing Completely At Random - пропуск не зависит ни от чегоПрибор случайно не записал измерениеУдаление строк безопасно
MARMissing At Random - пропуск зависит от наблюдаемых переменныхМужчины реже указывают вес (зависит от пола)Imputation с учётом наблюдаемых
MNARMissing Not At Random - пропуск зависит от самого пропущенного значенияБогатые не указывают доходМоделирование механизма пропуска

Метод 1: Z-score (параметрический, предполагает нормальность) z_i = (x_i - mean) / std Выброс если |z_i| > 3 Проблема: сам mean и std смещены выбросами! Лучше использовать modified Z-score: M_i = 0.6745 * (x_i - median) / MAD где MAD = median(|x_i - median|) Выброс если |M_i| > 3.5 Метод 2: IQR (непараметрический, Tukey fence) Нижний fence = Q1 - 1.5 * IQR Верхний fence = Q3 + 1.5 * IQR (крайний fence: 3.0 * IQR для "extreme outliers") Преимущество: работает для любого распределения Метод 3: Isolation Forest (ML-подход) Идея: аномалии легче "изолировать" - нужно меньше случайных splits в дереве решений contamination = ожидаемая доля выбросов (0.01-0.1) sklearn.ensemble.IsolationForest Преимущество: работает в многомерном пространстве

Упражнения

  1. Четыре датасета в квартете Анскомба имеют одинаковые mean, std, correlation и уравнение регрессии. Зачем вообще смотреть на графики? — Summary stats агрегируют форму распределения в несколько чисел, безвозвратно теряя паттерны: нелинейность, кластеры, выбросы Для датасета II линейная модель даёт систематически неверные предсказания за пределами обучающего диапазона - ошибка экстраполяции Для датасета III один выброс смещает slope регрессии на 30%+ - это нельзя увидеть из числа correlation=0.816 Датасет IV - вырожденный случай: все X одинаковы кроме одной точки. Regression line определяется буквально одним наблюдением Правило: числа описывают, визуализация показывает. Оба нужны
  2. В датасете о заработных платах 30% строк имеют пропуск в колонке 'income'. Как принимать решение: удалять или impute? — 30% пропусков - это много. Первый шаг: определить механизм (MCAR/MAR/MNAR) Для поля income MNAR наиболее вероятен: богатые не хотят раскрывать доход, малообеспеченные тоже. Удаление создаёт selection bias Проверка MAR: сравнить mean других переменных (возраст, образование, должность) между строками с income и без. Систематическое отличие = MAR или MNAR При MNAR простой imputation (mean/median) занижает дисперсию. Нужны: multiple imputation, модель пропуска, или включение индикатора 'was_missing' как фичи В production: документировать механизм пропуска в data card. Это часть model card для регуляторных требований
  3. Измерение pH воды показало значение 14.2. Максимальное теоретическое pH = 14. Это ошибка измерения? Как решить? — pH 14.2 - выброс, но не автоматически ошибка. pH шкала имеет практический максимум ~14 при 25°C, но при других температурах и концентрациях значение может быть чуть выше Алгоритм: 1. проверить паспорт прибора - точность ±0.1 или ±0.01? 2. проверить дату/время - может быть залповый сброс, (3) сравнить с соседними измерениями во времени Если соседние точки: 7.1, 7.3, 14.2, 7.2 - очевидная ошибка измерения (noise spike). Если: 7.1, 8.5, 11.2, 14.2 - возможно реальный химический процесс Стратегии: 1. удалить если физически невозможно 2. заменить медианой скользящего окна если технический сбой 3. оставить с флагом 'suspect' если реальный, но редкий Детективный принцип: outlier - это гипотеза, требующая проверки, а не приговор к удалению
  4. Датасет: 1000 признаков, 50,000 объектов. Как проводить EDA в высокоразмерном пространстве? — Univariate в первую очередь: distribution, missing, outlier для каждого из 1000 признаков - автоматизировать через ydata-profiling или написанный скрипт Correlation screening: heatmap 1000x1000 нечитаем. Нужны: иерархическая кластеризация признаков, поиск пар с |corr| > 0.95 для удаления дубликатов Снижение размерности для визуализации: PCA (2-3 компоненты) + scatter plot для понимания общей структуры и кластеров. UMAP для нелинейных структур (связь с stat-14) Target leakage EDA: для каждого признака проверить correlation с target - подозрительно высокий corr может означать data leakage Feature importance из baseline (Random Forest / XGBoost) как EDA-инструмент: выявляет 20 признаков, объясняющих 80% дисперсии, на которых фокусируется глубокий EDA

Что унести из урока

  • **EDA - это не опциональный шаг**: 80% ошибок ML случается до модели. Найтингейл изменила медицину не формулой, а диаграммой - данные нужно видеть
  • **Квартет Анскомба**: четыре датасета с одинаковыми mean/std/corr могут быть принципиально разными. Summary stats НИКОГДА не заменяют визуализацию
  • **MCAR / MAR / MNAR** - три механизма пропусков, требующие разных стратегий. Удалять строки безопасно только при MCAR; при MNAR - создаёт bias
  • **Outlier не равно error**: выброс - гипотеза, требующая расследования. IQR fence, modified Z-score и Isolation Forest дают разные инструменты в зависимости от размерности
  • **Парадокс Симпсона**: агрегированная корреляция может быть обратной корреляции внутри подгрупп. EDA по сегментам обязателен перед любым выводом о связи
  • **В production EDA автоматизирован**: ydata-profiling, Great Expectations, Evidently AI - EDA встроен в pipeline, а не делается вручную раз в год
  • **Freedman-Diaconis rule** адаптирует ширину бина гистограммы к данным: bin = 2*IQR*n^(-1/3)

Куда дальше

EDA - отправная точка. После него - понять связи, построить модели, проверить допущения.

  • Выборка и selection bias — stat-01: выброс в данных и выброс из выборки - разные вещи. EDA не компенсирует неправильный sampling design
  • Корреляция и её ловушки — stat-08: после EDA - формальный анализ correlation, partial correlation, spurious correlation
  • Диагностика регрессии — stat-09: EDA предшествует регрессии - проверка нормальности остатков, гетероскедастичности, влиятельных наблюдений
  • PCA для высокоразмерного EDA — stat-14: снижение размерности как EDA-инструмент в 1000-мерных пространствах
  • Kernel Density Estimation — stat-23: сглаженная альтернатива гистограмме - KDE для более точной оценки плотности распределения

Связанные уроки

  • prob-01-intro
  • ml-04-data-preprocessing
Exploratory Data Analysis: смотреть прежде чем считать

0

1

Войти