Кросс-валидация в Scikit-learn

scikit-learnBeginner
Практиковаться сейчас

Введение

В машинном обучении мы часто разделяем наши данные на обучающий (training set) и тестовый (testing set) наборы для оценки производительности модели. Однако эта оценка может сильно зависеть от того, какие точки данных попадут в обучающий набор, а какие — в тестовый. Более надежным методом является кросс-валидация (cross-validation, CV).

Зачем нужна кросс-валидация?

  • Снижает риск переобучения (overfitting): Тестирует модель на нескольких разделениях данных.
  • Улучшает оценку обобщающей способности (generalization): Более надежная производительность на невидимых данных.
  • Максимизирует использование данных: Каждый образец используется как для обучения, так и для тестирования.

Кросс-валидация включает разделение набора данных на несколько "фолдов" (folds), а затем многократное обучение и оценку модели, используя каждый раз разный фолд для тестирования. Это дает нам более надежную оценку производительности модели на невидимых данных.

В этой лабораторной работе вы научитесь использовать мощные и удобные функции scikit-learn для выполнения кросс-валидации классификатора на знаменитом наборе данных Iris. Вы научитесь использовать cross_val_score для получения оценок производительности, а затем вычислите их среднее значение и стандартное отклонение, чтобы лучше понять стабильность модели и общую точность.

Импортируйте cross_val_score из sklearn.model_selection

На этом шаге вы начнете с импорта необходимой функции для выполнения кросс-валидации. Функция cross_val_score является основным инструментом в scikit-learn для этой цели. Она упрощает процесс разделения данных, обучения модели и оценки ее производительности на нескольких фолдах.

Сначала откройте файл main.py, расположенный в директории ~/project, используя файловый менеджер в левой части вашей IDE.

Теперь добавьте оператор импорта для cross_val_score в ваш скрипт main.py. Разместите его вместе с другими импортами в верхней части файла.

from sklearn.model_selection import cross_val_score

Ваш файл main.py теперь должен выглядеть следующим образом:

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Загрузка набора данных Iris
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Инициализация классификатора на основе опорных векторов (SVC)
## Объяснение параметров:
## - kernel='linear': Использует линейное ядро для линейно разделимых данных, таких как Iris
## - C=1: Параметр регуляризации (более высокие значения = меньшая регуляризация)
## - random_state=42: Обеспечивает воспроизводимость результатов между запусками
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Ваш код будет ниже этой строки ---

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

python3 main.py

Вы не должны увидеть никакого вывода, что ожидаемо, поскольку мы еще не добавили код для вывода.

Инициализируйте KFold с n_splits=5 из sklearn.model_selection

Хотя cross_val_score может автоматически обрабатывать разделение данных, полезно понимать лежащий в его основе механизм. Наиболее распространенной стратегией кросс-валидации является K-Fold, при которой набор данных делится на 'k' фолдов. Модель обучается на k-1 фолдах и тестируется на оставшемся фолде, повторяя этот процесс k раз.

Параметры KFold:

  • n_splits=5: Делит данные на 5 равных частей (фолдов).
  • shuffle=False (по умолчанию): Сохраняет исходный порядок данных.
  • random_state: Контролирует рандомизацию, если shuffle=True.

Класс KFold в scikit-learn является итератором кросс-валидации, который предоставляет индексы для обучения/тестирования для разделения данных. Хотя на следующем шаге мы будем использовать более простой способ, понимание KFold является фундаментальным.

Давайте импортируем KFold и посмотрим, как его инициализировать. Добавьте следующие строки в ваш файл main.py.

Сначала добавьте оператор импорта вверху:

from sklearn.model_selection import KFold

Затем вы можете его инициализировать. Однако для этой лабораторной работы мы будем полагаться на параметр cv функции cross_val_score, который является более прямым подходом. Цель этого шага — познакомить вас с концепцией KFold. Для простоты и чтобы следовать ходу лабораторной работы, мы не будем добавлять код инициализации KFold в наш скрипт. Мы будем напрямую использовать cv=5 на следующем шаге, что внутренне использует стратегию K-Fold. Это самый распространенный и простой способ выполнения кросс-валидации.

Перейдем к следующему шагу, где мы применим эту концепцию на практике. Поскольку на этом шаге код не добавлялся, вы можете нажать "Continue" (Продолжить), чтобы перейти дальше.

Выполните кросс-валидацию с помощью cross_val_score(clf, X, y, cv=5)

Теперь пришло время выполнить кросс-валидацию. Мы будем использовать функцию cross_val_score, которую импортировали ранее. Эта функция принимает несколько аргументов:

Параметры cross_val_score:

  • estimator: Модель для оценки (наш классификатор clf).
  • X: Матрица признаков данных.
  • y: Массив целевых меток.
  • cv=5: Стратегия кросс-валидации (целое число = k-fold, или объект CV splitter).
  • scoring: Метрика оценки (по умолчанию используется метод оценки estimator).
  • n_jobs: Количество используемых ядер ЦП (по умолчанию=1, -1 для всех ядер).

Установив cv=5, мы говорим scikit-learn выполнить 5-кратную кросс-валидацию. Он автоматически разделит данные на 5 фолдов, затем обучит и протестирует модель 5 раз, возвращая массив, содержащий оценку для каждого прогона.

Добавьте следующий код в конец вашего файла main.py, под строкой с комментарием:

