Вопрос или проблема
Я пытаюсь выполнить кросс-валидацию с использованием классификации одного класса – я использую библиотеку 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
- Импорт библиотек: Используем необходимые модули из
sklearn
для выполнения кросс-валидации и оценки. - Инициализация KFold: Создаем объект
KFold
для реализации 10-кратной кросс-валидации. - Хранение метрик: Создаем списки для хранения метрик по каждому сплити.
- Обучение и предсказание: Для каждого сплита выполняем обучение модели и предсказание значений.
- Метрики: Считаем точность, прецизионность, полноту и F1-меру, добавляя их значения в соответствующие списки.
- Вывод результатов: После завершения всех разбиений вычисляются средние значения и стандартные отклонения, которые предоставляют общий обзор результатов.
Заключение
Корректная реализация кросс-валидации в однотипной классификации требует тщательной настройки подхода к накоплению и оценке показателей. Приведенный код предлагает эффективный способ для соблюдения профессиональных стандартов в машинном обучении, что может существенно улучшить не только математическую, но и практическую сторону анализа данных. Не забывайте проверять границы ваших моделей, чтобы гарантировать, что результаты реалистичны и полезны для вашего проекта.