Как построить кривые затрат с помощью Python

Этот вопрос уже спрашивали год назад на StackExchange/Stats, но он был помечен как не относящийся к теме и закрыт без ответа.

В итоге мой вопрос тот же: существует ли Python (scikit-learn или другая) реализация кривых затрат, как описано в Кривые стоимости: улучшенный метод визуализации производительности классификатора.? Если нет, то как я могу реализовать это, учитывая метки истинности, прогнозы и, возможно, затраты на неправильную классификацию?

Этот метод отображает производительность (нормализованную ожидаемую стоимость) по рабочим точкам (функция вероятностной стоимости, основанная на вероятности правильной классификации положительной выборки).

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

Здесь вам тоже может не повезти, так как «Вопросы, в которых нас просят порекомендовать или найти книгу, инструмент, библиотеку программного обеспечения, учебник или другой сторонний ресурс, не относятся к теме Stack Overflow». Лучше перефразировать как «Как построить кривые затрат с помощью Python».

jpa 29.05.2019 20:22

Я перефразировал это, чтобы избежать не по теме.

Renn Kane 29.05.2019 20:31

Вы проверили это? Я не знаю каких-либо конкретных модулей, но у Яна Буна есть довольно хорошее руководство, которое позволит вам реализовать его самостоятельно.

Alexandra Perkins 29.05.2019 20:43

@AlexandraPerkins Я могу ошибаться, но кривые затрат имеют другое значение в экономике, и это не то, что я ищу.

Renn Kane 29.05.2019 21:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
4
1 499
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я работал над этим, и я думаю, что у меня есть работающая реализация.

import numpy as np
from sklearn.metrics import roc_curve
import matplotlib.pyplot as plt

# %% INPUTS

# C(-|+)
cost_fn = <a scalar value>
# C(+|-)
cost_fp = <a scalar value>

# Ground truth
truth = <a list of 0 (negative class) or 1 (positive class)>
# Predictions from a classifier
score = <a list of [0,1] class probabilities>

# %% OUTPUTS

# 1D-array of x-axis values (normalized PC)
pc = None
# list of lines as (slope, intercept)
lines = []
# lower envelope of the list of lines as a 1D-array of y-axis values (NEC)
lower_envelope = []
# area under the lower envelope (the smaller, the better)
area = None

# %% COMPUTATION

# points from the roc curve, because a point in the ROC space <=> a line in the cost space
roc_fpr, roc_tpr, _ = roc_curve(truth, score)

# compute the normalized p(+)*C(-|+)
thresholds = np.arange(0, 1.01, .01)
pc = (thresholds*cost_fn) / (thresholds*cost_fn + (1-thresholds)*cost_fp)

# compute a line in the cost space for each point in the roc space
for fpr, tpr in zip(roc_fpr, roc_tpr):
    slope = (1-tpr-fpr)
    intercept = fpr
    lines.append((slope, intercept))

# compute the lower envelope
for x_value in pc:
    y_value = min([slope*x_value+intercept for slope, intercept in lines])
    lower_envelope.append(max(0, y_value))
lower_envelope = np.array(lower_envelope)

# compute the area under the lower envelope using the composite trapezoidal rule
area = np.trapz(lower_envelope, pc)

# %% EXAMPLE OF PLOT

# display each line as a thin dashed line
for slope, intercept in lines:
    plt.plot(pc, slope*pc+intercept, color = "grey", lw=1, linestyle = "--")

# display the lower envelope as a thicker black line
plt.plot(pc, lower_envelope, color = "black", lw=3, label = "area = {:.3f}".format(area))

# plot parameters
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05*max(lower_envelope)])
plt.xlabel("Probability Cost Function")
plt.ylabel("Normalized Expected Cost")
plt.title("Cost curve")
plt.legend(loc = "lower right")

plt.show()

Пример результата с использованием cost_fn=cost_fp=1, набора данных по раку молочной железы и оценок гауссовского наивного байесовского классификатора:

Example of cost curve

Другие вопросы по теме