Кросс-валидация с однолассной классификацией в Python

Вопрос или проблема

Я пытаюсь выполнить кросс-валидацию с использованием классификации одного класса – я использую библиотеку PyOD – но не знаю, делаю ли я это правильно. Точность слишком низка, и я также не могу вывести среднее и стандартное отклонение F1.

from sklearn.model_selection import KFold 
from sklearn.metrics import accuracy_score, precision_score, f1_score, recall_score
from sklearn.metrics import precision_recall_fscore_support as score


k = 10
kf = KFold(n_splits=k, random_state=None)

acc_score = []
pr_score = []
rc_score = []
model = clf
 
for train_index , test_index in kf.split(X, Y):
    x_train , x_test = X.iloc[train_index,:],X.iloc[test_index,:]
    y_train , y_test = Y[train_index] , Y[test_index]
     
    model.fit(x_train,y_train)
    pred_values = model.predict(x_test)
  
       
    acc = accuracy_score(pred_values , y_test)
    acc_score.append(acc)
    avg_acc_score = sum(acc_score)/k
    pr = precision_score(pred_values, y_test)
    pr_score.append(pr)
    avg_pr_score=sum(pr_score)/k
    rc = recall_score(pred_values, y_test)
    rc_score.append(rc)
    avg_rc_score=sum(rc_score)/k
    
print('точность для каждого сгиба - {}'.format(acc_score))
print('Средняя точность : {}'.format(avg_acc_score))
print('Точность: {}'.format(avg_pr_score))
print('Полнота: {}'.format(avg_rc_score))

Проблема, похоже, в том, что вы делите на 10 (k) на каждой итерации. Я могу подумать о том, чтобы попробовать рассчитать среднее значение, это неправильно, и, вероятно, это то, что заставляет вас видеть очень низкое значение метрики. Было бы проще и правильнее просто хранить значения метрики на каждой итерации в валидационном наборе, а затем просто вычислить среднее и стандартное отклонение списка, в котором вы сохранили значения.

Попробуйте:

import numpy as np
from sklearn.model_selection import KFold 
from sklearn.metrics import accuracy_score, precision_score, f1_score, recall_score
from sklearn.metrics import precision_recall_fscore_support as score


k = 10
kf = KFold(n_splits=k, random_state=None)

acc_score = []
pr_score = []
rc_score = []
model = clf
 
for train_index , test_index in kf.split(X, Y):
    x_train , x_test = X.iloc[train_index,:],X.iloc[test_index,:]
    y_train , y_test = Y[train_index] , Y[test_index]
     
    model.fit(x_train,y_train)
    pred_values = model.predict(x_test)
  
       
    acc = accuracy_score(pred_values , y_test)
    acc_score.append(acc)
    pr = precision_score(pred_values, y_test)
    pr_score.append(pr)
    rc = recall_score(pred_values, y_test)
    
print(f'точность для каждого сгиба - {acc_score}')
print(f'Средняя точность :{np.mean(acc_score)} ± {np.std(acc_score)} std')
print(f'Точность:{np.mean(pr_score)} ± {np.std(pr_score)} std')
print(f'Полнота:{np.mean(rc_score)} ± {np.std(rc_score)} std')

Ответ или решение

Кросс-валидация с однотипной классификацией в Python

Введение

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

Описание проблемы

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

Решение

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

import numpy as np
from sklearn.model_selection import KFold 
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

k = 10
kf = KFold(n_splits=k, random_state=None)

acc_scores = []
pr_scores = []
rc_scores = []
f1_scores = []

model = clf  # Ваш классификатор

# Начинаем кросс-валидацию
for train_index, test_index in kf.split(X, Y):
    x_train, x_test = X.iloc[train_index, :], X.iloc[test_index, :]
    y_train, y_test = Y[train_index], Y[test_index]

    model.fit(x_train, y_train)
    pred_values = model.predict(x_test)

    acc = accuracy_score(y_test, pred_values)
    acc_scores.append(acc)

    pr = precision_score(y_test, pred_values, zero_division=0)  # Zero division to handle cases with no positive predictions
    pr_scores.append(pr)

    rc = recall_score(y_test, pred_values, zero_division=0)
    rc_scores.append(rc)

    f1 = f1_score(y_test, pred_values, zero_division=0)
    f1_scores.append(f1)

# Выводим результаты
print(f'Точность каждого разбиения: {acc_scores}')
print(f'Средняя точность: {np.mean(acc_scores):.4f} ± {np.std(acc_scores):.4f} ст. откл.')
print(f'precision: {np.mean(pr_scores):.4f} ± {np.std(pr_scores):.4f} ст. откл.')
print(f'Полнота: {np.mean(rc_scores):.4f} ± {np.std(rc_scores):.4f} ст. откл.')
print(f'F1-меры: {np.mean(f1_scores):.4f} ± {np.std(f1_scores):.4f} ст. откл.')

Объяснение Code Snippet

  1. Импорт библиотек: Используем необходимые модули из sklearn для выполнения кросс-валидации и оценки.
  2. Инициализация KFold: Создаем объект KFold для реализации 10-кратной кросс-валидации.
  3. Хранение метрик: Создаем списки для хранения метрик по каждому сплити.
  4. Обучение и предсказание: Для каждого сплита выполняем обучение модели и предсказание значений.
  5. Метрики: Считаем точность, прецизионность, полноту и F1-меру, добавляя их значения в соответствующие списки.
  6. Вывод результатов: После завершения всех разбиений вычисляются средние значения и стандартные отклонения, которые предоставляют общий обзор результатов.

Заключение

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

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

Капча загружается...