有没有办法设置spacy的词性标记?

2024-10-02 12:29:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我们有一个包含三列的数据框架:主语、动词和宾语

  • 在主题列中,数据看起来像“我”或“我们”
  • 在动词栏中,它看起来像是“有”或“没有”或“爱”
  • 在“对象”列中,它看起来像“真空”或“地板”

我试图用spacy将所有这些列元素化,以添加三个新列:主语、动词和宾语。我可以用下面的代码做到这一点,但我有一个问题,就是有些东西没有被正确地引理化(例如,动词列中带有“love”的单元格没有被改为现在时的“love”,只是保持不变)。在做了一些测试之后,我认为这是因为spacy将“loved”标记为形容词而不是动词。我有什么办法解决这个问题吗?我在想,我可以将整个动词列的pos标记设置为动词,这样它就可以正确地将“loved”等动词词组化,但动词列中有一些词不是动词(例如“not”中的not)

可能是这里有另一个帖子解释了这一点,如果我看不到,很抱歉!非常感谢你的建议

import pandas as pd
import spacy
nlp = spacy.load('en_core_web_trf')

def spacy_lemmatizer(text):
    doc = nlp(text)
    lemmatized_sentence = " ".join([token.lemma_ for token in doc])
    return(lemmatized_sentence)

dataframe.loc[:,'subject_lemma'] = dataframe.loc[:,'subject'].apply(spacy_lemmatizer)
dataframe.loc[:,'verb_lemma'] = dataframe.loc[:,'verb'].apply(spacy_lemmatizer)
dataframe.loc[:,'object_lemma'] = dataframe.loc[:,'object'].apply(spacy_lemmatizer)

Tags: 数据标记importdataframespacynot动词loc
1条回答
网友
1楼 · 发布于 2024-10-02 12:29:41

首先要注意的是,柠檬化并不总是正确的。不过,在您的案例中,问题更大的是,它是一个上下文敏感的操作。在一个句子的上下文中,“loved”被正确地识别为一个动词,并相应地进行了语法化。我的解决方案是将complete语句传递给SpaCy,然后将生成的引理重新映射到原始标记化,这需要做更多的工作,但在引理化方面应该会得到最好的结果

1。重新连接和nlp-ing句子

df = pd.DataFrame.from_records([['He', 'loved', 'floors'],
                                ['I', 'don\'t like', 'vacuums']], columns=['subject', 'verb', 'object'])

df['raw_tokens'] = df[['subject', 'verb', 'object']].values.tolist()
df['doc'] = df.raw_tokens.agg(' '.join).apply(nlp)
  subject        verb   object                raw_tokens                          doc
0      He       loved   floors       [He, loved, floors]          (He, loved, floors)
1       I  don't like  vacuums  [I, don't like, vacuums]  (I, do, n't, like, vacuums)

2。对齐两个标记化

我们需要把doc列变成一个引理列表,我们可以在以后重新组合,同时保留原始标记化。实现这一点的一种方法是使用SpaCy的内置^{}模块。给定两个具有不同标记化的标记列表,这将通过索引将一个列表映射到另一个列表,例如

from spacy.training import Alignment

raw_toks = ['I', "don't like", 'vacuums']
spacy_toks = ['I', 'do', "n't", 'like', 'vacuums']

alignment = Alignment.from_strings(raw_toks, spacy_toks)

# [0, 1, 2, 3, 4]
print(list(alignment.x2y.dataXd))

# [0, 1, 1, 1, 2]
print(list(alignment.y2x.dataXd))

这告诉我们spacy_toks中索引1、2和3处的令牌属于raw_toks中的令牌1。在下面的函数中,在使用SpaCy处理标记后,我使用它将标记映射到原始标记化,但是我们收集引理,而不是标记字符串。想法是将上面的spacy_toks这样的输入转换为[['I'], ['do', "n't", 'like'], ['vacuum']]

from spacy.training import Alignment
from itertools import groupby

def lemmatize(row):
    
    tokens, lemmas = zip(*((x.text, x.lemma_) for x in row.doc))
    lemmas = iter(lemmas) # so we can use next()
    
    # get alignment of surface token strings 
    alignment = Alignment.from_strings(row.raw_tokens, tokens).y2x.dataXd
    lemma_map = list()
    
    # collect lemmas into subgroups
    for _,g in groupby(alignment):
        lemma_map.append([next(lemmas) for _ in g])
    
    return [' '.join(w) for w in lemma_map]

3。将其应用于数据帧

df['lemmas'] = df.apply(lemmatize, axis=1)

# some cleaning
df[['subject_lemma', 'verb_lemma', 'object_lemma']] = pd.DataFrame(df.lemmas.tolist(), index=df.index)

最终结果:

  subject        verb   object subject_lemma   verb_lemma object_lemma
0      He       loved   floors            he         love        floor
1       I  don't like  vacuums             I  do n't like       vacuum

相关问题 更多 >

    热门问题