## Выполнение 5-кратной кросс-валидации
scores = cross_val_score(clf, X, y, cv=5)

## Печать массива оценок
print("Scores:", scores)

Ваш полный файл main.py теперь должен выглядеть следующим образом:

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Load the iris dataset
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialize a Support Vector Classifier (SVC)
## Parameters explained:
## - kernel='linear': Uses a linear kernel for linearly separable data like Iris
## - C=1: Regularization parameter (higher values = less regularization)
## - random_state=42: Ensures reproducible results across runs
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Your code will go below this line ---

## Perform 5-fold cross-validation
scores = cross_val_score(clf, X, y, cv=5)

## Print the array of scores
print("Scores:", scores)

Теперь запустите скрипт из вашего терминала:

python3 main.py

Вы увидите вывод, показывающий массив из 5 оценок, по одной для каждого фолда кросс-валидации.

Scores: [0.96666667 1.         0.96666667 0.96666667 1.        ]
Mean score: 0.9800000000000001
Standard deviation: 0.016329931618554516

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

Вычислите средний балл кросс-валидации с помощью scores.mean()

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

Функция cross_val_score возвращает массив NumPy, который имеет множество полезных методов, включая .mean(). Мы можем вызвать этот метод непосредственно для нашей переменной scores.

Добавьте следующие строки в конец вашего скрипта main.py, чтобы вычислить и вывести среднюю оценку:

## Вычисление и печать среднего значения оценок
mean_score = scores.mean()
print("Mean score:", mean_score)

Ваш файл main.py теперь должен содержать следующий код:

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Load the iris dataset
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialize a Support Vector Classifier (SVC)
## Parameters explained:
## - kernel='linear': Uses a linear kernel for linearly separable data like Iris
## - C=1: Regularization parameter (higher values = less regularization)
## - random_state=42: Ensures reproducible results across runs
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Your code will go below this line ---

## Perform 5-fold cross-validation
scores = cross_val_score(clf, X, y, cv=5)

## Print the array of scores
print("Scores:", scores)

## Compute and print the mean of the scores
mean_score = scores.mean()
print("Mean score:", mean_score)

Снова выполните скрипт:

python3 main.py

Вывод теперь будет включать среднее значение из 5 оценок, предоставляя вам единую репрезентативную метрику производительности.

Scores: [0.96666667 1.         0.96666667 0.96666667 1.        ]
Mean score: 0.9800000000000001

Вычислите стандартное отклонение баллов кросс-валидации с помощью scores.std()

Средняя оценка показывает нам среднюю производительность, но не говорит о том, насколько последовательна эта производительность. Стандартное отклонение оценок дает нам меру этой вариативности.

Интерпретация стандартного отклонения:

  • Низкое ст. откл. (< 0.05): Модель демонстрирует стабильную производительность на всех подмножествах данных.
  • Среднее ст. откл. (0.05-0.15): Умеренная вариативность, приемлемо для большинства случаев.
  • Высокое ст. откл. (> 0.15): Значительная вариативность производительности, может указывать на проблемы с данными или нестабильность модели.

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

Как и у .mean(), у массивов NumPy также есть метод .std() для вычисления стандартного отклонения.

Добавьте последний фрагмент кода в ваш скрипт main.py, чтобы вычислить и вывести стандартное отклонение:

## Вычисление и печать стандартного отклонения оценок
std_dev = scores.std()
print("Standard deviation:", std_dev)

Ваш окончательный скрипт main.py теперь завершен и должен выглядеть следующим образом:

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Load the iris dataset
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialize a Support Vector Classifier (SVC)
## Parameters explained:
## - kernel='linear': Uses a linear kernel for linearly separable data like Iris
## - C=1: Regularization parameter (higher values = less regularization)
## - random_state=42: Ensures reproducible results across runs
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Your code will go below this line ---

## Perform 5-fold cross-validation
scores = cross_val_score(clf, X, y, cv=5)

## Print the array of scores
print("Scores:", scores)

## Compute and print the mean of the scores
mean_score = scores.mean()
print("Mean score:", mean_score)

## Compute and print the standard deviation of the scores
std_dev = scores.std()
print("Standard deviation:", std_dev)

Запустите скрипт в последний раз:

python3 main.py

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

Scores: [0.96666667 1.         0.96666667 0.96666667 1.        ]
Mean score: 0.9800000000000001
Standard deviation: 0.016329931618554516

Резюме

Поздравляем с завершением этой лабораторной работы! Вы успешно научились выполнять и интерпретировать k-кратную кросс-валидацию с использованием scikit-learn.

В этой лабораторной работе вы:

  • Поняли важность кросс-валидации для надежной оценки модели.
  • Использовали функцию cross_val_score для легкого выполнения 5-кратной кросс-валидации на классификаторе опорных векторов (Support Vector Classifier).
  • Проанализировали результаты, вычислив и выведя среднее значение и стандартное отклонение оценок кросс-валидации.

Практические советы по кросс-валидации:

  • Используйте 5-кратную или 10-кратную кросс-валидацию для большинства сценариев.
  • Рассмотрите стратифицированную кросс-валидацию (stratified CV) для несбалансированных наборов данных.
  • Используйте cross_validate вместо cross_val_score для нескольких метрик.
  • Всегда устанавливайте random_state для воспроизводимых результатов.

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