比较元组列表的两个字典以计算F分数

时间:2018-08-25 17:04:22

标签: python list dictionary tuples

Python noob在这里。

我有两个元组列表字典:my_gold_mentions(包括我的黄金数据)和my_coref(包括自动生成的数据)。

两个字典都看起来像这样:

{'Anakin': [(6532, 6538),
            (6590, 6592),
            (6673, 6675)],
 'He': [(3600, 3602),
        (3609, 3612)],...}  #  etc.

我正在尝试通过将自动生成的字典的元组与黄金数据的元组进行比较来计算 F分数

如果有一个元组匹配,那么我想检查两个匹配的元组是否具有相同的键,在这种情况下:共享字符的名称,例如'Anakin'

如果是这样:请将1添加到正阳性计数。

如果键不相似,但是自动生成的键作为通用键存在于黄金数据字典中(在这种情况下:'Anakin'以外的另一个字符),那么我应该认为它是误报

最后,如果密钥在黄金数据字典中根本不存在,则仅将其视为 False Negative

到目前为止,我已经尝试过:

TP = 0
FP = 0
FN = 0
for gold_key, gold_value in my_gold_mentions:
    for auto_key, auto_value in my_coref:
        if auto_value == gold_value:
            if auto_key == gold_key:
                TP += 1
            elif auto_key != gold_key and auto_key in my_gold_mentions:
                FN += 1
                FP += 1
        else:
            FN += 1

在我得到ValueError: too many values to unpack (expected 2)的情况下,看起来不太有效。

我不确定如何比较元组列表的两个字典。

关于如何改进上述代码以实现该目标的任何想法?

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

天真的O(n^2)解决方案是遍历随机生成的数据的所有列表(字典值)中的所有元组,并检查这些元组是否与以下任何一个的元组匹配:黄金数据。对于大型数据集,这将是低效率的,因为在没有匹配项的情况下,最糟糕的情况是,您需要遍历随机元组中每个元组的所有金数据数据元组。

一种更快的方法是使用允许平均情况下O(1)查找(而不是列表中的O(n)查找)的数据结构。 Python支持的类型为dictionaryset

set是项目的集合,其中每个项目通常都保存一个数据。当有两个链接的数据段时,dictionary更合适。在这里,您确实有两个链接/相关的项目,即名称和元组。

由于您将不断检查字典中的元组,因此只有以以下格式存储它们才有效率,因为您可以随后非常高效地查询任何元组。另外,当您找到一个元组并想知道其名称时,也可以立即找到它。

{(123,456):'some_name',
 (234,567):'another_name')}

要将my_gold_mentions字典转换为我建议的格式,可以使用以下字典理解:

{tup:name for name, tups in my_gold_mentions.items() for tup in tups}

给出:

{(6532, 6538): 'Anakin',
 (6590, 6592): 'Anakin',
 (6673, 6675): 'Anakin',
 (3600, 3602): 'He',
 (3609, 3612): 'He'}

现在您已经创建了一个更好的数据结构(我们称之为tup_gold_mentions),您可以有效地完成任务:

TP = FN = FP = 0
for name, tups in my_coref.items():
    for tup in tups:
        if tup in tup_gold_mentions:
            if name == tup_gold_mentions[tup]:
                TP += 1
            else:
                FN += 1
                FP += 1
        else:
            FN += 1

其中,my_coref为:

{'Anakin': [(6532, 6538),
            (123, 45)],
 'Bob': [(3600, 3602)],
 'Jim': [(12, 34)]}

给出正确的结果:

>>> TP
1
>>> FP
1
>>> FN
3

答案 1 :(得分:1)

my_gold_mentionsmy_coref更改为my_gold_mentions.items()my_coref.items(),这将允许您访问要比较的keysvalues < / p>

for gold_key, gold_value in my_gold_mentions.items():
    for auto_key, auto_value in my_coref.items():