在Python上基于Markov鏈生成偽隨機(jī)文本的教程
首先看一下來(lái)自Wolfram的定義
馬爾可夫鏈?zhǔn)请S機(jī)變量{X_t}的集合(t貫穿0,1,...),給定當(dāng)前的狀態(tài),未來(lái)與過(guò)去條件獨(dú)立。
Wikipedia的定義更清楚一點(diǎn)兒
...馬爾可夫鏈?zhǔn)蔷哂旭R爾可夫性質(zhì)的隨機(jī)過(guò)程...[這意味著]狀態(tài)改變是概率性的,未來(lái)的狀態(tài)僅僅依賴(lài)當(dāng)前的狀態(tài)。
馬爾可夫鏈具有多種用途,現(xiàn)在讓我看一下如何用它生產(chǎn)看起來(lái)像模像樣的胡言亂語(yǔ)。
算法如下,
- 找一個(gè)作為語(yǔ)料庫(kù)的文本,語(yǔ)料庫(kù)用于選擇接下來(lái)的轉(zhuǎn)換。
- 從文本中兩個(gè)連續(xù)的單詞開(kāi)始,最后的兩個(gè)單詞構(gòu)成當(dāng)前狀態(tài)。
- 生成下一個(gè)單詞的過(guò)程就是馬爾可夫轉(zhuǎn)換。為了生成下一個(gè)單詞,首先查看語(yǔ)料庫(kù),查找這兩個(gè)單詞之后跟著的單詞。從它們中隨機(jī)選擇一個(gè)。
- 重復(fù)2,直到生成的文本達(dá)到需要的大小。
代碼如下
import random
class Markov(object):
def __init__(self, open_file):
self.cache = {}
self.open_file = open_file
self.words = self.file_to_words()
self.word_size = len(self.words)
self.database()
def file_to_words(self):
self.open_file.seek(0)
data = self.open_file.read()
words = data.split()
return words
def triples(self):
""" Generates triples from the given data string. So if our string were
"What a lovely day", we'd generate (What, a, lovely) and then
(a, lovely, day).
"""
if len(self.words) < 3:
return
for i in range(len(self.words) - 2):
yield (self.words[i], self.words[i+1], self.words[i+2])
def database(self):
for w1, w2, w3 in self.triples():
key = (w1, w2)
if key in self.cache:
self.cache[key].append(w3)
else:
self.cache[key] = [w3]
def generate_markov_text(self, size=25):
seed = random.randint(0, self.word_size-3)
seed_word, next_word = self.words[seed], self.words[seed+1]
w1, w2 = seed_word, next_word
gen_words = []
for i in xrange(size):
gen_words.append(w1)
w1, w2 = w2, random.choice(self.cache[(w1, w2)])
gen_words.append(w2)
return ' '.join(gen_words)
為了看到一個(gè)示例結(jié)果,我們從古騰堡計(jì)劃中拿了沃德豪斯的《My man jeeves》作為文本,示例結(jié)果如下。
In [1]: file_ = open('/home/shabda/jeeves.txt')
In [2]: import markovgen
In [3]: markov = markovgen.Markov(file_)
In [4]: markov.generate_markov_text()
Out[4]: 'Can you put a few years of your twin-brother Alfred,
who was apt to rally round a bit. I should strongly advocate
the blue with milk'
[如果想執(zhí)行這個(gè)例子,請(qǐng)下載jeeves.txt和markovgen.py
馬爾可夫算法怎樣呢?
- 最后兩個(gè)單詞是當(dāng)前狀態(tài)。
- 接下來(lái)的單詞僅僅依賴(lài)最后兩個(gè)單詞,也就是當(dāng)前狀態(tài)。
- 接下來(lái)的單詞是從語(yǔ)料庫(kù)的統(tǒng)計(jì)模型中隨機(jī)選擇的。
這是一個(gè)示例文本。
這個(gè)文本對(duì)應(yīng)的語(yǔ)料庫(kù)像這樣,
{('The', 'quick'): ['brown'],
('brown', 'fox'): ['jumps', 'who', 'who'],
('fox', 'jumps'): ['over'],
('fox', 'who'): ['is', 'is'],
('is', 'slow'): ['jumps'],
('jumps', 'over'): ['the', 'the'],
('over', 'the'): ['brown', 'brown'],
('quick', 'brown'): ['fox'],
('slow', 'jumps'): ['over'],
('the', 'brown'): ['fox', 'fox'],
('who', 'is'): ['slow', 'dead.']}
現(xiàn)在如果我們從"brown fox"開(kāi)始,接下來(lái)的單詞可以是"jumps"或者"who"。如果我們選擇"jumps",然后當(dāng)前的狀態(tài)就變成了"fox jumps",再接下的單詞就是"over",之后依此類(lèi)推。
提示
- 我們選擇的文本越大,每次轉(zhuǎn)換的選擇更多,生成的文本更好看。
- 狀態(tài)可以設(shè)置為依賴(lài)一個(gè)單詞、兩個(gè)單詞或者任意數(shù)量的單詞。隨著每個(gè)狀態(tài)的單詞數(shù)的增加,生成的文本更不隨機(jī)。
- 不要去掉標(biāo)點(diǎn)符號(hào)等。它們會(huì)使語(yǔ)料庫(kù)更具代表性,隨機(jī)文本更好看。
相關(guān)文章
Python教程通過(guò)公共鍵對(duì)不同字典進(jìn)行排序示例詳解
本篇文章是Python教程基礎(chǔ)篇,通過(guò)一些示例為大家講解Python通過(guò)公共鍵對(duì)不同字典進(jìn)行排序的方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09
11個(gè)Python Pandas小技巧讓你的工作更高效(附代碼實(shí)例)
這篇文章主要介紹了11個(gè)Python Pandas小技巧讓你的工作更高效(附代碼實(shí)例),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-04-04
零基礎(chǔ)寫(xiě)python爬蟲(chóng)之抓取百度貼吧并存儲(chǔ)到本地txt文件改進(jìn)版
前面已經(jīng)發(fā)了一篇關(guān)于百度貼吧抓取的代碼,今天我們來(lái)看下代碼的改進(jìn)版,參考了上篇抓取糗事百科的思路,給需要的小伙伴們參考下吧2014-11-11
Python實(shí)現(xiàn)多張圖片合成文字的效果
前段時(shí)間看到有人問(wèn)如何使用Python實(shí)現(xiàn)多張圖片組成文字的效果?覺(jué)得還挺有意思,于是嘗試做了一下,剛好趕上端午節(jié),所以打算從網(wǎng)上下載1000張王心凌的照片,組成端午安康的字樣,感興趣的可以了解一下2022-06-06
Python實(shí)現(xiàn)AI自動(dòng)玩俄羅斯方塊游戲
提到《俄羅斯方塊》,那真是幾乎無(wú)人不知無(wú)人不曉。其歷史之悠久,可玩性之持久,能手輕輕一揮,吊打一大波游戲。本文將利用Python實(shí)現(xiàn)俄羅斯方塊進(jìn)階版—AI自動(dòng)玩俄羅斯方塊,感興趣的可以學(xué)習(xí)一下2022-03-03
使用Playwright進(jìn)行視覺(jué)回歸測(cè)試詳解
這篇文章主要介紹了使用Playwright進(jìn)行視覺(jué)回歸測(cè)試詳解,視覺(jué)回歸測(cè)試是一種軟件測(cè)試技術(shù),專(zhuān)注于檢測(cè)Web應(yīng)用程序或網(wǎng)站的用戶界面中的視覺(jué)變化和差異,需要的朋友可以參考下2023-08-08
Python的Flask框架及Nginx實(shí)現(xiàn)靜態(tài)文件訪問(wèn)限制功能
這篇文章主要介紹了Python的Flask框架及Nginx實(shí)現(xiàn)靜態(tài)文件訪問(wèn)限制功能,Nginx方面利用到了自帶的XSendfile,需要的朋友可以參考下2016-06-06

