AUC/ROC: знания, которые задают в 80% интервью

машинное обучение

Аннотация: 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~