在Python上基于Markov链生成伪随机文本的教程


Posted in Python onApril 17, 2015

 首先看一下来自Wolfram的定义

    马尔可夫链是随机变量{X_t}的集合(t贯穿0,1,...),给定当前的状态,未来与过去条件独立。

Wikipedia的定义更清楚一点儿

    ...马尔可夫链是具有马尔可夫性质的随机过程...[这意味着]状态改变是概率性的,未来的状态仅仅依赖当前的状态。

马尔可夫链具有多种用途,现在让我看一下如何用它生产看起来像模像样的胡言乱语。

算法如下,

  1.     找一个作为语料库的文本,语料库用于选择接下来的转换。
  2.     从文本中两个连续的单词开始,最后的两个单词构成当前状态。
  3.     生成下一个单词的过程就是马尔可夫转换。为了生成下一个单词,首先查看语料库,查找这两个单词之后跟着的单词。从它们中随机选择一个。
  4.     重复2,直到生成的文本达到需要的大小。

代码如下
 

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)

为了看到一个示例结果,我们从古腾堡计划中拿了沃德豪斯的《My man jeeves》作为文本,示例结果如下。
 

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'

[如果想执行这个例子,请下载jeeves.txt和markovgen.py
马尔可夫算法怎样呢?

  •     最后两个单词是当前状态。
  •     接下来的单词仅仅依赖最后两个单词,也就是当前状态。
  •     接下来的单词是从语料库的统计模型中随机选择的。

这是一个示例文本。

"The quick brown fox jumps over the brown fox who is slow jumps over the brown fox who is dead."

这个文本对应的语料库像这样,
 

{('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.']}

现在如果我们从"brown fox"开始,接下来的单词可以是"jumps"或者"who"。如果我们选择"jumps",然后当前的状态就变成了"fox jumps",再接下的单词就是"over",之后依此类推。

提示

  •     我们选择的文本越大,每次转换的选择更多,生成的文本更好看。
  •     状态可以设置为依赖一个单词、两个单词或者任意数量的单词。随着每个状态的单词数的增加,生成的文本更不随机。
  •     不要去掉标点符号等。它们会使语料库更具代表性,随机文本更好看。
Python 相关文章推荐
matplotlib简介,安装和简单实例代码
Dec 26 Python
Python程序运行原理图文解析
Feb 10 Python
浅谈Python脚本开头及导包注释自动添加方法
Oct 27 Python
Django中使用 Closure Table 储存无限分级数据
Jun 06 Python
Python使用sklearn实现的各种回归算法示例
Jul 04 Python
python 实现保存最新的三份文件,其余的都删掉
Dec 22 Python
使用Python 自动生成 Word 文档的教程
Feb 13 Python
python实现提取COCO,VOC数据集中特定的类
Mar 10 Python
pandas dataframe 中的explode函数用法详解
May 18 Python
keras自定义回调函数查看训练的loss和accuracy方式
May 23 Python
Python爬虫之Selenium下拉框处理的实现
Dec 04 Python
pytorch 中autograd.grad()函数的用法说明
May 12 Python
基于scrapy实现的简单蜘蛛采集程序
Apr 17 #Python
在Python的Django框架中实现Hacker News的一些功能
Apr 17 #Python
由Python运算π的值深入Python中科学计算的实现
Apr 17 #Python
在Python中实现贪婪排名算法的教程
Apr 17 #Python
在Linux下调试Python代码的各种方法
Apr 17 #Python
Python脚本在Appium库上对移动应用实现自动化测试
Apr 17 #Python
Python中生成器和yield语句的用法详解
Apr 17 #Python
You might like
在WIN98下以apache模块方式安装php
2006/10/09 PHP
基于mysql的论坛(5)
2006/10/09 PHP
php项目打包方法
2008/02/18 PHP
使用openssl实现rsa非对称加密算法示例
2014/01/24 PHP
PHP代码覆盖率统计详解
2020/07/22 PHP
Ext JS Grid在IE6 下宽度的问题解决方法
2009/02/15 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(一)让静态人物动起来
2013/01/23 Javascript
jquery动态添加元素事件失效问题解决方法
2014/05/23 Javascript
Node.js异步I/O学习笔记
2014/11/04 Javascript
Javascript实现获取及设置光标位置的方法
2015/07/21 Javascript
基于jQuery实现简单的折叠菜单效果
2015/11/23 Javascript
node文件上传功能简易实现代码
2017/06/16 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
2017/12/16 jQuery
vue.js的vue-cli脚手架中使用百度地图API的实例
2019/01/21 Javascript
详解JavaScript的变量
2019/04/04 Javascript
详解JavaScript自定义函数
2020/07/29 Javascript
html+vue.js 实现漂亮分页功能可兼容IE
2020/11/07 Javascript
python基础教程之元组操作使用详解
2014/03/25 Python
python自动化测试之连接几组测试包实例
2014/09/28 Python
Python中有趣在__call__函数
2015/06/21 Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
2019/10/30 Python
Win下PyInstaller 安装和使用教程
2019/12/25 Python
pandas 对group进行聚合的例子
2019/12/27 Python
Python drop方法删除列之inplace参数实例
2020/06/27 Python
解决keras模型保存h5文件提示无此目录问题
2020/07/01 Python
Python使用urlretrieve实现直接远程下载图片的示例代码
2020/08/17 Python
python模块内置属性概念及实例
2021/02/18 Python
详解移动端HTML5音频与视频问题及解决方案
2018/08/22 HTML / CSS
Under Armour瑞典官方网站:美国高端运动科技品牌
2018/11/21 全球购物
LN-CC英国:伦敦时尚生活的缩影
2019/09/01 全球购物
企业安全生产月活动总结
2014/07/05 职场文书
财务工作犯错检讨书
2014/10/07 职场文书
考察邀请函范文
2015/01/31 职场文书
有关三国演义的读书笔记
2015/06/25 职场文书
导游词之神仙居景区
2019/11/15 职场文书
Promise面试题详解之控制并发
2021/05/14 面试题