Предварительная обработка данных в машинном обучении: инструкция, инструменты, полезные ресурсы для начинающих

В статье рассказываем, зачем обрабатывать данные перед загрузкой в модель, как провести предобработку и какие инструменты использовать.

dfb365d2e537133a08dab62a4690c012.pngМария Жарова

Data Scientist, Альфа-Банк

Что такое предобработка данных

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

Артефакты могут появляться по разным причинам:

  • Человеческий фактор: ошибки при ручном вводе — опечатки, пропуски или неправильные значения.

  • Неполные данные: информация может быть недоступна, например, сотрудник не указал свое место проживания.

  • Ошибки при сборе: сбои в автоматических системах, например, временные проблемы с сетью, из-за чего часть данных теряется.

  • Объединение данных из разных источников: разные форматы или отсутствие значений при объединении нескольких баз.

  • Технические ограничения: например, система принимает только положительные числа, а передали отрицательное значение.

  • Устаревшая информация: данные не обновляются вовремя, из-за чего информация устаревает.

  • Ошибки при миграции: повреждение или потеря данных при переносе из одной системы в другую.

Пример датасета с артефактами:

ID

Имя

Возраст

Зарплата

Город

Дата приема

Отдел

1

Иванов Иван

28

100000

Москва

2018–05–20

Продажи

2

NaN

NaN

60000

Санкт-Петербург

2019–03–15

Маркетинг

3

Ольга Петрова

35

-1500

Новосибирск

NaN

Разработка

4

Андрей Сидоров

NaN

70000

Неизвестно

2021–11–10

NaN

5

NaN

45

80000

Казань

2020–08–01

HR

6

Елена Белова

29

NaN

NaN

2017–09–23

Продажи

Пропуски: пропущенные значения в столбцах: Имя, Возраст, Зарплата, Город, Дата приема на работу, Отдел (NaN).

Ошибки в данных: отрицательное значение в столбце Зарплата (значение »-1500»).

Неоднородные данные:  

  1. В столбце Город указан заполнитель «Неизвестно» вместо названия города;

  2. Разное представление пропущенных или неизвестных значений:  

  • NaN (Not a Number) автоматически используется в некоторых системах, например, при выгрузке данных из баз или при считывании в библиотеке для анализа данных (такие как pandas);

  • «Неизвестно» — это пример текстового заполнителя, который вводят вручную, когда нет информации, — его также нужно обрабатывать как пропуск.

Предобработка помогает устранить все эти проблемы, а в результате — улучшить качество данных и повысить точность модели. 

Как автоматизировать предобработку данных

Автоматизация предобработки сокращает время на рутинные задачи и снижает риск ошибок. 

Для этого можно использовать различные инструменты и подходы:

  1. Использование библиотек для предобработки: библиотеки, такие как Scikit-Learn, предоставляют множество готовых инструментов: например, SimpleImputer для заполнения пропусков, StandardScaler для масштабирования, LabelEncoder для кодирования категориальных данных. 

    Эти инструменты можно объединить в Pipeline — последовательность шагов для автоматической обработки данных.

  2. Pipeline из Scikit-Learn: объединяет несколько этапов предобработки в один процесс, облегчая повторное применение тех же шагов к разным наборам данных и делая код более структурированным и понятным. 

    Пример: создание Pipeline для автоматического выполнения всех необходимых шагов предобработки, таких как заполнение пропусков, масштабирование и кодирование признаков.

  3. Автоматизация с помощью библиотек для подготовки данных:

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

  • Feature-engine: библиотека с удобными функциями для автоматизации задач: создание новых признаков, кодирование категорий и работа с выбросами.

  • Polars: новая библиотека для высокоэффективной работы с данными и их анализа на Python, альтернатива Pandas для работы с очень большими объемами данных.

  1. Другие подходы:

  • Платформы для машинного обучения: инструменты AutoML, такие как H2O.ai, LAMA и TPOT, автоматически подбирают модели и выполняют предобработку данных, что упрощает процесс для пользователя.

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

