machine-learning Лабораторная работа

Введение в ML: Пайплайны, Кросс-валидация и GridSearch

Лабораторная работа №15: Пайплайны, Кросс-валидация и GridSearch

Цель: Собрать все знания курса в единый профессиональный инструмент. Мы откажемся от ручного вызова fit/transform для каждого шага, чтобы избежать утечки данных. Мы построим Pipeline (конвейер), который объединит масштабирование, снижение размерности и классификацию, а затем автоматически подберем лучшие гиперпараметры с помощью GridSearchCV.

Инструменты:

  • sklearn.pipeline: Pipeline.
  • sklearn.model_selection: GridSearchCV, cross_val_score, StratifiedKFold.
  • sklearn.preprocessing: StandardScaler.
  • sklearn.decomposition: PCA.
  • sklearn.svm: SVC (Метод опорных векторов — модель, очень чувствительная к масштабу).

Данные: Breast Cancer Wisconsin. Бинарная классификация (Рак: Злокачественный/Доброкачественный).


Часть 1: Проблема ручного подхода

Когда вы пишете код ручной предобработки, он выглядит примерно так:

scaler.fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)
model.fit(X_train_scaled, y_train)

Проблема масштабируемости и утечки данных

Это работает. Но если вы захотите добавить PCA? А потом отбор признаков? Код превратится в лапшу. А если вы захотите сделать Кросс-валидацию? Вам придется руками делать scaler.fit внутри каждого фолда, иначе случится Data Leakage.

Pipeline решает эту проблему. Это “коробка”, в которую мы кладем шаги. Она ведет себя как одна модель.

Задание 1.1: Создание простого Пайплайна

  1. Загрузите датасет load_breast_cancer. Разделите на Train/Test (80/20, random_state=42).
  2. Создайте Pipeline, состоящий из двух шагов:
    • 'scaler': StandardScaler()
    • 'svm': SVC() (Support Vector Classifier)
  3. Обучите пайплайн (fit) на X_train.
  4. Сделайте предсказание и оцените точность.
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score

# Загрузка
data = load_breast_cancer()
X = data.data
y = data.target

# TODO: Split (80/20)
# X_train, X_test, y_train, y_test = ...

# TODO: Создайте Pipeline
# pipe_simple = Pipeline([
#     ('scaler', ...),
#     ('svm', ...)
# ])

# TODO: Обучение (как обычной модели)
# pipe_simple.fit(..., ...)

# TODO: Предсказание
# y_pred = pipe_simple.predict(...)
# print(f"Simple Pipeline Accuracy: {accuracy_score(y_test, y_pred):.4f}")

Часть 2: Кросс-валидация (Cross-Validation)

Одной оценки Accuracy на тесте мало. Может нам просто повезло с разбиением? Проверим устойчивость пайплайна на 5 фолдах.

Задание 2.1: cross_val_score

  1. Используйте cross_val_score.
  2. Передайте туда наш pipe_simple, X_train и y_train.
  3. Число фолдов cv=5.

Магия Пайплайна

Важный момент: Пайплайн сам позаботится о том, чтобы StandardScaler обучался заново на каждом фолде!

from sklearn.model_selection import cross_val_score

# TODO: Вычислите скоры на кросс-валидации
# cv_scores = cross_val_score(..., ..., ..., cv=5)

# print(f"CV Scores: {cv_scores}")
# print(f"Mean Accuracy: {cv_scores.mean():.4f} (+/- {cv_scores.std():.4f})")

Часть 3: Тюнинг архитектуры (GridSearch)

Теперь самое интересное. Мы не знаем:

  1. Какое ядро (kernel) лучше для SVM: линейное или RBF?
  2. Какой коэффициент регуляризации C выбрать?
  3. Нужен ли нам PCA перед SVM? И если да, сколько компонент оставить?

Мы можем перебрать это ВСЁ сразу с помощью GridSearchCV.

Задание 3.3: Запуск поиска

  1. Создайте GridSearchCV с нашим пайплайном и сеткой.
  2. cv=5, n_jobs=-1 (параллельно), verbose=1 (чтобы видеть прогресс).
  3. Запустите fit на X_train.
from sklearn.model_selection import GridSearchCV

# TODO: Инициализация GridSearch
# grid = GridSearchCV(estimator=pipe_advanced, param_grid=param_grid, cv=5, n_jobs=-1, verbose=1)

# TODO: Запуск перебора (может занять пару секунд)
# grid.fit(X_train, y_train)

# Результаты
# print(f"Лучшие параметры: {grid.best_params_}")
# print(f"Лучший кросс-валидационный скор: {grid.best_score_:.4f}")

Часть 4: Финальная проверка

grid после обучения автоматически ведет себя как лучшая найденная модель. Мы можем сразу делать grid.predict().

Задание 4.1: Оценка на отложенном тесте

  1. Сделайте предсказание на X_test с помощью обученного объекта grid.
  2. Сравните точность с простым пайплайном из Части 1.
# TODO: Предсказание лучшей моделью
# y_pred_best = grid.predict(X_test)

# print(f"Final Test Accuracy: {accuracy_score(y_test, y_pred_best):.4f}")

Вопрос на понимание: Если GridSearch выбрал pca__n_components: None, что это значит? Помогло ли снижение размерности в этой задаче?


🧠 Проверка знаний

Какую главную проблему предотвращает использование инструмента Pipeline при проведении кросс-валидации (Cross-Validation) с предобработкой данных?

Как правильно указать название гиперпараметра для поиска по сетке в GridSearchCV, если этот параметр принадлежит шагу с названием 'svm' внутри Pipeline?