當前位置: 首頁>>技術教程>>正文


Python 使用nltk WordNetLemmatizer做整個句子的詞形還原

詞形還原一般是指:

loving => love
helping => help
helps => help
scaling => scale
cars => car
cats => cat

在這篇文章中,我們將使用NLTK中的WordNetLemmatizer對句子進行詞形還原。 該詞形還原器接受輸入字符串並嘗試對其進行詞形還原,默認情況下,如果您傳入一個單詞,它會將其視為名詞進行詞形還原。

所以,簡單詞形還原的如下:


>>> nltk.stem.WordNetLemmatizer().lemmatize('loving')
'loving'
>>> nltk.stem.WordNetLemmatizer().lemmatize('loving', 'v')
u'love'

其中, ‘v’是指單詞的詞性為“動詞”。可以看到,如果不給定單詞的詞形,詞形還原的結果可能不是你想要的。那麽,對於一個完整的句子,如何根據上下文做好詞形還原呢?

為了使詞形還原更好地依賴於句子的上下文,我們需要找出詞性標記(如動詞、名詞、形容詞等),並將其傳遞給詞形還原器。 做法流程為,首先使用 NLTK 的post_tag找出每個單詞的 POS 標記(也就是詞性標記),然後使用這個標記在 WordNet 中查找相應的詞性,最後使用詞形還原器根據詞性標記對標記進行詞形還原。Python代碼示例如下:


import nltk
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet

lemmatizer = WordNetLemmatizer()

# function to convert nltk tag to wordnet tag
def nltk_tag_to_wordnet_tag(nltk_tag):
    if nltk_tag.startswith('J'):
        return wordnet.ADJ
    elif nltk_tag.startswith('V'):
        return wordnet.VERB
    elif nltk_tag.startswith('N'):
        return wordnet.NOUN
    elif nltk_tag.startswith('R'):
        return wordnet.ADV
    else:          
        return None

def lemmatize_sentence(sentence):
    #tokenize the sentence and find the POS tag for each token
    nltk_tagged = nltk.pos_tag(nltk.word_tokenize(sentence))  
    #tuple of (token, wordnet_tag)
    wordnet_tagged = map(lambda x: (x[0], nltk_tag_to_wordnet_tag(x[1])), nltk_tagged)
    lemmatized_sentence = []
    for word, tag in wordnet_tagged:
        if tag is None:
            #if there is no available tag, append the token as is
            lemmatized_sentence.append(word)
        else:        
            #else use the tag to lemmatize the token
            lemmatized_sentence.append(lemmatizer.lemmatize(word, tag))
    return " ".join(lemmatized_sentence)

print(lemmatizer.lemmatize("I am loving it")) #輸出:I am loving it
print(lemmatizer.lemmatize("loving")) #輸出:loving
print(lemmatizer.lemmatize("loving", "v")) #輸出:love
print(lemmatize_sentence("I am loving it")) #輸出:I be love it

以上就是一個較完整的句子詞形還原例程了。

nltk lemmatizer詞形還原

補充,最近從cnblogs找到了另外一個版本,做法比較類似。不同點在於,上文版本中將沒有找到詞性的詞直接輸出;而下麵的版本,將沒有找到詞性的單詞作為名詞進行詞形還原處理之後再輸出。示例如下:


from nltk import word_tokenize, pos_tag
from nltk.corpus import wordnet
from nltk.stem import WordNetLemmatizer

# 獲取單詞的詞性
def get_wordnet_pos(tag):
    if tag.startswith('J'):
        return wordnet.ADJ
    elif tag.startswith('V'):
        return wordnet.VERB
    elif tag.startswith('N'):
        return wordnet.NOUN
    elif tag.startswith('R'):
        return wordnet.ADV
    else:
        return None

sentence = 'football is a family of team sports that involve, to varying degrees, kicking a ball to score a goal.'
tokens = word_tokenize(sentence)  # 分詞
tagged_sent = pos_tag(tokens)     # 獲取單詞詞性

wnl = WordNetLemmatizer()
lemmas_sent = []
for tag in tagged_sent:
    wordnet_pos = get_wordnet_pos(tag[1]) or wordnet.NOUN
    lemmas_sent.append(wnl.lemmatize(tag[0], pos=wordnet_pos)) # 詞形還原

print(lemmas_sent)

輸出:

['football', 'be', 'a', 'family', 'of', 'team', 'sport', 'that', 'involve', ',', 'to', 'vary', 'degree', ',', 'kick', 'a', 'ball', 'to', 'score', 'a', 'goal', '.']

參考資料:
[1]: Lemmatize whole sentences with Python and nltk’s WordNetLemmatizer
[2]:NLTK WordNet Lemmatizer: Shouldn’t it lemmatize all inflections of a word?

本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/4753.html,轉載請注明來源鏈接。