因此有人提出了N-GRAM的演算法,這個演算法其實就是一種馬可夫模型,主要用來計算同樣類型的事件依序發生的機率,例如昨天與今天、後天天氣的關係(引自:Google 搜尋預測、拼字檢查、與即時翻譯背後的統計模型:N-Gram) 那運用在文字上,我們就可以觀察不同單字前後的關係。
中文字是方塊字,一個字有獨立的意思,但是基本上我們講話的時候還是以兩個字以上組合的"詞彙"作為單位,N-GRAM模型主要特點可以用來觀察兩個字一組、三個字一組、或四個字、五個字一組的詞彙出現的機率。我們根據這個想法來設計演算法。選擇PYTHON而不用R的原因在於PYTHON對於字串的處理相對簡單,而且程式碼看起來也會比R直覺。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import codecs | |
#處理編碼的套件 | |
import operator | |
##處理字典檔排序的套件 | |
text = codecs.open("text.txt","r","utf-8") | |
#讀取存成TXT檔的文字,讀入後統一轉成UTF-8格式 | |
text_new ="" | |
for line in text.readlines(): | |
text_new += "".join(line.split('\n')) | |
#在這邊先做一個小處理,把不同行的文章串接再一起,如果未來要做一些去除標點符號的處理也會是在這邊。 | |
def ngram(text,n): #第一個參數放處理好的文章,第二個參數放字詞的長度單位 | |
words=[] #存放擷取出來的字詞 | |
words_freq={}#存放字詞:計算個數 | |
for w in range(len(text)-(n-1)): #要讀取的長度隨字詞長度改變 | |
words.append(text[w:w+n]) #抓取長度w-(n-1)的字串 | |
for word in words: | |
if word not in words_freq: #如果這個字詞還沒有被放在字典檔中 | |
words_freq[word] = words.count(word) #就開一個新的字詞,裡面放入字詞計算的頻次 | |
words_freq = sorted(words_freq.iteritems(),key=operator.itemgetter(1),reverse=True) #change words_freq from dict to list | |
return words_freq | |
words_freqs = ngram(text_new,3) | |
for i in words_freqs: | |
print i[0],i[1] | |
''' | |
道:" 35 | |
笑道: 13 | |
"那僧 9 | |
聽了, 8 | |
"士隱 8 | |
。士隱 7 | |
。"那 7 | |
那僧道 6 | |
.... | |
''' | |
words_freqs = ngram(text_new,2) | |
for i in words_freqs: | |
print i[0],i[1] | |
''' | |
:" 45 | |
道: 36 | |
士隱 33 | |
雨村 25 | |
,不 24 | |
。" 22 | |
那僧 17 | |
,便 16 | |
... | |
''' |
未來更新重點:
1. 將標點符號視為句子間的分格符號,每一句獨立分析字詞頻次。
2. 將中文英文分開來辨識,中文是用一個"字"作為基本單位,英文是用一個"單字"
參考資料:
演算法筆記
How to Use UTF-8 with Python
協助解決 Google 難題的資訊萃取機制
nice article! thank you very much!
回覆刪除nice article! thank you very much!
回覆刪除welcome!
刪除請問R方面有相關library嗎
回覆刪除有許多詞彙用tmcn等等切割是錯誤的
不知有沒有類似演算法能自己切割正確
請參考 https://github.com/qinwf/jiebaR
刪除結巴分詞R版本
好的謝謝您!
刪除