Как проводится предобработка данных — на примере

Предобработка данных — это главная стадия подготовки набора данных перед загрузкой в модель машинного обучения. 

На каждом этапе можно выполнить ручную обработку, использовать автоматические инструменты для упрощения задачи или комбинировать оба способа. 

Представим, что у нас есть набор данных о квартирах:

ID

Площадь (кв. м)

Число комнат

Возраст дома (лет)

Стоимость (млн руб.)

Тип недвижимости

Район

1

80

3

20

8

квартира

А

2

100

NaN

150

10

дом

Б

3

2000

2

NaN

50

квартира

А

4

100

4

30

6

апартаменты

В

5

150

3

5

NaN

дом

Б

6

500

5

300

70

квартира

А

7

100

3

25

14

дом

Б

8

80

3

-5

8

апартаменты

В

9

-150

3

15

12

дом

Б

10

100

3

25

14

квартира

А

Разберем поэтапно обработку данных с использованием информации выше.

Используем следующие инструменты:  

  • Pandas: библиотека для работы с таблицами данных (DataFrame), очистки данных, заполнения пропусков, удаления дубликатов и фильтрации данных.

  • Scikit-Learn: библиотека для машинного обучения. Включает инструменты для предобработки данных, которые используются для заполнения пропусков, масштабирования признаков и работы с выбросами.

  • Matplotlib и Seaborn: библиотеки для визуализации данных, используемые для анализа, в том числе обнаружения выбросов и шумов.

  • Numpy: библиотека для быстрой и эффективной работы с числовыми массивами, включая сложные математические преобразования.

Этап 1 — сбор и анализ данных

На первом этапе важно собрать данные и проанализировать их качество, так как это напрямую влияет на качество модели. На этом этапе можно понять структуру данных, выявить проблемы (пропуски, дубликаты, выбросы) и спланировать методы их устранения.

Сбор данных вручную. Данные можно получить из различных источников: баз данных, веб-скрейпинга, API, CSV-файлов и др. Например, вы можете загрузить данные с использованием Pandas:

Пример кода для загрузки данных:

import pandas as pd

# Создание DataFrame с данными о недвижимости

data = {

    'ID': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],

    'Площадь (кв. м)': [80, 100, 2000, None, 150, 500, 120, 80, -150, 100],

    'Число комнат': [3, None, 2, 4, 3, 5, 3, 3, 3, 3],

    'Возраст дома (лет)': [20, 150, None, 30, 5, 300, 25, -5, 15, 25],

    'Цена (млн руб.)': [8, 10, 50, 6, None, 70, 14, 8, 12, 14],

    'Тип недвижимости': ['квартира', 'дом', 'квартира', 'апартаменты', 'дом', 'квартира', 'дом', 'апартаменты', 'дом', 'квартира'],

    'Район': ['А', 'Б', 'А', 'В', 'Б', 'А', 'Б', 'В', 'Б', 'А']

}

df = pd.DataFrame(data)

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

API-запросы: использование библиотек, таких как requests, для получения данных по API.

import requests

import pandas as pd

response = requests.get('https://api.example.com/data')

data = response.json()

df = pd.DataFrame(data)

Веб-скраппинг: использование библиотек, таких как BeautifulSoup и Selenium, для сбора данных с веб-сайтов.

from bs4 import BeautifulSoup

import requests

url = 'https://example.com/data'

response = requests.get(url)

soup = BeautifulSoup(response.text, 'html.parser')

# Пример извлечения данных и создания DataFrame

table_data = soup.find_all('table')[0]  # Найти таблицу

df = pd.read_html(str(table_data))[0]

Интеграция с базами данных: Использование библиотек, таких как SQLAlchemy или pyodbc, для подключения и извлечения данных из баз.

from sqlalchemy import create_engine

import pandas as pd

engine = create_engine('sqlite:///example.db')

df = pd.read_sql('SELECT * FROM data_table', con=engine)

Анализ данных

