淺談Python NLP入門

來源:互聯網
上載者:User
本文主要介紹了Python NLP入門教程,Python自然語言處理(NLP),使用Python的NLTK庫。NLTK是Python的自然語言處理工具包,在NLP領域中,最常使用的一個Python庫。小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望能協助到大家。

什麼是NLP?

簡單來說,自然語言處理(NLP)就是開發能夠理解人類語言的應用程式或服務。

這裡討論一些自然語言處理(NLP)的實際應用例子,如語音辨識、語音翻譯、理解完整的句子、理解匹配詞的同義字,以及產生文法正確完整句子和段落。

這並不是NLP能做的所有事情。

NLP實現

搜尋引擎: 比如Google,Yahoo等。Google搜尋引擎知道你是一個技術人員,所以它顯示與技術相關的結果;

社交網站推送:比如Facebook News Feed。如果News Feed演算法知道你的興趣是自然語言處理,就會顯示相關的廣告和文章。

語音引擎:比如Apple的Siri。

垃圾郵件過濾:如Google垃圾郵件過濾器。和普通垃圾郵件過濾不同,它通過瞭解郵件內容裡面的的深層意義,來判斷是不是垃圾郵件。

NLP庫

下面是一些開源的自然語言處理庫(NLP):

  1. Natural language toolkit (NLTK);

  2. Apache OpenNLP;

  3. Stanford NLP suite;

  4. Gate NLP library

其中自然語言工具包(NLTK)是最受歡迎的自然語言處理庫(NLP),它是用Python編寫的,而且背後有非常強大的社區支援。

NLTK也很容易上手,實際上,它是最簡單的自然語言處理(NLP)庫。

在這個NLP教程中,我們將使用Python NLTK庫。

安裝 NLTK

如果您使用的是Windows/Linux/Mac,您可以使用pip安裝NLTK:


pip install nltk

開啟python終端匯入NLTK檢查NLTK是否正確安裝:


import nltk

如果一切順利,這意味著您已經成功地安裝了NLTK庫。首次安裝了NLTK,需要通過運行以下代碼來安裝NLTK擴充包:


import nltknltk.download()

這將彈出NLTK 下載視窗來選擇需要安裝哪些包:

您可以安裝所有的包,因為它們的大小都很小,所以沒有什麼問題。

使用Python Tokenize文本

首先,我們將抓取一個web頁面內容,然後分析文本瞭解頁面的內容。

我們將使用urllib模組來抓取web頁面:


import urllib.requestresponse = urllib.request.urlopen('http://php.net/')html = response.read()print (html)

從列印結果中可以看到,結果包含許多需要清理的HTML標籤。

然後BeautifulSoup模組來清洗這樣的文字:


from bs4 import BeautifulSoupimport urllib.requestresponse = urllib.request.urlopen('http://php.net/')html = response.read()soup = BeautifulSoup(html,"html5lib")# 這需要安裝html5lib模組text = soup.get_text(strip=True)print (text)

現在我們從抓取的網頁中得到了一個乾淨的文本。

下一步,將文本轉換為tokens,像這樣:


from bs4 import BeautifulSoupimport urllib.requestresponse = urllib.request.urlopen('http://php.net/')html = response.read()soup = BeautifulSoup(html,"html5lib")text = soup.get_text(strip=True)tokens = text.split()print (tokens)

統計詞頻

text已經處理完畢了,現在使用Python NLTK統計token的頻率分布。

可以通過調用NLTK中的FreqDist()方法實現:


from bs4 import BeautifulSoupimport urllib.requestimport nltkresponse = urllib.request.urlopen('http://php.net/')html = response.read()soup = BeautifulSoup(html,"html5lib")text = soup.get_text(strip=True)tokens = text.split()freq = nltk.FreqDist(tokens)for key,val in freq.items():  print (str(key) + ':' + str(val))

如果搜尋輸出結果,可以發現最常見的token是PHP。

您可以調用plot函數做出頻率分布圖:


freq.plot(20, cumulative=False)# 需要安裝matplotlib庫

這上面這些單詞。比如of,a,an等等,這些詞都屬於停用詞。

一般來說,停用詞應該刪除,防止它們影響分析結果。

處理停用詞

NLTK內建了許多種語言的停用詞列表,如果你擷取英文停用詞:


from nltk.corpus import stopwordsstopwords.words('english')

現在,修改下代碼,在繪圖之前清除一些無效的token:


clean_tokens = list()sr = stopwords.words('english')for token in tokens:  if token not in sr:    clean_tokens.append(token)

最終的代碼應該是這樣的:


from bs4 import BeautifulSoupimport urllib.requestimport nltkfrom nltk.corpus import stopwordsresponse = urllib.request.urlopen('http://php.net/')html = response.read()soup = BeautifulSoup(html,"html5lib")text = soup.get_text(strip=True)tokens = text.split()clean_tokens = list()sr = stopwords.words('english')for token in tokens:  if not token in sr:    clean_tokens.append(token)freq = nltk.FreqDist(clean_tokens)for key,val in freq.items():  print (str(key) + ':' + str(val))

現在再做一次詞頻統計圖,效果會比之前好些,因為剔除了停用詞:


freq.plot(20,cumulative=False)

使用NLTK Tokenize文本

在之前我們用split方法將文本分割成tokens,現在我們使用NLTK來Tokenize文本。

文本沒有Tokenize之前是無法處理的,所以對文本進行Tokenize非常重要的。token化過程意味著將大的組件分割為小組件。

你可以將段落tokenize成句子,將句子tokenize成單個詞,NLTK分別提供了句子tokenizer和單詞tokenizer。

假如有這樣這段文本:

Hello Adam, how are you? I hope everything is going well. Today is a good day, see you dude.

使用句子tokenizer將文本tokenize成句子:


from nltk.tokenize import sent_tokenizemytext = "Hello Adam, how are you? I hope everything is going well. Today is a good day, see you dude."print(sent_tokenize(mytext))

輸出如下:

['Hello Adam, how are you?', 'I hope everything is going well.', 'Today is a good day, see you dude.']

這是你可能會想,這也太簡單了,不需要使用NLTK的tokenizer都可以,直接使用Regex來拆分句子就行,因為每個句子都有標點和空格。

那麼再來看下面的文本:

Hello Mr. Adam, how are you? I hope everything is going well. Today is a good day, see you dude.

這樣如果使用標點符號拆分,Hello Mr將會被認為是一個句子,如果使用NLTK:


from nltk.tokenize import sent_tokenizemytext = "Hello Mr. Adam, how are you? I hope everything is going well. Today is a good day, see you dude."print(sent_tokenize(mytext))

輸出如下:
['Hello Mr. Adam, how are you?', 'I hope everything is going well.', 'Today is a good day, see you dude.']

這才是正確的拆分。

接下來試試單詞tokenizer:


from nltk.tokenize import word_tokenizemytext = "Hello Mr. Adam, how are you? I hope everything is going well. Today is a good day, see you dude."print(word_tokenize(mytext))

輸出如下:

['Hello', 'Mr.', 'Adam', ',', 'how', 'are', 'you', '?', 'I', 'hope', 'everything', 'is', 'going', 'well', '.', 'Today', 'is', 'a', 'good', 'day', ',', 'see', 'you', 'dude', '.']

Mr.這個詞也沒有被分開。NLTK使用的是punkt模組的PunktSentenceTokenizer,它是NLTK.tokenize的一部分。而且這個tokenizer經過訓練,可以適用於多種語言。

非英文Tokenize

Tokenize時可以指定語言:


from nltk.tokenize import sent_tokenizemytext = "Bonjour M. Adam, comment allez-vous? J'espère que tout va bien. Aujourd'hui est un bon jour."print(sent_tokenize(mytext,"french"))

輸出結果如下:

['Bonjour M. Adam, comment allez-vous?', "J'espère que tout va bien.", "Aujourd'hui est un bon jour."]

同義字處理

使用nltk.download()安裝介面,其中一個包是WordNet。

WordNet是一個為自然語言處理而建立的資料庫。它包括一些同義字組和一些簡短的定義。

您可以這樣擷取某個給定單詞的定義和樣本:


from nltk.corpus import wordnetsyn = wordnet.synsets("pain")print(syn[0].definition())print(syn[0].examples())

輸出結果是:

a symptom of some physical hurt or disorder
['the patient developed severe pain and distension']

WordNet包含了很多定義:


from nltk.corpus import wordnetsyn = wordnet.synsets("NLP")print(syn[0].definition())syn = wordnet.synsets("Python")print(syn[0].definition())

結果如下:

the branch of information science that deals with natural language information
large Old World boas

可以像這樣使用WordNet來擷取同義字:


from nltk.corpus import wordnetsynonyms = []for syn in wordnet.synsets('Computer'):  for lemma in syn.lemmas():    synonyms.append(lemma.name())print(synonyms)

輸出:

['computer', 'computing_machine', 'computing_device', 'data_processor', 'electronic_computer', 'information_processing_system', 'calculator', 'reckoner', 'figurer', 'estimator', 'computer']

