将Spacy生成的依赖项转换为CoNLL格式不能处理多个ROOT?

时间:2019-09-03 22:50:13

标签: nlp spacy dependency-parsing conll

我使用SpaCy库生成依赖关系,并使用以下代码将其保存为CoNLL格式。

import pandas as pd
import spacy

df1 = pd.read_csv('cleantweets', encoding='latin1')
df1['tweet'] = df1['tweet'].astype(str)
tweet_list = df1['tweet'].values.tolist()
nlp = spacy.load("en_core_web_sm")
for i in tweet_list:
    doc = nlp(i)
    for sent in doc.sents:
        print('\n')
        for i, word in enumerate(sent):
            if word.head is word:
                head_idx = 0
            else:
                 head_idx = doc[i].head.i + 1
            print("%d\t%s\t%d\t%s\t%s\t%s" % (
                i+1, 
                word.head,
                head_idx,
                word.text,
                word.dep_,
                word.pos_, 
                ))

这可行,但是我的数据集中有一些句子被Spacy分成两部分,因为它们有两个ROOTS。这导致CoNLL格式的一个句子有两个字段。

示例:我数据集中的一个随机句子是:“ teanna trump可能更清洁,但是twitter头”

以CoNLL格式保存为:

    1   trump   2   teanna      compound
    2   cleaner 4   trump       nsubj
    3   cleaner 4   probably    advmod
    4   cleaner 4   cleaner     ROOT
    5   hoe     6   twitter     amod
    6   cleaner 4   hoe         dobj


    1   but 2   but ROOT

是否有一种方法可以将所有内容保存在一个字段中而不是两个字段中,即使它有两个ROOTS也是如此,以便“ but”成为字段号1中的第7个项目?这意味着它看起来像这样

    1   trump   2   teanna      compound
    2   cleaner 4   trump       nsubj
    3   cleaner 4   probably    advmod
    4   cleaner 4   cleaner     ROOT
    5   hoe     6   twitter     amod
    6   cleaner 4   hoe         dobj
    7   but     2   but         ROOT

1 个答案:

答案 0 :(得分:2)

我建议使用(或改编)文本CoNLL导出程序以获取正确的格式,请参见:How to generate .conllu from a Doc object?

Spacy的解析器正在对句子进行分段,并且您正在遍历doc.sents,因此您将看到它分别导出的每个句子。如果您想提供自己的句子细分,则可以使用自定义组件来实现,例如:

def set_custom_boundaries(doc):
    for token in doc[:-1]:
        if token.text == "...":
            doc[token.i+1].is_sent_start = True
    return doc

nlp.add_pipe(set_custom_boundaries, before="parser")

详细信息(尤其是如何处理NoneFalseTrue的对比):https://spacy.io/usage/linguistic-features#sbd-custom

Spacy的默认模型没有在类似Twitter的文本上训练,解析器在此处可能无法很好地处理句子边界。

((请将不相关的问题作为单独的问题提出,并查看spacy的文档:https://spacy.io/usage/linguistic-features#special-cases