在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登录QQ邮箱发信的实现代码
Feb 10 Python
python中日期和时间格式化输出的方法小结
Mar 19 Python
在Django中创建动态视图的教程
Jul 15 Python
python在Windows下安装setuptools(easy_install工具)步骤详解
Jul 01 Python
python探索之BaseHTTPServer-实现Web服务器介绍
Oct 28 Python
基于Django contrib Comments 评论模块(详解)
Dec 08 Python
Flask框架响应、调度方法和蓝图操作实例分析
Jul 24 Python
使用tensorflow实现矩阵分解方式
Feb 07 Python
基于Pyinstaller打包Python程序并压缩文件大小
May 28 Python
Python decimal模块使用方法详解
Jun 08 Python
Pytorch自定义Dataset和DataLoader去除不存在和空数据的操作
Mar 03 Python
4种非常实用的python内置数据结构
Apr 28 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数组函数序列之array_unshift() 在数组开头插入一个或多个元素
2011/11/07 PHP
PHP实现提取一个图像文件并在浏览器上显示的代码
2012/10/06 PHP
javascript数组与php数组的地址传递及值传递用法实例
2015/01/22 PHP
jquery插件制作 图片走廊 gallery
2012/08/17 Javascript
引入JS文件IE6报语法错误或缺少对象问题的解决方法
2014/01/09 Javascript
使用原生js封装webapp滑动效果(惯性滑动、滑动回弹)
2014/05/06 Javascript
jQuery增加自定义函数的方法
2015/07/18 Javascript
JS不完全国际化&amp;本地化手册 之 理论篇
2016/09/27 Javascript
KnockoutJS 3.X API 第四章之数据控制流if绑定和ifnot绑定
2016/10/10 Javascript
js实现下拉框效果(select)
2017/03/28 Javascript
vue监听滚动事件实现滚动监听
2017/04/11 Javascript
jquery加载单文件vue组件的方法
2017/06/20 jQuery
VUE中v-model和v-for指令详解
2017/06/23 Javascript
一步步教你利用webpack如何搭一个vue脚手架(超详细讲解和注释)
2018/01/08 Javascript
详解jQuery中的isPlainObject()使用方法
2018/02/27 jQuery
微信小程序第三方框架对比 之 wepy / mpvue / taro
2019/04/10 Javascript
vue 通过 Prop 向子组件传递数据的实现方法
2020/10/30 Javascript
使用python将mdb数据库文件导入postgresql数据库示例
2014/02/17 Python
Python判断操作系统类型代码分享
2014/11/22 Python
Python中用startswith()函数判断字符串开头的教程
2015/04/07 Python
在Linux系统上部署Apache+Python+Django+MySQL环境
2015/12/24 Python
深入理解NumPy简明教程---数组2
2016/12/17 Python
python实现微信跳一跳辅助工具步骤详解
2018/01/04 Python
win8下python3.4安装和环境配置图文教程
2018/07/31 Python
python 递归深度优先搜索与广度优先搜索算法模拟实现
2018/10/22 Python
Django密码存储策略分析
2020/01/09 Python
django filter过滤器实现显示某个类型指定字段不同值方式
2020/07/16 Python
Python类class参数self原理解析
2020/11/19 Python
学生党支部先进事迹
2014/02/04 职场文书
完美的中文自荐信
2014/05/24 职场文书
世界读书日的活动方案
2014/08/20 职场文书
新店开张活动方案
2014/08/24 职场文书
客房部经理岗位职责
2015/02/02 职场文书
公司管理制度范本
2015/08/03 职场文书
MySQL 不等于的三种使用及区别
2021/06/03 MySQL
使用Python拟合函数曲线
2022/04/14 Python