После сбора нужно провести анализ для понимания структуры данных и выявления проблем, которые требуют предобработки.

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

  • head () выводит первые несколько строк таблицы, чтобы вы могли примерно ознакомиться с содержимым данных.

  • info () показывает количество непустых значений в каждом столбце и тип данных в них (целые числа, вещественные числа и т.д.).

  • describe () предоставляет сводную статистику, по числовым признакам: среднее, стандартное отклонение, минимальное и максимальное значения; для категориальных: количество уникальных категорий и частота самой ТОПовой.

Пример кода для анализа данных:

# Просмотр первых строк таблицы

display(df.head())

# Получение информации о типах данных и наличии пропусков

display(df.info())

# Статистическое описание числовых признаков

display(df.describe())

# Проверка на наличие дубликатов

duplicates_count = df.duplicated().sum()

print(f"\nКоличество дубликатов: {duplicates_count}")

Важно: display можно заменить на print, если вы работаете не в Jupyter-notebook, но тогда вывод на экран будет не таким наглядным.

На этом этапе можно найти следующие проблемы, которые потребуют дальнейшей предобработки:

  1. Пропуски. В столбцах «Площадь (кв. м)», «Число комнат», «Возраст дома (лет)» и «Цена (млн руб.)» — пропуски, которые нужно заполнить или обработать.

  2. Некорректные значения:

    • В столбце «Возраст дома (лет)» присутствует значение -5.

    • В столбце «Площадь (кв. м)» указано ошибочное отрицательное значение -150.

  3. Выбросы:

    • Значения, такие как площадь 2000 кв. м и 500 кв. м, подозрительно высокие для квартир и могут считаться выбросами.

    • Цена 70 млн руб. также выделяется среди остальных значений, что может указывать на выброс.

Этап 2 — очистка данных

После анализа данных можно приступать к очистке. Цель этапа — устранить проблемы, такие как пропуски, ошибки и выбросы, чтобы повысить качество датасета и, как следствие, предсказания модели.

Ручная очистка данных. Для удаления дубликатов или строк с ошибками можно использовать методы Pandas, для работы с NaN-значениями пригодится Numpy:

import numpy as np

# Удаление дубликатов

df = df.drop_duplicates()

# Удаление строк с некорректным значением возраста

df = df[df['Возраст дома (лет)'] >= 0]

# Замена ошибочных значений на NaN для последующей обработки

df.loc[df['Площадь (кв. м)'] < 0, 'Площадь (кв. м)'] = np.nan

Автоматизация очистки данных

Для автоматической очистки данных можно использовать библиотеку Scikit-Learn, например, SimpleImputer для заполнения пропусков.

Если у вас есть ошибочные значения, которые удобнее обработать как пропуски, перед использованием SimpleImputer их нужно заменить на NaN.

В этом случае пример кода будет выглядеть так:

from sklearn.impute import SimpleImputer

# Замена отрицательных значений на NaN
df.loc[df['Площадь (кв. м)'] < 0, 'Площадь (кв. м)'] = np.nan

# Использование SimpleImputer для заполнения пропусков
imputer = SimpleImputer(strategy='mean')
df[['Площадь (кв. м)', 'Число комнат', 'Возраст дома (лет)']] = imputer.fit_transform(df[['Площадь (кв. м)', 'Число комнат', 'Возраст дома (лет)']])

Вообще, пропуски в данных могут возникать по разным причинам: отсутствие информации, ошибки при сборе данных и т.д. Для их обработки можно использовать еще несколько подходов.

Удаление строк или столбцов с пропусками

Если пропуски присутствуют в небольшом количестве в одном признаке и не содержат важной информации, такие строки  можно просто удалить. А если их много в одном столбце — можно полностью его удалить.

# Удаление всех строк, содержащих хотя бы один пропуск

df = df.dropna()

# Удаление всех столбцов, содержащих хотя бы один пропуск

df = df.dropna(axis=1)

Этот метод используется, когда данных достаточно, и потеря нескольких строк не повлияет на анализ.

