理解应用于朴素贝叶斯分类器的 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**(特征数量) 不同的值)。
我是机器学习的新手,目前正在尝试实现 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**(特征数量) 不同的值)。