Pandas中比较绘制不同二元分类器ROC曲线的最简单方法是什么?

2024-10-01 07:37:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我有三个二元分类模型,我到了下一步,试图将它们组合成一个最终的比较ROC图

import pandas as pd
import numpy as np
import sklearn.metrics as metrics

y_test = ... # a numpy array containing the test values
dfo    = ... # a pd.DataFrame containing the model predictions
dfroc = dfo[['SVM',
             'RF',
             'NN']].apply(lambda y_pred: metrics.roc_curve(y_test[:-1], y_pred[:-1])[0:2], 
                          axis=0, result_type='reduce')
print(dfroc)
dfroc_auc = dfroc.apply(lambda x: metrics.auc(x[0], x[1]))
print(dfroc_auc)

输出以下内容(其中dfrocdfroc_auc类型为pandas.core.series.Series):

SVM     ([0.0, 0.016666666666666666, 1.0], [0.0, 0.923...
RF      ([0.0, 0.058333333333333334, 1.0], [0.0, 0.769...
NN      ([0.0, 0.06666666666666667, 1.0], [0.0, 1.0, 1...
dtype: object

SVM     0.953205
RF      0.855449
NN      0.966667
dtype: float64

为了能够将它们绘制成一个比较ROC,我需要将它们转换成以下数据透视结构dfroc{}。。。如何进行数据透视

      model   fpr       tpr
1     SVM     0.0       0.0        
2     SVM     0.16666   0.923
3     SVM     1.0       ...
4     RF      0.0       0.0       
5     RF      0.05833   0.769
6     RF      1.0       ... 
7     NN      ...       ...

然后对于绘图,从How to plot ROC curve in Python开始的以下方向是这样的:

import matplotlib.pyplot as plt
plt.title('Receiver Operating Characteristic')
dfroc.plot(label = 'AUC = %0.2f' % roc_auc)
plt.legend(loc = 'lower right')
plt.plot([0, 1], [0, 1],'r--')
plt.xlim([0, 1])
plt.ylim([0, 1])
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.show()

Tags: testimportnumpypandasplotaspltnn
1条回答
网友
1楼 · 发布于 2024-10-01 07:37:42

这不是理想的工作结构,但假设您有以下内容:

s = pd.Series({'SVC':([0.0, 0.016, 1.0], [0.0, 0.923, 0.5], [0.3, 0.4, 0.9]),
               'RF': ([0.0, 0.058, 1.0], [0.0, 0.923, 0.2], [0.5, 0.3, 0.9]),
               'NN': ([0.0, 0.06,  1.0], [0.0, 0.13, 0.4], [0.2, 0.4, 0.9])})

您可以定义一个函数来计算TPRFPR并返回具有指定结构的数据帧:

def tpr_fpr(g):
    model, cm = g
    cm = np.stack(cm.values)
    diag = np.diag(cm)
    FP = cm.sum(0) - diag   
    FN = cm.sum(1) - diag
    TP = diag
    TN = cm.sum() - (FP + FN + TP)
    TPR = TP/(TP+FN)
    FPR = FP/(FP+TN)
    return pd.DataFrame({'model':model,
                         'TPR':TPR, 
                         'FPR':FPR})

从第一级的groupby开始,将上述函数应用于每个组:

out = pd.concat([tpr_fpr(g) for g in s.explode().groupby(level=0)])

print(out)

  model       TPR       FPR
0    NN  0.000000  0.098522
1    NN  0.245283  0.179688
2    NN  0.600000  0.880503
0    RF  0.000000  0.177117
1    RF  0.821906  0.129804
2    RF  0.529412  0.550206
0   SVC  0.000000  0.099239
1   SVC  0.648630  0.159021
2   SVC  0.562500  0.615006

相关问题 更多 >