反義詞處理

也可以用同樣的方法得到反義詞:


from nltk.corpus import wordnetantonyms = []for syn in wordnet.synsets("small"):  for l in syn.lemmas():    if l.antonyms():      antonyms.append(l.antonyms()[0].name())print(antonyms)

輸出:
['large', 'big', 'big']

詞幹提取

語言形態學和資訊檢索裡,詞幹提取是去除詞綴得到詞根的過程,例如working的詞幹為work。

搜尋引擎在索引頁面時就會使用這種技術,所以很多人為相同的單詞寫出不同的版本。

有很多種演算法可以避免這種情況,最常見的是傳輸速率詞幹演算法。NLTK有一個名為PorterStemmer的類,就是這個演算法的實現:


from nltk.stem import PorterStemmerstemmer = PorterStemmer()print(stemmer.stem('working'))print(stemmer.stem('worked'))

輸出結果是:

work
work

還有其他的一些詞幹提取演算法,比如 Lancaster詞幹演算法。

非英文詞幹提取

除了英文之外,SnowballStemmer還支援13種語言。

支援的語言:


from nltk.stem import SnowballStemmerprint(SnowballStemmer.languages)'danish', 'dutch', 'english', 'finnish', 'french', 'german', 'hungarian', 'italian', 'norwegian', 'porter', 'portuguese', 'romanian', 'russian', 'spanish', 'swedish'

你可以使用SnowballStemmer類的stem函數來提取像這樣的非英文單詞:


from nltk.stem import SnowballStemmerfrench_stemmer = SnowballStemmer('french')print(french_stemmer.stem("French word"))

單詞變體還原

單詞變體還原類似於詞幹,但不同的是,變體還原的結果是一個真實的單詞。不同於詞幹,當你試圖提取某些詞時,它會產生類似的詞:


from nltk.stem import PorterStemmerstemmer = PorterStemmer()print(stemmer.stem('increases'))

結果:

increas

現在,如果用NLTK的WordNet來對同一個單詞進行變體還原,才是正確的結果:


from nltk.stem import WordNetLemmatizerlemmatizer = WordNetLemmatizer()print(lemmatizer.lemmatize('increases'))

結果:

increase

結果可能會是一個同義字或同一個意思的不同單詞。

有時候將一個單詞做變體還原時,總是得到相同的詞。

這是因為語言的預設部分是名詞。要得到動詞,可以這樣指定:


from nltk.stem import WordNetLemmatizerlemmatizer = WordNetLemmatizer()print(lemmatizer.lemmatize('playing', pos="v"))

結果:
play

實際上,這也是一種很好的文本壓縮方式,最終得到文本只有原先的50%到60%。

結果還可以是動詞(v)、名詞(n)、形容詞(a)或副詞(r):


from nltk.stem import WordNetLemmatizerlemmatizer = WordNetLemmatizer()print(lemmatizer.lemmatize('playing', pos="v"))print(lemmatizer.lemmatize('playing', pos="n"))print(lemmatizer.lemmatize('playing', pos="a"))print(lemmatizer.lemmatize('playing', pos="r"))

輸出:
play
playing
playing
playing

詞乾和變體的區別

通過下面例子來觀察:


from nltk.stem import WordNetLemmatizerfrom nltk.stem import PorterStemmerstemmer = PorterStemmer()lemmatizer = WordNetLemmatizer()print(stemmer.stem('stones'))print(stemmer.stem('speaking'))print(stemmer.stem('bedroom'))print(stemmer.stem('jokes'))print(stemmer.stem('lisa'))print(stemmer.stem('purple'))print('----------------------')print(lemmatizer.lemmatize('stones'))print(lemmatizer.lemmatize('speaking'))print(lemmatizer.lemmatize('bedroom'))print(lemmatizer.lemmatize('jokes'))print(lemmatizer.lemmatize('lisa'))print(lemmatizer.lemmatize('purple'))

輸出:
stone
speak
bedroom
joke
lisa
purpl
---------------------
stone
speaking
bedroom
joke
lisa
purple

詞幹提取不會考慮語境,這也是為什麼詞幹提取比變體還原快且準確度低的原因。

個人認為,變體還原比詞幹提取更好。單詞變體還原返回一個真實的單詞,即使它不是同一個單詞,也是同義字,但至少它是一個真實存在的單詞。

如果你只關心速度,不在意準確度,這時你可以選用詞幹提取。

在此NLP教程中討論的所有步驟都只是文本預先處理。在以後的文章中,將會使用Python NLTK來實現文本分析。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.