Accuracy, precision, recall and f-score是机器学习系统中系统质量的衡量标准。它取决于真/假阳性/阴性的混淆矩阵。
鉴于二进制分类任务,我尝试了以下方法来获得一个返回准确性,精确度,召回率和f分数的函数:
gold = [1] + [0] * 9
predicted = [1] * 10
def evaluation(gold, predicted):
true_pos = sum(1 for p,g in zip(predicted, gold) if p==1 and g==1)
true_neg = sum(1 for p,g in zip(predicted, gold) if p==0 and g==0)
false_pos = sum(1 for p,g in zip(predicted, gold) if p==1 and g==0)
false_neg = sum(1 for p,g in zip(predicted, gold) if p==0 and g==1)
try:
recall = true_pos / float(true_pos + false_neg)
except:
recall = 0
try:
precision = true_pos / float(true_pos + false_pos)
except:
precision = 0
try:
fscore = 2*precision*recall / (precision + recall)
except:
fscore = 0
try:
accuracy = (true_pos + true_neg) / float(len(gold))
except:
accuracy = 0
return accuracy, precision, recall, fscore
但似乎我已经多次循环数据集4次以获得真/假阳性/阴性。
另外,抓住try-excepts
的多个ZeroDivisionError
有点多余。
那么在没有多个循环通过数据集的情况下获得真/假阳性/阴性计数的pythonic方法是什么?
如何在没有多次尝试排除的情况下以热情方式捕获ZeroDivisionError
我还可以执行以下操作来计算一个循环中的真/假阳性/阴性但是否有另一种方法没有多个if
?:
for p,g in zip(predicted, gold):
if p==1 and g==1:
true_pos+=1
if p==0 and g==0:
true_neg+=1
if p==1 and g==0:
false_pos+=1
if p==0 and g==1:
false_neg+=1
答案 0 :(得分:11)
什么是获得真/假计数的pythonic方法 没有通过数据集的多个循环的肯定/否定?
我会使用collections.Counter
,大致是您对所有if
所做的事情(您应该使用elif
s,因为您的条件是互斥的)最后:
counts = Counter(zip(predicted, gold))
然后,例如true_pos = counts[1, 1]
。
如何在没有倍数的情况下pythonically捕获ZeroDivisionError 尝试-节选?
首先,你应该(几乎)不要使用裸except:
。如果您要抓住ZeroDivisionError
,请写下except ZeroDivisionError
。您还可以考虑采用"look before you leap"方法,在尝试除法之前检查分母是否为0
,例如
accuracy = (true_pos + true_neg) / float(len(gold)) if gold else 0
答案 1 :(得分:5)
这是bitarray包的一个非常自然的用例。
import bitarray as bt
tp = (bt.bitarray(p) & bt.bitarray(g)).count()
tn = (~bt.bitarray(p) & ~bt.bitarray(g)).count()
fp = (bt.bitarray(p) & ~bt.bitarray(g)).count()
fn = (~bt.bitarray(p) & bt.bitarray(g)).count()
有一些类型转换开销,但在此之后,按位操作要快得多。
对于100个实例,我的PC上的timeit为您的方法提供0.036,在1000次通过时使用bitarray为0.017。对于1000个实例,它变为0.291和0.093。对于10000,3.177和0.863。你明白了。
它可以很好地扩展,不使用循环,也不必存储大型中间表示,在zip
中构建一个临时的元组列表。
答案 2 :(得分:4)
根据您的需要,有几个库可以计算精确度,召回率,F分数等。我使用的是scikit-learn
。假设您已经对齐list
个实际值和预测值,那么它就像......一样简单。
from sklearn.metrics import precision_recall_fscore_support as pr
bPrecis, bRecall, bFscore, bSupport = pr(gold, predicted, average='binary')
使用此库的一个优点是,不同风格的指标(如微观平均,宏观平均,加权,二进制等)都可以免费使用。