Заполнение пропусков

Среднее или медиана: для числовых данных можно использовать среднее значение или медиану. Упрощенная альтернатива SimpleImputer — метод filina из библиотеки Pandas.

Пример:

# Заполнение пропусков средним значением

df['Площадь (кв. м)'] = df['Площадь (кв. м)'].fillna(df['Площадь (кв. м)'].mean())

Медиану стоит применять, когда данные содержат выбросы, потому что она менее чувствительна к экстремальным значениям. Например, для признака «зарплата» медиана подходит лучше среднего, если в данных встречаются несколько аномально высоких зарплат.

Метод ближайших соседей (KNN): учитывает значения признаков ближайших объектов для заполнения пропусков. Перед применением метода нужно закодировать или удалить категориальные признаки, потому что он работает только с числовыми.

Пример:

from sklearn.impute import KNNImputer

from sklearn.preprocessing import LabelEncoder

# Кодирование категориального признака

encoder = LabelEncoder()

df['Тип недвижимости'] = encoder.fit_transform(df['Тип недвижимости'])

# Заполнение пропусков с использованием KNNImputer

imputer = KNNImputer(n_neighbors=2)

df[['Площадь (кв. м)', 'Число комнат', 'Возраст дома (лет)', 'Цена (млн руб.)']] = imputer.fit_transform(df[['Площадь (кв. м)', 'Число комнат', 'Возраст дома (лет)', 'Цена (млн руб.)']])

Метод полезен, когда значения признаков взаимосвязаны и пропуски можно логически предсказать на основе других значений.

Заполнение специальными значениями: Например, можно заполнить пропуски значением «неизвестно» для категориальных признаков или »0» для числовых, если это имеет смысл в контексте данных.

Обработка выбросов и устранение шумов

Выбросы — это значения, которые сильно отличаются от остальных данных. Они могут находиться далеко от большинства и обычно возникают из-за ошибок сбора данных или редких, необычных событий.

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

Шумы и выбросы могут привести к неверным выводам модели, затрудняя выделение значимых признаков. Например, если использовать алгоритм линейной регрессии — он пытается найти линию, которая минимизирует ошибки между прогнозом и фактом. Выбросы, которые сильно отличаются от остальных данных, могут «тянуть» эту линию и искажать результат.

Методы работы с выбросами

Обнаружение выбросов

  • Boxplot («Ящик с усами»): используется для визуализации выбросов. Выбросы отображаются как точки, находящиеся за пределами «усов» графика.

Диаграмма размаха, или «Ящик с усами». Источник

Диаграмма размаха, или «Ящик с усами». Источник

Пример:

import matplotlib.pyplot as plt

import seaborn as sns

# Визуализация выбросов с помощью boxplot

plt.figure(figsize=(8, 5))

sns.boxplot(x=df['Цена (млн руб.)'])

plt.title('Выбросы в цене квартир')

plt.show()

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

  • Метод межквартильного размаха (IQR): статистический метод, который используется для определения выбросов. Значения за пределами диапазона [Q1 — 1.5 * IQR, Q3 + 1.5 * IQR] считаются выбросами. Если данные содержат множество выбросов, можно использовать более жесткое ограничение, например, [Q1 — 3 * IQR, Q3 + 3 * IQR].

Пример:

# Определение границ для выбросов

Q1 = df['Цена (млн руб.)'].quantile(0.25)

Q3 = df['Цена (млн руб.)'].quantile(0.75)

IQR = Q3 - Q1

lower_bound = Q1 - 1.5 * IQR

upper_bound = Q3 + 1.5 * IQR

# Обнаружение выбросов

outliers = df[(df['Цена (млн руб.)'] < lower_bound) | (df['Цена (млн руб.)'] > upper_bound)]

print(f"Количество выбросов: {len(выбросы)}")

print("Найдены выбросы:\n", outliers)

Обработка выбросов

  • Удаление выбросов: если выбросы — это результат ошибок или они не отражают реальные данные, их можно удалить.

