3.4. Метрики и оценивание: количественная оценка качества предсказаний
3.4.1. Какую функцию оценивания следует использовать?
Прежде чем подробнее рассмотреть множество оценок и метрик оценки, мы хотим дать несколько рекомендаций по выбору функций оценивания для обучения с учителем, опираясь на теорию статистических решений, см. [Gneiting2009]:
- Какую функцию оценивания следует использовать?
- Какая функция оценивания подходит для моей задачи?
Вкратце: если функция оценивания задана, например в соревновании kaggle или в бизнес-контексте, используйте именно её. Если вы можете выбрать её самостоятельно, начните с рассмотрения конечной цели и области применения предсказания. Полезно различать два этапа:
- Предсказание
- Принятие решений
Предсказание: Обычно целевая переменная \(Y\) является случайной величиной в том смысле, что не существует детерминированной функции \(Y = g(X)\) от признаков \(X\). Вместо этого существует вероятностное распределение \(F\) переменной \(Y\). Можно стремиться предсказать всё распределение — это называется вероятностным предсказанием, — или, что чаще рассматривается в scikit-learn, выдать точечное предсказание (или точечный прогноз), выбрав свойство или функционал этого распределения \(F\). Типичные примеры — среднее (математическое ожидание), медиана или квантиль целевой переменной \(Y\) (условно относительно \(X\)).
После этого используйте для данного (целевого) функционала строго согласованную функцию оценивания, см. [Gneiting2009]. Это означает, что нужно использовать функцию оценивания, согласованную с измерением расстояния между предсказаниями y_pred и истинным целевым функционалом с помощью наблюдений \(Y\), т. е. y_true. Для строго правильных правил оценивания в классификации см. статью в Википедии о правилах оценивания и [Gneiting2007]: они совпадают со строго согласованными функциями оценивания. Примеры приведены в таблице ниже. Можно сказать, что согласованные функции оценивания служат сывороткой правды, поскольку они гарантируют, «что говорить правду […] — оптимальная стратегия в среднем» [Gneiting2014].
Выбрав строго согласованную функцию оценивания, лучше всего использовать её и как функцию потерь при обучении модели, и как метрику/оценку при оценке и сравнении моделей.
Обратите внимание: для регрессоров предсказание выполняется с помощью predict, а для классификаторов — обычно с помощью predict_proba.
Принятие решений: Чаще всего решения принимаются в задачах бинарной классификации, где результат predict_proba преобразуется в один итоговый результат. Например, на основе предсказанной вероятности дождя принимается решение о том, как поступить (взять ли средства защиты, например зонт). Для классификаторов именно это возвращает predict. См. также раздел Настройка порога принятия решения для предсказания класса. Существует множество функций оценивания, измеряющих различные аспекты такого решения; большинство из них охватываются матрицей metrics.confusion_matrix или выводятся из неё.
Список строго согласованных функций оценивания: Ниже перечислены некоторые наиболее важные статистические функционалы и соответствующие им строго согласованные функции оценивания, применяемые на практике. Обратите внимание, что список неполный и существуют другие варианты. Дополнительные критерии выбора конкретной функции см. в [Fissler2022].
функционал | функция оценивания или потерь | отклик | предсказание |
|---|---|---|---|
Классификация | |||
среднее | многоклассовый |
| |
среднее | многоклассовый |
| |
мода | многоклассовый |
| |
Регрессия | |||
среднее | все действительные числа |
| |
среднее | неотрицательные |
| |
среднее | строго положительные |
| |
среднее | зависит от |
| |
медиана | все действительные числа |
| |
квантиль | все действительные числа |
| |
мода | согласованной функции не существует | действительные числа |
1 Оценка Брайера — это просто другое название квадратичной ошибки в случае классификации с целевыми значениями, закодированными методом one-hot.
2 Ошибка 0–1 является согласованной, но не строго согласованной для моды. Ошибка 0–1 эквивалентна единице минус оценка точности: она даёт другие значения оценок, но тот же порядок моделей.
3 R² даёт тот же порядок моделей, что и квадратичная ошибка.
Условный пример: Рассмотрим приведённые выше аргументы на более конкретном примере. Представьте задачу из области проектирования надёжности сетей, например поддержание стабильного подключения к интернету или Wi-Fi. Как поставщик сети вы располагаете набором журналов сетевых подключений, содержащим данные о нагрузке на сеть с течением времени и множество других полезных признаков. Ваша цель — повысить надёжность подключений. Фактически вы обещаете клиентам, что как минимум в 99% дней не будет разрывов соединения длительностью более 1 минуты. Поэтому вас интересует предсказание 99-го квантиля (максимальной длительности разрыва соединения за день), чтобы заранее знать, когда следует увеличить пропускную способность и тем самым удовлетворить клиентов. Таким образом, целевой функционал — это 99-й квантиль. Из таблицы выше вы выбираете в качестве функции оценивания потерю pinball (вполне разумный выбор, учитывая, что вариантов немного) как для обучения модели (например, HistGradientBoostingRegressor(loss="quantile", quantile=0.99)), так и для оценки модели (mean_pinball_loss(..., alpha=0.99) — приносим извинения за разные имена аргументов: quantile и alpha), будь то поиск гиперпараметров с помощью поиска по сетке или сравнение с другими моделями, например QuantileRegressor(quantile=0.99).
Ссылки
T. Gneiting и A. E. Raftery. Строго правильные правила оценивания, предсказание и оценивание. В: Journal of the American Statistical Association 102 (2007), с. 359–378. ссылка на pdf
T. Gneiting. Создание и оценка точечных прогнозов. Journal of the American Statistical Association 106 (2009): 746–762.
T. Gneiting и M. Katzfuss. Вероятностное прогнозирование. В: Annual Review of Statistics and Its Application 1.1 (2014), с. 125–151.
T. Fissler, C. Lorentzen и M. Mayer. Сравнение моделей и оценка калибровки: руководство по согласованным функциям оценивания в машинном обучении и актуарной практике.
3.4.2. Обзор API оценивания
Существует 3 разных API для оценки качества предсказаний модели:
-
Метод score оценщика: У оценщиков есть метод
score, предоставляющий критерий оценки по умолчанию для решаемой ими задачи. Чаще всего это точность для классификаторов и коэффициент детерминации (\(R^2\)) для регрессоров. Подробную информацию о каждом оценщике можно найти в его документации. -
Параметр scoring: Инструменты оценки моделей, использующие перекрёстную проверку (например,
model_selection.GridSearchCV,model_selection.validation_curveиlinear_model.LogisticRegressionCV), опираются на внутреннюю стратегию оценивания. Её можно задать с помощью параметраscoringэтого инструмента; он рассматривается в разделе Параметр scoring: определение правил оценки модели. -
Функции метрик: Модуль
sklearn.metricsреализует функции для оценки ошибки предсказания в конкретных задачах. Эти метрики подробно рассматриваются в разделах о метриках классификации, метриках ранжирования для многометочной классификации, метриках регрессии и метриках кластеризации.
Наконец, фиктивные оценщики пригодятся для получения базовых значений этих метрик для случайных предсказаний.
См. также
О «попарных» метриках для объектов выборки, а не оценщиков или предсказаний, см. раздел Попарные метрики, меры близости и ядра.
3.4.3. Параметр scoring: определение правил оценки модели
Инструменты выбора и оценки моделей, которые внутри используют перекрёстную проверку (например, model_selection.GridSearchCV, model_selection.validation_curve и linear_model.LogisticRegressionCV), принимают параметр scoring, который задаёт метрику для оценки моделей.
Его можно задать несколькими способами:
-
None: используется критерий оценки по умолчанию для оценщика (то есть метрика, применяемая в методеscoreоценщика). - Строковое имя: распространённые метрики можно задать с помощью строкового имени.
- Вызываемый объект: более сложные метрики можно задать с помощью пользовательского вызываемого объекта метрики (например, функции).
Некоторые инструменты также поддерживают оценку по нескольким метрикам. Подробности см. в разделе Использование оценки по нескольким метрикам.
3.4.3.1. Оценщики со строковым именем
Для наиболее распространённых случаев использования объект оценщика можно задать для параметра scoring с помощью строкового имени; в таблице ниже приведены все возможные значения. Для всех объектов оценщиков действует соглашение: чем выше возвращаемое значение, тем лучше. Поэтому метрики, измеряющие расстояние между моделью и данными, такие как metrics.mean_squared_error, доступны как ‘neg_mean_squared_error’ и возвращают значение метрики с обратным знаком.
Строковое имя метрики | Функция | Комментарий |
|---|---|---|
Классификация | ||
‘accuracy’ | ||
‘balanced_accuracy’ | ||
‘top_k_accuracy’ | ||
‘average_precision’ | ||
‘neg_brier_score’ | требуется поддержка | |
‘f1’ | для бинарных целевых значений | |
‘f1_micro’ | усреднение микро | |
‘f1_macro’ | усреднение макро | |
‘f1_weighted’ | взвешенное среднее | |
‘f1_samples’ | по примерам с несколькими метками | |
‘neg_log_loss’ | требуется поддержка | |
‘precision’ и т. д. | суффиксы применяются так же, как для ‘f1’ | |
‘recall’ и т. д. | суффиксы применяются так же, как для ‘f1’ | |
‘jaccard’ и т. д. | суффиксы применяются так же, как для ‘f1’ | |
‘roc_auc’ | ||
‘roc_auc_ovr’ | ||
‘roc_auc_ovo’ | ||
‘roc_auc_ovr_weighted’ | ||
‘roc_auc_ovo_weighted’ | ||
‘d2_log_loss_score’ | требуется поддержка | |
‘d2_brier_score’ | требуется поддержка | |
Кластеризация | ||
‘adjusted_mutual_info_score’ | ||
‘adjusted_rand_score’ | ||
‘completeness_score’ | ||
‘fowlkes_mallows_score’ | ||
‘homogeneity_score’ | ||
‘mutual_info_score’ | ||
‘normalized_mutual_info_score’ | ||
‘rand_score’ | ||
‘v_measure_score’ | ||
Регрессия | ||
‘explained_variance’ | ||
‘neg_max_error’ | ||
‘neg_mean_absolute_error’ | ||
‘neg_mean_squared_error’ | ||
‘neg_root_mean_squared_error’ | ||
‘neg_mean_squared_log_error’ | ||
‘neg_root_mean_squared_log_error’ | ||
‘neg_median_absolute_error’ | ||
‘r2’ | ||
‘neg_mean_poisson_deviance’ | ||
‘neg_mean_gamma_deviance’ | ||
‘neg_mean_absolute_percentage_error’ | ||
‘d2_absolute_error_score’ |
Примеры использования:
>>> from sklearn import svm, datasets >>> from sklearn.model_selection import cross_val_score >>> X, y = datasets.load_iris(return_X_y=True) >>> clf = svm.SVC(random_state=0) >>> cross_val_score(clf, X, y, cv=5, scoring='recall_macro') array([0.96, 0.96, 0.96, 0.93, 1. ])
Примечание
Если указано неверное имя метрики, возникает исключение InvalidParameterError. Получить имена всех доступных оценщиков можно вызовом get_scorer_names.
3.4.3.2. Вызываемые оценщики
Для более сложных сценариев использования и большей гибкости параметру scoring можно передать вызываемый объект. Это можно сделать следующим образом:
- Адаптация предопределённых метрик с помощью make_scorer
- Создание пользовательского объекта оценщика (наиболее гибкий вариант)
3.4.3.2.1. Адаптация предопределённых метрик с помощью make_scorer
Следующие функции метрик не реализованы как именованные оценщики, в некоторых случаях потому, что им требуются дополнительные параметры, например fbeta_score. Их нельзя передать параметрам scoring; вместо этого вызываемый объект функции нужно передать в make_scorer вместе со значениями параметров, настраиваемых пользователем.
Функция | Параметр | Пример использования |
|---|---|---|
Классификация | ||
|
|
|
Регрессия | ||
|
|
|
|
|
|
|
|
|
|
|
|
Один из типичных сценариев использования — обёртывание существующей функции метрики из библиотеки с нестандартными значениями её параметров, например параметра beta функции fbeta_score:
>>> from sklearn.metrics import fbeta_score, make_scorer
>>> ftwo_scorer = make_scorer(fbeta_score, beta=2)
>>> from sklearn.model_selection import GridSearchCV
>>> from sklearn.svm import LinearSVC
>>> grid = GridSearchCV(LinearSVC(), param_grid={'C': [1, 10]},
... scoring=ftwo_scorer, cv=5)
Модуль sklearn.metrics также предоставляет набор простых функций для измерения ошибки предсказания по истинным значениям и предсказаниям:
- функции, заканчивающиеся на
_score, возвращают значение, которое нужно максимизировать: чем оно выше, тем лучше. - функции, заканчивающиеся на
_error,_lossили_deviance, возвращают значение, которое нужно минимизировать: чем оно ниже, тем лучше. При преобразовании такой функции в объект оценщика с помощьюmake_scorerзадайте параметруgreater_is_betterзначениеFalse(по умолчанию используетсяTrue; см. описание параметра ниже).
3.4.3.2.2. Создание пользовательского объекта оценщика
Создать собственный пользовательский объект оценщика можно с помощью make_scorer.
Пользовательские объекты оценщиков с помощью make_scorer
С помощью make_scorer можно создать полностью пользовательский объект оценщика на основе простой функции Python. Функции можно передать несколько параметров:
- функция Python, которую нужно использовать (в примере ниже —
my_custom_loss_func) - возвращает ли функция Python оценку (
greater_is_better=True, значение по умолчанию) или функцию потерь (greater_is_better=False). Если возвращается функция потерь, объект оценщика меняет знак результата функции Python в соответствии с соглашением перекрёстной проверки: оценщики возвращают более высокие значения для лучших моделей. - только для метрик классификации: требуется ли предоставленной функции Python непрерывная оценка уверенности при принятии решения. Если функция оценки принимает только оценки вероятностей (например,
metrics.log_loss), нужно задать параметрresponse_method="predict_proba". Некоторые функции оценки могут требовать не оценки вероятностей, а непрерывные значения решения без применения порога (например,metrics.roc_auc_score). В этом случае можно передать список (например,response_method=["decision_function", "predict_proba"]), и оценщик будет использовать первый доступный метод из указанного списка для вычисления оценок. - любые дополнительные параметры функции оценки, например
betaилиlabels.
Ниже приведён пример создания пользовательских оценщиков и использования параметра greater_is_better:
>>> import numpy as np >>> def my_custom_loss_func(y_true, y_pred): ... diff = np.abs(y_true - y_pred).max() ... return float(np.log1p(diff)) ... >>> # score will negate the return value of my_custom_loss_func, >>> # which will be np.log(2), 0.693, given the values for X >>> # and y defined below. >>> score = make_scorer(my_custom_loss_func, greater_is_better=False) >>> X = [[1], [1]] >>> y = [0, 1] >>> from sklearn.dummy import DummyClassifier >>> clf = DummyClassifier(strategy='most_frequent', random_state=0) >>> clf = clf.fit(X, y) >>> my_custom_loss_func(y, clf.predict(X)) 0.69 >>> score(clf, X, y) -0.69
Использование пользовательских оценщиков в функциях, где n_jobs > 1
Определение пользовательской функции оценки рядом с вызывающей функцией должно работать без дополнительной настройки с используемым по умолчанию бэкендом joblib (loky). Однако импорт такой функции из другого модуля — более надёжный подход, который работает независимо от бэкенда joblib.
Например, чтобы в примере ниже использовать n_jobs больше 1, функция custom_scoring_function сохраняется в созданном пользователем модуле (custom_scorer_module.py) и импортируется:
>>> from custom_scorer_module import custom_scoring_function >>> cross_val_score(model, ... X_train, ... y_train, ... scoring=make_scorer(custom_scoring_function, greater_is_better=False), ... cv=5, ... n_jobs=-1)
3.4.3.3. Использование оценки по нескольким метрикам
Scikit-learn также позволяет оценивать модели по нескольким метрикам в GridSearchCV, RandomizedSearchCV и cross_validate.
Задать несколько метрик для параметра scoring можно тремя способами:
-
В виде итерируемого объекта со строковыми именами метрик:
>>> scoring = ['accuracy', 'precision']
-
В виде сопоставления
dict, где имена оценщиков сопоставлены функциям оценки:>>> from sklearn.metrics import accuracy_score >>> from sklearn.metrics import make_scorer >>> scoring = {'accuracy': make_scorer(accuracy_score), ... 'prec': 'precision'}Обратите внимание: значениями словаря могут быть как функции оценщиков, так и одна из предопределённых строковых метрик.
-
В виде вызываемого объекта, возвращающего словарь оценок:
>>> from sklearn.model_selection import cross_validate >>> from sklearn.metrics import confusion_matrix >>> # A sample toy binary classification dataset >>> X, y = datasets.make_classification(n_classes=2, random_state=0) >>> svm = LinearSVC(random_state=0) >>> def confusion_matrix_scorer(clf, X, y): ... y_pred = clf.predict(X) ... cm = confusion_matrix(y, y_pred) ... return {'tn': cm[0, 0], 'fp': cm[0, 1], ... 'fn': cm[1, 0], 'tp': cm[1, 1]} >>> cv_results = cross_validate(svm, X, y, cv=5, ... scoring=confusion_matrix_scorer) >>> # Getting the test set true positive scores >>> print(cv_results['test_tp']) [10 9 8 7 8] >>> # Getting the test set false negative scores >>> print(cv_results['test_fn']) [0 1 2 3 2]
3.4.4. Метрики классификации
Модуль sklearn.metrics реализует несколько функций потерь, оценки и полезности для измерения качества классификации. Для некоторых метрик могут потребоваться оценки вероятности положительного класса или значения решения без пороговой обработки (возвращаемые функцией decision_function некоторыми классификаторами). В большинстве реализаций можно учитывать вклад каждого образца в общую оценку с помощью параметра sample_weight.
Некоторые из этих метрик применимы только к задаче бинарной классификации:
| Вычисляет пары значений точности и полноты для разных порогов вероятности. |
| Вычисляет ROC-кривую (характеристику работы приёмника). |
| Вычисляет отношения правдоподобия для положительного и отрицательного классов в бинарной классификации. |
| Вычисляет кривую компромисса ошибок обнаружения (DET) для разных порогов вероятности. |
| Вычисляет элементы матрицы ошибок бинарной классификации для каждого порога. |
Другие метрики также применимы к многоклассовым задачам:
| Вычисляет сбалансированную точность. |
| Вычисляет каппу Коэна — статистику, измеряющую согласованность между аннотаторами. |
| Вычисляет матрицу ошибок для оценки точности классификации. |
| Средняя шарнирная функция потерь (без регуляризации). |
| Вычисляет коэффициент корреляции Мэттьюса (MCC). |
| Вычисляет площадь под ROC-кривой (ROC AUC) на основе оценок предсказаний. |
| Оценка точности классификации Top-k. |
Некоторые метрики применимы и к задачам с несколькими метками:
| Оценка точности классификации. |
| Формирует текстовый отчёт с основными метриками классификации. |
| Вычисляет оценку F1, также известную как сбалансированная F-мера или F-мера. |
| Вычисляет оценку F-бета. |
| Вычисляет среднюю функцию потерь Хэмминга. |
| Оценка коэффициента сходства Жаккара. |
| Логарифмическая функция потерь, также называемая логистической функцией потерь или функцией потерь на основе перекрёстной энтропии. |
| Вычисляет матрицу ошибок для каждого класса или образца. |
| Вычисляет точность, полноту, F-меру и поддержку для каждого класса. |
| Вычисляет точность. |
| Вычисляет полноту. |
| Вычисляет площадь под ROC-кривой (ROC AUC) на основе оценок предсказаний. |
| Функция потерь 0–1 для классификации. |
| Функция оценки \(D^2\), доля объяснённой логарифмической функции потерь. |
Некоторые метрики работают с бинарными задачами и задачами с несколькими метками (но не с многоклассовыми задачами):
| Вычисляет среднюю точность (AP) на основе оценок предсказаний. |
В следующих подразделах мы рассмотрим каждую из этих функций, предварительно обсудив общие замечания об API и определении метрик.
3.4.4.1. От бинарной классификации к многоклассовой классификации и классификации с несколькими метками
Некоторые метрики по своей сути определены для задач бинарной классификации (например, f1_score, roc_auc_score). В таких случаях по умолчанию оценивается только положительная метка, причём предполагается, что положительному классу соответствует метка 1 (это можно настроить с помощью параметра pos_label).
При переносе бинарной метрики на многоклассовые задачи или задачи с несколькими метками данные рассматриваются как набор бинарных задач — по одной для каждого класса. Существует несколько способов усреднения значений бинарной метрики по набору классов; каждый из них может быть полезен в определённых ситуациях. Если такая возможность доступна, выберите способ с помощью параметра average.
-
"macro"просто вычисляет среднее значение бинарных метрик, придавая каждому классу одинаковый вес. В задачах, где редкие классы тем не менее важны, макроусреднение позволяет выделить качество их обработки. С другой стороны, предположение о равной важности всех классов часто неверно, поэтому макроусреднение может чрезмерно подчёркивать обычно низкое качество на редком классе. -
"weighted"учитывает дисбаланс классов, вычисляя среднее значение бинарных метрик, где оценка каждого класса взвешивается пропорционально его доле в истинных данных. -
"micro"придаёт каждой паре «образец — класс» одинаковый вклад в общую метрику (за исключением влияния весов образцов). Вместо суммирования метрики по классам этот способ суммирует числители и знаменатели, из которых состоят метрики для каждого класса, чтобы вычислить общее отношение. Микроусреднение может быть предпочтительным в задачах с несколькими метками, в том числе при многоклассовой классификации, когда требуется игнорировать класс большинства. -
"samples"применяется только к задачам с несколькими метками. Метрика не вычисляется отдельно для каждого класса: вместо этого она рассчитывается по истинным и предсказанным классам для каждого образца в оцениваемых данных, а затем возвращается их среднее, взвешенное поsample_weight. - При выборе
average=Noneвозвращается массив с оценкой для каждого класса.
В многоклассовых задачах метрике передаётся массив меток классов, как и в бинарных задачах. Данные с несколькими метками задаются матрицей индикаторов, в которой ячейка [i, j] имеет значение 1, если образцу i присвоена метка j, и значение 0 в противном случае.
3.4.4.2. Оценка точности
Функция accuracy_score вычисляет точность — долю (по умолчанию) или количество (normalize=False) правильных предсказаний.
В классификации с несколькими метками функция возвращает точность по подмножествам. Если весь набор предсказанных меток для образца в точности совпадает с истинным набором меток, точность по подмножествам равна 1.0; в противном случае она равна 0.0.
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-го образца, а \(y_i\) — соответствующее истинное значение, то доля правильных предсказаний среди \(n_\text{samples}\) образцов определяется следующим образом:
где \(1(x)\) — индикаторная функция.
>>> import numpy as np >>> from sklearn.metrics import accuracy_score >>> y_pred = [0, 2, 1, 3] >>> y_true = [0, 1, 2, 3] >>> accuracy_score(y_true, y_pred) 0.5 >>> accuracy_score(y_true, y_pred, normalize=False) 2.0
В случае классификации с несколькими метками и бинарными индикаторами меток:
>>> accuracy_score(np.array([[0, 1], [1, 1]]), np.ones((2, 2))) 0.5
Примеры
- Пример использования оценки точности с перестановками набора данных см. в разделе Проверка значимости оценки классификации с помощью перестановок.
3.4.4.3. Оценка точности Top-k
Функция top_k_accuracy_score является обобщением функции accuracy_score. Разница заключается в том, что предсказание считается правильным, если истинная метка связана с одной из k наиболее высоких оценок предсказания. accuracy_score — частный случай k = 1.
Функция применима к задачам бинарной и многоклассовой классификации, но не к задачам с несколькими метками.
Если \(\hat{f}_{i,j}\) — предсказанный класс для \(i\)-го образца, соответствующий \(j\)-й по величине оценке предсказания, а \(y_i\) — соответствующее истинное значение, то доля правильных предсказаний среди \(n_\text{samples}\) образцов определяется следующим образом:
где \(k\) — допустимое количество вариантов, а \(1(x)\) — индикаторная функция.
>>> import numpy as np >>> from sklearn.metrics import top_k_accuracy_score >>> y_true = np.array([0, 1, 2, 2]) >>> y_score = np.array([[0.5, 0.2, 0.2], ... [0.3, 0.4, 0.2], ... [0.2, 0.4, 0.3], ... [0.7, 0.2, 0.1]]) >>> top_k_accuracy_score(y_true, y_score, k=2) 0.75 >>> # Not normalizing gives the number of "correctly" classified samples >>> top_k_accuracy_score(y_true, y_score, k=2, normalize=False) 3.0
3.4.4.4. Оценка сбалансированной точности
Функция balanced_accuracy_score вычисляет сбалансированную точность, которая позволяет избежать завышенных оценок качества на несбалансированных наборах данных. Она представляет собой макроусреднение оценок полноты по классам или, что эквивалентно, обычную точность, где вес каждого образца обратно пропорционален распространённости его истинного класса. Поэтому на сбалансированных наборах данных эта оценка равна точности.
В бинарном случае сбалансированная точность равна среднему арифметическому чувствительности (доле истинно положительных результатов) и специфичности (доле истинно отрицательных результатов) или площади под ROC-кривой, вычисленной по бинарным предсказаниям, а не оценкам:
Если классификатор одинаково хорошо работает с обоими классами, эта величина сводится к обычной точности (то есть к числу правильных предсказаний, делённому на общее число предсказаний).
Напротив, если обычная точность превышает случайный уровень лишь потому, что классификатор использует дисбаланс тестового набора, сбалансированная точность, как и следует ожидать, снизится до \(\frac{1}{n\_classes}\).
Оценка принимает значения от 0 до 1. При использовании adjusted=True её шкала преобразуется в диапазон от \(\frac{1}{1 - n\_classes}\) до 1 включительно, причём случайные предсказания получают оценку 0.
Если \(y_i\) — истинное значение для \(i\)-го образца, а \(w_i\) — соответствующий вес образца, то скорректированный вес образца вычисляется так:
где \(1(x)\) — индикаторная функция. Для предсказанного значения \(\hat{y}_i\) образца \(i\) сбалансированная точность определяется следующим образом:
При использовании adjusted=True сбалансированная точность показывает относительный прирост по сравнению с \(\texttt{balanced-accuracy}(y, \mathbf{0}, w) = \frac{1}{n\_classes}\). В бинарном случае эта величина также известна как статистика J Юдена, или информированность.
Примечание
Представленное здесь определение для многоклассового случая представляется наиболее разумным обобщением метрики, используемой в бинарной классификации, хотя в литературе нет однозначного консенсуса:
- Наше определение: [Mosley2013], [Kelleher2015] и [Guyon2015], где в [Guyon2015] используется скорректированная версия, гарантирующая оценку \(0\) для случайных предсказаний и оценку \(1\) для идеальных предсказаний.
- Сбалансированная по классам точность, описанная в [Mosley2013]: для каждого класса вычисляется минимум между точностью и полнотой. Затем эти значения усредняются по всем классам, чтобы получить сбалансированную точность.
- Сбалансированная точность, описанная в [Urbanowicz2015]: для каждого класса вычисляется среднее чувствительности и специфичности, после чего результаты усредняются по всем классам.
Ссылки
I. Guyon, K. Bennett, G. Cawley, H.J. Escalante, S. Escalera, T.K. Ho, N. Macià, B. Ray, M. Saeed, A.R. Statnikov, E. Viegas, Design of the 2015 ChaLearn AutoML Challenge, IJCNN 2015.
John. D. Kelleher, Brian Mac Namee, Aoife D’Arcy, Fundamentals of Machine Learning for Predictive Data Analytics: Algorithms, Worked Examples, and Case Studies, 2015.
Urbanowicz R.J., Moore, J.H. ExSTraCS 2.0: description and evaluation of a scalable learning classifier system, Evol. Intel. (2015) 8: 89.
3.4.4.5. Каппа Коэна
Функция cohen_kappa_score вычисляет статистику каппа Коэна. Эта мера предназначена для сравнения разметок, созданных разными людьми-аннотаторами, а не для сравнения классификатора с эталонной разметкой.
Оценка каппа — число от -1 до 1. Значения выше 0,8 обычно считаются свидетельством хорошей согласованности; нулевое или отрицательное значение означает отсутствие согласованности (практически случайные метки).
Оценки каппа можно вычислять для бинарных и многоклассовых задач, но не для задач с несколькими метками (кроме случаев, когда оценка вручную вычисляется отдельно для каждой метки) и не для более чем двух аннотаторов.
>>> from sklearn.metrics import cohen_kappa_score >>> labeling1 = [2, 0, 2, 2, 0, 1] >>> labeling2 = [0, 0, 2, 2, 0, 2] >>> cohen_kappa_score(labeling1, labeling2) 0.4285714285714286
3.4.4.6. Матрица ошибок
Функция confusion_matrix оценивает точность классификации, вычисляя матрицу ошибок, в которой каждой строке соответствует истинный класс (в Википедии и других источниках для осей может использоваться другое соглашение).
По определению, элемент \(i, j\) матрицы ошибок — это количество наблюдений, фактически принадлежащих группе \(i\), но отнесённых к группе \(j\). Вот пример:
>>> from sklearn.metrics import confusion_matrix
>>> y_true = [2, 0, 2, 2, 0, 1]
>>> y_pred = [0, 0, 2, 2, 0, 2]
>>> confusion_matrix(y_true, y_pred)
array([[2, 0, 0],
[0, 0, 1],
[1, 0, 2]])
Объект ConfusionMatrixDisplay можно использовать для наглядного представления матрицы ошибок, как показано в примере Оценка качества классификатора с помощью матрицы ошибок, в котором строится следующий график:
Параметр normalize позволяет выводить доли вместо количеств. Матрицу ошибок можно нормализовать тремя способами: 'pred', 'true' и 'all' — в этих случаях количества делятся соответственно на сумму значений в каждом столбце, каждой строке или во всей матрице.
>>> y_true = [0, 0, 0, 1, 1, 1, 1, 1]
>>> y_pred = [0, 1, 0, 1, 0, 1, 0, 1]
>>> confusion_matrix(y_true, y_pred, normalize='all')
array([[0.25 , 0.125],
[0.25 , 0.375]])
Для бинарных задач можно получить количества истинно отрицательных, ложноположительных, ложноотрицательных и истинно положительных результатов следующим образом:
>>> y_true = [0, 0, 0, 1, 1, 1, 1, 1] >>> y_pred = [0, 1, 0, 1, 0, 1, 0, 1] >>> tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel().tolist() >>> tn, fp, fn, tp (2, 1, 2, 3)
С помощью confusion_matrix_at_thresholds можно получить количества истинно отрицательных, ложноположительных, ложноотрицательных и истинно положительных результатов для разных порогов:
>>> from sklearn.metrics import confusion_matrix_at_thresholds >>> y_true = np.array([0., 0., 1., 1.]) >>> y_score = np.array([0.1, 0.4, 0.35, 0.8]) >>> tns, fps, fns, tps, thresholds = confusion_matrix_at_thresholds(y_true, y_score) >>> tns array([2., 1., 1., 0.]) >>> fps array([0., 1., 1., 2.]) >>> fns array([1., 1., 0., 0.]) >>> tps array([1., 1., 2., 2.]) >>> thresholds array([0.8, 0.4, 0.35, 0.1])
Обратите внимание, что пороги представляют собой различные значения y_score, расположенные в порядке убывания.
Примеры
- Пример использования матрицы ошибок для оценки качества выходных данных классификатора см. в разделе Оценка качества классификатора с помощью матрицы ошибок.
- Пример использования матрицы ошибок для классификации рукописных цифр см. в разделе Распознавание рукописных цифр.
- Пример использования матрицы ошибок для классификации текстовых документов см. в разделе Классификация текстовых документов с использованием разреженных признаков.
3.4.4.7. Отчёт о классификации
Функция classification_report формирует текстовый отчёт с основными метриками классификации. Вот небольшой пример с пользовательскими target_names и выведенными автоматически метками:
>>> from sklearn.metrics import classification_report
>>> y_true = [0, 1, 2, 2, 0]
>>> y_pred = [0, 0, 2, 1, 0]
>>> target_names = ['class 0', 'class 1', 'class 2']
>>> print(classification_report(y_true, y_pred, target_names=target_names))
precision recall f1-score support
class 0 0.67 1.00 0.80 2
class 1 0.00 0.00 0.00 1
class 2 1.00 0.50 0.67 2
accuracy 0.60 5
macro avg 0.56 0.50 0.49 5
weighted avg 0.67 0.60 0.59 5
Примеры
- Пример использования отчёта о классификации рукописных цифр см. в разделе Распознавание рукописных цифр.
- Пример использования отчёта о классификации при поиске по сетке с вложенной перекрёстной проверкой см. в разделе Пользовательская стратегия повторного обучения для поиска по сетке с перекрёстной проверкой.
3.4.4.8. Потери Хэмминга
hamming_loss вычисляет средние потери Хэмминга, или расстояние Хэмминга, между двумя наборами образцов.
Пусть \(\hat{y}_{i,j}\) — предсказанное значение для \(j\)-й метки заданного образца \(i\), \(y_{i,j}\) — соответствующее истинное значение, \(n_\text{samples}\) — число образцов, а \(n_\text{labels}\) — число меток. Тогда потери Хэмминга \(L_{Hamming}\) определяются следующим образом:
где \(1(x)\) — индикаторная функция.
Приведённое выше уравнение не применимо в случае многоклассовой классификации. Дополнительные сведения см. в примечании ниже.
>>> from sklearn.metrics import hamming_loss >>> y_pred = [1, 2, 3, 4] >>> y_true = [2, 2, 3, 4] >>> hamming_loss(y_true, y_pred) 0.25
В случае многометочной классификации с бинарными индикаторами меток:
>>> hamming_loss(np.array([[0, 1], [1, 1]]), np.zeros((2, 2))) 0.75
Примечание
В многоклассовой классификации потери Хэмминга соответствуют расстоянию Хэмминга между y_true и y_pred, которое аналогично функции потерь 0/1. Однако если потери 0/1 штрафуют наборы предсказаний, которые не совпадают в точности с истинными наборами, то потери Хэмминга штрафуют отдельные метки. Таким образом, потери Хэмминга, ограниченные сверху потерями 0/1, всегда находятся в диапазоне от нуля до единицы включительно; предсказание правильного подмножества или надмножества истинных меток приводит к потерям Хэмминга строго между нулём и единицей.
3.4.4.9. Точность, полнота и F-меры
Интуитивно точность — это способность классификатора не относить отрицательный образец к положительному классу, а полнота — способность классификатора находить все положительные образцы.
F-меру (меры \(F_\beta\) и \(F_1\)) можно интерпретировать как среднее гармоническое точности и полноты с весами. Мера \(F_\beta\) достигает наилучшего значения 1 и наихудшего значения 0. При \(\beta = 1\) меры \(F_\beta\) и \(F_1\) эквивалентны, а полнота и точность имеют одинаковую важность.
precision_recall_curve строит кривую точности-полноты на основе истинных меток и оценок, выданных классификатором, изменяя порог принятия решения.
Функция average_precision_score вычисляет среднюю точность (AP) по оценкам предсказаний. Значение находится в диапазоне от 0 до 1; чем оно выше, тем лучше. AP определяется следующим образом:
где \(P_n\) и \(R_n\) — точность и полнота при n-м пороге. При случайных предсказаниях AP равна доле положительных образцов.
В работах [Manning2008] и [Everingham2010] представлены альтернативные варианты AP, в которых кривая точности-полноты интерполируется. В настоящее время average_precision_score не реализует ни один из интерполированных вариантов. В работах [Davis2006] и [Flach2015] объясняется, почему линейная интерполяция точек на кривой точности-полноты даёт чрезмерно оптимистичную оценку качества классификатора. Эта линейная интерполяция используется при вычислении площади под кривой методом трапеций в auc. В работе [Chen2024] сравниваются различные стратегии интерполяции, чтобы продемонстрировать их влияние.
Несколько функций позволяют анализировать точность, полноту и F-меру:
| Вычисляет среднюю точность (AP) по оценкам предсказаний. |
| Вычисляет F1-меру, также известную как сбалансированная F-мера или F-мера. |
| Вычисляет F-бета-меру. |
| Вычисляет пары «точность-полнота» для различных порогов вероятности. |
| Вычисляет точность, полноту, F-меру и поддержку для каждого класса. |
| Вычисляет точность. |
| Вычисляет полноту. |
Обратите внимание, что функция precision_recall_curve применима только к бинарному случаю. Функция average_precision_score поддерживает многоклассовый и многометочный форматы: она вычисляет оценку для каждого класса по схеме «один против остальных» (OvR), а затем усредняет их или нет в зависимости от значения аргумента average.
Функции PrecisionRecallDisplay.from_estimator и PrecisionRecallDisplay.from_predictions строят кривую точности-полноты следующим образом.
Примеры
- Пример использования
precision_scoreиrecall_scoreдля оценки параметров с помощью поиска по сетке с вложенной перекрёстной проверкой см. в разделе Настраиваемая стратегия повторного обучения для поиска по сетке с перекрёстной проверкой. - Пример использования
precision_recall_curveдля оценки качества вывода классификатора см. в разделе Точность и полнота.
Литература
C.D. Manning, P. Raghavan, H. Schütze, Введение в информационный поиск, 2008.
M. Everingham, L. Van Gool, C.K.I. Williams, J. Winn, A. Zisserman, Задача Pascal по распознаванию визуальных объектов (VOC), IJCV 2010.
J. Davis, M. Goadrich, Связь между кривыми точности-полноты и ROC-кривыми, ICML 2006.
P.A. Flach, M. Kull, Кривые прироста точности-полноты: правильный анализ PR, NIPS 2015.
W. Chen, C. Miao, Z. Zhang, C.S. Fung, R. Wang, Y. Chen, Y. Qian, L. Cheng, K.Y. Yip, S.K Tsui, Q. Cao, Широко используемые программные инструменты дают противоречивые и чрезмерно оптимистичные значения AUPRC, Genome Biology 2024.
3.4.4.9.1. Бинарная классификация
В задаче бинарной классификации термины «положительный» и «отрицательный» относятся к предсказанию классификатора, а термины «истинный» и «ложный» указывают на то, соответствует ли предсказание внешней оценке (иногда называемой «наблюдением»). Исходя из этих определений, можно составить следующую таблицу:
Фактический класс (наблюдение) | ||
Предсказанный класс (ожидание) | tp (истинно положительный) Правильный результат | fp (ложно положительный) Неожиданный результат |
fn (ложно отрицательный) Пропущенный результат | tn (истинно отрицательный) Правильное отсутствие результата | |
В этом контексте можно определить понятия точности и полноты:
(Полноту иногда также называют «чувствительностью».)
F-мера — это среднее гармоническое точности и полноты с весами; вклад точности в среднее взвешивается параметром \(\beta\):
Чтобы избежать деления на ноль, когда точность и полнота равны нулю, Scikit-Learn вычисляет F-меру по следующей эквивалентной формуле:
Обратите внимание, что эта формула всё ещё не определена, если отсутствуют истинно положительные, ложно положительные или ложно отрицательные результаты. По умолчанию значение F-1 для набора, состоящего только из истинно отрицательных результатов, вычисляется как 0, однако это поведение можно изменить с помощью параметра zero_division. Ниже приведено несколько небольших примеров бинарной классификации:
>>> from sklearn import metrics >>> y_pred = [0, 1, 0, 0] >>> y_true = [0, 1, 0, 1] >>> metrics.precision_score(y_true, y_pred) 1.0 >>> metrics.recall_score(y_true, y_pred) 0.5 >>> metrics.f1_score(y_true, y_pred) 0.66 >>> metrics.fbeta_score(y_true, y_pred, beta=0.5) 0.83 >>> metrics.fbeta_score(y_true, y_pred, beta=1) 0.66 >>> metrics.fbeta_score(y_true, y_pred, beta=2) 0.55 >>> metrics.precision_recall_fscore_support(y_true, y_pred, beta=0.5) (array([0.66, 1. ]), array([1. , 0.5]), array([0.71, 0.83]), array([2, 2])) >>> import numpy as np >>> from sklearn.metrics import precision_recall_curve >>> from sklearn.metrics import average_precision_score >>> y_true = np.array([0, 0, 1, 1]) >>> y_scores = np.array([0.1, 0.4, 0.35, 0.8]) >>> precision, recall, threshold = precision_recall_curve(y_true, y_scores) >>> precision array([0.5 , 0.66, 0.5 , 1. , 1. ]) >>> recall array([1. , 1. , 0.5, 0.5, 0. ]) >>> threshold array([0.1 , 0.35, 0.4 , 0.8 ]) >>> average_precision_score(y_true, y_scores) 0.83
3.4.4.9.2. Многоклассовая и многометочная классификация
В задачах многоклассовой и многометочной классификации понятия точности, полноты и F-мер можно применять отдельно к каждой метке. Есть несколько способов объединения результатов по меткам; они задаются аргументом average функций average_precision_score, f1_score, fbeta_score, precision_recall_fscore_support, precision_score и recall_score, как описано выше.
При усреднении учитывайте следующие особенности:
- Если включены все метки, усреднение «micro» в многоклассовом случае даёт точность, полноту и \(F\), совпадающие с долей правильных ответов.
- Усреднение «weighted» может дать F-меру, не лежащую между точностью и полнотой.
- Усреднение «macro» для F-мер вычисляется как среднее арифметическое F-мер по отдельным меткам/классам, а не как среднее гармоническое средних арифметических точности и полноты. В литературе встречаются оба способа вычисления, но они не эквивалентны; подробности см. в работе [OB2019].
Чтобы пояснить это более подробно, введём следующие обозначения:
- \(y\) — множество пар \((sample, label)\) с истинными значениями
- \(\hat{y}\) — множество пар \((sample, label)\) с предсказанными значениями
- \(L\) — множество меток
- \(S\) — множество образцов
- \(y_s\) — подмножество \(y\) для образца \(s\), то есть \(y_s := \left\{(s', l) \in y | s' = s\right\}\)
- \(y_l\) — подмножество \(y\) для метки \(l\)
- аналогично, \(\hat{y}_s\) и \(\hat{y}_l\) — подмножества \(\hat{y}\)
- \(P(A, B) := \frac{\left| A \cap B \right|}{\left|B\right|}\) для некоторых множеств \(A\) и \(B\)
- \(R(A, B) := \frac{\left| A \cap B \right|}{\left|A\right|}\) (Существуют разные соглашения об обработке случая \(A = \emptyset\); в этой реализации используется \(R(A, B):=0\), а для \(P\) применяется аналогичное правило.)
- \(F_\beta(A, B) := \left(1 + \beta^2\right) \frac{P(A, B) \times R(A, B)}{\beta^2 P(A, B) + R(A, B)}\)
Тогда метрики определяются следующим образом:
| Точность | Полнота | F_beta |
|---|---|---|---|
| \(P(y, \hat{y})\) | \(R(y, \hat{y})\) | \(F_\beta(y, \hat{y})\) |
| \(\frac{1}{\left|S\right|} \sum_{s \in S} P(y_s, \hat{y}_s)\) | \(\frac{1}{\left|S\right|} \sum_{s \in S} R(y_s, \hat{y}_s)\) | \(\frac{1}{\left|S\right|} \sum_{s \in S} F_\beta(y_s, \hat{y}_s)\) |
| \(\frac{1}{\left|L\right|} \sum_{l \in L} P(y_l, \hat{y}_l)\) | \(\frac{1}{\left|L\right|} \sum_{l \in L} R(y_l, \hat{y}_l)\) | \(\frac{1}{\left|L\right|} \sum_{l \in L} F_\beta(y_l, \hat{y}_l)\) |
| \(\frac{1}{\sum_{l \in L} \left|y_l\right|} \sum_{l \in L} \left|y_l\right| P(y_l, \hat{y}_l)\) | \(\frac{1}{\sum_{l \in L} \left|y_l\right|} \sum_{l \in L} \left|y_l\right| R(y_l, \hat{y}_l)\) | \(\frac{1}{\sum_{l \in L} \left|y_l\right|} \sum_{l \in L} \left|y_l\right| F_\beta(y_l, \hat{y}_l)\) |
| \(\langle P(y_l, \hat{y}_l) | l \in L \rangle\) | \(\langle R(y_l, \hat{y}_l) | l \in L \rangle\) | \(\langle F_\beta(y_l, \hat{y}_l) | l \in L \rangle\) |
>>> from sklearn import metrics >>> y_true = [0, 1, 2, 0, 1, 2] >>> y_pred = [0, 2, 1, 0, 0, 1] >>> metrics.precision_score(y_true, y_pred, average='macro') 0.22 >>> metrics.recall_score(y_true, y_pred, average='micro') 0.33 >>> metrics.f1_score(y_true, y_pred, average='weighted') 0.267 >>> metrics.fbeta_score(y_true, y_pred, average='macro', beta=0.5) 0.238 >>> metrics.precision_recall_fscore_support(y_true, y_pred, beta=0.5, average=None) (array([0.667, 0., 0.]), array([1., 0., 0.]), array([0.714, 0., 0.]), array([2, 2, 2]))
Для многоклассовой классификации с «отрицательным классом» можно исключить некоторые метки:
>>> metrics.recall_score(y_true, y_pred, labels=[1, 2], average='micro') ... # excluding 0, no labels were correctly recalled 0.0
Аналогичным образом, метки, отсутствующие в образце данных, можно учитывать при макроусреднении.
>>> metrics.precision_score(y_true, y_pred, labels=[0, 1, 2, 3], average='macro') 0.166
Литература
3.4.4.10. Оценка коэффициента сходства Жаккара
Функция jaccard_score вычисляет среднее значение коэффициентов сходства Жаккара, также называемых индексом Жаккара, для пар наборов меток.
Коэффициент сходства Жаккара для набора истинных меток \(y\) и набора предсказанных меток \(\hat{y}\) определяется следующим образом:
jaccard_score (как и precision_recall_fscore_support) изначально предназначена для бинарных целевых значений. При вычислении для множеств её можно расширить на многометочную и многоклассовую классификацию с помощью average (см. выше).
В бинарном случае:
>>> import numpy as np >>> from sklearn.metrics import jaccard_score >>> y_true = np.array([[0, 1, 1], ... [1, 1, 0]]) >>> y_pred = np.array([[1, 1, 1], ... [1, 0, 0]]) >>> jaccard_score(y_true[0], y_pred[0]) 0.6666
В случае двумерного сравнения (например, при сравнении сходства изображений):
>>> jaccard_score(y_true, y_pred, average="micro") 0.6
В случае многометочной классификации с бинарными индикаторами меток:
>>> jaccard_score(y_true, y_pred, average='samples') 0.5833 >>> jaccard_score(y_true, y_pred, average='macro') 0.6666 >>> jaccard_score(y_true, y_pred, average=None) array([0.5, 0.5, 1. ])
Многоклассовые задачи преобразуются в бинарный формат и обрабатываются как соответствующие многометочные задачи:
>>> y_pred = [0, 2, 1, 2] >>> y_true = [0, 1, 2, 2] >>> jaccard_score(y_true, y_pred, average=None) array([1. , 0. , 0.33]) >>> jaccard_score(y_true, y_pred, average='macro') 0.44 >>> jaccard_score(y_true, y_pred, average='micro') 0.33
3.4.4.11. Шарнирные потери
Функция hinge_loss вычисляет среднее расстояние между моделью и данными с использованием шарнирных потерь — односторонней метрики, учитывающей только ошибки предсказания. (Шарнирные потери используются в классификаторах с максимальным зазором, например в машинах опорных векторов.)
Пусть истинная метка \(y_i\) в задаче бинарной классификации закодирована как \(y_i=\left\{-1, +1\right\}\) для каждого образца \(i\), а \(w_i\) — соответствующее предсказанное решение (массив формы (n_samples,), возвращаемый методом decision_function). Тогда шарнирные потери определяются следующим образом:
Если меток больше двух, hinge_loss использует многоклассовый вариант, предложенный Краммером и Сингером. Здесь находится статья с его описанием.
В этом случае предсказанное решение представляет собой массив формы (n_samples, n_labels). Пусть \(w_{i, y_i}\) — предсказанное решение для истинной метки \(y_i\) i-го образца, а \(\hat{w}_{i, y_i} = \max\left\{w_{i, y_j}~|~y_j \ne y_i \right\}\) — максимальное из предсказанных решений для всех остальных меток. Тогда многоклассовые шарнирные потери определяются следующим образом:
Ниже приведён небольшой пример использования функции hinge_loss с классификатором svm в задаче бинарной классификации:
>>> from sklearn import svm >>> from sklearn.metrics import hinge_loss >>> X = [[0], [1]] >>> y = [-1, 1] >>> est = svm.LinearSVC(random_state=0) >>> est.fit(X, y) LinearSVC(random_state=0) >>> pred_decision = est.decision_function([[-2], [3], [0.5]]) >>> pred_decision array([-2.18, 2.36, 0.09]) >>> hinge_loss([-1, 1, 1], pred_decision) 0.3
Ниже приведён пример использования функции hinge_loss с классификатором svm в задаче многоклассовой классификации:
>>> X = np.array([[0], [1], [2], [3]]) >>> Y = np.array([0, 1, 2, 3]) >>> labels = np.array([0, 1, 2, 3]) >>> est = svm.LinearSVC() >>> est.fit(X, Y) LinearSVC() >>> pred_decision = est.decision_function([[-1], [2], [3]]) >>> y_true = [0, 2, 3] >>> hinge_loss(y_true, pred_decision, labels=labels) 0.56
3.4.4.12. Логарифмические потери
Логарифмические потери, также называемые потерями логистической регрессии или кросс-энтропийными потерями, определяются для оценок вероятности. Они широко используются в логистической регрессии (мультиномиальной) и нейронных сетях, а также в некоторых вариантах алгоритма максимизации ожидания; их можно применять для оценки вероятностных выходов (predict_proba) классификатора вместо его дискретных предсказаний.
В бинарной классификации с истинной меткой \(y \in \{0,1\}\) и оценкой вероятности \(\hat{p} \approx \operatorname{Pr}(y = 1)\) логарифмические потери на образце равны отрицательному логарифму правдоподобия классификатора при заданной истинной метке:
Этот подход обобщается на многоклассовый случай следующим образом. Пусть истинные метки набора образцов закодированы в виде бинарной матрицы-индикатора 1-of-K \(Y\), то есть \(y_{i,k} = 1\), если образец \(i\) имеет метку \(k\) из множества, содержащего \(K\) меток. Пусть \(\hat{P}\) — матрица оценок вероятности с элементами \(\hat{p}_{i,k} \approx \operatorname{Pr}(y_{i,k} = 1)\). Тогда логарифмические потери для всего набора равны
Чтобы увидеть, как это обобщает приведённые выше бинарные логарифмические потери, учтите, что в бинарном случае \(\hat{p}_{i,0} = 1 - \hat{p}_{i,1}\) и \(y_{i,0} = 1 - y_{i,1}\), поэтому раскрытие внутренней суммы по \(y_{i,k} \in \{0,1\}\) даёт бинарные логарифмические потери.
Функция log_loss вычисляет логарифмические потери по списку истинных меток и матрице вероятностей, возвращаемой методом predict_proba оценщика.
>>> from sklearn.metrics import log_loss >>> y_true = [0, 0, 1, 1] >>> y_proba = [[.9, .1], [.8, .2], [.3, .7], [.01, .99]] >>> log_loss(y_true, y_proba) 0.1738
Первое значение [.9, .1] в y_proba указывает на вероятность 90 %, что первый образец имеет метку 0. Логарифмические потери неотрицательны.
3.4.4.13. Коэффициент корреляции Мэтьюса
Функция matthews_corrcoef вычисляет коэффициент корреляции Мэтьюса (MCC) для бинарных классов. Цитата из Википедии:
«Коэффициент корреляции Мэтьюса используется в машинном обучении как мера качества бинарной классификации (с двумя классами). Он учитывает истинно- и ложно-положительные, а также истинно- и ложно-отрицательные результаты и в целом считается сбалансированной мерой, которую можно использовать даже в том случае, если размеры классов сильно различаются. По сути, MCC — это значение коэффициента корреляции в диапазоне от -1 до +1. Коэффициент +1 соответствует идеальному прогнозу, 0 — среднему случайному прогнозу, а -1 — обратному прогнозу. Эта статистическая характеристика также известна как коэффициент фи».
В бинарном случае (два класса) \(tp\), \(tn\), \(fp\) и \(fn\) — это соответственно количество истинно-положительных, истинно-отрицательных, ложно-положительных и ложно-отрицательных результатов; MCC определяется следующим образом:
В случае многоклассовой классификации коэффициент корреляции Мэтьюса можно определить через confusion_matrix \(C\) для \(K\) классов. Чтобы упростить определение, рассмотрим следующие промежуточные переменные:
- \(t_k=\sum_{i}^{K} C_{ik}\) — количество случаев, когда класс \(k\) действительно встречался,
- \(p_k=\sum_{i}^{K} C_{ki}\) — количество случаев, когда был предсказан класс \(k\),
- \(c=\sum_{k}^{K} C_{kk}\) — общее количество правильно предсказанных образцов,
- \(s=\sum_{i}^{K} \sum_{j}^{K} C_{ij}\) — общее количество образцов.
Тогда многоклассовый MCC определяется следующим образом:
Если меток больше двух, значение MCC уже не будет находиться в диапазоне от -1 до +1. Вместо этого минимальное значение будет где-то между -1 и 0 в зависимости от количества и распределения истинных меток. Максимальное значение всегда равно +1. Дополнительные сведения см. в [WikipediaMCC2021].
Вот небольшой пример использования функции matthews_corrcoef:
>>> from sklearn.metrics import matthews_corrcoef >>> y_true = [+1, +1, +1, -1] >>> y_pred = [+1, -1, +1, +1] >>> matthews_corrcoef(y_true, y_pred) -0.33
Литература
Участники Википедии. Коэффициент фи. Википедия, свободная энциклопедия. 21 апреля 2021 г., 12:21 CEST. Доступно по адресу: https://en.wikipedia.org/wiki/Phi_coefficient. Дата обращения: 21 апреля 2021 г.
3.4.4.14. Матрица ошибок для многометочной классификации
Функция multilabel_confusion_matrix вычисляет матрицу ошибок для многометочной классификации по классам (по умолчанию) или по образцам (samplewise=True), чтобы оценить точность классификации. Функция multilabel_confusion_matrix также обрабатывает многоклассовые данные так, как если бы они были многометочными, поскольку такое преобразование часто используется для оценки задач многоклассовой классификации с помощью метрик бинарной классификации (например, точности, полноты и т. д.).
При вычислении матрицы ошибок для многометочной классификации по классам \(C\) количество истинно-отрицательных результатов для класса \(i\) равно \(C_{i,0,0}\), ложно-отрицательных — \(C_{i,1,0}\), истинно-положительных — \(C_{i,1,1}\), а ложно-положительных — \(C_{i,0,1}\).
Вот пример использования функции multilabel_confusion_matrix со входными данными в виде индикаторной матрицы многометочной классификации:
>>> import numpy as np
>>> from sklearn.metrics import multilabel_confusion_matrix
>>> y_true = np.array([[1, 0, 1],
... [0, 1, 0]])
>>> y_pred = np.array([[1, 0, 0],
... [0, 1, 1]])
>>> multilabel_confusion_matrix(y_true, y_pred)
array([[[1, 0],
[0, 1]],
[[1, 0],
[0, 1]],
[[0, 1],
[1, 0]]])
Также можно построить матрицу ошибок для меток каждого образца:
>>> multilabel_confusion_matrix(y_true, y_pred, samplewise=True)
array([[[1, 0],
[1, 1]],
[[1, 1],
[0, 1]]])
Вот пример использования функции multilabel_confusion_matrix с входными данными для многоклассовой классификации:
>>> y_true = ["cat", "ant", "cat", "cat", "ant", "bird"]
>>> y_pred = ["ant", "ant", "cat", "cat", "ant", "cat"]
>>> multilabel_confusion_matrix(y_true, y_pred,
... labels=["ant", "bird", "cat"])
array([[[3, 1],
[0, 2]],
[[5, 0],
[1, 0]],
[[2, 1],
[1, 2]]])
Ниже приведены примеры использования функции multilabel_confusion_matrix для вычисления полноты (или чувствительности), специфичности, доли ложноположительных результатов и доли пропусков для каждого класса в задаче с входными данными в виде индикаторной матрицы многометочной классификации.
Вычисление полноты (также называемой долей истинно-положительных результатов или чувствительностью) для каждого класса:
>>> y_true = np.array([[0, 0, 1], ... [0, 1, 0], ... [1, 1, 0]]) >>> y_pred = np.array([[0, 1, 0], ... [0, 0, 1], ... [1, 1, 0]]) >>> mcm = multilabel_confusion_matrix(y_true, y_pred) >>> tn = mcm[:, 0, 0] >>> tp = mcm[:, 1, 1] >>> fn = mcm[:, 1, 0] >>> fp = mcm[:, 0, 1] >>> tp / (tp + fn) array([1. , 0.5, 0. ])
Вычисление специфичности (также называемой долей истинно-отрицательных результатов) для каждого класса:
>>> tn / (tn + fp) array([1. , 0. , 0.5])
Вычисление доли ложноположительных результатов (также называемой долей ложных срабатываний) для каждого класса:
>>> fp / (fp + tn) array([0. , 1. , 0.5])
Вычисление доли пропусков (также называемой долей ложноотрицательных результатов) для каждого класса:
>>> fn / (fn + tp) array([0. , 0.5, 1. ])
3.4.4.15. Рабочая характеристика приёмника (ROC)
Функция roc_curve вычисляет кривую рабочей характеристики приёмника, или ROC-кривую. Цитата из Википедии:
«Рабочая характеристика приёмника (ROC), или просто ROC-кривая, — это график, показывающий качество работы бинарного классификатора при изменении порога классификации. Она строится путём нанесения доли истинно-положительных результатов среди положительных (TPR = доля истинно-положительных результатов) относительно доли ложно-положительных результатов среди отрицательных (FPR = доля ложно-положительных результатов) для различных значений порога. TPR также называется чувствительностью, а FPR равна единице минус специфичность, или доля истинно-отрицательных результатов».
Для этой функции требуются истинные бинарные значения и целевые оценки, которые могут быть либо оценками вероятности положительного класса, либо значениями решения без применения порога (возвращаемыми методом decision_function у некоторых классификаторов). Вот небольшой пример использования функции roc_curve:
>>> import numpy as np >>> from sklearn.metrics import roc_curve >>> y = np.array([1, 1, 2, 2]) >>> scores = np.array([0.1, 0.4, 0.35, 0.8]) >>> fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2) >>> fpr array([0. , 0. , 0.5, 0.5, 1. ]) >>> tpr array([0. , 0.5, 0.5, 1. , 1. ]) >>> thresholds array([ inf, 0.8 , 0.4 , 0.35, 0.1 ])
В отличие от таких метрик, как точность по подмножествам, функция потерь Хэмминга или F1-мера, ROC не требует подбора порога для каждой метки.
Функция roc_auc_score, обозначаемая ROC-AUC или AUROC, вычисляет площадь под ROC-кривой. Таким образом, информация о кривой сводится к одному числу.
На следующем рисунке показаны ROC-кривая и оценка ROC-AUC для классификатора, предназначенного для отличия цветка вида virginica от остальных видов в наборе данных о растениях ириса:
Дополнительные сведения см. в статье Википедии о AUC.
3.4.4.15.1. Бинарный случай
В бинарном случае можно передать либо оценки вероятности с помощью метода classifier.predict_proba(), либо значения решения без применения порога, возвращаемые методом classifier.decision_function(). Если передаются оценки вероятности, необходимо указать вероятность класса с «большей меткой». «Большая метка» соответствует classifier.classes_[1] и, следовательно, classifier.predict_proba(X)[:, 1]. Поэтому параметр y_score имеет размер (n_samples,).
>>> from sklearn.datasets import load_breast_cancer >>> from sklearn.linear_model import LogisticRegression >>> from sklearn.metrics import roc_auc_score >>> X, y = load_breast_cancer(return_X_y=True) >>> clf = LogisticRegression().fit(X, y) >>> clf.classes_ array([0, 1])
Можно использовать оценки вероятности, соответствующие clf.classes_[1].
>>> y_score = clf.predict_proba(X)[:, 1] >>> roc_auc_score(y, y_score) 0.99
В противном случае можно использовать значения решения без применения порога:
>>> roc_auc_score(y, clf.decision_function(X)) 0.99
3.4.4.15.2. Многоклассовый случай
Функцию roc_auc_score также можно использовать для многоклассовой классификации. В настоящее время поддерживаются две стратегии усреднения: алгоритм «один против одного» вычисляет среднее попарных оценок ROC AUC, а алгоритм «один против всех» — среднее оценок ROC AUC для каждого класса относительно всех остальных. В обоих случаях предсказанные метки передаются в массиве со значениями от 0 до n_classes, а оценки соответствуют вероятностям принадлежности образца к определённому классу. Алгоритмы OvO и OvR поддерживают равномерное взвешивание (average='macro') и взвешивание по распространённости (average='weighted').
Алгоритм «один против одного»
Вычисляет среднее значение AUC для всех возможных попарных сочетаний классов. В работе [HT2001] определена многоклассовая метрика AUC с равномерным взвешиванием:
где \(c\) — количество классов, а \(\text{AUC}(j | k)\) — значение AUC, в котором класс \(j\) является положительным, а класс \(k\) — отрицательным. В общем случае многоклассовой классификации \(\text{AUC}(j | k) \neq \text{AUC}(k | j)\). Этот алгоритм используется, если задать аргумент-ключевое слово multiclass равным 'ovo', а average — 'macro'.
Многоклассовую метрику AUC из работы [HT2001] можно расширить, взвешивая её по распространённости классов:
где \(c\) — количество классов. Этот алгоритм используется, если задать аргумент-ключевое слово multiclass равным 'ovo', а average — 'weighted'. Параметр 'weighted' возвращает среднее, взвешенное по распространённости классов, как описано в [FC2009].
Алгоритм «один против всех»
Вычисляет AUC каждого класса относительно остальных [PD2000]. Этот алгоритм функционально эквивалентен алгоритму для многометочного случая. Чтобы включить его, задайте аргумент-ключевое слово multiclass равным 'ovr'. Помимо усреднения 'macro' [F2006] и 'weighted' [F2001], OvR поддерживает усреднение 'micro'.
В приложениях, где недопустима высокая доля ложноположительных результатов, параметр max_fpr функции roc_auc_score можно использовать для обобщения ROC-кривой до заданного предела.
На следующем рисунке показаны ROC-кривая с микроусреднением и соответствующая оценка ROC-AUC для классификатора, предназначенного для различения видов в наборе данных о растениях ириса:
3.4.4.15.3. Многометочный случай
В многометочной классификации функция roc_auc_score расширяется за счёт усреднения по меткам, как описано выше. В этом случае следует передать y_score формы (n_samples, n_classes). Поэтому при использовании оценок вероятности для каждого выхода нужно выбрать вероятность класса с большей меткой.
>>> from sklearn.datasets import make_multilabel_classification >>> from sklearn.multioutput import MultiOutputClassifier >>> X, y = make_multilabel_classification(random_state=0) >>> inner_clf = LogisticRegression(random_state=0) >>> clf = MultiOutputClassifier(inner_clf).fit(X, y) >>> y_score = np.transpose([y_pred[:, 1] for y_pred in clf.predict_proba(X)]) >>> roc_auc_score(y, y_score, average=None) array([0.828, 0.851, 0.94, 0.87, 0.95])
Для значений решения такая обработка не требуется.
>>> from sklearn.linear_model import RidgeClassifierCV >>> clf = RidgeClassifierCV().fit(X, y) >>> y_score = clf.decision_function(X) >>> roc_auc_score(y, y_score, average=None) array([0.82, 0.85, 0.93, 0.87, 0.94])
Примеры
- См. пример использования ROC для оценки качества выходных данных классификатора в разделе Многоклассовая рабочая характеристика приёмника (ROC).
- См. пример использования ROC для оценки качества выходных данных классификатора с применением перекрёстной проверки в разделе Рабочая характеристика приёмника (ROC) с перекрёстной проверкой.
- См. пример использования ROC для моделирования распространения видов в разделе Моделирование распространения видов.
Литература
Hand, D.J. и Till, R.J. (2001). Простое обобщение площади под ROC-кривой для задач многоклассовой классификации. Machine Learning, 45(2), с. 171–186.
Ferri, Cèsar, Hernandez-Orallo, Jose и Modroiu, R. (2009). Экспериментальное сравнение метрик качества классификации. Pattern Recognition Letters. 30. 27–38.
Provost, F. и Domingos, P. (2000). Хорошо обученные PET: улучшение деревьев оценки вероятностей (раздел 6.2), рабочий документ CeDER № IS-00-04, Школа бизнеса имени Стерна, Нью-Йоркский университет.
Fawcett, T., 2006. Введение в анализ ROC. Pattern Recognition Letters, 27(8), с. 861–874.
Fawcett, T., 2001. Использование наборов правил для максимизации качества ROC. В сборнике Data Mining, 2001. Материалы международной конференции IEEE, с. 131–138.
3.4.4.16. Компромисс ошибок обнаружения (DET)
Функция det_curve вычисляет кривую компромисса ошибок обнаружения (DET) [WikipediaDET2017]. Цитата из Википедии:
«График компромисса ошибок обнаружения (DET) показывает частоты ошибок бинарных систем классификации: доля ошибочных отказов откладывается по одной оси, а доля ошибочных допусков — по другой. Оси x и y нелинейно масштабируются с помощью стандартных нормальных квантилей (или просто логарифмического преобразования), в результате чего кривые компромисса становятся более линейными, чем ROC-кривые, а большая часть площади графика используется для выделения важных различий в критической рабочей области».
Кривые DET — это разновидность ROC-кривых, в которых по оси y откладывается доля ложноотрицательных результатов вместо доли истинно-положительных. Кривые DET обычно строятся в шкале нормальных квантилей с помощью преобразования \(\phi^{-1}\) (где \(\phi\) — функция распределения). Полученные кривые качества наглядно показывают компромисс между типами ошибок для заданных алгоритмов классификации. Примеры и дополнительное обоснование см. в [Martin1997].
На этом рисунке сравниваются ROC- и DET-кривые двух классификаторов, решающих одну и ту же задачу классификации:
Свойства
- Если оценки обнаружения имеют нормальное (или близкое к нормальному) распределение, кривые DET в шкале нормальных квантилей образуют прямую линию. В работе [Navratil2007] показано, что обратное утверждение неверно: линейные кривые DET могут соответствовать распределениям более общего вида.
- Преобразование в шкалу нормальных квантилей распределяет точки таким образом, что они занимают сравнительно большую площадь графика. Поэтому кривые классификаторов со схожими характеристиками могут быть легче различимы на графике DET.
- Поскольку доля ложноотрицательных результатов является «обратной» доле истинно-положительных, идеальная точка для кривых DET находится в начале координат (в отличие от левого верхнего угла для ROC-кривых).
Применение и ограничения
Кривые DET интуитивно понятны, поэтому позволяют быстро оценить качество работы классификатора. Кроме того, их можно использовать для анализа порогов и выбора рабочей точки. Это особенно полезно, если необходимо сравнить типы ошибок.
Однако кривые DET не сводят свою метрику к одному числу. Поэтому для автоматизированной оценки или сравнения с другими задачами классификации лучше подходят такие метрики, как вычисляемая площадь под ROC-кривой.
Примеры
- См. пример сравнения ROC-кривых и кривых компромисса ошибок обнаружения (DET) в разделе Кривая компромисса ошибок обнаружения (DET).
Литература
Участники Википедии. Компромисс ошибок обнаружения. Википедия, свободная энциклопедия. 4 сентября 2017 г., 23:33 UTC. Доступно по адресу: https://en.wikipedia.org/w/index.php?title=Detection_error_tradeoff&oldid=798982054. Дата обращения: 19 февраля 2018 г.
A. Martin, G. Doddington, T. Kamm, M. Ordowski и M. Przybocki, Кривая DET при оценке качества обнаружения, NIST, 1997.
3.4.4.17. Функция потерь 0–1
Функция zero_one_loss вычисляет сумму или среднее значение функции потерь классификации 0–1 (\(L_{0-1}\)) по \(n_{\text{samples}}\) образцам. По умолчанию функция нормализует результат по количеству образцов. Чтобы получить сумму \(L_{0-1}\), задайте normalize равным False.
В многометочной классификации функция zero_one_loss присваивает подмножеству значение 1, если его метки точно совпадают с предсказаниями, и значение 0, если имеются ошибки. По умолчанию функция возвращает долю подмножеств с несовершенными предсказаниями. Чтобы получить количество таких подмножеств, задайте normalize равным False.
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-го образца, а \(y_i\) — соответствующее истинное значение, то функция потерь 0–1 \(L_{0-1}\) определяется следующим образом:
где \(1(x)\) — индикаторная функция. Функцию потерь 0–1 также можно вычислить как \(\text{zero-one loss} = 1 - \text{accuracy}\).
>>> from sklearn.metrics import zero_one_loss >>> y_pred = [1, 2, 3, 4] >>> y_true = [2, 2, 3, 4] >>> zero_one_loss(y_true, y_pred) 0.25 >>> zero_one_loss(y_true, y_pred, normalize=False) 1.0
В многометочном случае с бинарными индикаторами меток, если в первом наборе меток [0,1] допущена ошибка:
>>> zero_one_loss(np.array([[0, 1], [1, 1]]), np.ones((2, 2))) 0.5 >>> zero_one_loss(np.array([[0, 1], [1, 1]]), np.ones((2, 2)), normalize=False) 1.0
Примеры
- Пример использования функции потерь 0–1 для рекурсивного исключения признаков с перекрёстной проверкой см. в разделе Рекурсивное исключение признаков с перекрёстной проверкой.
3.4.4.18. Потеря по оценке Брайера
Функция brier_score_loss вычисляет оценку Брайера для вероятностных прогнозов в бинарной и многоклассовой классификации и эквивалентна среднеквадратичной ошибке. Цитата из Википедии:
«Оценка Брайера — это строго правильное правило оценки, измеряющее точность вероятностных прогнозов. […] Она применима к задачам, в которых прогнозы должны назначать вероятности набору взаимоисключающих дискретных исходов или классов».
Пусть истинные метки для набора из \(N\) точек данных закодированы в виде бинарной индикаторной матрицы 1-of-K \(Y\), то есть \(y_{i,k} = 1\), если образец \(i\) имеет метку \(k\) из набора, состоящего из \(K\) меток. Пусть \(\hat{P}\) — матрица оценок вероятностей с элементами \(\hat{p}_{i,k} \approx \operatorname{Pr}(y_{i,k} = 1)\). Согласно исходному определению [Brier1950], оценка Брайера задаётся формулой:
Оценка Брайера лежит в интервале \([0, 2]\); чем меньше её значение, тем лучше оценки вероятностей (меньше среднеквадратичное отклонение). Оценка Брайера — строго правильное правило оценки, то есть наилучшая оценка достигается только тогда, когда оценённые вероятности совпадают с истинными.
Обратите внимание, что в бинарном случае оценку Брайера обычно делят на два, и она принимает значения в интервале \([0,1]\). Для бинарных целевых значений \(y_i \in \{0, 1\}\) и оценок вероятности \(\hat{p}_i \approx \operatorname{Pr}(y_i = 1)\) для положительного класса оценка Брайера равна:
Функция brier_score_loss вычисляет оценку Брайера по истинным меткам и предсказанным вероятностям, возвращаемым методом predict_proba оценщика. Параметр scale_by_half определяет, какое из двух приведённых выше определений использовать.
>>> import numpy as np >>> from sklearn.metrics import brier_score_loss >>> y_true = np.array([0, 1, 1, 0]) >>> y_true_categorical = np.array(["spam", "ham", "ham", "spam"]) >>> y_prob = np.array([0.1, 0.9, 0.8, 0.4]) >>> brier_score_loss(y_true, y_prob) 0.055 >>> brier_score_loss(y_true, 1 - y_prob, pos_label=0) 0.055 >>> brier_score_loss(y_true_categorical, y_prob, pos_label="ham") 0.055 >>> brier_score_loss( ... ["eggs", "ham", "spam"], ... [[0.8, 0.1, 0.1], [0.2, 0.7, 0.1], [0.2, 0.2, 0.6]], ... labels=["eggs", "ham", "spam"], ... ) 0.146
Примечание
Как строго правильное правило оценки вероятностных прогнозов, оценка Брайера одновременно оценивает калибровку (надёжность) и дискриминирующую способность (разрешение) модели, а также случайность данных (неопределённость). Это следует из известного разложения оценки Брайера, предложенного Мёрфи [Murphy1973]. Поскольку неясно, какой член разложения преобладает, эта оценка мало пригодна для самостоятельной оценки калибровки (если не вычислить каждый член разложения). Например, меньшая потеря по оценке Брайера не обязательно означает, что модель лучше откалибрована: она может быть откалибрована хуже, но обладать значительно большей дискриминирующей способностью, например за счёт использования гораздо большего числа признаков.
Примеры
- Пример использования потери по оценке Брайера для калибровки вероятностей классификаторов см. в разделе Калибровка вероятностей классификаторов.
Литература
G. Brier (1950). «Verification of forecasts expressed in terms of probability». Monthly Weather Review 78(1), 1-3
Allan H. Murphy (1973). «A New Vector Partition of the Probability Score» Journal of Applied Meteorology and Climatology, 12(4), 595-600
3.4.4.19. Отношения правдоподобия классов
Функция class_likelihood_ratios вычисляет положительное и отрицательное отношения правдоподобия \(LR_\pm\) для бинарных классов. Их можно интерпретировать как отношение шансов после теста к шансам до теста, как описано ниже. Поэтому эта метрика не зависит от распространённости классов (числа образцов положительного класса, делённого на общее число образцов), и её можно переносить между популяциями независимо от возможного дисбаланса классов.
Таким образом, метрики \(LR_\pm\) очень полезны в ситуациях, когда доступные для обучения и оценки классификатора данные представляют собой исследуемую популяцию с почти сбалансированными классами, например в исследовании «случай — контроль», а целевое применение, то есть генеральная популяция, характеризуется очень низкой распространённостью.
Положительное отношение правдоподобия \(LR_+\) — это вероятность того, что классификатор правильно предскажет принадлежность образца к положительному классу, делённая на вероятность предсказания положительного класса для образца, принадлежащего к отрицательному классу:
Здесь обозначения относятся к предсказанной (\(P\)) или истинной (\(T\)) метке, а знаки \(+\) и \(-\) обозначают соответственно положительный и отрицательный классы; например, \(P+\) означает «предсказан положительный класс».
Аналогично, отрицательное отношение правдоподобия \(LR_-\) — это вероятность того, что образец положительного класса будет классифицирован как принадлежащий к отрицательному классу, делённая на вероятность правильной классификации образца отрицательного класса:
Для классификаторов, работающих лучше случайного угадывания, значение \(LR_+\) больше 1; чем оно выше, тем лучше. Значение \(LR_-\) находится в диапазоне от 0 до 1; чем оно ниже, тем лучше. Значения \(LR_\pm\approx 1\) соответствуют случайному угадыванию.
Обратите внимание, что вероятности отличаются от количеств: например, \(\operatorname{PR}(P+|T+)\) не равно числу истинно положительных результатов tp (формулы см. на странице Википедии).
Примеры
Интерпретация при различной распространённости
Оба отношения правдоподобия классов можно интерпретировать через отношение шансов (до и после теста):
В общем случае шансы связаны с вероятностями следующим образом:
или, что эквивалентно,
Для данной популяции вероятность до теста определяется распространённостью. Преобразовав шансы в вероятности, отношения правдоподобия можно перевести в вероятность действительной принадлежности к каждому из классов до и после предсказания классификатора:
Математические особенности
Положительное отношение правдоподобия (LR+) не определено при \(fp=0\), то есть когда классификатор не ошибочно классифицирует отрицательные метки как положительные. Это условие может указывать на безошибочное определение всех отрицательных случаев или, если также отсутствуют истинно положительные прогнозы (\(tp=0\)), на то, что классификатор вообще не предсказывает положительный класс. В первом случае LR+ можно интерпретировать как np.inf, во втором (например, при сильном дисбалансе данных) — как np.nan.
Отрицательное отношение правдоподобия (LR-) не определено при \(tn=0\). Такое расхождение некорректно, поскольку \(LR_- > 1.0\) означало бы увеличение шансов принадлежности образца к положительному классу после его классификации как отрицательного, как если бы сама классификация вызывала положительное состояние. Сюда входит случай, когда DummyClassifier всегда предсказывает положительный класс (то есть при \(tn=fn=0\)).
Оба отношения правдоподобия классов (LR+ and LR-) не определены при \(tp=fn=0\), то есть когда в тестовом наборе нет образцов положительного класса. Такое может произойти при перекрёстной проверке сильно несбалансированных данных и также приводит к делению на ноль.
Если происходит деление на ноль и raise_warning задано как True (по умолчанию), функция class_likelihood_ratios вызывает UndefinedMetricWarning и по умолчанию возвращает np.nan, чтобы избежать искажения результатов при усреднении по фолдам перекрёстной проверки. Пользователи могут задать возвращаемые значения при делении на ноль с помощью параметра replace_undefined_by.
Подробный пример работы функции class_likelihood_ratios приведён ниже.
Литература
- Статья в Википедии об отношениях правдоподобия в диагностическом тестировании
- Brenner, H., & Gefeller, O. (1997). Variation of sensitivity, specificity, likelihood ratios and predictive values with disease prevalence. Statistics in medicine, 16(9), 981-991.
3.4.4.20. Оценка D² для классификации
Оценка D² вычисляет долю объяснённого девианса. Это обобщение R², в котором квадрат ошибки обобщается и заменяется выбранным девиансом классификации \(\text{dev}(y, \hat{y})\) (например, log loss или оценкой Брайера). D² представляет собой разновидность оценки качества модели. Она вычисляется следующим образом:
Здесь \(y_{\text{null}}\) — оптимальное предсказание модели только со свободным членом (например, доля y_true каждого класса для log loss и оценки Брайера).
Как и для R², наилучшее возможное значение равно 1.0; оценка может быть отрицательной (поскольку модель может быть сколь угодно хуже). Постоянная модель, всегда предсказывающая \(y_{\text{null}}\) и игнорирующая входные признаки, получит оценку D², равную 0.0.
Оценка D² по log loss
Функция d2_log_loss_score реализует частный случай D² с log loss, см. раздел Log loss, то есть:
Ниже приведены примеры использования функции d2_log_loss_score:
>>> from sklearn.metrics import d2_log_loss_score >>> y_true = [1, 1, 2, 3] >>> y_proba = [ ... [0.5, 0.25, 0.25], ... [0.5, 0.25, 0.25], ... [0.5, 0.25, 0.25], ... [0.5, 0.25, 0.25], ... ] >>> d2_log_loss_score(y_true, y_proba) 0.0 >>> y_true = [1, 2, 3] >>> y_proba = [ ... [0.98, 0.01, 0.01], ... [0.01, 0.98, 0.01], ... [0.01, 0.01, 0.98], ... ] >>> d2_log_loss_score(y_true, y_proba) 0.981 >>> y_true = [1, 2, 3] >>> y_proba = [ ... [0.1, 0.6, 0.3], ... [0.1, 0.6, 0.3], ... [0.4, 0.5, 0.1], ... ] >>> d2_log_loss_score(y_true, y_proba) -0.552
Оценка D² по оценке Брайера
Функция d2_brier_score реализует частный случай D² с оценкой Брайера, см. раздел Потеря по оценке Брайера, то есть:
Эту оценку также называют оценкой качества по Брайеру (BSS) и масштабированной оценкой Брайера.
Ниже приведены примеры использования функции d2_brier_score:
>>> from sklearn.metrics import d2_brier_score >>> y_true = [1, 1, 2, 3] >>> y_pred = [ ... [0.5, 0.25, 0.25], ... [0.5, 0.25, 0.25], ... [0.5, 0.25, 0.25], ... [0.5, 0.25, 0.25], ... ] >>> d2_brier_score(y_true, y_pred) 0.0 >>> y_true = [1, 2, 3] >>> y_pred = [ ... [0.98, 0.01, 0.01], ... [0.01, 0.98, 0.01], ... [0.01, 0.01, 0.98], ... ] >>> d2_brier_score(y_true, y_pred) 0.9991 >>> y_true = [1, 2, 3] >>> y_pred = [ ... [0.1, 0.6, 0.3], ... [0.1, 0.6, 0.3], ... [0.4, 0.5, 0.1], ... ] >>> d2_brier_score(y_true, y_pred) -0.370...
3.4.5. Многометочные метрики ранжирования
При обучении с несколькими метками каждому образцу может соответствовать любое число истинных меток. Цель состоит в том, чтобы присваивать истинным меткам высокие оценки и более высокие ранги.
3.4.5.1. Ошибка покрытия
Функция coverage_error вычисляет среднее число меток, которые необходимо включить в итоговое предсказание, чтобы предсказать все истинные метки. Эта метрика полезна, если нужно узнать, сколько меток с наивысшими оценками в среднем следует предсказать, чтобы не пропустить ни одной истинной метки. Поэтому наилучшее значение этой метрики равно среднему числу истинных меток.
Примечание
Оценка в нашей реализации на 1 больше, чем в работе Tsoumakas et al., 2010. Это расширение позволяет обрабатывать вырожденный случай, когда у экземпляра нет истинных меток.
Формально, для бинарной индикаторной матрицы истинных меток \(y \in \left\{0, 1\right\}^{n_\text{samples} \times n_\text{labels}}\) и оценки, связанной с каждой меткой, \(\hat{f} \in \mathbb{R}^{n_\text{samples} \times n_\text{labels}}\), покрытие определяется как
где \(\text{rank}_{ij} = \left|\left\{k: \hat{f}_{ik} \geq \hat{f}_{ij} \right\}\right|\). Согласно определению ранга, равные значения в y_scores разрешаются присвоением максимального ранга, который был бы назначен всем равным значениям.
Ниже приведён небольшой пример использования этой функции:
>>> import numpy as np >>> from sklearn.metrics import coverage_error >>> y_true = np.array([[1, 0, 0], [0, 0, 1]]) >>> y_score = np.array([[0.75, 0.5, 1], [1, 0.2, 0.1]]) >>> coverage_error(y_true, y_score) 2.5
3.4.5.2. Средняя точность ранжирования меток
Функция label_ranking_average_precision_score реализует среднюю точность ранжирования меток (LRAP). Эта метрика связана с функцией average_precision_score, но основана на понятии ранжирования меток, а не на точности и полноте.
Средняя точность ранжирования меток (LRAP) усредняет по образцам ответ на следующий вопрос: для каждой истинной метки какая доля меток с более высоким рангом также является истинной? Эта оценка качества будет выше, если удаётся присвоить более высокие ранги меткам, связанным с каждым образцом. Полученная оценка всегда строго больше 0, а её наилучшее значение равно 1. Если для каждого образца существует ровно одна релевантная метка, средняя точность ранжирования меток эквивалентна среднему обратному рангу.
Формально, для бинарной индикаторной матрицы истинных меток \(y \in \left\{0, 1\right\}^{n_\text{samples} \times n_\text{labels}}\) и оценки, связанной с каждой меткой, \(\hat{f} \in \mathbb{R}^{n_\text{samples} \times n_\text{labels}}\), средняя точность определяется как
где \(\mathcal{L}_{ij} = \left\{k: y_{ik} = 1, \hat{f}_{ik} \geq \hat{f}_{ij} \right\}\), \(\text{rank}_{ij} = \left|\left\{k: \hat{f}_{ik} \geq \hat{f}_{ij} \right\}\right|\), \(|\cdot|\) вычисляет мощность множества (то есть число элементов в множестве), а \(||\cdot||_0\) — это «норма» \(\ell_0\) (она вычисляет число ненулевых элементов вектора).
Ниже приведён небольшой пример использования этой функции:
>>> import numpy as np >>> from sklearn.metrics import label_ranking_average_precision_score >>> y_true = np.array([[1, 0, 0], [0, 0, 1]]) >>> y_score = np.array([[0.75, 0.5, 1], [1, 0.2, 0.1]]) >>> label_ranking_average_precision_score(y_true, y_score) 0.416
3.4.5.3. Потеря ранжирования
Функция label_ranking_loss вычисляет потерю ранжирования — усреднённое по образцам число неправильно упорядоченных пар меток, то есть случаев, когда истинные метки имеют более низкую оценку, чем ложные. Результат взвешивается обратным числом упорядоченных пар ложных и истинных меток. Минимально достижимая потеря ранжирования равна нулю.
Формально, для бинарной индикаторной матрицы истинных меток \(y \in \left\{0, 1\right\}^{n_\text{samples} \times n_\text{labels}}\) и оценки, связанной с каждой меткой, \(\hat{f} \in \mathbb{R}^{n_\text{samples} \times n_\text{labels}}\), потеря ранжирования определяется как
где \(|\cdot|\) вычисляет мощность множества (то есть число элементов в множестве), а \(||\cdot||_0\) — это «норма» \(\ell_0\) (она вычисляет число ненулевых элементов вектора).
Ниже приведён небольшой пример использования этой функции:
>>> import numpy as np >>> from sklearn.metrics import label_ranking_loss >>> y_true = np.array([[1, 0, 0], [0, 0, 1]]) >>> y_score = np.array([[0.75, 0.5, 1], [1, 0.2, 0.1]]) >>> label_ranking_loss(y_true, y_score) 0.75 >>> # With the following prediction, we have perfect and minimal loss >>> y_score = np.array([[1.0, 0.1, 0.2], [0.1, 0.2, 0.9]]) >>> label_ranking_loss(y_true, y_score) 0.0
Литература
- Tsoumakas, G., Katakis, I., & Vlahavas, I. (2010). Mining multi-label data. In Data mining and knowledge discovery handbook (pp. 667-685). Springer US.
3.4.5.4. Нормализованный дисконтированный кумулятивный выигрыш
Дисконтированный кумулятивный выигрыш (DCG) и нормализованный дисконтированный кумулятивный выигрыш (NDCG) — это метрики ранжирования, реализованные в функциях dcg_score и ndcg_score; они сравнивают предсказанный порядок с истинными оценками, например с релевантностью ответов на запрос.
Со страницы Википедии о дисконтированном кумулятивном выигрыше:
«Дисконтированный кумулятивный выигрыш (DCG) — это мера качества ранжирования. В информационном поиске его часто используют для оценки эффективности алгоритмов веб-поиска и связанных приложений. Используя градуированную шкалу релевантности документов в результатах поисковой системы, DCG измеряет полезность, или выигрыш, документа в зависимости от его позиции в списке результатов. Выигрыш накапливается от начала списка к его концу, при этом выигрыш каждого результата уменьшается для более низких позиций».
DCG располагает истинные целевые значения (например, релевантность ответов на запрос) в предсказанном порядке, затем умножает их на логарифмический коэффициент убывания и суммирует результат. Суммирование можно ограничить первыми \(K\) результатами; в этом случае метрика называется DCG@K. NDCG, или NDCG@K, — это DCG, делённый на значение DCG для идеального предсказания, поэтому метрика всегда находится в диапазоне от 0 до 1. Обычно предпочтение отдают NDCG.
В отличие от потери ранжирования, NDCG может учитывать оценки релевантности, а не только истинный порядок. Поэтому, если истинные данные содержат только порядок, предпочтительнее использовать потерю ранжирования; если истинные данные содержат фактические оценки полезности (например, 0 — нерелевантно, 1 — релевантно, 2 — очень релевантно), можно использовать NDCG.
Для одного образца пусть \(y \in \mathbb{R}^{M}\) — вектор непрерывных истинных значений для каждой целевой переменной, где \(M\) — число выходов, а \(\hat{y}\) — предсказание, задающее функцию ранжирования \(f\). Тогда оценка DCG равна
а оценка NDCG — это оценка DCG, делённая на значение DCG, полученное для \(y\).
Литература
- Статья в Википедии о дисконтированном кумулятивном выигрыше
- Jarvelin, K., & Kekalainen, J. (2002). Cumulated gain-based evaluation of IR techniques. ACM Transactions on Information Systems (TOIS), 20(4), 422-446.
- Wang, Y., Wang, L., Li, Y., He, D., Chen, W., & Liu, T. Y. (2013, May). A theoretical analysis of NDCG ranking measures. In Proceedings of the 26th Annual Conference on Learning Theory (COLT 2013)
- McSherry, F., & Najork, M. (2008, March). Computing information retrieval performance measures efficiently in the presence of tied scores. In European conference on information retrieval (pp. 414-421). Springer, Berlin, Heidelberg.
3.4.6. Метрики регрессии
Модуль sklearn.metrics реализует несколько функций потерь, оценок и полезности для измерения качества регрессии. Некоторые из них были расширены для поддержки случая с несколькими выходами: mean_squared_error, mean_absolute_error, r2_score, explained_variance_score, mean_pinball_loss, d2_pinball_score и d2_absolute_error_score.
Эти функции имеют именованный аргумент multioutput, который задаёт способ усреднения оценок или потерь для каждой отдельной целевой переменной. По умолчанию используется значение 'uniform_average', задающее среднее с равными весами по выходам. Если передан ndarray формы (n_outputs,), его элементы интерпретируются как веса, и возвращается соответствующее взвешенное среднее. Если multioutput равен 'raw_values', все неизменённые индивидуальные оценки или потери будут возвращены в массиве формы (n_outputs,).
Функции r2_score и explained_variance_score принимают дополнительное значение 'variance_weighted' для параметра multioutput. При этом каждая индивидуальная оценка взвешивается по дисперсии соответствующей целевой переменной. Эта настройка характеризует общую объяснённую нескорректированную дисперсию. Если целевые переменные имеют разный масштаб, такая оценка придаёт большее значение переменным с большей дисперсией.
3.4.6.1. Оценка R², коэффициент детерминации
Функция r2_score вычисляет коэффициент детерминации, обычно обозначаемый как \(R^2\).
Он представляет собой долю дисперсии (y), объяснённую независимыми переменными модели. Эта величина показывает качество аппроксимации, а значит, и то, насколько хорошо модель, вероятно, будет предсказывать неизвестные выборки, исходя из доли объяснённой дисперсии.
Поскольку дисперсия зависит от набора данных, значения \(R^2\) нельзя осмысленно сравнивать для разных наборов данных. Наилучшая возможная оценка равна 1.0; она может быть отрицательной (поскольку модель может работать сколь угодно хуже). Постоянная модель, всегда предсказывающая ожидаемое (среднее) значение y и игнорирующая входные признаки, получит оценку \(R^2\), равную 0.0.
Примечание: если среднее значение остатков предсказания равно нулю, оценка \(R^2\) совпадает с оценкой объяснённой дисперсии.
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-й выборки, а \(y_i\) — соответствующее истинное значение для всего набора из \(n\) выборок, то оценка \(R^2\) определяется следующим образом:
где \(\bar{y} = \frac{1}{n} \sum_{i=1}^{n} y_i\) и \(\sum_{i=1}^{n} (y_i - \hat{y}_i)^2 = \sum_{i=1}^{n} \epsilon_i^2\).
Обратите внимание, что r2_score вычисляет нескорректированное значение \(R^2\), не поправляя смещение выборочной дисперсии y.
В частном случае, когда истинная целевая переменная является константой, оценка \(R^2\) не является конечной: она равна либо NaN (идеальные предсказания), либо -Inf (неидеальные предсказания). Такие бесконечные оценки могут помешать корректной оптимизации модели, например при перекрёстной проверке с поиском по сетке. Поэтому по умолчанию функция r2_score заменяет их на 1.0 (идеальные предсказания) или 0.0 (неидеальные предсказания). Если для force_finite задано значение False, функция возвращается к исходному определению \(R^2\).
Ниже приведён небольшой пример использования функции r2_score:
>>> from sklearn.metrics import r2_score >>> y_true = [3, -0.5, 2, 7] >>> y_pred = [2.5, 0.0, 2, 8] >>> r2_score(y_true, y_pred) 0.948 >>> y_true = [[0.5, 1], [-1, 1], [7, -6]] >>> y_pred = [[0, 2], [-1, 2], [8, -5]] >>> r2_score(y_true, y_pred, multioutput='variance_weighted') 0.938 >>> y_true = [[0.5, 1], [-1, 1], [7, -6]] >>> y_pred = [[0, 2], [-1, 2], [8, -5]] >>> r2_score(y_true, y_pred, multioutput='uniform_average') 0.936 >>> r2_score(y_true, y_pred, multioutput='raw_values') array([0.965, 0.908]) >>> r2_score(y_true, y_pred, multioutput=[0.3, 0.7]) 0.925 >>> y_true = [-2, -2, -2] >>> y_pred = [-2, -2, -2] >>> r2_score(y_true, y_pred) 1.0 >>> r2_score(y_true, y_pred, force_finite=False) nan >>> y_true = [-2, -2, -2] >>> y_pred = [-2, -2, -2 + 1e-8] >>> r2_score(y_true, y_pred) 0.0 >>> r2_score(y_true, y_pred, force_finite=False) -inf
Примеры
- Пример использования оценки R² для оценки Lasso и Elastic Net на разреженных сигналах см. в разделе Модели на основе L1-нормы для разреженных сигналов.
3.4.6.2. Средняя абсолютная ошибка
Функция mean_absolute_error вычисляет среднюю абсолютную ошибку — метрику риска, соответствующую математическому ожиданию потерь в виде абсолютной ошибки или потерь по норме \(l1\).
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-й выборки, а \(y_i\) — соответствующее истинное значение, то средняя абсолютная ошибка (MAE), рассчитанная по \(n_{\text{samples}}\) выборкам, определяется следующим образом:
Ниже приведён небольшой пример использования функции mean_absolute_error:
>>> from sklearn.metrics import mean_absolute_error >>> y_true = [3, -0.5, 2, 7] >>> y_pred = [2.5, 0.0, 2, 8] >>> mean_absolute_error(y_true, y_pred) 0.5 >>> y_true = [[0.5, 1], [-1, 1], [7, -6]] >>> y_pred = [[0, 2], [-1, 2], [8, -5]] >>> mean_absolute_error(y_true, y_pred) 0.75 >>> mean_absolute_error(y_true, y_pred, multioutput='raw_values') array([0.5, 1. ]) >>> mean_absolute_error(y_true, y_pred, multioutput=[0.3, 0.7]) 0.85
3.4.6.3. Среднеквадратичная ошибка
Функция mean_squared_error вычисляет среднеквадратичную ошибку — метрику риска, соответствующую математическому ожиданию квадрата ошибки или потерь.
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-й выборки, а \(y_i\) — соответствующее истинное значение, то среднеквадратичная ошибка (MSE), рассчитанная по \(n_{\text{samples}}\) выборкам, определяется следующим образом:
Ниже приведён небольшой пример использования функции mean_squared_error:
>>> from sklearn.metrics import mean_squared_error >>> y_true = [3, -0.5, 2, 7] >>> y_pred = [2.5, 0.0, 2, 8] >>> mean_squared_error(y_true, y_pred) 0.375 >>> y_true = [[0.5, 1], [-1, 1], [7, -6]] >>> y_pred = [[0, 2], [-1, 2], [8, -5]] >>> mean_squared_error(y_true, y_pred) 0.7083
Примеры
- Пример использования среднеквадратичной ошибки для оценки регрессии с градиентным бустингом см. в разделе Регрессия с градиентным бустингом.
Извлечение квадратного корня из MSE даёт среднеквадратичную ошибку (RMSE) — ещё одну распространённую метрику, значение которой выражено в тех же единицах, что и целевая переменная. RMSE можно вычислить с помощью функции root_mean_squared_error.
3.4.6.4. Среднеквадратичная логарифмическая ошибка
Функция mean_squared_log_error вычисляет метрику риска, соответствующую математическому ожиданию квадрата логарифмической ошибки или потерь.
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-й выборки, а \(y_i\) — соответствующее истинное значение, то среднеквадратичная логарифмическая ошибка (MSLE), рассчитанная по \(n_{\text{samples}}\) выборкам, определяется следующим образом:
Здесь \(\log_e (x)\) означает натуральный логарифм \(x\). Эту метрику лучше всего применять к целевым переменным с экспоненциальным ростом, например к численности населения или средним продажам товара за несколько лет. Обратите внимание, что эта метрика сильнее штрафует заниженные оценки, чем завышенные.
Ниже приведён небольшой пример использования функции mean_squared_log_error:
>>> from sklearn.metrics import mean_squared_log_error >>> y_true = [3, 5, 2.5, 7] >>> y_pred = [2.5, 5, 4, 8] >>> mean_squared_log_error(y_true, y_pred) 0.0397 >>> y_true = [[0.5, 1], [1, 2], [7, 6]] >>> y_pred = [[0.5, 2], [1, 2.5], [8, 8]] >>> mean_squared_log_error(y_true, y_pred) 0.044
Среднеквадратичная логарифмическая ошибка (RMSLE) доступна через функцию root_mean_squared_log_error.
3.4.6.5. Средняя абсолютная процентная ошибка
mean_absolute_percentage_error (MAPE), также известная как среднее абсолютное процентное отклонение (MAPD), — это метрика оценки задач регрессии. Она чувствительна к относительным ошибкам. Например, её значение не меняется при глобальном масштабировании целевой переменной.
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-й выборки, а \(y_i\) — соответствующее истинное значение, то средняя абсолютная процентная ошибка (MAPE), рассчитанная по \(n_{\text{samples}}\) выборкам, определяется следующим образом:
где \(\epsilon\) — произвольное малое, но строго положительное число, используемое для предотвращения неопределённых результатов при нулевом y.
Функция mean_absolute_percentage_error поддерживает несколько выходов.
Ниже приведён небольшой пример использования функции mean_absolute_percentage_error:
>>> from sklearn.metrics import mean_absolute_percentage_error >>> y_true = [1, 10, 1e6] >>> y_pred = [0.9, 15, 1.2e6] >>> mean_absolute_percentage_error(y_true, y_pred) 0.2666
В приведённом выше примере, если бы мы использовали mean_absolute_error, малые по величине значения были бы проигнорированы, а учитывалась бы только ошибка предсказания значения с наибольшей величиной. MAPE решает эту проблему, поскольку вычисляет относительную процентную ошибку по отношению к фактическому выходному значению.
Примечание
Используемая здесь формула MAPE не соответствует распространённому определению «процента»: процент в диапазоне [0, 100] преобразуется в относительное значение в диапазоне [0, 1] делением на 100. Таким образом, ошибка в 200% соответствует относительной ошибке 2. Это сделано для того, чтобы диапазон значений был более согласован с другими метриками ошибок в scikit-learn, например с accuracy_score.
Чтобы получить среднюю абсолютную процентную ошибку согласно формуле Википедии, умножьте вычисленное здесь значение mean_absolute_percentage_error на 100.
3.4.6.6. Медианная абсолютная ошибка
Функция median_absolute_error особенно интересна тем, что она устойчива к выбросам. Потери вычисляются как медиана всех абсолютных разностей между целевыми и предсказанными значениями.
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-й выборки, а \(y_i\) — соответствующее истинное значение, то медианная абсолютная ошибка (MedAE), рассчитанная по \(n_{\text{samples}}\) выборкам, определяется следующим образом:
Функция median_absolute_error не поддерживает несколько выходов.
Ниже приведён небольшой пример использования функции median_absolute_error:
>>> from sklearn.metrics import median_absolute_error >>> y_true = [3, -0.5, 2, 7] >>> y_pred = [2.5, 0.0, 2, 8] >>> median_absolute_error(y_true, y_pred) 0.5
3.4.6.7. Максимальная ошибка
Функция max_error вычисляет максимальную ошибку остатка — метрику, отражающую наихудшую ошибку между предсказанным и истинным значениями. В идеально подогнанной модели регрессии с одним выходом max_error на обучающем наборе будет равна 0. Хотя в реальном мире такое маловероятно, эта метрика показывает величину ошибки модели при обучении.
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-й выборки, а \(y_i\) — соответствующее истинное значение, то максимальная ошибка определяется следующим образом:
Ниже приведён небольшой пример использования функции max_error:
>>> from sklearn.metrics import max_error >>> y_true = [3, 2, 7, 1] >>> y_pred = [9, 2, 7, 1] >>> max_error(y_true, y_pred) 6.0
Функция max_error не поддерживает несколько выходов.
3.4.6.8. Оценка объяснённой дисперсии
Функция explained_variance_score вычисляет оценку объяснённой дисперсии для регрессии.
Если \(\hat{y}\) — оценённое целевое значение, \(y\) — соответствующее (правильное) целевое значение, а \(Var\) — дисперсия, равная квадрату стандартного отклонения, то объяснённая дисперсия оценивается следующим образом:
Наилучшая возможная оценка равна 1.0; меньшие значения хуже.
В частном случае, когда истинная целевая переменная является константой, оценка объяснённой дисперсии не является конечной: она равна либо NaN (идеальные предсказания), либо -Inf (неидеальные предсказания). Такие бесконечные оценки могут помешать корректной оптимизации модели, например при перекрёстной проверке с поиском по сетке. Поэтому по умолчанию функция explained_variance_score заменяет их на 1.0 (идеальные предсказания) или 0.0 (неидеальные предсказания). Чтобы отключить это исправление и использовать исходную оценку объяснённой дисперсии, задайте параметру force_finite значение False.
Ниже приведён небольшой пример использования функции explained_variance_score:
>>> from sklearn.metrics import explained_variance_score >>> y_true = [3, -0.5, 2, 7] >>> y_pred = [2.5, 0.0, 2, 8] >>> explained_variance_score(y_true, y_pred) 0.957 >>> y_true = [[0.5, 1], [-1, 1], [7, -6]] >>> y_pred = [[0, 2], [-1, 2], [8, -5]] >>> explained_variance_score(y_true, y_pred, multioutput='raw_values') array([0.967, 1. ]) >>> explained_variance_score(y_true, y_pred, multioutput=[0.3, 0.7]) 0.990 >>> y_true = [-2, -2, -2] >>> y_pred = [-2, -2, -2] >>> explained_variance_score(y_true, y_pred) 1.0 >>> explained_variance_score(y_true, y_pred, force_finite=False) nan >>> y_true = [-2, -2, -2] >>> y_pred = [-2, -2, -2 + 1e-8] >>> explained_variance_score(y_true, y_pred) 0.0 >>> explained_variance_score(y_true, y_pred, force_finite=False) -inf
3.4.6.9. Средние девиансы Пуассона, Гамма-распределения и Твиди
Функция mean_tweedie_deviance вычисляет среднюю ошибку девианса Твиди с параметром power (\(p\)). Эта метрика позволяет оценивать ожидаемые значения целевых переменных регрессии.
Существуют следующие частные случаи:
- при
power=0она эквивалентнаmean_squared_error. - при
power=1она эквивалентнаmean_poisson_deviance. - при
power=2она эквивалентнаmean_gamma_deviance.
Если \(\hat{y}_i\) — предсказанное значение для \(i\)-й выборки, а \(y_i\) — соответствующее истинное значение, то средняя ошибка девианса Твиди (D) с параметром степени \(p\), рассчитанная по \(n_{\text{samples}}\) выборкам, определяется следующим образом:
Девианс Твиди — однородная функция степени 2-power. Поэтому для гамма-распределения, где power=2, одновременное масштабирование y_true и y_pred не влияет на девианс. Для распределения Пуассона при power=1 девианс масштабируется линейно, а для нормального распределения (power=0) — квадратично. В общем случае чем выше power, тем меньший вес придаётся большим отклонениям между истинными и предсказанными целевыми значениями.
Например, сравним два предсказания: 1.5 и 150, каждое из которых на 50% превышает соответствующее истинное значение.
Среднеквадратичная ошибка (power=0) очень чувствительна к разнице в предсказании для второй точки:
>>> from sklearn.metrics import mean_tweedie_deviance >>> mean_tweedie_deviance([1.0], [1.5], power=0) 0.25 >>> mean_tweedie_deviance([100.], [150.], power=0) 2500.0
Если увеличить power до 1:
>>> mean_tweedie_deviance([1.0], [1.5], power=1) 0.189 >>> mean_tweedie_deviance([100.], [150.], power=1) 18.9
разница между ошибками уменьшится. Наконец, задав power=2:
>>> mean_tweedie_deviance([1.0], [1.5], power=2) 0.144 >>> mean_tweedie_deviance([100.], [150.], power=2) 0.144
мы получим одинаковые ошибки. Таким образом, девианс при power=2 чувствителен только к относительным ошибкам.
3.4.6.10. Функция потерь «пинбол»
Функция mean_pinball_loss используется для оценки качества предсказаний моделей квантильной регрессии.
При значении параметра квантиля alpha, равном 0.5, значение функции потерь «пинбол» равно половине значения mean_absolute_error.
Ниже приведён небольшой пример использования функции mean_pinball_loss:
>>> from sklearn.metrics import mean_pinball_loss >>> y_true = [1, 2, 3] >>> mean_pinball_loss(y_true, [0, 2, 3], alpha=0.1) 0.033 >>> mean_pinball_loss(y_true, [1, 2, 4], alpha=0.1) 0.3 >>> mean_pinball_loss(y_true, [0, 2, 3], alpha=0.9) 0.3 >>> mean_pinball_loss(y_true, [1, 2, 4], alpha=0.9) 0.033 >>> mean_pinball_loss(y_true, y_true, alpha=0.1) 0.0 >>> mean_pinball_loss(y_true, y_true, alpha=0.9) 0.0
Можно создать объект средства оценки, указав конкретное значение alpha:
>>> from sklearn.metrics import make_scorer >>> mean_pinball_loss_95p = make_scorer(mean_pinball_loss, alpha=0.95)
Такое средство оценки можно использовать для оценки обобщающей способности квантильного регрессора с помощью перекрёстной проверки:
>>> from sklearn.datasets import make_regression >>> from sklearn.model_selection import cross_val_score >>> from sklearn.ensemble import GradientBoostingRegressor >>> >>> X, y = make_regression(n_samples=100, random_state=0) >>> estimator = GradientBoostingRegressor( ... loss="quantile", ... alpha=0.95, ... random_state=0, ... ) >>> cross_val_score(estimator, X, y, cv=5, scoring=mean_pinball_loss_95p) array([14.3, 9.8, 23.9, 9.4, 10.8])
Также можно создавать объекты средств оценки для подбора гиперпараметров. Знак функции потерь необходимо изменить, чтобы большее значение считалось лучшим, как описано в примере по ссылке ниже.
Примеры
- Пример использования функции потерь «пинбол» для оценки и настройки гиперпараметров моделей квантильной регрессии на данных с несимметричным шумом и выбросами см. в разделе Интервалы предсказания для регрессии с градиентным бустингом.
3.4.6.11. Оценка D²
Оценка D² вычисляет долю объяснённого девианса. Это обобщение R², в котором квадратичная ошибка обобщается и заменяется выбранным девиансом \(\text{dev}(y, \hat{y})\) (например, девиансом Тьюди, pinball loss или средней абсолютной ошибкой). D² — это разновидность показателя качества. Она рассчитывается следующим образом:
Здесь \(y_{\text{null}}\) — оптимальное предсказание модели только со свободным членом (например, среднее значение y_true для случая Тьюди, медиана для абсолютной ошибки и альфа-квантиль для pinball loss).
Как и R², оценка может достигать максимального значения 1.0, а также быть отрицательной (поскольку модель может работать сколь угодно хуже). Константная модель, которая всегда предсказывает \(y_{\text{null}}\) и игнорирует входные признаки, получит оценку D², равную 0.0.
Оценка D² Тьюди
Функция d2_tweedie_score реализует частный случай D², в котором \(\text{dev}(y, \hat{y})\) — девианс Тьюди; см. Средний девианс Пуассона, Гамма-распределения и Тьюди. Эта оценка также известна как D² Тьюди и связана с индексом отношения правдоподобия Макфаддена.
Аргумент power задаёт показатель степени Тьюди, как и для mean_tweedie_deviance. Обратите внимание, что для power=0 функция d2_tweedie_score эквивалентна r2_score (для одной целевой переменной).
Объект оценщика с заданным значением power можно создать следующим образом:
>>> from sklearn.metrics import d2_tweedie_score, make_scorer >>> d2_tweedie_score_15 = make_scorer(d2_tweedie_score, power=1.5)
Оценка D² на основе pinball loss
Функция d2_pinball_score реализует частный случай D² с функцией потерь pinball; см. Функция потерь pinball, то есть:
Аргумент alpha задаёт наклон функции потерь pinball, как и для mean_pinball_loss (Функция потерь pinball). Он определяет уровень квантиля alpha, при котором функция потерь pinball, а также D² достигают оптимального значения. Обратите внимание, что для alpha=0.5 (значение по умолчанию) функция d2_pinball_score эквивалентна d2_absolute_error_score.
Объект оценщика с заданным значением alpha можно создать следующим образом:
>>> from sklearn.metrics import d2_pinball_score, make_scorer >>> d2_pinball_score_08 = make_scorer(d2_pinball_score, alpha=0.8)
Оценка D² на основе абсолютной ошибки
Функция d2_absolute_error_score реализует частный случай для средней абсолютной ошибки:
Ниже приведены примеры использования функции d2_absolute_error_score:
>>> from sklearn.metrics import d2_absolute_error_score >>> y_true = [3, -0.5, 2, 7] >>> y_pred = [2.5, 0.0, 2, 8] >>> d2_absolute_error_score(y_true, y_pred) 0.764 >>> y_true = [1, 2, 3] >>> y_pred = [1, 2, 3] >>> d2_absolute_error_score(y_true, y_pred) 1.0 >>> y_true = [1, 2, 3] >>> y_pred = [2, 2, 2] >>> d2_absolute_error_score(y_true, y_pred) 0.0
3.4.6.12. Визуальная оценка регрессионных моделей
Для оценки качества регрессионных моделей scikit-learn предоставляет класс PredictionErrorDisplay. Он позволяет визуально исследовать ошибки предсказаний модели двумя способами.
На графике слева показаны фактические и предсказанные значения. Для регрессионной задачи без шума, в которой требуется предсказать условное математическое ожидание y, идеальная регрессионная модель располагала бы точки данных на диагонали, где предсказанные значения равны фактическим. Чем дальше точки от этой оптимальной линии, тем больше ошибка модели. В более реалистичном случае с неустранимым шумом, то есть когда признаки в X не позволяют объяснить все вариации y, наилучшая модель создаёт облако точек, плотно сгруппированных вокруг диагонали.
Обратите внимание, что сказанное выше верно только в том случае, если предсказанные значения являются математическим ожиданием y при заданном X. Обычно так бывает для регрессионных моделей, минимизирующих целевую функцию среднеквадратичной ошибки или, в более общем случае, средний девианс Тьюди при любом значении параметра «степени».
Если построить график предсказаний оценщика, который предсказывает квантиль y при заданном X, например QuantileRegressor или любой другой модели, минимизирующей функцию потерь pinball, ожидается, что доля точек окажется выше или ниже диагонали в зависимости от оцениваемого уровня квантиля.
В целом этот график легко интерпретировать, но он не даёт чёткого представления о том, как улучшить модель.
На графике справа показаны остатки (то есть разность между фактическими и предсказанными значениями) в зависимости от предсказанных значений.
С помощью этого графика проще визуально определить, имеют ли остатки гомоскедастичное или гетероскедастичное распределение.
В частности, если истинное распределение y|X — распределение Пуассона или Гамма-распределение, ожидается, что дисперсия остатков оптимальной модели будет увеличиваться вместе с предсказанным значением E[y|X] (линейно для распределения Пуассона или квадратично для Гамма-распределения).
При обучении линейной модели регрессии методом наименьших квадратов (см. LinearRegression и Ridge) этот график можно использовать для проверки выполнения некоторых предположений модели: в частности, остатки должны быть некоррелированными, их математическое ожидание должно быть равно нулю, а дисперсия — постоянной (гомоскедастичность).
Если это не так, и особенно если график остатков имеет форму банана, это указывает на возможную неправильную спецификацию модели. В таком случае может быть полезно нелинейное конструирование признаков или переход к нелинейной регрессионной модели.
Пример оценки модели с помощью этой визуализации приведён ниже.
Примеры
- См. Влияние преобразования целевых переменных в регрессионной модели: в этом примере показано, как использовать
PredictionErrorDisplayдля визуализации улучшения качества предсказаний регрессионной модели, достигнутого путём преобразования целевой переменной перед обучением.
3.4.7. Метрики кластеризации
Модуль sklearn.metrics реализует несколько функций потерь, оценок и вспомогательных функций для измерения качества кластеризации. Дополнительные сведения см. в разделе Оценка качества кластеризации, посвящённом кластеризации экземпляров, и в разделе Оценка бикластеризации, посвящённом бикластеризации.
3.4.8. Наивные оценщики
При обучении с учителем полезно для быстрой проверки сравнить оценщик с простыми эмпирическими правилами. DummyClassifier реализует несколько таких простых стратегий классификации:
-
stratifiedгенерирует случайные предсказания, учитывая распределение классов в обучающей выборке. -
most_frequentвсегда предсказывает метку, наиболее часто встречающуюся в обучающей выборке. -
priorвсегда предсказывает класс с наибольшей априорной вероятностью (какmost_frequent), аpredict_probaвозвращает априорные вероятности классов. -
uniformгенерирует равномерно распределённые случайные предсказания. -
-
constantвсегда предсказывает постоянную метку, заданную пользователем. -
Этот метод особенно полезен для оценки F1, когда положительный класс является миноритарным.
-
Обратите внимание: при использовании всех этих стратегий метод predict полностью игнорирует входные данные!
Чтобы продемонстрировать работу DummyClassifier, сначала создадим несбалансированный набор данных:
>>> from sklearn.datasets import load_iris >>> from sklearn.model_selection import train_test_split >>> X, y = load_iris(return_X_y=True) >>> y[y != 1] = -1 >>> X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
Затем сравним точность SVC и most_frequent:
>>> from sklearn.dummy import DummyClassifier >>> from sklearn.svm import SVC >>> clf = SVC(kernel='linear', C=1).fit(X_train, y_train) >>> clf.score(X_test, y_test) 0.63 >>> clf = DummyClassifier(strategy='most_frequent', random_state=0) >>> clf.fit(X_train, y_train) DummyClassifier(random_state=0, strategy='most_frequent') >>> clf.score(X_test, y_test) 0.579
Как видим, SVC работает ненамного лучше наивного классификатора. Теперь изменим ядро:
>>> clf = SVC(kernel='rbf', C=1).fit(X_train, y_train) >>> clf.score(X_test, y_test) 0.94
Как видим, точность выросла почти до 100%. Для более точной оценки точности рекомендуется использовать стратегию перекрёстной проверки, если она не требует слишком много вычислительных ресурсов. Дополнительные сведения см. в разделе Перекрёстная проверка: оценка качества работы оценщика. Кроме того, если вы хотите оптимизировать параметры, настоятельно рекомендуется использовать подходящую методологию; подробности см. в разделе Настройка гиперпараметров оценщика.
В более общем случае, если точность классификатора лишь ненамного выше случайной, вероятно, что-то пошло не так: признаки неинформативны, гиперпараметр настроен неправильно, классификатор не справляется с дисбалансом классов и т. д.
DummyRegressor также реализует четыре простых эмпирических правила для регрессии:
-
meanвсегда предсказывает среднее значение целевых переменных обучающей выборки. -
medianвсегда предсказывает медиану целевых переменных обучающей выборки. -
quantileвсегда предсказывает заданный пользователем квантиль целевых переменных обучающей выборки. -
constantвсегда предсказывает постоянное значение, заданное пользователем.
Во всех этих стратегиях метод predict полностью игнорирует входные данные.
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/modules/model_evaluation.html