Аннотация: ROC/AUC очень важен как индекс оценки для машинного обучения, а также часто задаваемый вопрос на собеседованиях (будет задано 80%).
Эта статья опубликована в сообществе Huawei Cloud Community "Технические галантереи | Решить 80% проблем в интервью, реализовать AUC/ROC на основе MindSpore", оригинальный автор: Ли Цзяци.
ROC/AUC очень важен как метрика оценки машинного обучения, а также часто задаваемый вопрос на собеседованиях (будет задано 80%). На самом деле это не очень сложно понять, но многие друзья сталкивались с той же проблемой, а именно: каждый раз, когда я читаю книгу, я понимаю ее, но забываю, когда оглядываюсь назад, и часто легко понять ее. путать понятия. Некоторые друзья запомнили его перед собеседованием, но когда они нервничали, их мозг отключался, и они все забывали, что приводило к плохим ответам.
Я также столкнулся с подобными проблемами в предыдущем процессе собеседования Мой опыт собеседования таков: вообще говоря, если вы сталкиваетесь с вопросами с несколькими вариантами ответов в письменном тесте, вы в основном проверяете этот уровень, этот уровень или даете сценарий, чтобы позволить вам выбрать который из. В процессе интервью меня также много раз спрашивали, например, что такое AUC/ROC? Что представляют собой горизонтальная и вертикальная оси? Каковы преимущества? Зачем это использовать?
Помню, когда отвечал в первый раз, перепутал понятия точность, точность, полнота и т.д., и в конце получилась каша. После того, как я вернулся, я разобрал все соответствующие концепции от начала до конца, и последующие интервью были в основном очень хорошими. Теперь я хочу поделиться с вами своим пониманием и надеюсь, что после прочтения этой статьи я смогу хорошо вспомнить концепцию ROC/AUC.
Полное название ROC — Receiver Operating Characteristic, а его основным инструментом анализа является кривая, начерченная на двумерной плоскости — ROC-кривая. По оси абсцисс отложена доля ложноположительных результатов (FPR), а по оси ординат — доля истинных положительных результатов (TPR). Для классификатора мы можем получить пару точек TPR и FPR на основе его производительности на тестовой выборке. Таким образом, этот классификатор может быть сопоставлен с точкой на плоскости ROC. Настроив порог, используемый этим классификатором для классификации, мы можем получить кривую через (0, 0), (1, 1), которая является ROC-кривой этого классификатора. В общем случае эта кривая должна быть выше линии, соединяющей (0, 0) и (1, 1). Потому что кривая ROC, образованная связью между (0, 0) и (1, 1), фактически представляет собой случайный классификатор. Если, к сожалению, вы получаете классификатор ниже этой строки, интуитивное решение состоит в том, чтобы отменить все прогнозы, то есть: если классификатор выводит положительный класс, окончательный результат классификации является отрицательным классом, и наоборот, это положительный класс. . Тем не менее, кривая ROC интуитивно понятна и проста в использовании для представления производительности классификатора.
Однако люди всегда хотят иметь числовое значение, чтобы отметить качество классификатора. Так появилась Кривая Area Under roc Curve (AUC). Как следует из названия, значение AUC — это размер области под ROC-кривой. Как правило, значение AUC находится в диапазоне от 0,5 до 1,0, при этом большее значение AUC соответствует лучшей производительности. AUC (Area Under roc Curve) — это стандарт, используемый для измерения качества модели классификации.
Пример кривой ROC (задача двух классов):
Интерпретируйте некоторые концептуальные определения диаграммы ROC:
- Модель предсказывает True (True Positive, TP) как положительную положительную пробу;
- Ложноотрицательный (FN) прогнозируется моделью как отрицательный положительный образец;
- Ложноположительный результат (FP) предсказывается моделью как положительный отрицательный образец;
- True Negative (TN) — отрицательный образец, предсказанный моделью как отрицательный.
Чувствительность, специфичность, истинная частота, частота ложноположительных результатов
Прежде чем формально ввести ROC/AUC, нам нужно ввести два индикатора, и выбор этих двух индикаторов точноROC и AUC могут игнорировать причину дисбаланса образца. Этими двумя показателями являются: чувствительность и (1-специфичность), также известные как истинная частота (TPR) и ложноположительная частота (FPR).
Чувствительность = TP/(TP+FN)
Специфичность = TN/(FP+TN)
На самом деле, мы можем обнаружить, что чувствительность и отзыв точно такие же, но название изменилось.
Поскольку нас больше интересуют положительные образцы, нам нужно увидеть, сколько отрицательных образцов неверно предсказано как положительные образцы, поэтому используйте (1-специфичность) вместо специфичности.
Истинная скорость (TPR) = Чувствительность = TP/(TP+FN)
Частота ложноположительных результатов (FPR) = 1- Специфичность = FP/(FP+TN)
Ниже приведена иллюстрация истинной скорости и ложноположительной скорости, Мы обнаружили, что TPR и FPR основаны на фактической производительности 1 и 0, соответственно, то есть они наблюдают связанные проблемы вероятности в фактических положительных выборках и отрицательных выборках. , соответственно.
Из-за этого это не повлияет на то, сбалансирован образец или нет. Например, в общей выборке 90 % составляют положительные образцы, а 10 % — отрицательные образцы. Мы знаем, что в использовании показателя точности есть вода, но использование TPR и FPR — это не одно и то же. Здесь TPR обращает внимание только на то, какая часть из 90% положительных образцов фактически покрыта, и не имеет ничего общего с 10% Точно так же FPR обращает внимание только на то, какая часть из 10% отрицательных образцов покрыта. по ошибкам, и это не имеет отношения к 90%.% не имеет значения, поэтому видно, что:
Если исходить из различных результатов фактической производительности, можно избежать проблемы несбалансированности выборки, поэтому TPR и FPR выбраны в качестве индикаторов ROC/AUC.
Или мы можем также подумать об этом с другой точки зрения: условная вероятность. Предположим, что X — прогнозируемое значение, а Y — истинное значение. Тогда эти показатели можно выразить в виде условных вероятностей:
- Точность = P(Y=1 | X=1)
- Напомним = Чувствительность = P (X = 1 | Y = 1)
- Специфичность = P (X = 0 | Y = 0)
Это видно из приведенных выше трех формул: если мы сначала обусловливаем фактические результаты (уровень полноты, специфичность), то рассматривается только одна выборка, а прогнозируемое значение является первым условием (уровень точности), тогда нам нужно учитывать оба положительные и отрицательные образцы. Следовательно, на показатели, обусловленные фактическими результатами, несбалансированность выборки не повлияет, а наоборот, повлияет на показатели, обусловленные прогнозируемыми результатами.
ROC (кривая рабочих характеристик приемника)
** Кривая ROC (рабочая характеристика приемника), также известная как кривая рабочих характеристик приемника. **Эта кривая была впервые использована в области обнаружения радиолокационных сигналов, чтобы отличить сигнал от шума. Позже он был использован для оценки прогностической способности модели, и кривая ROC была получена на основе матрицы путаницы.
Двумя основными показателями на кривой ROC являются истинная скорость и ложноположительная скорость, Преимущества этого выбора также объясняются выше. По оси абсцисс отложена доля ложноположительных результатов (FPR), по оси ординат — доля истинных результатов (TPR).Ниже представлена стандартная кривая ROC.
- Пороговая проблема ROC-кривой
Подобно предыдущей кривой PR, кривая ROC также рисует всю кривую, пересекая все пороговые значения. Если мы продолжим преодолевать все пороги, предсказанные положительные и отрицательные выборки будут постоянно меняться, и соответствующая ROC-кривая будет скользить вдоль кривой.
- Как оценить качество ROC-кривой?
Изменение порога только постоянно изменяет количество предсказанных положительных и отрицательных выборок, а именно TPR и FPR, но сама кривая не изменится. Итак, как определить, что кривая ROC модели хороша? Это снова вернемся к нашей цели: FPR представляет собой степень ответа, о котором модель ложно сообщает, а TPR представляет степень охвата ответа, предсказанного моделью. Чего мы, конечно же, хотим: чем меньше ложных сообщений, тем лучше, и чем больше охват, тем лучше. Подводя итог, можно сказать, что чем выше TPR и ниже FPR (т. е. чем круче кривая ROC), тем лучше производительность модели. Обратитесь к следующей динамической диаграмме для понимания.
- Кривая ROC игнорирует дисбаланс выборки
Причина, по которой кривая ROC может игнорировать дисбаланс выборки, была объяснена ранее, давайте снова покажем, как это работает, в виде динамического графика. Мы обнаружили, что как бы ни менялось соотношение красных и синих образцов, ROC-кривая не влияла.
AUC (площадь под кривой)
Чтобы вычислить точки на кривой ROC, мы могли бы несколько раз оценивать модель логистической регрессии с разными порогами классификации, но это очень неэффективно. К счастью, существует эффективный алгоритм на основе сортировки, который может предоставить нам эту информацию, и этот алгоритм называется Area Under Curve.
Интересно, что если соединить диагональ, то ее площадь будет ровно 0,5. Фактическое значение диагональной линии: случайная оценка ответа и отсутствия ответа,Охват положительных и отрицательных образцов должен составлять 50%.,Выражатьслучайный эффект. Чем круче кривая ROC, тем лучше, поэтому идеальное значение равно 1, квадрат, а наихудшее случайное суждение равно 0,5, поэтому общее значение AUC находится в диапазоне от 0,5 до 1.
- Общие критерии суждения для AUC
0,5–0,7: низкий эффект, но достаточно хороший для прогнозирования акций 0,7–0,85: удовлетворительный эффект 0,85–0,95: хороший эффект 0,95–1: очень хороший эффект, но в целом маловероятный
- Физический смысл AUC
Площадь под кривой представляет собой составную меру влияния всех возможных порогов классификации. Один из способов интерпретации площади под кривой — это вероятность того, что модель ранжирует некоторую случайную выборку положительного класса над некоторой случайной выборкой отрицательного класса. Взяв в качестве примера следующий пример, прогнозы логистической регрессии расположены в порядке возрастания слева направо:
Что ж, принцип объяснен, переходим к коду фреймворка MindSpore.
Реализация кода MindSpore (ROC)
"""ROC"""
import numpy as np
from mindspore._checkparam import Validator as validator
from .metric import Metric
class ROC(Metric):
def __init__(self, class_num=None, pos_label=None):
super().__init__()
# 分类数为一个整数
self.class_num = class_num if class_num is None else validator.check_value_type("class_num", class_num, [int])
# 确定正类的整数,对于二分类问题,它被转换为1。对于多分类问题,不应设置此参数,因为它在[0,num_classes-1]范围内迭代更改。
self.pos_label = pos_label if pos_label is None else validator.check_value_type("pos_label", pos_label, [int])
self.clear()
def clear(self):
"""清除历史数据"""
self.y_pred = 0
self.y = 0
self.sample_weights = None
self._is_update = False
def _precision_recall_curve_update(self, y_pred, y, class_num, pos_label):
"""更新曲线"""
if not (len(y_pred.shape) == len(y.shape) or len(y_pred.shape) == len(y.shape) + 1):
raise ValueError("y_pred and y must have the same number of dimensions, or one additional dimension for"
" y_pred.")
# 二分类验证
if len(y_pred.shape) == len(y.shape):
if class_num is not None and class_num != 1:
raise ValueError('y_pred and y should have the same shape, but number of classes is different from 1.')
class_num = 1
if pos_label is None:
pos_label = 1
y_pred = y_pred.flatten()
y = y.flatten()
# 多分类验证
elif len(y_pred.shape) == len(y.shape) + 1:
if pos_label is not None:
raise ValueError('Argument `pos_label` should be `None` when running multiclass precision recall '
'curve, but got {}.'.format(pos_label))
if class_num != y_pred.shape[1]:
raise ValueError('Argument `class_num` was set to {}, but detected {} number of classes from '
'predictions.'.format(class_num, y_pred.shape[1]))
y_pred = y_pred.transpose(0, 1).reshape(class_num, -1).transpose(0, 1)
y = y.flatten()
return y_pred, y, class_num, pos_label
def update(self, *inputs):
"""
更新预测值和真实值。
"""
# 输入数量的校验
if len(inputs) != 2:
raise ValueError('ROC need 2 inputs (y_pred, y), but got {}'.format(len(inputs)))
# 将输入转为numpy
y_pred = self._convert_data(inputs[0])
y = self._convert_data(inputs[1])
# 更新曲线
y_pred, y, class_num, pos_label = self._precision_recall_curve_update(y_pred, y, self.class_num, self.pos_label)
self.y_pred = y_pred
self.y = y
self.class_num = class_num
self.pos_label = pos_label
self._is_update = True
def _roc_(self, y_pred, y, class_num, pos_label, sample_weights=None):
if class_num == 1:
fps, tps, thresholds = self._binary_clf_curve(y_pred, y, sample_weights=sample_weights,
pos_label=pos_label)
tps = np.squeeze(np.hstack([np.zeros(1, dtype=tps.dtype), tps]))
fps = np.squeeze(np.hstack([np.zeros(1, dtype=fps.dtype), fps]))
thresholds = np.hstack([thresholds[0][None] + 1, thresholds])
if fps[-1] <= 0:
raise ValueError("No negative samples in y, false positive value should be meaningless.")
fpr = fps / fps[-1]
if tps[-1] <= 0:
raise ValueError("No positive samples in y, true positive value should be meaningless.")
tpr = tps / tps[-1]
return fpr, tpr, thresholds
# 定义三个列表
fpr, tpr, thresholds = [], [], []
for c in range(class_num):
preds_c = y_pred[:, c]
res = self.roc(preds_c, y, class_num=1, pos_label=c, sample_weights=sample_weights)
fpr.append(res[0])
tpr.append(res[1])
thresholds.append(res[2])
return fpr, tpr, thresholds
def roc(self, y_pred, y, class_num=None, pos_label=None, sample_weights=None):
"""roc"""
y_pred, y, class_num, pos_label = self._precision_recall_curve_update(y_pred, y, class_num, pos_label)
return self._roc_(y_pred, y, class_num, pos_label, sample_weights)
def (self):
"""
计算ROC曲线。返回的是一个元组,由`fpr`、 `tpr`和 `thresholds`组成的元组。
"""
if self._is_update is False:
raise RuntimeError('Call the update method before calling .')
y_pred = np.squeeze(np.vstack(self.y_pred))
y = np.squeeze(np.vstack(self.y))
return self._roc_(y_pred, y, self.class_num, self.pos_label)
Способ применения следующий:
-
пример бинарной классификации
import numpy as np from mindspore import Tensor from mindspore.nn.metrics import ROC binary classification example x = Tensor(np.array([3, 1, 4, 2])) y = Tensor(np.array([0, 1, 2, 3])) metric = ROC(pos_label=2) metric.clear() metric.update(x, y) fpr, tpr, thresholds = metric.() print(fpr, tpr, thresholds) [0., 0., 0.33333333, 0.6666667, 1.] [0., 1, 1., 1., 1.] [5, 4, 3, 2, 1]
-
пример мультикласса
import numpy as np from mindspore import Tensor from mindspore.nn.metrics import ROC multiclass classification example x = Tensor(np.array([[0.28, 0.55, 0.15, 0.05], [0.10, 0.20, 0.05, 0.05], [0.20, 0.05, 0.15, 0.05],0.05, 0.05, 0.05, 0.75]])) y = Tensor(np.array([0, 1, 2, 3])) metric = ROC(class_num=4) metric.clear() metric.update(x, y) fpr, tpr, thresholds = metric.() print(fpr, tpr, thresholds) [array([0., 0., 0.33333333, 0.66666667, 1.]), array([0., 0.33333333, 0.33333333, 1.]), array([0., 0.33333333, 1.]), array([0., 0., 1.])] [array([0., 1., 1., 1., 1.]), array([0., 0., 1., 1.]), array([0., 1., 1.]), array([0., 1., 1.])] [array([1.28, 0.28, 0.2, 0.1, 0.05]), array([1.55, 0.55, 0.2, 0.05]), array([1.15, 0.15, 0.05]), array([1.75, 0.75, 0.05])]
Реализация кода MindSpore (AUC)
"""auc"""
import numpy as np
def auc(x, y, reorder=False):
"""
使用梯形法则计算曲线下面积(AUC)。这是一个一般函数,给定曲线上的点。计算ROC曲线下的面积。
"""
# 输入x是由ROC曲线得到的fpr值或者一个假阳性numpy数组。如果是多类的,这是一个这样的list numpy,每组代表一类。
# 输入y是由ROC曲线得到的tpr值或者一个真阳性numpy数组。如果是多类的,这是一个这样的list numpy,每组代表一类。
if not isinstance(x, np.ndarray) or not isinstance(y, np.ndarray):
raise TypeError('The inputs must be np.ndarray, but got {}, {}'.format(type(x), type(y)))
# 检查所有数组的第一个维度是否一致。检查数组中的所有对象是否具有相同的形状或长度。
_check_consistent_length(x, y)
# 展开列或1d numpy数组。
x = _column_or_1d(x)
y = _column_or_1d(y)
# 进行校验
if x.shape[0] < 2:
raise ValueError('At least 2 points are needed to compute the AUC, but x.shape = {}.'.format(x.shape))
direction = 1
if reorder:
order = np.lexsort((y, x))
x, y = x[order], y[order]
else:
dx = np.diff(x)
if np.any(dx < 0):
if np.all(dx 1:
raise ValueError("Found input variables with inconsistent numbers of samples: {}."
.format([int(length) for length in lengths]))
Способ применения следующий:
-
Используйте значения fpr и tpr ROC, чтобы найти auc
импортировать numpy как np импорт из mindspore.nn.metrics х = тензор (np.array ([[3, 0, 1], [1, 3, 0], [1, 0, 2]])) y = тензор (np.array ([[0, 2, 1], [1, 2, 1], [0, 0, 1]])) метрика = ROC (pos_label = 1) метрика.очистить() metric.update(х, у) fpr, tpr, thre = metric.eval() Используйте значения fpr и tpr ROC, чтобы найти auc вывод = auc(fpr, tpr) печать (вывод) 0,45
Нажмите «Подписаться», чтобы впервые узнать о новых технологиях HUAWEI CLOUD~