Пример:  

# Удаление выбросов

df = df[(df['Цена (млн руб.)'] >= lower_bound) & (df['Цена (млн руб.)'] <= upper_bound)]
  • Трансформация данных: если выбросы связаны с высокой вариативностью признака, можно использовать логарифмическую или другую нелинейную трансформацию. 

Обратите внимание, что логарифмическая трансформация применима только к положительным значениям.

Пример:

# Логарифмическая трансформация признака

df['Цена (млн руб.)'] = df['Цена (млн руб.)'].apply(lambda x: np.log1p(x) if x > 0 else x)

Логарифмирование помогает уменьшить влияние больших значений и сделать распределение данных более симметричным.

  • Использование робастных моделей. Некоторые модели устойчивы к выбросам, что помогает минимизировать их влияние. В отличие от линейной регрессии, робастные методы, такие как RANSAC, адаптируются к выбросам, исключая аномальные точки при создании модели.

Пример:  

from sklearn.linear_model import RANSACRegressor

from sklearn.linear_model import LinearRegression

# Пример использования робастной регрессии

model = RANSACRegressor(base_estimator=LinearRegression(), random_state=42)

X = df[['Площадь (кв. м)', 'Число комнат', 'Возраст дома (лет)']]

y = df['Цена (млн руб.)']

model.fit(X, y)

Методы обработки шумов

Обнаружение шумов

Шумы могут быть обнаружены с помощью визуализации данных. Методы вроде анализа временных графиков помогают увидеть колебания, которые можно считать шумом. Для временных рядов можно использовать скользящие средние, чтобы лучше понять общие тренды и отбросить случайные колебания.

Сглаживание данных

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

Удаление или сглаживание шумов

Применение фильтров, таких как медианный или фильтр скользящего среднего, помогает сгладить шумы, особенно во временных данных. Первый эффективен для устранения выбросов, а второй подходит для сглаживания временных данных.

Пример:

# Пример сглаживания с использованием скользящего среднего

df['Цена (млн руб.)'] = df['Цена (млн руб.)'].rolling(window=3, min_periods=1).mean()

Этот код сглаживает цену, используя среднее значение соседних трех элементов. Параметр min_periods=1 помогает избежать появления NaN в начале ряда.

Устранение аномальных значений

  • Робастные методы. В случае табличных данных шумы могут быть похожи на выбросы. Например, незначительные ошибки, такие как «цена на 5% выше или ниже ожидаемого значения», можно сгладить с помощью робастных методов, которые менее чувствительны к небольшим отклонениям. Также такие методы, как RANSAC или Theil-Sen Estimator, помогают уменьшить влияние выбросов. Они присваивают меньший вес значениям, которые сильно отклоняются от общей тенденции.

  • Сглаживание кривых (Spline Fitting). Подходит для данных с трендом, которые содержат случайные колебания. Сплайны представляют данные в виде гладкой функции, чтобы устранить мелкие шумы и сохранить основную структуру, в первую очередь используются для аппроксимации данных.

Этап 3 — кодирование категориальных данных

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

Для этого используют несколько методов. 

Label Encoding

Метод, при котором каждой категории присваивается уникальное числовое значение. Подходит для категорий с естественным порядком (например, «низкий», «средний», «высокий») или небольшим количеством вариантов.

Важно: если порядок категорий не имеет значения, использование Label Encoding может привести к некорректной интерпретации данных моделью.

Пример кода:  

from sklearn.preprocessing import LabelEncoder

# Применение Label Encoding к столбцу "Тип недвижимости" (если категории имеют естественный порядок)

encoder = LabelEncoder()

df['Тип недвижимости'] = encoder.fit_transform(df['Тип недвижимости'])

print(df[['ID', 'Тип недвижимости']])

В результате применения LabelEncoder категории «квартира», «дом», «апартаменты» будут преобразованы в числовые значения, например, 0, 1, 2.

One-Hot Encoding

