1.概念學習
馬爾科夫模型常用於分析大量隨機事件,隨機事件的特點是一個離散事件發生之後,另一個離散事件將在前一個事件的條件下以一定的概率發生。以天氣的馬爾科夫模型爲例:
在這個天氣系統模型中,如果今天是晴天,那麼明天有70%的可能是晴天,20%的可能是多雲,10%的可能下雨。如果今天是下雨天,那麼明天有50%的可能也下雨,25%的可能是晴天,25%的可能是多雲。
需要注意以下幾點:
- 任何一個節點引出的所有可能的總和必須等於100%。無論是多麼複雜的系統,必然會在下一步發生若干事件中的一個事件;
- 雖然這個天氣系統在任一時間都只有三種可能,但是你可以用這個模型生成一個天氣狀態的無限次轉移列表;
- 只有當前節點的狀態會影響後一天的狀態。如果你在“晴天”節點上,即使前100天都是晴天或雨天都沒有關係,明天晴天的概率還是70%;
- 有些節點可能比其他節點較難到達,這個現象的原因用數學來解釋非常複雜,但是可以直觀地看出,在這個系統中任意時間節點上,第二天是“雨天”的可能性(指向它的箭頭概率之後下雨100%),比“晴天”和“多雲”要小很多
2. 實戰演練
from urllib.request import urlopen
from random import randint
def wordListSum(wordList):
sum=0
for word,value in wordList.items():
sum+=value
return sum
def retrieveRandomWord(wordList):
randIndex=randint(1,wordListSum(wordList))
for word,value in wordList.items():
randIndex-=value
if randIndex<0:
return word
def buildWordDict(text):
#剔除換行符和引號
text=text.replace("\n"," ")
text=text.replace("\"","")
text=text.replace("--","")
#保證每個標點符號都和前面的單詞在一起
#這樣不會被剔除,保留在馬爾科夫鏈中
punctuation=[',','.',';',':']
for symbol in punctuation:
text=text.replace(symbol," "+symbol+" ")
words=text.split(" ")
#過濾空單詞
words=[word for word in words id word !=""]
wordDict={}
for i in range(1,len(words)):
if words[i-1] not in wordDict:
#爲單詞新建一個字典
wordDict[words[i-1]]={}
if words[i] not in wordDict[words[i-1]]:
wordDict[words[i-1]][words[i]] = 0
wordDict[words[i-1]][words[i]]=wordDict[words[i-1]][words[i]]+1
return wordDict
text=str(urlopen("http://pythonscraping.com/files/inaugurationSpeech.txt").read(),'utf-8')
wordDict=buildWordDict(text)
#生成鏈長爲100的馬爾科夫鏈
length=100
chain=""
currentWord="I"
for i in range(0,length):
chain += str(currentWord)
currentWord=retrieveRandomWord(wordDict[currentWord])
print(chain)
{word_a:{word_b:2,word_c:1,word_d:1},
word_e:{word_b:5,word_d:2}...}
在這個字典中,“word_a”出現了四次,其中兩次後面跟的單詞是“word_b”,一次是“word_c”,一次是“word_d”。“word_e”出現了七次,其中五次後面跟的是“word_b”,兩次是“word_d”。