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

时间:2019-03-08 10:45:56

标签: 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版本中使用。但是,它仅比较文本级别。对于依赖关系,这是一个完全不同的故事,对于spaCy来说还没有得到答案,当然,现在除了这个线程之外。

2 个答案:

答案 0 :(得分:1)

令牌级别比较

如果您想知道注解是否不同,则必须逐个标记浏览文档标记以比较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

可视化分析比较

如果您要目视检查差异,则可能正在寻找类似What's Wrong With My NLP?的东西。如果两个版本的文档的标记化都相同,那么我认为您可以执行以下操作来比较解析:

首先,您需要将注释导出为受支持的格式(某些版本的CoNLL用于依赖性解析),这是文本处理可以做到的。 (请参阅:https://www.pydoc.io/pypi/textacy-0.4.0/autoapi/export/index.html#export.export.doc_to_conll

from textacy import export
export.doc_to_conll(nlp('What's wrong with my NLP?'))

输出:

# 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

vs。 What's wring wit my 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

然后,您需要将两个文件都转换为whatswrong支持的较旧版本的CoNLL。 (主要问题只是删除以#开头的注释行。)现有的一个选择是UD工具CoNLL-U到CoNLL-X转换器:https://github.com/UniversalDependencies/tools/blob/master/conllu_to_conllx.pl,然后您可以:

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   _       _

您可以加载这些文件(一个作为黄金文件,另一个作为猜测文件),并使用错的方式进行比较。选择格式CoNLL 2006(CoNLL 2006与CoNLL-X相同)。

What's Wrong With My NLP? screenshot

这个出错的python端口有点不稳定,但基本上也可以正常工作:https://github.com/ppke-nlpg/whats-wrong-python

What's Wrong With My NLP? python port screenshot

不过,他们两个似乎都假设我们拥有金色POS标签,因此不会自动显示比较结果。您还可以将POS列连接在一起,以便能够看到两者(就像使用令牌一样),因为您确实需要POS标签来理解为什么解析不同。

对于令牌对和POS对,我认为修改原始实现或python端口以在额外的行中分别显示这两种选择将很容易,因此您不必进行恶意的串联。 / p>

答案 1 :(得分:0)

尝试使用spaCy的Level 0 | Level 1 | Level 2 | A 123 2019-01-28 17:00:00 | 3 | 1 | 2 2019-01-28 18:00:00 | 2 | 1.5 | 1 2019-01-28 19:00:00 | 5 | 5 | 5 234 2019-01-28 05:00:00 | 1 | 1 | 3 2019-01-28 06:00:00 | 0 | 0 | 0 功能。

例如:

doc.similarity()

结果将是: similarity calculation

引用自: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))