将 Spacy 生成的依赖项转换为 CoNLL 格式不能处理多个 ROOT?
Converting Spacy generated dependency into CoNLL format cannot handle more than one 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 分成两部分,因为它们有两个 ROOTS。这导致在 CoNLL 格式中一个句子有两个字段。
示例:我的数据集中的一个随机句子是:"teanna trump probably cleaner 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
有没有办法将它全部保存在一个字段而不是两个字段中,即使它有两个 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
我建议使用(或改编)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")
细节(尤其是关于如何处理 None
vs. False
vs. True
):https://spacy.io/usage/linguistic-features#sbd-custom
Spacy 的默认模型未针对类似 Twitter 的文本进行训练,解析器在此处的句子边界方面可能表现不佳。
(请将不相关的问题作为单独的问题提出,并查看 spacy 的文档:https://spacy.io/usage/linguistic-features#special-cases)
我使用 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 probably cleaner 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
有没有办法将它全部保存在一个字段而不是两个字段中,即使它有两个 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
我建议使用(或改编)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")
细节(尤其是关于如何处理 None
vs. False
vs. True
):https://spacy.io/usage/linguistic-features#sbd-custom
Spacy 的默认模型未针对类似 Twitter 的文本进行训练,解析器在此处的句子边界方面可能表现不佳。
(请将不相关的问题作为单独的问题提出,并查看 spacy 的文档:https://spacy.io/usage/linguistic-features#special-cases)