При решении сложных практических задач на построение надежной модели машинного обучения уходит лишь малая часть времени. Основной и самый трудоемкий этап — это сбор, очистка и предварительное исследование данных. Сегодня мы обсудим жизненный цикл ML-проектов, познакомимся со структурой библиотеки Pandas и проведем первичный разведочный анализ (EDA) на примере реального датасета аренды квартир.
В сфере анализа данных существует фундаментальный принцип — GIGO (Garbage In, Garbage Out), что означает «мусор на входе — мусор на выходе». Даже самая передовая модель машинного обучения не сможет показать высокую точность прогнозирования, если на этапе обучения в нее были поданы зашумленные, некорректные или нерепрезентативные данные.
Жизненный цикл типичного ML-проекта выглядит следующим образом:
Сбор данных → Очистка → EDA → Инжиниринг признаков → Обучение модели → Оценка
Практический инсайт: На сбор, предобработку, очистку и исследование данных уходит до 80% времени работы специалиста. Опыт оценки соревнований и хакатонов показывает, что победу в 99% случаев одерживает не та команда, которая выбрала сложную архитектуру нейросети, а та, которая качественнее и глубже провела очистку и разведочный анализ данных.
Прежде чем начать исследование, данные необходимо собрать. Основными источниками для ML-проектов выступают:
Pandas — это ключевая библиотека языка Python для анализа и манипуляции структурированными данными. Она построена поверх библиотеки NumPy, наследуя ее скорость вычислений (за счет низкоуровневой реализации операций на C и Fortran), но предоставляет гораздо более удобный прикладной интерфейс.
Основные структуры данных в Pandas:
EDA (Exploratory Data Analysis) — это этап глубокого исследования структуры, состава и масштаба проблем внутри имеющегося набора данных до перехода к непосредственному обучению моделей.
Ключевые цели EDA:
В качестве практического примера мы используем реальный датасет аренды квартир в Москве, выгруженный с сайта ЦИАН (содержит 5437 строк и 25 признаков). Первичный осмотр структуры мы выполняем с помощью встроенных инструментов DataFrame:
data.shape — возвращает размерность таблицы (количество строк и столбцов).data.head() и data.tail() — выводят первые и последние 5 строк таблицы для визуального знакомства с содержимым.data.columns — выводит список всех признаков (колонок). На этом этапе мы качественно оцениваем релевантность признаков и принимаем решение удалить неинформативные столбцы (ID объявления, ссылки, номера телефонов), которые не влияют на цену, но могут вызвать переобучение модели.data.dtypes — показывает типы данных каждого столбца (целые числа int, дробные числа float или категориальные/текстовые объекты object).Метод data.describe() вычисляет базовые статистические метрики для числовых столбцов: среднее значение, минимум, максимум, стандартное отклонение и квантили (включая медиану — квантиль 50%).
Анализ экстремумов (минимумов и максимумов) позволяет быстро выявить выбросы. Например, при анализе высоты потолков в нашем датасете среднее значение составило 2.77 м, а максимум — 28 метров. Очевидно, что потолок высотой 28 метров — это аномалия (скорее всего, опечатка при вводе данных, где забыли поставить разделительную точку: 2.80 м). Оставлять такие значения без изменений нельзя, так как они исказят веса линейных моделей.
Наличие пропусков (пустых ячеек NaN) — одна из главных проблем реальных датасетов. На этапе EDA наша задача — оценить масштаб проблемы при помощи метода data.isna().sum().
Для лучшего понимания распределения пропусков по колонкам используется тепловая карта библиотеки Seaborn:
sns.heatmap(data.isna().transpose(), cbar=False)
Такая тепловая карта наглядно подсвечивает плотность пропущенных данных. Если в каком-то второстепенном признаке пропущено более \(70\%\) значений, в большинстве случаев эту колонку целесообразно просто удалить.
Для качественного анализа текстовых категориальных колонок (например, типа парковки или округа) применяются методы:
data['Колонка'].unique() — выводит уникальный список всех встреченных категорий.data['Колонка'].value_counts() — подсчитывает количество упоминаний каждого значения.Этот шаг позволяет оценить сбалансированность классов в выборке. Если распределение категорий имеет сильный перекос (например, один класс занимает 95% выборки, а остальные по 1-2%), датасет считается несбалансированным. Визуально оценить эту характеристику помогает гистограмма распределения признаков sns.histplot().
Запустите интерактивный блокнот в Google Colab, подгрузите исследуемый датасет ЦИАН и пройдите все шаги первичного осмотра. Попробуйте вывести распределение уникальных значений для категориальных признаков «Округ» и «Ремонт», зафиксировав обнаруженные пропуски или аномалии.
Series) и двумерные таблицы (DataFrame).shape), вывод первых и последних строк таблицы (head()), tail()).dtypes) и наименований колонок.describe().NaN) по признакам через isna().sum().sns.heatmap()).unique()) и подсчет их распределения (value_counts()).sns.histplot()).