Баннер мобильный (3) Пройти тест

Что такое предварительная обработка данных в машинном обучении и как ее провести

Инструкция для начинающих дата-сайентистов и ML-инженеров

Инструкция

10 октября 2024

Поделиться

Скопировано
Что такое предварительная обработка данных в машинном обучении и как ее провести

Содержание

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

    Составить инструкцию помогла Мария Жарова, Data Scientist компании Wildberries.

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

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

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

    • Человеческий фактор: ошибки при ручном вводе — опечатки, пропуски или неправильные значения.
    • Неполные данные: информация может быть недоступна, например, сотрудник не указал свое место проживания.
    • Ошибки при сборе: сбои в автоматических системах, например временные проблемы с сетью, из-за чего часть данных теряется.
    • Объединение данных из разных источников: разные форматы или отсутствие значений при объединении нескольких баз.
    • Технические ограничения: например, система принимает только положительные числа, а передали отрицательное значение.
    • Устаревшая информация: данные не обновляются вовремя, из-за чего информация устаревает.
    • Ошибки при миграции: повреждение или потеря данных при переносе из одной системы в другую.

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

    IDИмяВозрастЗарплатаГородДата приемаОтдел
    1Иванов Иван28100000Москва2018-05-20Продажи
    2NaNNaN60000Санкт-Петербург2019-03-15Маркетинг
    3Ольга Петрова35-1500НовосибирскNaNРазработка
    4Андрей СидоровNaN70000Неизвестно2021-11-10NaN
    5NaN4580000Казань2020-08-01HR
    6Елена Белова29NaNNaN2017-09-23Продажи

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

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

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

    1. В столбце Город указан заполнитель «Неизвестно» вместо названия города.
    2. Разное представление пропущенных или неизвестных значений: 
    • NaN (Not a Number) автоматически используется в некоторых системах, например при выгрузке данных из баз или при считывании в библиотеке для анализа данных (такой как pandas);
    • «Неизвестно» — это пример текстового заполнителя, который вводят вручную, когда нет информации, — его также нужно обрабатывать как пропуск.

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

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

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

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

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

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

      Пример: создание Pipeline для автоматического выполнения всех необходимых шагов предобработки, таких как заполнение пропусков, масштабирование и кодирование признаков.
    1. Автоматизация с помощью библиотек для подготовки данных:
    • Pandas: часто используют для ручной предобработки, но можно создать функции, которые автоматически заполняют пропуски, масштабируют данные и кодируют признаки.
    • Feature-engine: библиотека с удобными функциями для автоматизации задач: создание новых признаков, кодирование категорий и работа с выбросами.
    • Polars: новая библиотека для высокоэффективной работы с данными и их анализа на Python, альтернатива Pandas для работы с очень большими объемами данных.
    1. Другие подходы:
    • Платформы для машинного обучения: инструменты AutoML, такие как H2O.ai, LAMA и TPOT, автоматически подбирают модели и выполняют предобработку данных, что упрощает процесс для пользователя.
    • Написание собственных функций: можно написать функции для типовых задач, например заполнения пропусков медианой или удаления выбросов, и использовать их каждый раз для обработки данных. Это экономит время и обеспечивает единообразие.

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

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

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

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

    IDПлощадь (кв. м)Число комнатВозраст дома (лет)Стоимость (млн руб.)Тип недвижимостиРайон
    1803208квартираА
    2100NaN15010домБ
    320002NaN50квартираА
    41004306апартаментыВ
    515035NaNдомБ
    6500530070квартираА
    710032514домБ
    8803-58апартаментыВ
    9-15031512домБ
    1010032514квартираА

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

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

    • 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.

    Инструкция

    Поделиться

    Скопировано
    0 комментариев
    Комментарии