Precision / Recall / F1
Accuracy показывает качество модели в целом. Но иногда нас интересует не вся модель сразу, а то, насколько хорошо она находит один конкретный класс.
Например, в задаче с породами собак нас может интересовать класс спаниель.
Тогда мы временно считаем:
спаниель — положительный классне спаниель — остальные объектыПоложительный класс — это не “хороший” класс и не обязательно класс с меткой 1. Это просто класс, на который мы сейчас обращаем внимание.
TP, FP, FN, TN
Заголовок раздела «TP, FP, FN, TN»Когда выбран положительный класс, матрицу ошибок можно записать так:
Предсказано →Реально ↓ спаниель не спаниельспаниель TP FNне спаниель FP TNЗдесь:
TP— настоящий спаниель предсказан как спаниель;FP— не спаниель ошибочно предсказан как спаниель;FN— настоящий спаниель ошибочно предсказан как не спаниель;TN— не спаниель предсказан как не спаниель.
В примере со спаниелями выбор положительного класса условный: мы могли бы выбрать и бульдог. Но в некоторых задачах положительный класс выбирают не произвольно, а по смыслу задачи.
Например, в задаче диагностики:
болен — положительный классздоров — отрицательный классВ такой задаче обычно важно найти людей, которым нужно дополнительное обследование. Поэтому положительным классом часто выбирают болен.
Тогда ошибки имеют разный смысл:
FP— здорового человека ошибочно отнесли к больным;FN— больного человека ошибочно отнесли к здоровым.
Положительный класс выбирают не по номеру метки, а по смыслу задачи. Обычно это класс, который нужно обнаружить, найти или проконтролировать.
Precision
Заголовок раздела «Precision»Precision отвечает на вопрос:
Если модель сказала “спаниель”, насколько ей можно доверять?Формула:
Precision = TP / (TP + FP)То есть среди всех объектов, которые модель назвала спаниелями, мы считаем долю настоящих спаниелей.
Высокий Precision означает, что модель редко ошибается, когда предсказывает выбранный класс.
Recall отвечает на другой вопрос:
Какую долю настоящих спаниелей модель смогла найти?Формула:
Recall = TP / (TP + FN)То есть среди всех настоящих спаниелей мы считаем долю найденных.
Высокий Recall означает, что модель редко пропускает объекты выбранного класса.
Precision и Recall
Заголовок раздела «Precision и Recall»Эти метрики смотрят на ошибки с разных сторон:
| Метрика | Главный вопрос |
|---|---|
Precision | Насколько точны предсказания выбранного класса? |
Recall | Какую долю объектов выбранного класса модель нашла? |
В задаче диагностики высокий Precision означает меньше ложных тревог, а высокий Recall — меньше пропущенных больных.
F1 объединяет Precision и Recall в одно число.
F1 = 2 * Precision * Recall / (Precision + Recall)F1 полезна, когда хочется учитывать и ложные срабатывания, и пропуски. Она принимает высокое значение только тогда, когда и Precision, и Recall достаточно высокие.
Возьмём тот же пример с бульдогами и спаниелями. После обучения модели и предсказания на тестовой выборке посчитаем метрики для класса спаниель, а затем разберём результат через матрицу ошибок.
uses MLABC;
begin var df := DataFrame.FromCsvText(''' Вес,ВысотаВХолке,Порода 20,33,бульдог 17,43,спаниель 16,41,спаниель 25,36,бульдог 26,34,бульдог 21,35,бульдог 24,35,бульдог 20,36,бульдог 14,39,спаниель 15,40,спаниель 19,39,бульдог 18,42,спаниель 22,34,бульдог 15,38,спаниель 19,40,спаниель 16,40,спаниель ''');
var X := df.ToMatrix(['Вес', 'ВысотаВХолке']); var target := df.EncodeTarget('Порода'); var y := target.Labels;
var (Xtrain, Xtest, ytrain, ytest) := Validation.TrainTestSplit(X, y, testRatio := 0.25, seed := 42);
var model := new KNNClassifier(3); model.Fit(Xtrain, ytrain);
var ypred := model.Predict(Xtest);
Println('Precision:', Metrics.Precision(ytest, ypred):0:3); Println('Recall:', Metrics.Recall(ytest, ypred):0:3); Println('F1:', Metrics.F1(ytest, ypred):0:3);end.Вывод программы:
Precision: 1.000Recall: 0.500F1: 0.667Для этих значений матрица ошибок относительно положительного класса спаниель выглядит так:
Предсказано →Реально ↓ спаниель не спаниельспаниель 1 1не спаниель 0 2Разберём результат для класса спаниель:
Precision = 1.000: если модель сказаласпаниель, она не ошиблась;Recall = 0.500: модель нашла только половину настоящих спаниелей;F1 = 0.667: итоговая оценка с учётом и точности, и полноты.
В этом примере задача бинарная: есть спаниель и не спаниель. Поэтому можно использовать прямые функции Metrics.Precision, Metrics.Recall и Metrics.F1.
Что выбрать
Заголовок раздела «Что выбрать»| Метрика | Когда особенно полезна |
|---|---|
Accuracy | Нужна общая доля правильных ответов |
Precision | Важно, чтобы предсказания выбранного класса были надёжными |
Recall | Важно не пропустить объекты выбранного класса |
F1 | Нужен баланс между Precision и Recall |
Precision, Recall и F1 особенно важны, когда классы несбалансированы или когда ошибки разных типов имеют разную цену.