玩點好玩的--使用馬爾可夫模型自動生成文章
馬爾可夫鏈是一個隨機過程,在這個過程中,我們假設前一個或前幾個狀態對預測下一個狀態起決定性作用。和拋硬幣不同,這些事件之間不是相互獨立的。通過一個例子更容易理解。
想像一下天氣只能是下雨天或者晴天。也就是說,狀態空間是雨天或者晴天。我們可以將馬爾可夫模型表示為一個轉移矩陣,矩陣的每一行代表一個狀態,每一列代表該狀態轉移到另外一個狀態的概率。
然而,通過這個狀態轉移示意圖更容易理解。
換句話說,假如今天是晴天,那麼有90%的概率明天也是晴天,有10%的概率明天是下雨天。
文章生成器
馬爾可夫模型有個很酷的應用是一種語言模型,在這個模型中,我們根據當前的一個或幾個詞預測下一個詞是什麼。如果我們只是根據上一個詞預測,則它是一個一階馬爾可夫模型。如果我們用上兩個詞預測,則它是一個二階馬爾可夫模型。
在我的實例中,我使用Henry Thoreau的小說Walden做訓練。為了好做實驗,我也加入了Nietszche的Thus Spoke Zarathustra,以及一些Obama的演講。無論你訓練什麼樣的文本,模型都會生成相似的結果,是不是很酷?
首先我們引入NLTK,它是Python中最好的NLP庫。我想說,雖然我們這裡做的自然語言處理很簡單,但NLTK的內置函數還是幫我節省了很多代碼。然後我們利用split()函數將字元串(從文本文件中獲得的)轉換成一個數組。
import nltkfile = open(Text/Walden.txt, r)walden = file.read()walden = walden.split()
下邊兩個函數是代碼的基本函數。我們最終要使用的NLTK中的「條件頻率字典」必須以成對數組作為輸入,所以短語「Hi my name is Alex」需要變為[(「Hi」, 「my」), (「my, 「name」), (「name」, 「is」), (「is」, 「Alex」)]。函數makePairs以一個數組(以詞分割字元串得到)作為輸入,輸出符合上邊格式的數組。
生成文章的方法,需要一個條件頻率分布作為輸入。想想看,「farm」的後邊每一個詞出現的次數是多少?這是一個「條件頻率分布」的輸出(對於所有的詞,而不只是「farm」)。生成函數的其餘部分是根據訓練數據中觀察到的分布輸出文本。我通過創建一個出現在當前詞後邊的每一個片語成的數組實現這一點。數組中也有正確的計數,因此,接下來我只需要隨機選擇數組中的一個詞即可,而這個過程也是服從分布的。
def makePairs(arr): pairs = [] for i in range(len(arr)): if i < len(arr) - 1: temp = (arr[i], arr[i + 1]) pairs.append(temp) return pairsdef generate(cfd, word=the, num=50): for i in range(num): # make an array with the words shown by proper count arr = [] for j in cfd[word]: for k in range(cfd[word][j]): arr.append(j) print(word, end= ) # choose the word randomly from the conditional distribution word = arr[int((len(arr)) * random.random())]
最後三行代碼,我們輸出了一些很像Walden風格的文本。
pairs = makePairs(walden)cfd = nltk.ConditionalFreqDist(pairs)generate(cfd)
最終的結果:
the quality in fact that I catch."—"Whats your cheek bones. Each time, and philanthropist. How often that we say that it conforms to seat of Indian and perchance the love comfort and then the Indians subject of a male or shiner may be connected under a sense will be along its whole new enlightened countries. There was as I had selected were suent. The authority of, the pond, and sudden accident I shall I required, about the universe and the inlet there.
我建議你看一下我Github上的iPython筆記,因為我繼續完成了一個方法。利用這個方法,你只需要輸入一個文件名,它就能輸出生成的文本。Obama的例子也非常的酷。
如果你想自己嘗試一下,只需要創建一個文本文件,然後把它放在合適的目錄即可。
同時我也把代碼和文檔放到我自己的Github:xianhu/LearnPython
=============================================================
作者主頁:笑虎(Python愛好者,關注爬蟲、數據分析、數據挖掘、數據可視化等)
作者專欄主頁:擼代碼,學知識 - 知乎專欄
作者GitHub主頁:擼代碼,學知識 - GitHub
歡迎大家拍磚、提意見。相互交流,共同進步!
==============================================================
推薦閱讀:
※RStudio | R語言應用及發展峰會(精華分享)
※購物籃關聯分析——R挖掘Apriori演算法
※用R語言分析我和男友的聊天記錄
※【資源收藏】想學AI和數據挖掘,關注這些號就夠了!