python 词形还原器,将 "political" 和 "politics" 词形化为同一个词

python lemmatizer that lemmatize "political" and "politics" to the same word

我一直在为我正在构建的解决方案测试不同的 python 词形还原器。我遇到的一个难题是词干分析器生成的非英语单词不适用于我的用例。虽然词干分析器将 "politics" 和 "political" 正确地放到同一个词干上,但我想用词形还原器来做到这一点,但是 spacy 和 nltk 正在为 "political" 和 [=22= 生成不同的词].有谁知道更强大的词形还原器?我理想的解决方案是这样的:

from nltk.stem import WordNetLemmatizer

lemmatizer = WordNetLemmatizer()

print("political = ", lemmatizer.lemmatize("political"))
print("politics = ", lemmatizer.lemmatize("politics"))  

returning:

political =  political
politics =  politics  

我想去的地方return:

political =  politics
politics =  politics  

首先,引理不是您认为的 "root" 词。它只是字典中存在的一种形式,对于 NLTK WordNetLemmatizer 中的英语,字典是 WordNet,只要字典条目在 WordNet 中,它就是一个词条,"political" 和 "politics",所以它们是有效的引理:

from itertools import chain
print(set(chain(*[ss.lemma_names() for ss in wn.synsets('political')])))
print(set(chain(*[ss.lemma_names() for ss in wn.synsets('politics')])))

[输出]:

{'political'}
{'political_sympathies', 'political_relation', 'government', 'politics', 'political_science'}

也许还有其他工具可以做到这一点,但我会先尝试一下。

首先,提取所有词干名称并将具有相同词干的词条分组:

from collections import defaultdict

from wn import WordNet
from nltk.stem import PorterStemmer

porter = PorterStemmer()
wn = WordNet()

x = defaultdict(set)
i = 0
for lemma_name in wn.all_lemma_names():
    if lemma_name:
        x[porter.stem(lemma_name)].add(lemma_name)
        i += 1

注: pip install -U wn

然后作为完整性检查,我们检查没有。引理 > 没有。组数:

print(len(x.keys()), i)

[输出]:

(128442, 147306)

然后我们可以看一下分组:

for k in sorted(x):
    if len(x[k]) > 1:
        print(k, x[k])

它似乎完成了我们需要将单词与其 "root word" 组合在一起的操作,例如

poke {'poke', 'poking'}
polar {'polarize', 'polarity', 'polarization', 'polar'}
polaris {'polarisation', 'polarise'}
pole_jump {'pole_jumping', 'pole_jumper', 'pole_jump'}
pole_vault {'pole_vaulter', 'pole_vault', 'pole_vaulting'}
poleax {'poleaxe', 'poleax'}
polem {'polemically', 'polemics', 'polemic', 'polemical', 'polemize'}
police_st {'police_state', 'police_station'}
polish {'polished', 'polisher', 'polish', 'polishing'}
polit {'politics', 'politic', 'politeness', 'polite', 'politically', 'politely', 'political'}
poll {'poll', 'polls'}

但是如果我们仔细观察就会发现一些混乱:

polit {'politics', 'politic', 'politeness', 'polite', 'politically', 'politely', 'political'}

所以我建议下一步是

再次遍历分组和运行一些语义并检查单词的"relatedness"并拆分可能不相关的单词,也许尝试像 Universal Sentence Encoder 这样的东西,例如https://colab.research.google.com/drive/1BM-eKdFb2G2zXqNt3dHgVm4gH8PaPJOq(可能不是一项微不足道的任务)

或者做一些手工工作并对分组重新排序。 (繁重的工作已经由分组中的 porter stemmer 完成,现在是时候做一些人工工作了)

然后你将不得不以某种方式在每组单词中找到词根(即 prototype/label 为簇)。

终于用自己创建的词组资源,“找不到词根”了。