N-Gram(有時也稱爲N元模型)是天然語言處理中一個很是重要的概念,一般在NLP中,人們基於必定的語料庫,能夠利用N-Gram來預計或者評估一個句子是否合理。另一方面,N-Gram的另一個做用是用來評估兩個字符串之間的差別程度。這是模糊匹配中經常使用的一種手段。本文將今後開始,進而向讀者展現N-Gram在天然語言處理中的各類powerful的應用。java
歡迎關注白馬負金羈的博客 http://blog.csdn.net/baimafujinji,爲保證公式、圖表得以正確顯示,強烈建議你從該地址上查看原版博文。本博客主要關注方向包括:數字圖像處理、算法設計與分析、數據結構、機器學習、數據挖掘、統計分析方法、天然語言處理。算法
在天然語言處理時,最經常使用也最基礎的一個操做是就是「模式匹配」,或者稱爲「字符串查找」。而模式匹配(字符串查找)又分爲精確匹配和模糊匹配兩種。apache
所謂精確匹配,你們應該並不陌生,好比咱們要統計一篇文章中關鍵詞 「information」 出現的次數,這時所使用的方法就是精確的模式匹配。這方面的算法也比較多,並且應該是計算機相關專業必修的基礎課中都會涉及到的內容,例如KMP算法、BM算法和BMH算法等等。markdown
另一種匹配就是所謂的模糊匹配,它的應用也隨處可見。例如,通常的文字處理軟件(例如,Microsoft Word等)都會提供拼寫檢查功能。當你輸入一個錯誤的單詞,例如 「 informtaion」 時,系統會提示你是否要輸入的詞實際上是 「information」 。將一個可能錯拼單詞映射到一個推薦的正確拼寫上所採用的技術就是模糊匹配。數據結構
模糊匹配的關鍵在於如何衡量兩個長得很像的單詞(或字符串)之間的「差別」。這種差別一般又稱爲「距離」。這方面的具體算法有不少,例如基於編輯距離的概念,人們設計出了 Smith-Waterman 算法和Needleman-Wunsch 算法,其中後者仍是歷史上最先的應用動態規劃思想設計的算法之一。如今Smith-Waterman 算法和Needleman-Wunsch 算法在生物信息學領域也有重要應用,研究人員經常用它們來計算兩個DNA序列片斷之間的「差別」(或稱「距離」)。甚至於在LeetCode上也有一道「No.72 Edit Distance」,其本質就是在考察上述兩種算法的實現。可見相關問題離咱們並不遙遠。機器學習
事實上,筆者在新出版的《算法之美——隱匿在數據結構背後的原理》一書中已經詳細介紹了包括Needleman-Wunsch算法、Smith-Waterman算法、N-Gram算法、Soundex算法、Phonix算法等在內的多種距離定義算法(或模糊匹配算法)。而今天爲了引出N-Gram模型在NLP中的其餘應用,咱們首先來介紹一下如何利用N-Gram來定義字符串之間的距離。函數
咱們除了能夠定義兩個字符串之間的編輯距離(一般利用Needleman-Wunsch算法或Smith-Waterman算法)以外,還能夠定義它們之間的N-Gram距離。N-Gram(有時也稱爲N元模型)是天然語言處理中一個很是重要的概念。假設有一個字符串 ss,那麼該字符串的N-Gram就表示按長度 N 切分原詞獲得的詞段,也就是 ss 中全部長度爲 N 的子字符串。設想若是有兩個字符串,而後分別求它們的N-Gram,那麼就能夠從它們的共有子串的數量這個角度去定義兩個字符串間的N-Gram距離。可是僅僅是簡單地對共有子串進行計數顯然也存在不足,這種方案顯然忽略了兩個字符串長度差別可能致使的問題。好比字符串 girl 和 girlfriend,兩者所擁有的公共子串數量顯然與 girl 和其自身所擁有的公共子串數量相等,可是咱們並不能據此認爲 girl 和girlfriend 是兩個等同的匹配。工具
爲了解決該問題,有學者便提出以非重複的N-Gram分詞爲基礎來定義 N-Gram距離這一律念,能夠用下面的公式來表述: post
在《算法之美——隱匿在數據結構背後的原理》一書中,咱們給出了在C++下實現的計算兩個字符串間N-Gram距離的函數,鑑於全書代碼已經在本博客中發佈,這裏再也不重複列出。事實上,不少語言的函數庫或者工具箱中都已經提供了封裝好的計算 N-Gram 距離的函數,下面這個例子演示了在Java中使用N-Gram 距離的方法。學習
針對這個例子,這裏須要說明的是:
import org.apache.lucene.search.spell.*; public class NGram_distance { public static void main(String[] args) { NGramDistance ng = new NGramDistance(); float score1 = ng.getDistance("Gorbachev", "Gorbechyov"); System.out.println(score1); float score2 = ng.getDistance("girl", "girlfriend"); System.out.println(score2); } }
有興趣的讀者能夠在引用相關JAR包以後在Eclipse中執行上述Java程序,你會發現,和咱們預期的同樣,字符串Gorbachev和Gorbechyov所得之距離評分較高(=0.7),說明兩者很接近;而girl和girlfriend所得之距離評分並不高(=0.3999),說明兩者並不很接近。
從如今開始,咱們所討論的N-Gram模型跟前面講過N-Gram模型從外在來看已經大不相同,可是請注意它們內在的聯繫(或者說本質上它們仍然是統一的概念)。
爲了引入N-Gram的這個應用,咱們從幾個例子開始。
首先,從統計的角度來看,天然語言中的一個句子 ss 能夠由任何詞串構成,不過幾率 P(s)P(s) 有大有小。例如:
顯然,對於中文而言 s1s1 是一個通順而有意義的句子,而s2s2 則不是,因此對於中文來講,P(s1)>P(s2)P(s1)>P(s2) 。但不一樣語言來講,這兩個機率值的大小可能會反轉。
其次,另一個例子是,若是咱們給出了某個句子的一個節選,咱們其實能夠可以猜想後續的詞應該是什麼,例如
顯然,若是咱們知道這個句子片斷更多前面的內容的狀況下,咱們會獲得一個更加準確的答案。這就告訴咱們,前面的(歷史)信息越多,對後面未知信息的約束就越強。
若是咱們有一個由 mm 個詞組成的序列(或者說一個句子),咱們但願算得機率 P(w1,w2,⋯,wm)P(w1,w2,⋯,wm) ,根據鏈式規則,可得
來看一個具體的例子,假設咱們如今有一個語料庫以下,其中<s1><s2><s1><s2> 是句首標記,</s2></s1></s2></s1> 是句尾標記:
再舉一個來自文獻[1]的例子,假設如今有一個語料庫,咱們統計了下面一些詞出現的數量
有研究人員用150萬詞的訓練語料來訓練 trigram 模型,而後用一樣來源的測試語料來作驗證,結果發現23%的 trigram 沒有在訓練語料中出現過。這其實就意味着上一節咱們所計算的那些機率有空爲 0,這就致使了數據稀疏的可能性,咱們的表3中也確實有些爲0的狀況。對語言而言,因爲數據稀疏的存在,極大似然法不是一種很好的參數估計辦法。
這時的解決辦法,咱們稱之爲「平滑技術」(Smoothing)或者 「減值」 (Discounting)。其主要策略是把在訓練樣本中出現過的事件的機率適當減少,而後把減少獲得的機率密度分配給訓練語料中沒有出現過的事件。實際中平滑算法有不少種,例如:
▸ Laplacian (add-one) smoothing
▸ Add-k smoothing
▸ Jelinek-Mercer interpolation
▸ Katz backoff
▸ Absolute discounting
▸ Kneser-Ney
對於這些算法的詳細介紹,咱們將在後續的文章中結合一些實例再來進行討論。
若是你能從前面那些繁冗、複雜的概念和公式中挺過來,恭喜你,你對N-Gram模型已經有所認識了。儘管,咱們還沒來得及探討平滑算法(但它即將出如今個人下一篇博文裏,若是你以爲還未過癮的話),可是其實你已經掌握了一個相對powerful的工具。你能夠能會問,在實踐中N-Gram模型有哪些具體應用,做爲本文的結束,主頁君便在此補充幾個你曾見過的或者曾經好奇它是如何實現的例子。
Eg.1
搜索引擎(Google或者Baidu)、或者輸入法的猜測或者提示。你在用百度時,輸入一個或幾個詞,搜索框一般會如下拉菜單的形式給出幾個像下圖同樣的備選,這些備選實際上是在猜測你想要搜索的那個詞串。再者,當你用輸入法輸入一個漢字的時候,輸入法一般能夠聯繫出一個完整的詞,例如我輸入一個「劉」字,一般輸入法會提示我是否要輸入的是「劉備」。經過上面的介紹,你應該可以很敏銳的發覺,這實際上是以N-Gram模型爲基礎來實現的,若是你能有這種覺悟或者想法,那我不得不恭喜你,都學會搶答了!
Eg.2
某某做家或者語料庫風格的文本自動生成。這是一個至關有趣的話題。來看下面這段話(該例子取材自文獻【1】):
「You are uniformly charming!」 cried he, with a smile of associating and now and then I bowed and they perceived a chaise and four to wish for.
你應該尚未感受到它有什麼異樣吧。但事實上這並非由人類寫出的句子,而是計算機根據Jane Austen的語料庫利用trigram模型自動生成的文段。(Jane Austen是英國著名女做家,表明做有《傲慢與偏見》等)
再來看兩個例子,你是否能看出它們是按照哪位文豪(或者語料庫)的風格生成的嗎?
答案是第一個是莎士比亞,第二個是華爾街日報。最後一個問題留給讀者思考,你以爲上面兩個文段所運用的n-gram模型中,n應該等於多少?
[1] Speech and Language Processing. Daniel Jurafsky & James H. Martin, 3rd. Chapter 4
[2] 本文中的一些例子和描述來自 北京大學 常寶寶 以及 The University of Melbourne 「Web Search and Text Analysis」 課程的幻燈片素材