учтите, что у меня есть 2 класса данных, и я использую sklearn для классификации,
def cv_classif_wrapper(classifier, X, y, n_splits=5, random_state=42, verbose=0):
'''
cross validation wrapper
'''
cv = StratifiedKFold(n_splits=n_splits, shuffle=True,
random_state=random_state)
scores = cross_validate(classifier, X, y, cv=cv, scoring=[
'f1_weighted', 'accuracy', 'recall_weighted', 'precision_weighted'])
if verbose:
print(f"==================== = ")
print(f"Accuracy: {scores['test_accuracy'].mean():.3f} (+/- {scores['test_accuracy'].std()*2:.3f})")
print(f"Recall: {scores['test_recall_weighted'].mean():.3f} (+/- {scores['test_recall_weighted'].std()*2:.3f})")
print(f"Precision: {scores['test_precision_weighted'].mean():.3f} (+/- {scores['test_precision_weighted'].std()*2:.3f})")
print(f"F1: {scores['test_f1_weighted'].mean():.3f} (+/- {scores['test_f1_weighted'].std()*2:.3f})")
return scores
и я называю это
scores = cv_classif_wrapper(LogisticRegression(), Xs, y0, n_splits=5, verbose=1)
Затем я вычисляю матрицу путаницы следующим образом:
model = LogisticRegression(random_state=42)
y_pred = cross_val_predict(model, Xs, y0, cv=5)
cm = sklearn.metrics.confusion_matrix(y0, y_pred)
Вопрос в том, что я получаю 0,95 балла за F1, но матрица путаницы
Это соответствует F1 score=0.95
? Где не так, если есть?
обратите внимание, что в классе 0 35 предметов и 364 в классе 1.
Accuracy: 0.952 (+/- 0.051)
Recall: 0.952 (+/- 0.051)
Precision: 0.948 (+/- 0.062)
F1: 0.947 (+/- 0.059)
Вы используете взвешенную оценку F1. Оценка F1 взвешивается по поддержке (поддержка означает количество примеров в каждом классе).
Рассчитайте метрики для каждой метки и найдите их среднее значение, взвешенное по поддержке (количество истинных экземпляров для каждой метки). Это изменяет «макро» для учета дисбаланса меток; это может привести к F-оценке, которая не находится между точностью и полнотой. 1
Поскольку ваши классы распределены очень неравномерно («другой» класс, то есть 2-й класс) имеет в 10 раз больше примеров, чем первый класс, их оценка F1 будет относиться к этому классу.
Мы также можем видеть, что в Формуле (пусть индексы обозначают классы):
(F1_1 * n1 + F1_2 * n2) / n1 + n2
В вашем случае это будет означать:
0,66 * 35 + 0,99 * 364 / 400 = 95,865
(не уверен, почему цифры отличаются, но вы поняли).
Поскольку вы используете только 2 класса (двоичная классификация), взвешенная оценка F1, на мой взгляд, не лучшая оценка для использования, и я бы использовал обычную невзвешенную версию. Другие бы согласились 2.
Ваши данные несбалансированы, т. е. целевые классы распределены неравномерно. Как указал niid в своем ответе, оценка f1, возвращаемая по умолчанию, является взвешенной оценкой f1, которая может ввести в заблуждение, если ее неправильно интерпретировать, особенно если ваши классы не одинаково важны. Подумайте об оттоке клиентов или классификации спама по электронной почте: ваша модель может быть верной на 99% (или иметь очень высокий балл f1) и при этом быть бесполезной.
Обычно мы рассчитываем метрики для сравнения разных моделей друг с другом. Для этого часто используют площадь под ROC-кривой (AUC-ROC). Он обобщает информацию ROC, которая показывает отношение истинного положительного результата к показателю ложного положительного результата для различных пороговых значений. Используя эту метрику, вы используете метрику, которая не зависит от выбранного вами порога, в отличие от точности, точности, отзыва и оценки f1, которые зависят от выбранного вами порога.
В случае несбалансированных данных площадь под кривой полноты точности (AUC-PR) еще больше подходит для сравнения разных классификаторов:
Следовательно, вы можете пересмотреть свои показатели.
Кроме того, LogisticRegression() не является лучшим классификатором для несбалансированных данных, поскольку он может быть смещен в сторону большинства классов, что приведет к снижению производительности в отношении класса меньшинства. Вы можете рассмотреть возможность применения стратегий для обработки несбалансированных данных.