Преобразования данных в машинном обучении
Data Preprocessing and Feature Engineering — совокупность методов подготовки сырых данных к анализу и обучению моделей машинного обучения. Включает в себя очистку, нормализацию, кодирование и генерацию новых признаков для повышения качества прогнозов.
Подробное описание
В реальных задачах данные редко бывают готовы к немедленному использованию. Они могут содержать пропуски, выбросы, иметь разный масштаб или быть представлены в категориальном виде. Алгоритмы машинного обучения, особенно основанные на расстояниях (k-NN, SVM) или градиентных спусках (нейронные сети, линейная регрессия), чувствительны к распределению и масштабу входных переменных.
Ключевая идея: Привести данные к единому стандарту, устраняя шум и несоответствия, чтобы модель могла выявлять истинные закономерности, а не артефакты сбора данных.
Входные данные: Сырой датасет (таблица, текст, изображения). Выходные данные: Очищенный и трансформированный набор признаков, пригодный для подачи на вход алгоритма ML.
Основные принципы
1. Масштабирование признаков
Многие алгоритмы интерпретируют большие значения признаков как более важные. Чтобы избежать этого, применяют масштабирование.
Стандартизация (Z-score normalization)
Приводит данные к распределению с нулевым средним и единичной дисперсией.
Где: - \(x\) — исходное значение признака - \(\mu\) — среднее значение признака - \(\sigma\) — стандартное отклонение
Min-Max нормализация
Сжимает значения в заданный диапазон, обычно \([0, 1]\).
Где: - \(x_{min}\) и \(x_{max}\) — минимальное и максимальное значения в выборке
2. Кодирование категориальных переменных
Алгоритмы работают с числами, поэтому текстовые категории необходимо преобразовать.
One-Hot Encoding: Создает бинарный вектор для каждой категории. Если категорий \(N\), то создается \(N\) новых признаков. Label Encoding: Присваивает каждой категории уникальное целое число. Подходит только для порядковых данных или деревьев решений.
3. Обработка пропущенных значений (Imputation)
Стратегии заполнения пропусков: - Среднее/медиана (для числовых данных) - Мода (для категориальных) - Константа (специальное значение, например, -1 или "Unknown")
Пример реализации на Python
Для демонстрации принципов используем только стандартную библиотеку и numpy, избегая тяжелых фреймворков вроде sklearn, чтобы показать внутреннюю логику алгоритмов.
import numpy as np
from typing import List, Dict, Union
class DataPreprocessor:
"""Класс для базовых преобразований данных."""
@staticmethod
def standardize(data: np.ndarray) -> np.ndarray:
"""
Стандартизация данных (Z-score).
:param data: двумерный массив numpy
:return: стандартизированный массив
"""
mean = np.mean(data, axis=0)
std = np.std(data, axis=0)
# Избегаем деления на ноль
std[std == 0] = 1
return (data - mean) / std
@staticmethod
def min_max_normalize(data: np.ndarray, feature_range=(0, 1)) -> np.ndarray:
"""
Min-Max нормализация.
:param data: двумерный массив numpy
:param feature_range: кортеж (min, max) целевого диапазона
:return: нормализованный массив
"""
min_val = np.min(data, axis=0)
max_val = np.max(data, axis=0)
range_val = max_val - min_val
range_val[range_val == 0] = 1
normalized = (data - min_val) / range_val
return normalized * (feature_range[1] - feature_range[0]) + feature_range[0]
@staticmethod
def one_hot_encode(categories: List[str]) -> Dict[str, List[int]]:
"""
Простое One-Hot кодирование списка категорий.
:param categories: список строк
:return: словарь {категория: бинарный вектор}
"""
unique_cats = sorted(list(set(categories)))
encoding = {}
for cat in unique_cats:
vector = [0] * len(unique_cats)
index = unique_cats.index(cat)
vector[index] = 1
encoding[cat] = vector
return encoding
@staticmethod
def impute_mean(data: np.ndarray) -> np.ndarray:
"""
Заполнение пропусков (NaN) средним значением столбца.
:param data: массив с возможными NaN
:return: массив без NaN
"""
processed_data = data.copy()
for col in range(processed_data.shape[1]):
column = processed_data[:, col]
mask = np.isnan(column)
if np.any(mask):
mean_val = np.nanmean(column)
column[mask] = mean_val
return processed_data
if __name__ == "__main__":
# Пример 1: Масштабирование
raw_data = np.array([[10, 200], [20, 300], [30, 400]])
print("Исходные данные:\n", raw_data)
standardized = DataPreprocessor.standardize(raw_data)
print("\nСтандартизированные данные:\n", standardized)
normalized = DataPreprocessor.min_max_normalize(raw_data)
print("\nMin-Max нормализованные данные:\n", normalized)
# Пример 2: Кодирование
colors = ['red', 'blue', 'green', 'blue']
encoded = DataPreprocessor.one_hot_encode(colors)
print("\nOne-Hot Encoding для 'blue':", encoded['blue'])
# Пример 3: Обработка пропусков
data_with_nan = np.array([[1.0, 2.0], [np.nan, 4.0], [3.0, np.nan]])
imputed = DataPreprocessor.impute_mean(data_with_nan)
print("\nДанные после импутации средних:\n", imputed)
Достоинства и недостатки
Достоинства: 1. Повышение точности моделей: Устранение шума и приведение к единому масштабу позволяет алгоритмам находить более четкие границы решений. 2. Ускорение сходимости: Градиентные методы оптимизации работают значительно быстрее на нормализованных данных. 3. Универсальность: Большинство современных ML-библиотек требуют предварительно обработанные данные.
Недостатки: 1. Риск утечки данных (Data Leakage): Если параметры преобразования (например, среднее значение) вычисляются на всем датасете включая тестовую выборку, оценка модели будет необъективно завышена. 2. Потеря интерпретируемости: После сложных преобразований (например, PCA или полиномиальных) исходный смысл признаков может быть утрачен. 3. Вычислительная сложность: Некоторые методы (например, заполнение пропусков сложными моделями) могут требовать значительных ресурсов.
Области применения
- Машинное обучение и рекомендательные системы (подготовка признаков для коллаборативной фильтрации и градиентного бустинга)
- Обработка естественного языка (токенизация и векторизация текста перед подачей в трансформеры)
- Экономика и финансы (нормализация финансовых показателей для скоринга и прогнозирования временных рядов)
- Биотехнологии и медицина (стандартизация результатов лабораторных анализов для диагностических моделей)
- Компьютерное зрение (нормализация пиксельных значений изображений для обучения сверточных нейросетей)