2011-12-28 45 views
4

我想生成一個隨機文本,使用字母頻率從書中的.txt文件,以便每個新字符(string.lowercase + ' ')取決於前一個。馬爾可夫鏈上的字母和隨機文本

如何使用馬爾可夫鏈來做到這一點?或者每個字母使用27個帶條件頻率的數組更簡單嗎?

+0

隨機文本或隨機的話嗎?如果它只是隨機文本,則不需要使用馬爾可夫鏈。 – jknupp 2011-12-28 19:02:25

+0

@jknupp它只是隨機字母和空格,而不是單詞。我怎麼沒有馬爾可夫鏈? – Julia 2011-12-28 19:13:24

+0

如果您不關心字母頻率是否相同,您可以使用隨機數字生成器生成一個隨機字符,其範圍涵蓋您感興趣的編碼類型。如果您需要的頻率相同,則計算基於前一封信的字母頻率將是最直接的方式。 – jknupp 2011-12-28 19:16:27

回答

8

我想在一個txt文件使用從 本書信的頻率而生成隨機文本

在文本文件中的兩個字母循環時考慮使用collections.Counter來積聚的頻率一次。

如何使用markov鏈來做到這一點?或者是更簡單的使用27個數組 與每個字母的條件頻率?

這兩個語句是等價的。馬爾可夫鏈是你在做什麼。具有條件頻率的27個陣列是您正在做什麼

下面是一些基於字典的代碼,讓你開始:

from collections import defaultdict, Counter 
from itertools import ifilter 
from random import choice, randrange 

def pairwise(iterable): 
    it = iter(iterable) 
    last = next(it) 
    for curr in it: 
     yield last, curr 
     last = curr 

valid = set('abcdefghijklmnopqrstuvwxyz ') 

def valid_pair((last, curr)): 
    return last in valid and curr in valid 

def make_markov(text): 
    markov = defaultdict(Counter) 
    lowercased = (c.lower() for c in text) 
    for p, q in ifilter(valid_pair, pairwise(lowercased)): 
     markov[p][q] += 1 
    return markov 

def genrandom(model, n): 
    curr = choice(list(model)) 
    for i in xrange(n): 
     yield curr 
     if curr not in model: # handle case where there is no known successor 
      curr = choice(list(model)) 
     d = model[curr] 
     target = randrange(sum(d.values())) 
     cumulative = 0 
     for curr, cnt in d.items(): 
      cumulative += cnt 
      if cumulative > target: 
       break 

model = make_markov('The qui_.ck brown fox') 
print ''.join(genrandom(model, 20)) 
+1

我編輯了你的答案,以免滾動文字 – joaquin 2011-12-28 19:21:29

+0

非常感謝! – Julia 2011-12-28 20:27:30

+0

@Julia不客氣:-) – 2011-12-28 20:41:18

1

如果每個字符只取決於前一個字符,則可以計算所有27^2個字符對的概率。