Метод, который для каждой категории создает отдельный бинарный признак, указывающий на принадлежность объекта к этой категории. Полезен, если категории не обладают естественным порядком.

Обратите внимание: при большом количестве уникальных категорий One-Hot Encoding может сильно увеличить размер данных. Это снизит производительность и потребует больше памяти. В таких случаях лучше использовать альтернативы, например, Target Encoding.

Пример кода One-Hot Encoding:  

# Применение One-Hot Encoding к столбцу "Район"

df = pd.get_dummies(df, columns=['Район'], prefix='Район')

print(df.head())

В результате применения One-Hot Encoding к столбцу «Район» будут созданы новые столбцы: «Район_А», «Район_Б», «Район_В» со значениями 0 или 1, указывающие, к какому району принадлежит каждая строка.

Пример кода Target Encoding

# Применение Target Encoding к категориальному признаку "Район"

mean_encoding = df.groupby('Район')['Цена (млн руб.)'].mean().to_dict()

df['Район_encoded'] = df['Район'].map(mean_encoding)

df[['ID', 'Район', 'Район_encoded']]

Этап 4 — разделение данных на обучающую и тестовую выборки

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

Основные подходы

Разделение на обучающую и тестовую выборки (Train-Test Split)

Обычно данные делятся на две части: обучающая выборка (80% данных) и тестовая выборка (20% данных), которая используется для оценки точности на данных, которые модель ранее не видела.

Пример кода:

from sklearn.model_selection import train_test_split

# Разделение данных на обучающую и тестовую выборки

X = df.drop(columns=['Цена (млн руб.)', 'ID'])  # Признаки (features), удаляем ID как неинформативный признак

y = df['Цена (млн руб.)']  # Целевая переменная (target)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

print("Размер обучающей выборки:", X_train.shape)

print("Размер тестовой выборки:", X_test.shape)

В этом коде мы используем функцию train_test_split из библиотеки Scikit-Learn для разделения данных. Параметр test_size=0.2 указывает, что 20% информации будет использовано для тестирования, а параметр random_state=42 нужен, чтобы при каждом запуске код делил данные одинаково.

Делить данные на выборки можно с учётом времени (out-of-time подход, в тестирование таким образом попадают более новые объекты) или без этого (out-of-sample).

Кросс-валидация (Cross-Validation)

Используется для более точной оценки модели. Вместо одного разделения данные разбиваются на несколько частей (folds), и модель обучается на k-1 частях, тестируясь на оставшейся. Процесс повторяется k раз, чтобы каждая часть данных побывала в тестовой выборке. 

Перемешивание данных (shuffle=True) помогает избежать смещения и помогает получить более точную оценку.

Пример кода:

from sklearn.model_selection import KFold

# Создание объекта KFold для кросс-валидации

kf = KFold(n_splits=5, shuffle=True, random_state=42)

for train_index, test_index in kf.split(X):

    X_train, X_test = X.loc[train_index], X.loc[test_index]

    y_train, y_test = y.loc[train_index], y.loc[test_index]

    # Обучение и тестирование модели происходит внутри этого цикла

В примере выше KFold делит данные на 5 частей и повторяет процесс обучения 5 раз: каждый раз на одной из частей запускается тест, а на остальных –- обучение. 

Если решается задача классификации, и целевая переменная несбалансирована, стоит использовать StratifiedKFold, который сохраняет пропорцию классов в каждой выборке.

Этап 5 — масштабирование признаков

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

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

Разберем основные методы масштабирования. 

Стандартизация (Standardization)

Приведение признаков к нулевому среднему и стандартному отклонению, равному единице. Стандартизация делает признаки сопоставимыми по масштабу, но не обязательно приводит их к нормальному распределению.

Пример кода:

from sklearn.preprocessing import StandardScaler

# Применение стандартизации к числовым признакам (сначала обучаем скейлер на обучающих данных)

scaler = StandardScaler()

X_train_scaled = scaler.fit_transform(X_train)

