如何在不使用 sklearn 的情况下计算 Python 中的 TPR 和 FPR?

How to calculate TPR and FPR in Python without using sklearn?

初始化列表列表:

data = [[1.0, 0.635165,0.0], [1.0, 0.766586,1.0], [1.0, 0.724564,1.0],
        [1.0, 0.766586,1.0],[1.0, 0.889199,1.0],[1.0, 0.966586,1.0],
        [1.0, 0.535165,0.0],[1.0, 0.55165,0.0],[1.0, 0.525165,0.0],
        [1.0, 0.5595165,0.0] ]

创建 Pandas 数据框:

df = pd.DataFrame(data, columns = ['y', 'prob','y_predict']) 

打印数据框。

print(df)

对于这个数据集,我想找到:

  1. 不使用 Sklearn 的混淆矩阵
  2. 不使用 Sklearn 的 TPR 和 FPR 的 Numpy 数组,用于绘制 ROC。

如何在 python 中执行此操作?

... 没有 sklearn python 模块:

  1. 不使用 Sklearn 的混淆矩阵

    • 您可以使用 pandas_ml

      从 pandas_ml 导入 ConfusionMatrix

    • 您可以为混淆矩阵构建数学公式
  2. 关于ROC的你

    • 请参阅 python MatLab 示例求解
    • 可以构建您的数组并使用 np 并使用数学公式构建您的源代码。

如果你看看这些文章,你会更了解:

logistic-regression-using-numpy - python 个例子回归;

what-is-the-roc-curve - 理论;

roc-curve-part-2-numerical-example - python练习;

您可以计算与不同阈值级别相关的误报率和真报率,如下所示:

import numpy as np

def roc_curve(y_true, y_prob, thresholds):

    fpr = []
    tpr = []

    for threshold in thresholds:

        y_pred = np.where(y_prob >= threshold, 1, 0)

        fp = np.sum((y_pred == 1) & (y_true == 0))
        tp = np.sum((y_pred == 1) & (y_true == 1))

        fn = np.sum((y_pred == 0) & (y_true == 1))
        tn = np.sum((y_pred == 0) & (y_true == 0))

        fpr.append(fp / (fp + tn))
        tpr.append(tp / (tp + fn))

    return [fpr, tpr]
import numpy as np

def calculate_cm(predicted, actual):
  fp = np.sum((y_pred == 1) & (y_true == 0))
  tp = np.sum((y_pred == 1) & (y_true == 1))

  fn = np.sum((y_pred == 0) & (y_true == 1))
  tn = np.sum((y_pred == 0) & (y_true == 0))
  return tp, fp, fn, tn

def calculate_recall(tp, fp, fn, tn):
  return (tp)/(tp + fn)

def calculate_fallout(tp, fp, fn, tn):
  return (fp)/(fp + tn)

def calculate_at_threshold(threshold, actual, predicted):
  p = np.where(predicted >= threshold, 1, 0)
  tp, fp, fn, tn = calculate_cm(p, actual)
  tpr = calculate_recall(tp, fp, fn, tn)
  fpr = calculate_fallout(tp, fp, fn, tn)
  return fpr, tpr 

def roc_curve(actual, predicted, thresholds):
  tpr = []
  fpr = []
  for threshold in thresholds:
    fpr_t, tpr_t = calculate_at_threshold(threshold, actual, predicted)
    tpr.append(fpr_t)
    fpr.append(tpr_t)
  return fpr, tpr

这是 Flavia Giammarino 的 的稍快版本,它只使用 NumPy 数组;我还添加了一些评论并提供了替代的、更通用的变量名称:

import numpy as np

def roc_curve(probabilities, ground_truth, thresholds):

    # Initialize FPR & TPR arrays
    fpr = np.empty_like(thresholds)
    tpr = np.empty_like(thresholds)

    # Compute FPR & TPR
    for t in range(0, len(thresholds)):
        y_pred = np.where(ground_truth >= thresholds[t], 1, 0)
        fp = np.sum((y_pred == 1) & (probabilities == 0))
        tp = np.sum((y_pred == 1) & (probabilities == 1))
        fn = np.sum((y_pred == 0) & (probabilities == 1))
        tn = np.sum((y_pred == 0) & (probabilities == 0))
        fpr[t] = fp / (fp + tn)
        tpr[t] = tp / (tp + fn)

    return fpr, tpr

可以使用像 NumPy 的 linspace:

这样的函数轻松生成阈值
np.linspace(start, end, n)

其中[start, end]是阈值的范围(包括极值;应该是start = 0end = 1),n是阈值的数量;根据经验,我可以说 n = 50 是速度和准确性之间的一个很好的权衡,尽管 n >= 100 会产生更平滑的曲线。