在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 相关文章推荐
Python字符串格式化
Jun 15 Python
Python+django实现文件上传
Jan 17 Python
Python3单行定义多个变量或赋值方法
Jul 12 Python
python+opencv实现霍夫变换检测直线
Oct 23 Python
django搭建项目配置环境和创建表过程详解
Jul 22 Python
PyQt Qt Designer工具的布局管理详解
Aug 07 Python
python求加权平均值的实例(附纯python写法)
Aug 22 Python
Python之数据序列化(json、pickle、shelve)详解
Aug 30 Python
python网络爬虫 CrawlSpider使用详解
Sep 27 Python
Python图像处理库PIL的ImageFilter模块使用介绍
Feb 26 Python
python之生成多层json结构的实现
Feb 27 Python
python numpy实现多次循环读取文件 等间隔过滤数据示例
Mar 14 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
php的curl实现get和post的代码
2008/08/23 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十六)
2014/06/30 PHP
PHP 实现的将图片转换为TXT
2015/10/21 PHP
PHP实现长文章分页实例代码(附源码)
2016/02/03 PHP
Laravel定时任务的每秒执行代码
2019/10/22 PHP
JS 自定义函数缺省值的设置方法
2010/05/05 Javascript
javascript写的简单的计算器,内容很多,方法实用,推荐
2011/12/29 Javascript
用js读、写、删除Cookie代码分享及详细注释说明
2014/06/05 Javascript
iframe里的页面禁止右键事件的方法
2014/06/10 Javascript
JavaScript页面模板库handlebars的简单用法
2015/03/02 Javascript
jQuery使用empty()方法删除元素及其所有子元素的方法
2015/03/26 Javascript
JS响应鼠标点击实现两个滑块区间拖动效果
2015/10/26 Javascript
原生js实现可爱糖果数字时间特效
2016/12/30 Javascript
实例教学如何写vue插件
2017/11/30 Javascript
vue的一个分页组件的示例代码
2017/12/25 Javascript
JavaScript对象的浅拷贝与深拷贝实例分析
2018/07/25 Javascript
react native 获取地理位置的方法示例
2018/08/28 Javascript
详解小程序退出页面时清除定时器
2019/04/28 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
2019/05/07 Javascript
[03:23]我的刀塔你不可能这么可爱 第一期金萌萌的故事
2014/06/20 DOTA
[55:56]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.22
2019/09/05 DOTA
Python中使用不同编码读写txt文件详解
2015/05/28 Python
python获得一个月有多少天的方法
2015/06/04 Python
详解Python的Flask框架中的signals信号机制
2016/06/13 Python
vscode 远程调试python的方法
2017/12/01 Python
python接口自动化(十七)--Json 数据处理---一次爬坑记(详解)
2019/04/18 Python
python算的上脚本语言吗
2020/06/22 Python
求职简历中自我评价
2014/01/28 职场文书
好人好事事迹材料
2014/02/12 职场文书
会计核算科岗位职责
2014/03/19 职场文书
教师教学评估方案
2014/05/09 职场文书
硕士生找工作求职信
2014/07/05 职场文书
2015年五一劳动节慰问信
2015/03/23 职场文书
出国导师推荐信
2015/03/25 职场文书
2015年世界急救日宣传活动方案
2015/05/06 职场文书
Redis基本数据类型List常用操作命令
2022/06/01 Redis