Почему EDA — это не набор графиков, а способ понять задачу
Exploratory Data Analysis часто сводят к «посмотрим на распределения и построим пару графиков». Из-за этого EDA воспринимается как красивая, но второстепенная часть проекта. На практике все наоборот. Именно на этапе EDA становится понятно, с какими данными ты реально работаешь, какие признаки живые, где сидят пропуски и выбросы, как распределена целевая переменная и не встроена ли в данные будущая утечка.
Хороший EDA не показывает все подряд. Он отвечает на конкретные вопросы. Что является объектом наблюдения? Есть ли дубликаты? Насколько редки положительные случаи? Не смешались ли в одной колонке разные логики? Какие признаки можно использовать в модели, а какие просто отражают последствия события?
С чего начинать исследование
Первый шаг — понять структуру таблицы: размер, типы, пропуски, базовая статистика. Второй — посмотреть целевую переменную и ее баланс. Третий — проверить ключевые признаки на распределения, аномалии и выбросы. Четвертый — посмотреть отношения между признаками и таргетом. Пятый — сформулировать первые гипотезы, которые потом либо пойдут в feature engineering, либо покажут, что модель пока рано строить.
Очень полезно думать так: EDA — это предварительный допрос данных. Ты еще не веришь им полностью и пытаешься понять, не скрыта ли внутри структура, которая обманет модель.
Какие сигналы нельзя пропускать
Если целевая переменная сильно несбалансирована, это уже влияет на выбор метрик. Если в данных есть временная ось, нельзя перемешивать наблюдения как попало. Если часть признаков сильно коррелирует между собой, это повод подумать об интерпретации и стабильности модели. Если в таблице есть столбцы, которые появляются только после целевого события, это потенциальная утечка.
То есть качественный EDA — это не только про описание, но и про защиту будущей модели от грубых ошибок еще до обучения.
Как это обычно выглядит в Python
import pandas as pd
df = pd.DataFrame({
'segment': ['A', 'A', 'B', 'B', 'C', 'C'],
'sessions': [2, 5, 1, 8, 3, 9],
'revenue': [0, 500, 0, 1200, 200, 1500],
'target': [0, 1, 0, 1, 0, 1]
})
print(df.info())
print(df.describe())
print(df['target'].value_counts(normalize=True).round(2))
print(df.groupby('segment', as_index=False).agg(avg_revenue=('revenue', 'mean'), conv=('target', 'mean')))Даже такой короткий скрипт уже отвечает на несколько важных вопросов: какие типы в данных, как распределен таргет, отличаются ли сегменты и где может быть сигнал. Это и есть нормальная отправная точка EDA — не максимальная красота, а максимальная ясность.