在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文件读取的3种方法及路径转义
Jun 21 Python
详解Swift中属性的声明与作用
Jun 30 Python
利用python程序生成word和PDF文档的方法
Feb 14 Python
Request的中断和ErrorHandler实例解析
Feb 12 Python
python实现在pandas.DataFrame添加一行
Apr 04 Python
python 循环读取txt文档 并转换成csv的方法
Oct 26 Python
Pycharm更换python解释器的方法
Oct 29 Python
使用pyecharts生成Echarts网页的实例
Aug 12 Python
在Python中使用MySQL--PyMySQL的基本使用方法
Nov 19 Python
python实现感知机模型的示例
Sep 30 Python
记一次python 爬虫爬取深圳租房信息的过程及遇到的问题
Nov 24 Python
python不同版本的_new_不同点总结
Dec 09 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
当年上海收录机产品生产,进口和价格情况
2021/03/04 无线电
PHP 结合 Boostrap 结合 js 实现学生列表删除编辑及搜索功能
2019/05/21 PHP
详解Laravel服务容器的绑定与解析
2019/11/05 PHP
xml分页+ajax请求数据源+dom取结果实例代码
2008/10/31 Javascript
ExtJS 2.0实用简明教程 之ExtJS版的Hello
2009/04/29 Javascript
Javascript 判断客户端浏览器类型代码
2010/03/01 Javascript
IE6下javasc#ipt:void(0) 无效的解决方法
2013/12/23 Javascript
JS onkeypress兼容性写法详解
2016/04/27 Javascript
jQuery插件扩展实例【添加回调函数】
2016/11/26 Javascript
微信小程序技巧之show内容展示,上传文件编码问题
2017/01/23 Javascript
ES6新特性一: let和const命令详解
2017/04/20 Javascript
Angular2学习教程之组件中的DOM操作详解
2017/05/28 Javascript
js 只比较时间大小的实例
2017/10/26 Javascript
JavaScript语句错误throw、try及catch实例解析
2020/08/18 Javascript
Python中的文件和目录操作实现代码
2011/03/13 Python
python网页请求urllib2模块简单封装代码
2014/02/07 Python
编写Python脚本抓取网络小说来制作自己的阅读器
2015/08/20 Python
Python Pandas找到缺失值的位置方法
2018/04/12 Python
TensorFlow实现卷积神经网络
2018/05/24 Python
Python基本语法之运算符功能与用法详解
2019/10/22 Python
关于pandas的离散化,面元划分详解
2019/11/22 Python
tensorflow2.0保存和恢复模型3种方法
2020/02/03 Python
TensorFlow2.X结合OpenCV 实现手势识别功能
2020/04/08 Python
tensorflow下的图片标准化函数per_image_standardization用法
2020/06/30 Python
台湾网友喜爱的综合型网路购物商城:Yahoo! 奇摩购物中心
2018/03/10 全球购物
Easy Spirit官网:美国休闲鞋履中的代表品牌
2019/04/12 全球购物
艺术应用与设计专业个人的自我评价
2013/11/19 职场文书
校园公益广告语
2014/03/13 职场文书
企业标语口号
2014/06/10 职场文书
小学网上祭英烈活动总结
2014/07/05 职场文书
小学生2014国庆节演讲稿:祖国在我心中
2014/09/21 职场文书
党委领导班子整改方案
2014/09/30 职场文书
自荐信大全
2019/03/21 职场文书
比较node.js和Deno
2021/04/27 Javascript
Vue全家桶入门基础教程
2021/05/14 Vue.js
Python socket如何解析HTTP请求内容
2022/02/12 Python