我是机器学习的新手,我目前正在尝试在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分类器的定义中准确指定的。
接下来,我想为此分类器构建ROC曲线,但问题是我的classify
函数返回一个二进制值,它实际上通过计算argmin
来显示给定人的预测性别我之前说过。
我需要一种threshold
值,必须与classify
函数结果进行比较才能绘制ROC曲线,可以更改+/-
以获得多个(TPR,FPR)点。
请帮助我消除这种不幸的误解,这样我就可以建立我的ROC曲线。
答案 0 :(得分:0)
Receiver operating characteristic (ROC)用于说明二进制(两类)分类器的性能。因此,对于单个曲线,您必须将自己限制为两个类(X与Y或X与非X)(但您可以重复为其他类对生成曲线)。
不是找到-log prob(C | O)最小的类C,而是使用值prob(C1 | O)(假设它们在数据样本的行之间以相同的方式标准化)。
然后,您可以扫描一个阈值t,如果prob(C1 | O)> = t,则决定将一行归类为属于C1类。
对于每个t,你可以计算
在实践中,你只需要测试数据样本中你得到的值prob(C1 | O)为t(在你的例子中,我希望得到类似于2 **(特征数)的东西)值)。