scikit学习的特殊性

时间:2015-10-22 07:26:31

标签: python scikit-learn

我的分类需要specificity,定义如下: TN/(TN+FP)

我正在写一个自定义得分手功能:

from sklearn.metrics import make_scorer
def specificity_loss_func(ground_truth, predictions):
    print predictions
    tp, tn, fn, fp = 0.0,0.0,0.0,0.0
    for l,m in enumerate(ground_truth):        
        if m==predictions[l] and m==1:
            tp+=1
        if m==predictions[l] and m==0:
            tn+=1
        if m!=predictions[l] and m==1:
            fn+=1
        if m!=predictions[l] and m==0:
            fp+=1
    `return tn/(tn+fp)

score = make_scorer(specificity_loss_func, greater_is_better=True)

然后,

from sklearn.dummy import DummyClassifier
clf_dummy = DummyClassifier(strategy='most_frequent', random_state=0)
ground_truth = [0,0,1,0,1,1,1,0,0,1,0,0,1]
p  = [0,0,0,1,0,1,1,1,1,0,0,1,0]
clf_dummy = clf_dummy.fit(ground_truth, p)
score(clf_dummy, ground_truth, p)

当我运行这些命令时,我将p打印为:

[0 0 0 0 0 0 0 0 0 0 0 0 0]
1.0

为什么输入p时我的p = [0,0,0,1,0,1,1,1,1,0,0,1,0]会更改为一系列零

4 个答案:

答案 0 :(得分:11)

您可以从confusion matrix获得specificity。对于二进制分类问题,它将类似于:

from sklearn.metrics import confusion_matrix
y_true = [0, 0, 0, 1, 1, 1, 1, 1]
y_pred = [0, 1, 0, 1, 0, 1, 0, 1]
tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
specificity = tn / (tn+fp)

答案 1 :(得分:3)

首先,你需要知道:

DummyClassifier(strategy='most_frequent'...

将为您提供从您的训练集返回最频繁标签的分类器。它甚至没有考虑X中的样本。您可以在此行中传递任何内容而不是ground_truth:

clf_dummy = clf_dummy.fit(ground_truth, p)

训练结果,预测将保持不变,因为p内的大多数标签都是标签“0”。

第二次您需要知道的事情: make_scorer返回带有接口scorer(estimator, X, y)的函数。该函数将在集合X上调用估计器的预测方法,并计算预测标签与y之间的特异性函数。

因此它在任何数据集上调用clf_dummy(无关紧要,它将始终返回0),并返回0的向量,然后计算ground_truth和预测之间的特异性损失。您的预测为0,因为0在训练集中占多数。您的分数等于1,因为没有误报预测。

我更正了您的代码,以增加更多便利。

from sklearn.dummy import DummyClassifier
clf_dummy = DummyClassifier(strategy='most_frequent', random_state=0)
X = [[0],[0],[1],[0],[1],[1],[1],[0],[0],[1],[0],[0],[1]]
p  = [0,0,0,1,0,1,1,1,1,0,0,1,0]
clf_dummy = clf_dummy.fit(X, p)
score(clf_dummy, X, p)

答案 2 :(得分:0)

我很欣赏这是一个古老的问题,但我想我会提到sklearn(至少在scikit-learn v0.21.2中,但我相信它已经存在了很长时间)

据我了解,“特异性”只是“召回”的特例。召回率是针对实际阳性分类(TP / [TP + FN])计算的,而“特异性”是相同类型的计算,但针对实际阴性分类(TN / [TN + FP])。

对于二进制分类问题,只有这样的专用术语才有意义。对于多类别分类问题,谈论每个类别的召回会更方便。即使在处理二进制分类问题(例如,类别0的召回,类别1的召回)时,也没有理由不以这种方式谈论召回。

例如,回忆告诉我们实际被诊断出患有癌症的实际患癌症的患者比例。但是,概括地说,您可以说X类召回率告诉我们实际上属于X类的样本所占的比例,这些样本已被成功预测为属于X类。

鉴于此,您可以使用from sklearn.metrics import classification_report来生成dictionary of the precision, recall, f1-score and support for each label/class。您还可以根据自己的喜好使用from sklearn.metrics import precision_recall_fscore_supportDocumentation here

答案 3 :(得分:0)

记住,在二元分类中,召回肯定类别也称为“敏感性”;否定类的回忆是“特异性”,我用这个:

unique, counts = np.unique(y_test, return_counts=True)

for i in unique:
    score = precision_score(y_true, y_pred, labels=unique, pos_label=i)
    print('score ' + str(i) + '  ' + str(score))