Nlp 如何检查两个spaCy Doc对象之间的差异?

Nlp 如何检查两个spaCy Doc对象之间的差异?,nlp,spacy,equivalence,Nlp,Spacy,Equivalence,我有两个相同字符串的列表,除了第二个列表中的字符串略有变化,即没有大写字母、拼写错误等 我想检查spaCy在这两个字符串之间是否有任何不同。这意味着,即使字符串不是等价的,我想知道标记和解析是否存在差异 我尝试了以下方法: import spacy import en_core_web_sm nlp = en_core_web_sm.load() doc = nlp("foo") doc2 = nlp("foo") print(doc == doc2) 这会打印出False,因此=不是正确

我有两个相同字符串的列表,除了第二个列表中的字符串略有变化,即没有大写字母、拼写错误等

我想检查spaCy在这两个字符串之间是否有任何不同。这意味着,即使字符串不是等价的,我想知道标记和解析是否存在差异

我尝试了以下方法:

import spacy
import en_core_web_sm
nlp = en_core_web_sm.load()

doc = nlp("foo")
doc2 = nlp("foo")

print(doc == doc2)
这会打印出
False
,因此
=
不是正确的选择

理想情况下,我希望我的代码能够找到潜在的差异所在,但检查是否有任何差异将是非常有用的第一步

编辑:


==已更改为在较新的SpaCy版本中工作。但是,它只比较文本级别。对于依赖关系,这是一个完全不同的故事,spaCy还没有回答这个问题,当然现在除了这个线程。

尝试使用spaCy的
doc.similarity()
函数

例如:

import spacy

nlp = spacy.load('en_core_web_md')  # make sure to use larger model!
tokens = nlp(u'dog cat banana')

for token1 in tokens:
    for token2 in tokens:
        print(token1.text, token2.text, token1.similarity(token2))
结果将是:

请参阅:
https://spacy.io

令牌级别比较 如果您想知道注释是否不同,则必须逐个标记地查看文档,以比较POS标记、依赖项标签等。假设两个文本版本的标记化相同,您可以比较:

import spacy
nlp = spacy.load('en')
doc1 = nlp("What's wrong with my NLP?")
doc2 = nlp("What's wring wit my nlp?")
for token1, token2 in zip(doc1, doc2):
    print(token1.pos_, token2.pos_, token1.pos1 == token2.pos1)
输出:

NOUN NOUN True
VERB VERB True
ADJ VERB False
ADP NOUN False
ADJ ADJ True
NOUN NOUN True
PUNCT PUNCT True
# sent_id 1
1       What    what    NOUN    WP      _       2       nsubj   _       SpaceAfter=No
2       's      be      VERB    VBZ     _       0       root    _       _
3       wrong   wrong   ADJ     JJ      _       2       acomp   _       _
4       with    with    ADP     IN      _       3       prep    _       _
5       my      -PRON-  ADJ     PRP$    _       6       poss    _       _
6       NLP     nlp     NOUN    NN      _       4       pobj    _       SpaceAfter=No
7       ?       ?       PUNCT   .       _       2       punct   _       SpaceAfter=No

解析比较的可视化 如果您想直观地检查差异,您可能会寻找类似的东西。如果两个版本的文档的标记化相同,那么我认为您可以这样做来比较解析:

首先,您需要将注释导出为受支持的格式(用于依赖项解析的某些版本的CoNLL),这是textacy可以做到的。(见:)

输出:

NOUN NOUN True
VERB VERB True
ADJ VERB False
ADP NOUN False
ADJ ADJ True
NOUN NOUN True
PUNCT PUNCT True
# sent_id 1
1       What    what    NOUN    WP      _       2       nsubj   _       SpaceAfter=No
2       's      be      VERB    VBZ     _       0       root    _       _
3       wrong   wrong   ADJ     JJ      _       2       acomp   _       _
4       with    with    ADP     IN      _       3       prep    _       _
5       my      -PRON-  ADJ     PRP$    _       6       poss    _       _
6       NLP     nlp     NOUN    NN      _       4       pobj    _       SpaceAfter=No
7       ?       ?       PUNCT   .       _       2       punct   _       SpaceAfter=No
然后,您需要决定如何修改内容,以便在分析中可以看到令牌的两个版本。我建议在有变化的地方连接标记,比如:

1       What         what    NOUN    WP      _       2       nsubj   _       SpaceAfter=No
2       's           be      VERB    VBZ     _       0       root    _       _
3       wrong_wring  wrong   ADJ     JJ      _       2       acomp   _       _
4       with_wit     with    ADP     IN      _       3       prep    _       _
5       my           -PRON-  ADJ     PRP$    _       6       poss    _       _
6       NLP_nlp      nlp     NOUN    NN      _       4       pobj    _       SpaceAfter=No
7       ?            ?       PUNCT   .       _       2       punct   _       SpaceAfter=No
的注释相比,我的nlp写的是什么?

1       What         what    NOUN    WP      _       3       nsubj   _       SpaceAfter=No
2       's           be      VERB    VBZ     _       3       aux     _       _
3       wrong_wring  wr      VERB    VBG     _       4       csubj   _       _
4       with_wit     wit     NOUN    NN      _       0       root    _       _
5       my           -PRON-  ADJ     PRP$    _       6       poss    _       _
6       NLP_nlp      nlp     NOUN    NN      _       4       dobj    _       SpaceAfter=No
7       ?            ?       PUNCT   .       _       4       punct   _       SpaceAfter=No
然后,您需要将这两个文件转换为WhatsError支持的较旧版本的CoNLL。(主要问题是删除以
#
开头的注释行)现有的一个选项是UD工具CoNLL-U到CoNLL-X转换器:,然后您有:

1       What         what    NOUN    NOUN_WP _       2       nsubj   _       _
2       's           be      VERB    VERB_VBZ        _       0       root    _       _
3       wrong_wring  wrong   ADJ     ADJ_JJ  _       2       acomp   _       _
4       with_wit     with    ADP     ADP_IN  _       3       prep    _       _
5       my           -PRON-  ADJ     ADJ_PRP$        _       6       poss    _       _
6       NLP_nlp      nlp     NOUN    NOUN_NN _       4       pobj    _       _
7       ?            ?       PUNCT   PUNCT_. _       2       punct   _       _
您可以加载这些文件(一个作为gold,一个作为guess),并使用WhatsError比较它们。选择CoNLL 2006格式(CoNLL 2006与CoNLL-X相同)

这个python WhatsError端口有点不稳定,但基本上也可以工作:

不过,他们似乎都认为我们有黄金POS标签,所以比较不会自动显示。您还可以连接POS列,以便能够同时看到这两个列(就像标记一样),因为您确实需要POS标记来理解解析的不同之处


对于令牌对和POS对,我认为可以很容易地修改原始实现或python端口,以便在附加行中分别显示这两个备选方案,这样就不必进行复杂的连接。

可能的重复方向不正确。本例使用词汇/语义相似性度量来比较一个文档中的标记,而不是比较两个不同文档中的语言注释。非常感谢您为此花费的时间和精力。这正是我想要的,还有更多!