【火爐煉AI】機器學習036-NLP詞形還原

煉丹老頑童發表於2018-10-09

【火爐煉AI】機器學習036-NLP詞形還原

(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, NLTK 3.3)

詞形還原也是將單詞轉換為原來的相貌,和上一篇文章中介紹的詞幹提取不一樣,詞形還原要難的多,它是一個更加結構化的方法,在上一篇中的詞幹提取例子中,可以看到將wolves提取為wolv等,這些肯定不是我們所期望的。那麼此處我們使用NLP詞形還原的方式來將英語單詞還原。


1. NLP詞形還原

詞形還原是基於字典的對映,而且,NLTK還要求手動註明詞形,否則可能會還原不準確,所以在做自然語言處理的過程中,先對文字進行分詞,然後標註詞性,最後再進行詞形還原。

# 待還原的單詞
words = ['table', 'probably', 'wolves', 'playing', 'is', 
        'dog', 'the', 'beaches', 'grounded', 'dreamt', 'envision']

# 由於詞形還原需要先標註詞性,故而此處我們用名詞和動詞兩種詞性進行測試
lemmatizers = ['NOUN LEMMATIZER', 'VERB LEMMATIZER'] # 兩種詞性
lemmatizer = WordNetLemmatizer()
formatted_row = '{:>24}' * (len(lemmatizers) + 1) # 使其列印格式一致
print(formatted_row.format('WORD',*lemmatizers)) # 列印表頭

for word in words: # # 每個單詞逐一變換
    lemmatized=[lemmatizer.lemmatize(word, pos='n'), lemmatizer.lemmatize(word, pos='v')]
    # 注意裡面pos表示詞性,分別表示名稱和動詞
    print(formatted_row.format(word,*lemmatized)) # 對提取後的stem進行拆包
複製程式碼

---------------------------輸---------出--------------------------------

                WORD         NOUN LEMMATIZER         VERB LEMMATIZER
               table                   table                   table
            probably                probably                probably
              wolves                    wolf                  wolves
             playing                 playing                    play
                  is                      is                      be
                 dog                     dog                     dog
                 the                     the                     the
             beaches                   beach                   beach
            grounded                grounded                  ground
              dreamt                  dreamt                   dream
            envision                envision                envision
複製程式碼

------------------------------完-------------------------------------

可以看出,雖然WordNetLemmatizer很有用,但是需要事先判斷詞性,並且把詞性作為一個引數傳入到這個函式中,那麼有沒有可能自動判斷詞性,不需要我們認為判斷了?這是肯定的,NLTK有一個函式pos_tag可以自動判斷出某個單詞的詞性,所以基於此,我們可以編寫一個函式,來自動處理一整個句子,輸出器詞性還原之後的形式。如下程式碼:

# 定義一個函式來對一個句子中的所有單詞進行詞形還原
def lemmatize_all(sentence):
    wnl = WordNetLemmatizer()
    for word, tag in pos_tag(word_tokenize(sentence)):
        if tag.startswith('NN'):
            yield wnl.lemmatize(word, pos='n')
        elif tag.startswith('VB'):
            yield wnl.lemmatize(word, pos='v')
        elif tag.startswith('JJ'):
            yield wnl.lemmatize(word, pos='a')
        elif tag.startswith('R'):
            yield wnl.lemmatize(word, pos='r')
        else:
            yield word

複製程式碼
text ='dog runs, cats drunk wines, chicken eat apples, foxes jumped two meters'
print('/'.join(lemmatize_all(text)))
複製程式碼

---------------------------輸---------出--------------------------------

dog/run/,/cat/drink/wine/,/chicken/eat/apple/,/fox/jump/two/meter

---------------------------------完-------------------------------------

可以看出,句子中的名詞複數都轉變為了單數,動詞過去式都轉變為了現在式等。

關於pos_tag()函式,返回的是單詞和詞性標籤,這些詞性標籤有:

# NLTK 詞性標籤: 
CC 連詞 and, or,but, if, while,although
CD 數詞 twenty-four, fourth, 1991,14:24
DT 限定詞 the, a, some, most,every, no
EX 存在量詞 there, there's
FW 外來詞 dolce, ersatz, esprit, quo,maitre
IN 介詞連詞 on, of,at, with,by,into, under
JJ 形容詞 new,good, high, special, big, local
JJR 比較級詞語 bleaker braver breezier briefer brighter brisker
JJS 最高階詞語 calmest cheapest choicest classiest cleanest clearest
LS 標記 A A. B B. C C. D E F First G H I J K
MD 情態動詞 can cannot could couldn't
NN 名詞 year,home, costs, time, education
NNS 名詞複數 undergraduates scotches
NNP 專有名詞 Alison,Africa,April,Washington
NNPS 專有名詞複數 Americans Americas Amharas Amityvilles
PDT 前限定詞 all both half many
POS 所有格標記 ' 's
PRP 人稱代詞 hers herself him himself hisself
PRP$ 所有格 her his mine my our ours
RB 副詞 occasionally unabatingly maddeningly
RBR 副詞比較級 further gloomier grander
RBS 副詞最高階 best biggest bluntest earliest
RP 虛詞 aboard about across along apart
SYM 符號 % & ' '' ''. ) )
TO 詞to to
UH 感嘆詞 Goodbye Goody Gosh Wow
VB 動詞 ask assemble assess
VBD 動詞過去式 dipped pleaded swiped
VBG 動詞現在分詞 telegraphing stirring focusing
VBN 動詞過去分詞 multihulled dilapidated aerosolized
VBP 動詞現在式非第三人稱時態 predominate wrap resort sue
VBZ 動詞現在式第三人稱時態 bases reconstructs marks
WDT Wh限定詞 who,which,when,what,where,how
WP WH代詞 that what whatever
WP$ WH代詞所有格 whose
WRB WH副詞

複製程式碼

########################小**********結###############################

1,NLP詞形還原可以使用WordNetLemmatizer函式,但是這個函式在使用前需要先判斷某個單詞的詞性,然後將詞性作為引數輸入到這個函式中進行轉換。

2,為了簡化這種人為判斷的過程,NLTK有自帶的詞性判斷函式pos_tag,這個函式可以自動輸出某個單詞的詞性,所以將pos_tag和WordNetLemmatizer函式聯合起來,可以自動對某一整段文字進行分詞,詞形還原等操作。

#################################################################


注:本部分程式碼已經全部上傳到(我的github)上,歡迎下載。

參考資料:

1, Python機器學習經典例項,Prateek Joshi著,陶俊傑,陳小莉譯

相關文章