X_test_scaled = scaler.transform(X_test)  # Применение обученного скейлера к тестовой выборке

print(X_train_scaled[:5])  # Пример первых пяти строк стандартизированных данных

В результате применения StandardScaler, признаки, такие как «Площадь (кв. м)» и «Цена (млн руб.)», будут иметь среднее значение около 0 и стандартное отклонение 1. Но это не означает, что их распределение станет нормальным.

Нормализация (Min-Max Scaling)

Нормализация приводит значения признака к диапазону от 0 до 1, чтобы сделать их сопоставимыми. Она полезна, если у данных разные масштабы, что может мешать работе модели. 

Нормализация важна для алгоритмов, чувствительных к масштабу признаков, таких как KNN или SVM. Но, если в данных есть выбросы, Min-Max нормализация может сжать остальные значения, потому что учитывает экстремальные.

Пример кода:  

from sklearn.preprocessing import MinMaxScaler

# Применение нормализации к числовым признакам

minmax_scaler = MinMaxScaler()

X_train_scaled = minmax_scaler.fit_transform(X_train[numeric_features])

X_test_scaled = minmax_scaler.transform(X_test[numeric_features])

print(X_train_scaled[:5])

После применения MinMaxScaler, все числовые признаки будут находиться в диапазоне [0, 1].

Робастное масштабирование (Robust Scaling):

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

Пример кода:

from sklearn.preprocessing import RobustScaler

# Применение робастного масштабирования к числовым признакам

robust_scaler = RobustScaler()

X_train_scaled_robust = robust_scaler.fit_transform(X_train[numeric_features])

X_test_scaled_robust = robust_scaler.transform(X_test[numeric_features])

print(X_train_scaled_robust[:5])

RobustScaler помогает уменьшить влияние выбросов, сохраняя важную информацию в данных.

Этап 6 — Feature Engineering

Формально Feature Engineering, или генерация признаков, — это отдельный этап в ML, который не относится к предобработке данных. Но мы включили его, чтобы показать, как завершается работа с данными перед обучением модели. 

Специалисты извлекают, создают или трансформируют признаки, чтобы алгоритм лучше распознавал важные закономерности. 

Примеры:

  • Создание новых признаков на основе существующих («цена за квадратный метр»).

  • Разделение числовых признаков на категории (группировка возраста дома на «новый», «средний», «старый»).

  • Извлечение временных признаков (например, выделение дня недели или месяца из даты).

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

Полезные материалы и ссылки по теме

  • Документация Pandas: подробное руководство по использованию библиотеки для предобработки данных, включая работу с пропусками, фильтрацию и другие полезные методы.

  • Документация Scikit-Learn: разделы по предобработке данных, включая стандартные скейлеры, кодирование категориальных данных и создание Pipeline.

  • Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow, Aurélien Géron: книга содержит примеры и практические советы по предобработке данных с фокусом на использовании Python и Scikit-Learn.

  • Python for Data Analysis, Wes McKinney: основной ресурс по Pandas, написанный создателем библиотеки. В книге разбираются различные техники предобработки, очистки и анализа данных.

  • StatQuest — видеозаписи на YouTube с ясными и доступными объяснениями базовых понятий предобработки данных и ML-алгоритмов.

  • Kaggle Learn: курсы и практические задания по предобработке данных с использованием реальных датасетов.

  • Kaggle: платформа, где можно найти датасеты и проекты, попробовать выполнить предобработку данных самостоятельно и участвовать в соревнованиях.

  • Google Colab: интерактивная среда для написания и запуска Python-кода, в которой можно бесплатно работать с большими датасетами и библиотеками, такими как Pandas и Scikit-Learn.

ТГУ и Skillfactory создали магистерскую программу для тех, кто хочет глубже погрузиться в Data Science и машинное обучение. Она охватывает различные области применения — от IT и маркетинга до медицины. Студенты освоят базу по математике и программированию на Python, научатся работать с реальными данными на кейсах IT-компаний — партнеров программы.

© Habrahabr.ru