Einführung

Wenn man einen Test hat und wissen möchte, wie gut dieser funktioniert, kann eine ROC-Kurve hilfreich sein, um die Klassifikationsparameter zu bestimmen.

Der folgende Code führt diese Berechnung an einem Beispiel durch.

#! /usr/bin/env python2

from matplotlib import pyplot as plt

import random

def roc(posData, negData, label):
    #set up the plot, squared
    fig, ax = plt.subplots(figsize=(10,10))
    res = {}
    best = [-1]
    #look at all values in your two sets:
    for val in sorted(list(set(posData + negData))):
        #calculate FPR and TPR
        fpr = len([x for x in negData if x >= val]) / float(len(negData))
        tpr = len([x for x in posData if x >= val]) / float(len(posData))
        res[val] = [fpr, tpr]
        #calculate Youden Index
        youden = tpr - fpr
        if youden > best[0]:
            best = [youden, fpr, tpr, val]
    #plot and save
    plt.plot([x[0] for x in res.values()], \
        [x[1] for x in res.values()], "o", ms = 5, color = "darkorange", \
        alpha = .9, label = label + " ({})".format(best[-1]))
    plt.plot(best[1], best[2], marker = "+", ms = 12, lw = 3, mec = "k")
    plt.plot([0, 1], [0, 1], color='navy', linestyle='--')
    plt.legend()
    plt.axis("equal")
    plt.grid()
    plt.xlabel("fpr")
    plt.ylabel("tpr")
    plt.title("Receiver Operating Characteristics")
    plt.savefig("ROCplot.png")


if __name__ == "__main__":
    posData = [random.gauss(1, .25) for x in range(200)]
    negData = [random.gauss(.5, .25) for x in range(200)]
    plt.hist(posData)
    plt.hist(negData)
    plt.savefig("test.png")
    plt.close()
    roc(posData, negData, "Random ROC")

Das Ergebnis sieht dann in etwa so aus:

ROC zweier Normalverteilungen


Comments

comments powered by Disqus