如何修改 Wordnet Lemmatizer 以对特定单词进行 lemmitize?
how to modify Wordnet Lemmatizer to lemmitize specific words?
我正在将 wordNet lemmatizer 应用到我的语料库中,我需要为 lemmatizer 定义 pos 标注器:
stemmer = PorterStemmer()
def lemmitize(document):
return stemmer.stem(WordNetLemmatizer().lemmatize(document, pos='v'))
def preprocess(document):
output = []
for token in gensim.utils.simple_preprocess(document):
if token not in gensim.parsing.preprocessing.STOPWORDS and len(token) > 3:
print("lemmitize: ", lemmitize(token))
output.append(lemmitize(token))
return output
现在如您所见,我正在为动词定义 pos(并且我知道 wordNet 默认 pos 是一个名词),但是当我对文档进行词形还原时:
the left door closed at the night
我正在退出:
output: ['leav', 'door', 'close', 'night']
这不是我所期待的。在我上面的句子中,left
指向哪扇门(例如右门或左门)。如果我选择 pos ='n'
这个问题可能会解决,但它将作为 wornNet 默认值,并且不会对 taken
这样的词产生任何影响。
我在 here 中发现了类似的问题,我在 nltk_data/corpora/wordnet/verb.exc
中修改了例外列表,并将 left leave
更改为 left left
但我仍然得到相同的结果结果为 leav
.
现在我想知道这个问题是否有任何解决方案,或者在最好的情况下,有什么方法可以添加一些单词的自定义词典(仅限于我的文档),wordNet 不会像这样对它们进行词形还原:
my_dict_list = [left, ...]
您可以为某些单词添加自定义词典,例如 pos_dict = {'breakfasted':'v', 'left':'a', 'taken':'v'}
通过将此自定义 pos_dict
与 token
一起传递到 lemmitize
函数中,您可以为每个标记使用您指定的 POS 标记的词形还原器。
lemmatize(token, pos_dict.get(token, 'n'))
将传递 'n' 作为其第二个参数作为默认值,除非令牌在 pos_dict
键中。您可以将此默认值更改为您想要的任何值。
def lemmitize(document, pos_dict):
return stemmer.stem(WordNetLemmatizer().lemmatize(document, pos_dict.get(document, 'n')))
def preprocess(document, pos_dict):
output = []
for token in gensim.utils.simple_preprocess(document):
if token not in gensim.parsing.preprocessing.STOPWORDS and len(token) > 3:
print("lemmitize: ", lemmitize(token, pos_dict))
output.append(lemmitize(token, pos_dict))
return output
你在词形还原和词干化之间犯了一个常见的错误。
词干提取
词干提取意味着将单词缩减为其前缀。与语法无关,与你自己的数据或使用的算法有关。
最常用的词干提取器,例如Porter Stemmer,去掉了"morphological and inflexional endings from words" (Porter Stemmer Website)
因此,诸如 cook、cooking、cooked 和 cookie 等词的 morphological/inflexional 词尾被移除,词尾全部变为 "Cook"。但是,请注意,您将一个名词、一个现在进行时的动词、一个过去时的动词和另一个名词捆绑在一起(例如,请注意 cookie,尽管它是一种熟食,但实际上并不用 "cook" 或 "to cook" 一词分享 "hierarchy"。
当你这样做时:
stemmer.stem(WordNetLemmatizer().lemmatize(document))
您正在使用 wordnet 进行词干提取 - 首先对词进行词根化,然后进行词干提取,删除 "morphological/inflexional" 词。事实上,如果你进行词干提取,你甚至不需要词形还原(它只会改变不规则动词的内容)。
词形还原
词形还原,另一方面,使用词汇信息将单词缩减为 "default" 非弯曲形式。为使它起作用,提供 te POS 非常重要(因为如您所见,leaves 是一个既表示动词又表示名词的词素)。
但是如何找到词性呢?
今天有一些技术,但最常用的一种是基于查找 table 和周围的词 - 这些被输入预训练的机器学习算法,returns 最可能的标签。阅读更多内容:https://medium.com/greyatom/learning-pos-tagging-chunking-in-nlp-85f7f811a8cb
使用名为 NLTK 的流行 Python NLP 包,您可以:
(你必须先下载相关的包)
import nltk
sentence = "I want to tag these!"
token = nltk.word_tokenize(sentence)
nltk.pos_tag(token)
结果:
[('I', 'PRP'), ('want', 'VBP'), ('to', 'TO'), ('tag', 'VB'), ('these',
'DT'), ('!', '.')]
另一个流行的工具是 Spacy,如下所示:
(您必须先下载带有机器学习训练模型的语言模型)
import spacy
import spacy
nlp = spacy.load('en')
doc = nlp('I want to tag these!')
print([(token.text, token.pos_) for token in doc])
结果:
[('I', 'PRON'), ('want', 'VERB'), ('to', 'PART'), ('tag', 'VERB'), ('these', 'DET'), ('!', 'PUNCT')]
您可以在此处阅读有关 Spacy 词性标记的更多信息:https://spacy.io/usage/linguistic-features/
然后我建议您坚持使用词形还原,因为这将为您提供更细粒度的选项。
我正在将 wordNet lemmatizer 应用到我的语料库中,我需要为 lemmatizer 定义 pos 标注器:
stemmer = PorterStemmer()
def lemmitize(document):
return stemmer.stem(WordNetLemmatizer().lemmatize(document, pos='v'))
def preprocess(document):
output = []
for token in gensim.utils.simple_preprocess(document):
if token not in gensim.parsing.preprocessing.STOPWORDS and len(token) > 3:
print("lemmitize: ", lemmitize(token))
output.append(lemmitize(token))
return output
现在如您所见,我正在为动词定义 pos(并且我知道 wordNet 默认 pos 是一个名词),但是当我对文档进行词形还原时:
the left door closed at the night
我正在退出:
output: ['leav', 'door', 'close', 'night']
这不是我所期待的。在我上面的句子中,left
指向哪扇门(例如右门或左门)。如果我选择 pos ='n'
这个问题可能会解决,但它将作为 wornNet 默认值,并且不会对 taken
这样的词产生任何影响。
我在 here 中发现了类似的问题,我在 nltk_data/corpora/wordnet/verb.exc
中修改了例外列表,并将 left leave
更改为 left left
但我仍然得到相同的结果结果为 leav
.
现在我想知道这个问题是否有任何解决方案,或者在最好的情况下,有什么方法可以添加一些单词的自定义词典(仅限于我的文档),wordNet 不会像这样对它们进行词形还原:
my_dict_list = [left, ...]
您可以为某些单词添加自定义词典,例如 pos_dict = {'breakfasted':'v', 'left':'a', 'taken':'v'}
通过将此自定义 pos_dict
与 token
一起传递到 lemmitize
函数中,您可以为每个标记使用您指定的 POS 标记的词形还原器。
lemmatize(token, pos_dict.get(token, 'n'))
将传递 'n' 作为其第二个参数作为默认值,除非令牌在 pos_dict
键中。您可以将此默认值更改为您想要的任何值。
def lemmitize(document, pos_dict):
return stemmer.stem(WordNetLemmatizer().lemmatize(document, pos_dict.get(document, 'n')))
def preprocess(document, pos_dict):
output = []
for token in gensim.utils.simple_preprocess(document):
if token not in gensim.parsing.preprocessing.STOPWORDS and len(token) > 3:
print("lemmitize: ", lemmitize(token, pos_dict))
output.append(lemmitize(token, pos_dict))
return output
你在词形还原和词干化之间犯了一个常见的错误。
词干提取
词干提取意味着将单词缩减为其前缀。与语法无关,与你自己的数据或使用的算法有关。
最常用的词干提取器,例如Porter Stemmer,去掉了"morphological and inflexional endings from words" (Porter Stemmer Website)
因此,诸如 cook、cooking、cooked 和 cookie 等词的 morphological/inflexional 词尾被移除,词尾全部变为 "Cook"。但是,请注意,您将一个名词、一个现在进行时的动词、一个过去时的动词和另一个名词捆绑在一起(例如,请注意 cookie,尽管它是一种熟食,但实际上并不用 "cook" 或 "to cook" 一词分享 "hierarchy"。
当你这样做时:
stemmer.stem(WordNetLemmatizer().lemmatize(document))
您正在使用 wordnet 进行词干提取 - 首先对词进行词根化,然后进行词干提取,删除 "morphological/inflexional" 词。事实上,如果你进行词干提取,你甚至不需要词形还原(它只会改变不规则动词的内容)。
词形还原
词形还原,另一方面,使用词汇信息将单词缩减为 "default" 非弯曲形式。为使它起作用,提供 te POS 非常重要(因为如您所见,leaves 是一个既表示动词又表示名词的词素)。
但是如何找到词性呢?
今天有一些技术,但最常用的一种是基于查找 table 和周围的词 - 这些被输入预训练的机器学习算法,returns 最可能的标签。阅读更多内容:https://medium.com/greyatom/learning-pos-tagging-chunking-in-nlp-85f7f811a8cb
使用名为 NLTK 的流行 Python NLP 包,您可以: (你必须先下载相关的包)
import nltk
sentence = "I want to tag these!"
token = nltk.word_tokenize(sentence)
nltk.pos_tag(token)
结果:
[('I', 'PRP'), ('want', 'VBP'), ('to', 'TO'), ('tag', 'VB'), ('these', 'DT'), ('!', '.')]
另一个流行的工具是 Spacy,如下所示: (您必须先下载带有机器学习训练模型的语言模型)
import spacy
import spacy
nlp = spacy.load('en')
doc = nlp('I want to tag these!')
print([(token.text, token.pos_) for token in doc])
结果:
[('I', 'PRON'), ('want', 'VERB'), ('to', 'PART'), ('tag', 'VERB'), ('these', 'DET'), ('!', 'PUNCT')]
您可以在此处阅读有关 Spacy 词性标记的更多信息:https://spacy.io/usage/linguistic-features/
然后我建议您坚持使用词形还原,因为这将为您提供更细粒度的选项。