Понимание кривых ROC с помощью Python
Создание базовой интуиции для кривой рабочих характеристик приемника с помощью Python
Если вы загуглите: «Машинное обучение кривой ROC», вы получите такой ответ Википедии:
Кривая рабочих характеристик приемника, или кривая ROC, представляет собой графический график, который иллюстрирует диагностические возможности системы двоичного классификатора при изменении ее порога дискриминации.
Другое распространенное описание состоит в том, что кривая ROC отражает чувствительность модели к разным пороговым значениям классификации. Когда я только начинал заниматься машинным обучением, эти определения всегда сбивали меня с толку.
В этой статье я расскажу, как я научился распутывать свои «новичковые» заблуждения и развить достаточно хорошую интуицию относительно кривой ROC.
Что за чертовщина кривая ROC?
Один из способов понять кривую ROC состоит в том, что она описывает взаимосвязь между чувствительностью модели (истинно-положительным коэффициентом или TPR) и ее специфичностью (описывается в отношении частоты ложноположительных результатов: 1-FPR). .
Теперь давайте разберем здесь каждое понятие.
TPR, известный как чувствительность модели, представляет собой соотношение правильных классификаций «положительного» класса, деленное на все положительные классы, доступные в наборе данных, математически:

в то время как FPR - это соотношение между ложными срабатываниями (количество прогнозов, ошибочно классифицированных как положительные) и всеми доступными отрицательными классами, математически:

По сути, вы сравниваете, как изменяется чувствительность модели по отношению к частоте ложных срабатываний по разным пороговым оценкам, которые отражают границу принятия решения модели для классификации входных данных как положительных.
Разделение проблемы с пороговыми оценками
Интуиция, которая подсказывала мне вначале, заключалась в том, чтобы понять роль пороговой оценки. Хорошей отправной точкой является построение мысленной картины:

С помощью этой классической визуализации можно научиться первой интуиции, которая заключается в том, что идеальная модель - это модель с максимально высокой вероятностью истинных положительных результатов и минимальной вероятностью ложных срабатываний.
Порог соответствует некоторому значению T (например, значению от 0 до 1), которое служит границей принятия решения для классификатора и влияет на компромисс между TPR и FPR.
Давайте напишем код, чтобы визуализировать все эти компоненты.
Визуализация кривой ROC
Шаги для визуализации этого будут:
- Импортируйте наши зависимости
- Нарисуйте поддельные данные с помощью пакета
drawdataдля блокнотов Jupyter - Импортируйте поддельные данные в фреймворк pandas
- Подобрать для данных модель логистической регрессии
- Получение прогнозов модели логистической регрессии в виде значений вероятности
- Установите разные пороговые значения
- Визуализируйте график кривой roc
- Сделайте окончательные выводы
1. Импортируйте наши зависимости
from drawdata import draw_scatter
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_recall_curve,precision_score, plot_roc_curve
2. Нарисуйте поддельные данные с помощью пакета drawdata для блокнотов Jupyter.
draw_scatter()
Выход:

3. Импортируйте поддельные данные в фреймворк pandas
df = pd.read_csv("./data.csv")
4. Подберите модель логистической регрессии к данным.
def get_fp_tp(y, proba, threshold):
"""Return the number of false positives and true positives."""
# source: https://towardsdatascience.com/roc-curve-explained-50acab4f7bd8
# Classify into classes
pred = pd.Series(np.where(proba>=threshold, 1, 0),
dtype='category')
pred.cat.set_categories([0,1], inplace=True)
# Create confusion matrix
confusion_matrix = pred.groupby([y, pred]).size().unstack()\
.rename(columns={0: 'pred_0',
1: 'pred_1'},
index={0: 'actual_0',
1: 'actual_1'})
false_positives = confusion_matrix.loc['actual_0', 'pred_1']
true_positives = confusion_matrix.loc['actual_1', 'pred_1']
return false_positives, true_positives
# train test split on the fake generated dataset
X = df[["x", "y"]].values
Y = df["z"].values
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=42)
y_test = np.array([1 if p=="a" else 0 for p in y_test])
y_train = np.array([1 if p=="a" else 0 for p in y_train])
# create the model
lgr = LogisticRegression()
lgr.fit(X_train, y_train)
5. Получите прогнозы модели логистической регрессии в виде значений вероятности.
y_hat = lgr.predict_proba(X_test)[:,1]
6. Установите разные пороговые значения.
thresholds = np.linspace(0,1,100)
7. Визуализируйте график кривой ROC.
# defining fpr and tpr
tpr = []
fpr = []
# defining positives and negatives
positives = np.sum(y_test==1)
negatives = np.sum(y_test==0)
# looping over threshold scores and getting the number of false positives and true positives
for th in thresholds:
fp,tp = get_fp_tp(y_test, y_hat, th)
tpr.append(tp/positives)
fpr.append(fp/negatives)
plt.plot([0, 1], [0, 1], linestyle='--', lw=2, color='r',label='Random', alpha=.8)
plt.plot(fpr,tpr, label="ROC Curve",color="blue")
plt.text(0.5, 0.5, "varying threshold scores (0-1)", rotation=0, size=12,ha="center", va="center",bbox=dict(boxstyle="rarrow"))
plt.xlabel("False Positve Rate")
plt.ylabel("True Positive Rate")
plt.legend()
plt.show()

8. Сделайте окончательные выводы.
Изменяя пороговые значения, мы получаем увеличивающиеся значения как истинно положительных, так и ложноположительных оценок. Хорошая модель - это модель, в которой пороговая оценка ставит истинно положительное значение как можно ближе к 1, а количество ложных срабатываний - как можно меньше.
Но как мы могли выбрать лучший порог классификации?
Самый простой способ - выбрать тот, у которого максимальная сумма истинно положительных и ложноотрицательных результатов (1 - FPR).
Другим критерием может быть простой выбор точки, ближайшей к верхнему левому углу пространства ROC. Однако это означает, что истинно положительный коэффициент и истинно отрицательный коэффициент имеют одинаковый вес (источник) , что не обязательно верно в таких случаях, как классификация рака, где отрицательное влияние ложноположительного результата больше, чем влияние истинно положительного.
Заключительные мысли о кривых ROC
Я думаю, что время, потраченное на усвоение оценочных показателей, чрезвычайно полезно в долгосрочной перспективе для вашего пути к машинному обучению. Из этой статьи вы узнали:
- Базовое представление о том, как работают кривые ROC
- Как пороги классификации влияют на соотношение между чувствительностью и специфичностью модели
- Интуиция в том, как использовать кривую ROC для установки оптимального порога классификации
Если вы хотите узнать больше о Python для машинного обучения, ознакомьтесь с этими курсами:
Это партнерские ссылки, если вы воспользуетесь ими, я получу небольшую комиссию, ура! :)
- Машинное обучение от А до Я ™: практический опыт Python и R в науке о данных
- Учебный курс по Python для науки о данных и машинного обучения
Если вам понравился этот пост, подпишитесь на меня в Medium, подпишитесь на мою рассылку, свяжитесь со мной в Twitter, LinkedIn, Instagram или присоединитесь к Medium! Спасибо и увидимся в следующий раз! :)