Python 理解ROC曲线在朴素贝叶斯分类器中的应用

Python 理解ROC曲线在朴素贝叶斯分类器中的应用,python,machine-learning,roc,naivebayes,Python,Machine Learning,Roc,Naivebayes,我是机器学习新手,目前正在尝试在Python 3.4中实现ROC曲线,该曲线应用于朴素贝叶斯分类器。分类器的实际代码如下所示: from __future__ import division from collections import defaultdict from math import log def train(samples): classes, freq = defaultdict(lambda:0), defaultdict(lambda:0) for fea

我是机器学习新手,目前正在尝试在Python 3.4中实现ROC曲线,该曲线应用于朴素贝叶斯分类器。分类器的实际代码如下所示:

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))
例如,我有一些包含与性别相关的姓名的数据,我想将我的分类器应用于此类数据,以预测给定姓名的性别。 这里还有一些代码:

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曲线。可能是因为我对量词的一些基本概念有误解,其实我完全失望了。 使用我的分类器,我可以预测给定名称的“class”,作为值的argmin(-log((C | O))正如上面代码中所述,因此调用函数
classify
时,会搜索与给定名称相关的所有特征的对数值最小的类,这在Naive Bayes Classificator的定义中有明确规定

接下来,我想为这个分类器构建ROC曲线,但问题是我的
classify
函数返回一个二进制值,它通过计算
argmin
来实际显示给定人的预测性别,正如我前面所说的。 我需要一种
阈值
值,它必须与
分类
函数结果进行比较,以绘制ROC曲线,可以改变它以获得多个(TPR,FPR)点

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

用于说明二进制(两类)分类器的性能。因此,对于一条曲线,您必须将自己限制为两个类(X vs.Y或X vs.not X)(但可以为其他成对的类重复生成曲线)

与查找-log prob(C | O)最小的类C不同,您可以使用值prob(C1 | O)(假设它们在数据样本的行之间以相同的方式进行规范化)

然后,您可以扫描阈值t,并决定在prob(C1 | O)>=t时将行分类为属于类别C1

对于每个t,您可以计算

  • 真实阳性率:实际属于C1类且由于prob(C1 | O)>=t而被归类为属于C1的行的分数
  • 假阳性率:不属于C1类但由于概率(C1 | O)>=t而被分类为属于C1的行的分数
实际上,您只需测试数据样本行中t的值prob(C1 | O)(在您的示例中,我希望得到类似于2**(特征数)的不同值)。

用于说明二进制(两类)分类器的性能。因此您必须将自己限制为两类(X对Y或X对非X)用于单个曲线(但您可以为其他成对的类重复生成曲线)

与查找-log prob(C | O)最小的类C不同,您可以使用值prob(C1 | O)(假设它们在数据样本的行之间以相同的方式进行规范化)

然后,您可以扫描阈值t,并决定在prob(C1 | O)>=t时将行分类为属于类别C1

对于每个t,您可以计算

  • 真实阳性率:实际属于C1类且由于prob(C1 | O)>=t而被归类为属于C1的行的分数
  • 假阳性率:不属于C1类但由于概率(C1 | O)>=t而被分类为属于C1的行的分数
实际上,您只需要测试t的数据样本行上的值prob(C1 | O)(在您的示例中,我希望得到类似于2**(特征数)的不同值)