马尔可夫模型
网络爬虫-自然语言处理–马尔科夫文字生成器
先来看一个简单的例子:
以上是一个假定的天气模型,意思是,假如今天是已知的某种天气,那么明天三种天气可能出现的频率则可以给定。
注意:
• 任何一个节点引出的所有可能的总和必须等于 100%。无论是多么复杂的系统,必然会在下一步发生若干事件中的一个事件。
• 虽然这个天气系统在任一时间都只有三种可能,但是你可以用这个模型生成一个天气状态的无限次转移列表。
• 只有当前节点的状态会影响后一天的状态。如果你在“晴天”节点上,即使前 100 天都是晴天或雨天都没关系,明天晴天的概率还是 70%。
• 有些节点可能比其他节点较难到达。这个现象的原因用数学来解释非常复杂,但是可以直观地看出,在这个系统中任意时间节点上,第二天是“雨天”的可能性(指向它的箭头概率之和小于“100%”)比“晴天”或“多云”要小很多。
那么这个模型我们同样可以用在文本处理方面,会生成一段看似有逻辑,其实瞎扯淡的文本,思路就是:
- 获得原始文本
- 对文本进行清洗(处理字符等)
- 获取文本每个单词与可能相关单词在整个文本中出现的频率
- 从0生成一个我们自己新文本
- 我们先选取一个首发字母
- 然后开始随机取后续单词(根据(3)中我们得到的频率),然后重复这个过程
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("\"", "");
# 保证每个标点符号都和前面的单词在一起
# 这样不会被剔除,保留在马尔可夫链中
punctuation = [',', '.', ';',':']
for symbol in punctuation:
text = text.replace(symbol, " "+symbol+" ");
words = text.split(" ")
# 过滤空单词
words = [word for word in words if 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 += currentWord+" "
currentWord = retrieveRandomWord(wordDict[currentWord])
print(chain)
以下是结果: