Пример KFold из библиотеки sklearn (кроссвалидации по фолдам)

Практически всегда от моделей машинного обучения требуется указать их точность. Для расчета точности необходимо
1) обучить модель на тренировочном датасете
2) предсказать результаты на тестовом датасете
3) сравнить правильные данные с предсказанными
Данная процедура проста, но в зависимости от разбиения на обучающий датасет и тестовый датасет мы получим немного разные значения. И какой же результат более правильный?
Правильного нет, ведь точность классификатора само по себе понятие относительное. Но интуитивно понятно, что для лучшей оценки необходимо провести процедуру 1-2-3 как можно большее количество раз.

И вот как раз для оценки точности классификатора и придумали кросс-валидацию. Или K-fold cross-validation.
Идея проста, весь датасет делится на N частей. На каждой итерации N-1 часть идёт на train, и одна на test.
В sklearn для этого есть специальный метод cross_val_score:

import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier

# воспользуемся известным датасетом для примера
iris = load_iris()

clf = RandomForestClassifier(n_estimators=30, random_state=42)
# передаем классификатор, X, y и кол-во фолдов=5
res = cross_val_score(clf, iris['data'], iris['target'], cv=5)

print(res)
# [0.96666667 0.96666667 0.93333333 0.96666667 1.        ]
print(np.mean(res))
# 0.966

Как видим всё очень просто, по сравнению с train_test_split мы получим более точную оценку качества классификатора, т.к. провели эксперимент N раз (в нашем случае 5 раз).
Да, пришлось потратить в 5 раз больше времени по сравнению с train_test_split, но когда данных не очень много — это оправдано.

Однако не всегда удаётся воспользоваться методом cross_val_score, например если хотим что-то ещё подсчитать в это время.
Для этого есть более гибкий метод KFold.
Kfold часто используют не только для оценки точности классификатора, но и например для контроля переобучения для классификатора.
Для многих моделей очень важно знать, в какой момент начинается переобучение. Таким образом можно обучить 10 классификаторов с контролем переобучения и потом усреднить их предсказания. Это может дать дать лучий результат, чем если обучить одну модель сразу на всех данных, без контроля переобучения.
Для примера возьмем библиотеку catboost и будем валидироваться оставшемся фолде

from sklearn.model_selection import KFold
from sklearn.datasets import load_iris
from catboost import CatBoostClassifier

iris = load_iris()

# инициализация KFold с 5тью фолдами
cv = KFold(n_splits=5, random_state=42, shuffle=True)

classifiers = []
# метод split возвращает индексы для объектов train и test
for train_index, test_index in cv.split(iris['target']):
    clf = CatBoostClassifier(random_state=42, iterations=200, verbose=50, learning_rate=0.1)
    X_train, X_test = iris['data'][train_index], iris['data'][test_index]
    y_train, y_test = iris['target'][train_index], iris['target'][test_index]
    clf.fit(X_train, y_train, eval_set=(X_test, y_test), use_best_model=True)

    # получим 5 оптимальных классификаторов
    classifiers.append(clf)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>