使用sklearn.metrics对不在真实标签集中的预测标签进行多类别分类评估

时间:2019-10-07 11:25:00

标签: python pandas scikit-learn metrics multilabel-classification

我想为一个多分类器计算性能指标,特别是精度,召回率和F分数。

我的课程的独特之处在于,有些预测的标签没有出现在真正的标签集中。

metrics中的sklearn模块在​​处理召回和F分数时无法处理未出现在真实标签集中的预测标签。与其他帖子中的建议相反,提供明确的标签清单似乎无法解决问题。

例如,当您评估数据子集的性能时,可能会发生这种不匹配。例如,在命名实体识别系统中,您已经命名了实体标签(例如"PERSON""ORGANIZATION""LOCATION")和一个标签来表示未命名的实体(例如"O" )。为了进行评估,您通常只对命名实体的性能感兴趣(即,数据集中真正标签不是"O"的行)。但是,通常情况下,某些预测标签将为"O",因此在预测集和真实集中的标签清单之间会产生不匹配。

考虑这个玩具示例。您有一个包含3个类别的多类别分类问题:"a""b""c"。在真实标签集中,只有"a""b"出现,但是在其中一种情况下,分类器预测为"c"

import pandas as pd
import numpy as np
from sklearn import metrics
from prettytable import PrettyTable

data = pd.DataFrame(np.array([["a", "a"], ["b", "a"], ["b", "b"], ["c", "b"]]),
                    columns=['pred', 'true'])
>    pred   true
> 0     a   a
> 1     b   a
> 2     b   b
> 3     c   b

混淆矩阵的性能如下:

t = PrettyTable(['', 'a', 'b', 'c'])

t.add_row(['a', 1, 0, 0])
t.add_row(['b', 1, 1, 0])
t.add_row(['b', 0, 1, 0])

print(t)
> +---+---+---+---+
> |   | a | b | c |
> +---+---+---+---+
> | a | 1 | 0 | 0 |
> | b | 1 | 1 | 0 |
> | c | 0 | 1 | 0 |
> +---+---+---+---+

根据上述混淆矩阵,预期指标应如下:

PRECISION:

a: 1/1 = 1.0
b: 1/2 = 0.5
c: 0/1 = 0.0

overall => 0.5

RECALL:

a: 1/2 = 0.5
b: 1/2 = 0.5
c: 0/0 = NaN -> 0.0

overall => 0.(3)

请注意,当我在metrics中调用聚合的sklearn函数时,我在labels参数的函数调用list(set(data['pred']))中明确指定了真正的标签清单,因此它包括所有标签,甚至thouse在真实标签列(此处为"c"中都看不到)。这是以下文章中建议的解决方案:

UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples

还要注意,我想将average设置为'weighted',因为在现实世界中,我的课程通常非常不平衡。

metrics.precision_recall_fscore_support(data['true'], 
                                        data['pred'], 
                                        average='weighted', 
                                        labels=list(set(data['pred'])))[:-1]

我得到警告和以下结果:

# If you call the function more than once, 
# it will automatically suppress the warning, 
# so if you no longer see the warning, this is probably the reason.

UndefinedMetricWarning: Recall and F-score are ill-defined and being set to 0.0 in labels with no true samples.
  'recall', 'true', average, warn_for)

(0.75, 0.5, 0.5833333333333333)

如您所见,精度和召回率与我的计算有所不同。如果您在计算两个指标的平均值时都假设函数不包括"c"的性能,那么得分很有意义。

很显然,向函数提供真实标签的显式清单并不能消除问题。我该怎么做才能使sklearn在计算中包括"c"

0 个答案:

没有答案