首页 > 解决方案 > 将 Spacy 生成的依赖转换为 CoNLL 格式不能处理多个 ROOT?

问题描述

我使用 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 分成两部分,因为它们有两个根。这导致 CoNLL 格式的一个句子有两个字段。

示例:我的数据集中的一个随机句子是:“teanna trump 可能更干净 twitter hoe but”

以 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

有没有办法将它全部保存在一个字段而不是两个字段中,即使它有两个根,以便“但是”成为字段编号 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

标签: nlpspacydependency-parsingconll

解决方案


我建议使用(或调整)textacy 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")

详细信息(尤其是关于如何处理Nonevs. Falsevs. True):https ://spacy.io/usage/linguistic-features#sbd-custom

Spacy 的默认模型没有在类似 twitter 的文本上进行训练,解析器在此处的句子边界方面可能表现不佳。

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


推荐阅读