理解应用于朴素贝叶斯分类器的 ROC 曲线 python

Understanding of ROC Curve applied to Naive Bayesian Classifier python

我是机器学习的新手,目前正在尝试实现 Python 3.4 中的 ROC 曲线,它应用于朴素贝叶斯分类器。 classifier 的实际代码在此处给出:

from __future__ import division
from collections import defaultdict
from math import log

def train(samples):
    classes, freq = defaultdict(lambda:0), defaultdict(lambda:0)
    for feats, label in samples:
        classes[label] += 1                 # count classes frequencies
        for feat in feats:
            freq[label, feat] += 1          # count features frequencies

    for label, feat in freq:                # normalize features frequencies
        freq[label, feat] /= classes[label]
    for c in classes:                       # normalize classes frequencies
        classes[c] /= len(samples)

    return classes, freq                    # return P(C) and P(O|C)

def classify(classifier, feats):
    classes, prob = classifier
    return min(classes.keys(),              # calculate argmin(-log(C|O))
        key = lambda cl: -log(classes[cl]) + \
            sum(-log(prob.get((cl,feat), 10**(-7))) for feat in feats))

示例,我有一些包含与性别相关的姓名的数据,我想将我的 classifier 应用于此类数据以预测给定姓名的性别。 这里还有一些代码:

def get_features(sample): return (sample[-1],) # get last letter

samples = (line.split() for line in open('names.txt'))
features = [(get_features(feat), label) for feat, label in samples]
classifier = train(features)

print 'gender: ', classify(classifier, get_features('Mary'))

好的,所以我一直坚持在那里建立 ROC 曲线。也许这是因为我对分类器的一些基本概念的误解,实际上我完全失望了。 使用我的 classifier,我可以预测给定名称的 'class',作为值 (-log((C|O)) 的 argmin,如上面代码中所写,因此函数 classify,当被调用时,搜索 class 对于与给定名称相关的所有特征,对数的值将是最小的 - 这在朴素贝叶斯分类器的定义中完全指定。

接下来,我想为这个 class 生成器构建 ROC 曲线,但问题是我的 classify 函数 returns 一个二进制值,它实际上显示了预测的性别正如我之前所说,通过计算 argmin 给定的人。 我需要一种 threshold 值,必须将其与 classify 函数结果进行比较以绘制 ROC 曲线,可以更改 +/- 以获得多个(TPR,FPR)点。

请帮助我消除这种不幸的误解,这样我就可以建立我的 ROC 曲线了。

Receiver operating characteristic (ROC)用于说明二进制(两个class)classifier的性能。因此,对于一条曲线,您必须将自己限制为两个 classes(X 与 Y 或 X 与非 X)(但您可以为其他 classes 对重复生成曲线) .

而不是找到 -log prob(C|O) 最小的 class C,您将使用值 prob(C1|O)(假设它们在行之间以相同的方式标准化您的数据样本)。

然后您可以扫描超过阈值 t 并决定 class如果 prob(C1|O) >= t.

将一行确认为属于 class C1

对于每个 t 你可以计算

  • 真阳性率:实际在 class C1 中并且会被 class 确定为属于 C1 的行的分数,因为 prob(C1|O) >= t
  • 误报率:不在 class C1 中但会被 class 确定为属于 C1 的部分行,因为 prob(C1|O) >= t

实际上,您只需要测试在 t 的数据样本行中获得的值 prob(C1|O)(在您的示例中,我希望得到类似 2**(特征数量) 不同的值)。