Кривая ROC в питоне для активных соединений по сравнению с приманками - правильно ли она создается?

Я новичок в этом, но я хотел бы построить кривую ROC для небольшого набора данных активных соединений по сравнению с приманками. Я основывался на этой ссылке: кривая ROC для двоичной классификации в python В данном случае этот небольшой набор данных является результатом виртуального скрининга, в ходе которого были ранжированы и оценены соединения с известной активностью или неактивностью на основе экспериментальных данных (IC50).

Я не уверен, что сюжет и AUC верны. Я заметил, что даже если между тестовыми (истинными) прогнозируемыми значениями была разница только в одно значение, AUC составляла всего 0,5. Для истинных и предсказанных значений в коде, который я вставил ниже, это было всего около 0,49. Возможно, модель неправильно идентифицировала соединения. Однако я заметил, что для первых десяти соединений в ранге он идентифицировался правильно, к тому же некоторые в других позициях. Может быть, он лучше идентифицировал активные соединения, чем отрицательные, или, может быть, это было потому, что нужно было учитывать больше активных соединений. Кроме того, не лучше ли использовать другую систему классификации для проверенных и прогнозируемых значений, кроме бинарной классификации? Например, ранжирование значений IC50 от лучшего к худшему и сравнение с рейтингом виртуального скрининга, создание оценки для истинных и прогнозируемых результатов с учетом сходства между рангами каждого соединения (для IC50 и виртуального скрининга)?

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

import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc, roc_auc_score
test = [1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,0,1,1,1]
pred = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0]
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(2):
    fpr[i], tpr[i], _ = roc_curve(test, pred)
    roc_auc[i] = auc(fpr[i], tpr[i])

print(roc_auc_score(test, pred))
plt.figure()
plt.plot(fpr[1], tpr[1])
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.show()

person Camila Fonseca Amorim da Silva    schedule 17.03.2021    source источник
comment
В чем именно заключается ваш вопрос?   -  person Calimo    schedule 17.03.2021
comment
Я не знаю, правильно ли код генерирует кривую ROC или есть лучший способ для этого.   -  person Camila Fonseca Amorim da Silva    schedule 18.03.2021
comment
Тогда, пожалуйста, отредактируйте свой вопрос, чтобы отразить это. На данный момент это больше похоже на разглагольствование о ваших данных, чем на вопрос.   -  person Calimo    schedule 18.03.2021
comment
Я добавил основной вопрос в заголовок — проблему, которую я упоминаю в начале второго абзаца. Может быть, это было неясно, потому что я не поставил вопросительный знак, как и в двух других вопросах в том же абзаце. Это могло показаться разглагольствованием, потому что я подумал о том, чтобы включить больше деталей (наблюдений/мыслей) о ситуации с вопросами/проблемами в целом.   -  person Camila Fonseca Amorim da Silva    schedule 19.03.2021


Ответы (1)


Код, необходимый для построения кривой ROC, очень похож, но проще вашего. Нет необходимости хранить fpr и tpr как словари, это массивы. Я думаю, проблема в том, что ваши прогнозы являются абсолютными True/False, а не вероятностью, которую можно использовать для генерации пороговых значений с помощью функции roc_curve. Я изменил значения pred на вероятность (> 0,5 — Истина, ‹ 0,5 — Ложь), и теперь кривая выглядит ближе к тому, что вы, вероятно, ожидаете. Кроме того, только 66% предсказаний верны, и это делает кривую относительно близкой к линии «отсутствия дискриминации» (случайное событие с вероятностью 50%).

test = [1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,0,1,1,1]
pred = [0.91,0.87,0.9,0.75,0.85,0.97,0.99,0.98,0.66,0.97,0.98,0.57,0.89,0.62,0.93,0.97,0.55,0.99,0.11,0.84,0.45,0.35,0.3,0.39]

fpr, tpr, _ = roc_curve(test, pred)
roc_auc = auc(fpr, tpr)

print(roc_auc_score(test, pred))
plt.figure()
plt.plot(fpr, tpr)
plt.plot([0.0, 1.0], [0.0, 1.0], ls='--', lw=0.3, c='k')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.show()

Теперь значение AUC равно 0,5842105263157894.

Сюжет из кода выше

person Carlos Melus    schedule 19.03.2021