1.自然語言處理(NLP)與Python
自然語言工具包(NLTK)
NLTK 創建於 2001 年,最初是賓州大學計算機與資訊科學系計算語言學課程的一部分 。從那以後,在數十名貢獻者的幫助下不斷髮展壯大。如今,它已被幾十所大學的課程所採納 ,並作為許多研究專案的基礎。NLTK模組及功能介紹如下:
語言處理任務 | NLTK模組 | 功能描述 |
---|---|---|
獲取語料庫 | nltk.corpus | 語料庫和詞彙的標準化介面 |
字串處理 | nltk.tokenize, nltk.stem | 分詞器,句子分解提取主幹 |
搭配發現 | nltk.collocations | t-檢驗,卡方,點互資訊(PMI) |
詞性識別符號 | nltk.tag | n-gram,backoff,Brill,HMM,TnT |
分類 | nltk.classify, nltk.cluster | 決策樹,最大熵,貝葉斯,EM,k-means |
分塊 | nltk.chunk | 正則表示式,n-gram,命名實體 |
解析 | nltk.parse | 圖表,基於特徵,一致性,概率,依賴 |
語義解釋 | nltk.sem, nltk.inference | λ演算,一階邏輯,模型檢驗 |
指標評測 | nltk.metrics | 精度,召回率,協議係數 |
概率與估計 | nltk.probability | 頻率分佈,平滑概率分佈 |
應用 | nltk.app, nltk.chat | 圖形化的關鍵詞排序,分析器,WordNet檢視器,聊天機器人 |
語言學領域的工作 | nltk.toolbox | 處理 SIL工具箱格式的資料 |
NLTK設計中4個主要目標:
1、簡易性:提供一個直觀的框架以及大量的模組,使使用者獲取 NLP 知識而不必陷入像標註語言資料那樣繁瑣的事務中。
2、一致性:提供一個具有一致的介面和資料結構並且方法名稱容易被猜到的統一的框架。
3、可擴充套件性:提供一種結構,新的軟體模組包括同一個任務中的不同的實現和相互衝突的方法都可以方便新增進來。
4、模組化:提供可以獨立使用而與工具包的其他部分無關的元件。
NLTK入門
首先應該安裝 NLTk。可以從 http://www.nltk.org/免費下載。按照說明下載適合你的作業系統的版本。
安裝完 NLTK 之後,啟動 Python 直譯器。在 Python 提示符後面輸入下面兩個命令來安裝本書所需的資料,然後選擇 book進行下載。(我的Python版本是3.5.1)
>>>import nltk
>>>nltk.download()
此時會出現下載介面(我的已近下載完畢):
然後從nltk的book模組載入所有東西:
>>>from nltk.book import *
*** Introductory Examples for the NLTK Book ***
Loading text1, ..., text9 and sent1, ..., sent9
Type the name of the text or sentence to view it.
Type: 'texts()' or 'sents()' to list the materials.
text1: Moby Dick by Herman Melville 1851
text2: Sense and Sensibility by Jane Austen 1811
text3: The Book of Genesis
text4: Inaugural Address Corpus
text5: Chat Corpus
text6: Monty Python and the Holy Grail
text7: Wall Street Journal
text8: Personals Corpus
text9: The Man Who Was Thursday by G . K . Chesterton 1908
任何時候我們想要找到這些文字,只需要在 Python 提示符後輸入它們的名字。
>>> text1
<Text: Moby Dick by Herman Melville 1851>
>>> text2
<Text: Sense and Sensibility by Jane Austen 1811>
搜尋文字
我們輸入 text1 後面跟一個點,再輸入函式名 concordance,然後將 monstrous放在括號裡,來查一下《白鯨記》中的詞monstrous :
concordance使我們看到詞的上下文。例如:我們看到 monstrous 出現的上下文,如 the___ pictures 和 a___ size 。還有哪些詞出現在相似的上下文中?我們可以通過在被查詢的文字名後新增函式名 similar,然後在括號中插入相關的詞來查詢到。
函式common_contexts允許我們研究兩個或兩個以上的詞共同的上下文,如 monstrous 和 very 。我們必須用方括號和圓括號把這些詞括起來,中間用逗號分割。
>>> text2.common_contexts(["monstrous", "very"])
be_glad am_glad a_pretty is_pretty a_lucky
我們也可以判斷詞在文字中的位置:從文字開頭算起在它前面有多少詞。這個位置資訊可以用 離散圖表示。每一個豎線代表一個單詞,每一行代表整個文字。
>>> text4.dispersion_plot(["citizens", "democracy", "freedom", "duties", "America"])
計數詞彙
我們使用函式 len 獲取長度,請看在《創世紀》中使用的例子:
>>> len(text3)
44764
《創世紀》有 44764 個詞和標點符號或者叫“識別符號”。這樣重複出現的詞彙或標點也會被計入在內。
《創世紀》中有多少不同的詞?要用 Python 來回答這個問題,我們處理問題的方法將稍有改變 。一個文字詞彙表只是它用到的識別符號的集合,因為在集合中所有重複的元素都只算一個。
>>> sorted(set(text3))
['!', "'", '(', ')', ',', ',)', '.', '.)', ':', ';', ';)', '?', '?)','A', 'Abel', 'Abelmizraim', 'Abidah', 'Abide', 'Abimael', 'Abimelech','Abr', 'Abrah', 'Abraham', 'Abram', 'Accad', 'Achbor', 'Adah', ...]
>>> len(set(text3))
2789
>>>
用 sorted()包裹起 Python 表示式 set(text3),我們得到一個詞彙項的排序表,這個表以各種標點符號開始,然後是以 A 開頭的詞彙。大寫單詞排在小寫單詞前面。我們通過求集合中專案的個數間接獲得詞彙表的大小。再次使用 len 來獲得這個數值。
現在,讓我們對文字詞彙豐富度進行測量。下一個例子向我們展示了每個字平均被使用
了 16 次(我們需要確保 Python 使用的是浮點除法):
>>> len(text3) / len(set(text3))
16.050197203298673
>>>
接下來,讓我們專注於特定的詞。計數一個詞在文字中出現的次數,計算一個特定的詞在文字中佔據的百分比。
>>> text3.count("smote")
5
>>> 100 * text4.count('a') / len(text4)
1.4643016433938312
頻率分佈(Frequency Distributions)
讓我們使用 FreqDist 尋找《白鯨記》中最常見的 50 個詞:
第一次呼叫 FreqDist 時,傳遞文字的名稱作為引數。我們可以看到已經被計算出來的《白鯨記》中的總的詞數(“結果”)——高達 260,819。
我們可以產生一個這些詞彙的累積頻率圖,使用 fd1.plot(50, cumulative=True):
如果高頻詞對我們沒有幫助,那些只出現了一次的詞(所謂的 hapaxes)輸入 fdist1.hapaxes()檢視它們。
細粒度的詞語選擇(Fine-grained Selection of Words)
以下是聊天語料庫中所有長度超過7 個字元出現次數超過 7 次的詞:
>>> fdist5 = FreqDist(text5)
>>> sorted([w for w in set(text5) if len(w) > 7 and fdist5[w] > 7])
['#14-19teens', '#talkcity_adults', '((((((((((', '........', 'Question','actually', 'anything', 'computer', 'cute.-ass', 'everyone', 'football','innocent', 'listening', 'remember', 'seriously', 'something', 'together','tomorrow', 'watching']
詞語搭配和雙連詞(Collocations and Bigrams)
一個搭配是經常在一起出現的詞序列。 red wine 是一個搭配而 the wine 不是 。collocations()函式為我們做這些:
NLTK頻率分佈類中定義的函式
例子 | 描述 |
---|---|
fdist = FreqDist(samples) | 建立包含給定樣本的頻率分佈 |
fdist.inc(sample) | 增加樣本 |
fdist[‘monstrous’] | 計數給定樣本出現的次數 |
fdist.freq(‘monstrous’) | 給定樣本的頻率 |
fdist.N() | 樣本總數 |
fdist.most_common(n) | 前n個最長出現的樣本以及它們的頻率 |
for sample in fdist: | 遍歷樣本 |
fdist.max() | 數值最大的樣本 |
fdist.tabulate() | 繪製頻率分佈表 |
fdist.plot() | 繪製頻率分佈圖 |
fdist.plot(cumulative=True) | 繪製累積頻率分佈圖 |
fdist1 < fdist2 | 測試樣本在 fdist1 中出現的頻率是否小於 fdist2 |