在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 相关文章推荐
linux系统使用python监控apache服务器进程脚本分享
Jan 15 Python
Python中用format函数格式化字符串的用法
Apr 08 Python
python下MySQLdb用法实例分析
Jun 08 Python
Python矩阵常见运算操作实例总结
Sep 29 Python
python+pandas分析nginx日志的实例
Apr 28 Python
想学python 这5本书籍你必看!
Dec 11 Python
python使用pandas处理excel文件转为csv文件的方法示例
Jul 18 Python
Django REST framework 如何实现内置访问频率控制
Jul 23 Python
借助Paramiko通过Python实现linux远程登陆及sftp的操作
Mar 16 Python
ansible-playbook实现自动部署KVM及安装python3的详细教程
May 11 Python
Python pip安装模块提示错误解决方案
May 22 Python
python将数据插入数据库的代码分享
Aug 16 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实现密保卡功能实现代码&amp;lt;打包下载直接运行&amp;gt;
2011/10/09 PHP
CodeIgniter CLI模式简介
2014/06/17 PHP
WordPress中给媒体文件添加分类和标签的PHP功能实现
2015/12/31 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
PHP 7.4中使用预加载的方法详解
2019/07/08 PHP
JavaScript中的排序算法代码
2011/02/22 Javascript
JS写的贪吃蛇游戏(个人练习)
2013/07/08 Javascript
探讨jQuery的ajax使用场景(c#)
2013/12/03 Javascript
利用js(jquery)操作Cookie的方法说明
2013/12/19 Javascript
javascript写的一个模拟阅读小说的程序
2014/04/04 Javascript
jQuery不使用插件及swf实现无刷新文件上传
2014/12/08 Javascript
浅谈js多维数组和hash数组定义和使用
2016/07/27 Javascript
KnockoutJS 3.X API 第四章之事件event绑定
2016/10/10 Javascript
vue拦截器Vue.http.interceptors.push使用详解
2017/04/22 Javascript
使用use注册Vue全局组件和全局指令的方法
2018/03/08 Javascript
JavaScript设计模式之原型模式分析【ES5与ES6】
2018/07/26 Javascript
Vue框架TypeScript装饰器使用指南小结
2019/02/18 Javascript
layer提示框添加多个按钮选择的实例
2019/09/12 Javascript
vue视频播放暂停代码
2019/11/08 Javascript
vue Treeselect下拉树只能选择第N级元素实现代码
2020/08/31 Javascript
[00:44]TI7不朽珍藏III——军团指挥官不朽展示
2017/07/15 DOTA
[13:56]DAC2018 4.5SOLO赛决赛 MidOne vs Paparazi第一场
2018/04/06 DOTA
编写Python小程序来统计测试脚本的关键字
2016/03/12 Python
Selenium及python实现滚动操作多种方法
2020/07/21 Python
Python如何执行精确的浮点数运算
2020/07/31 Python
python字典按照value排序方法
2020/12/28 Python
CSS3属性box-sizing使用指南
2014/12/09 HTML / CSS
shell的种类有哪些
2015/04/15 面试题
大学生工作推荐信范文
2013/12/02 职场文书
法人委托书范本
2014/09/15 职场文书
党委工作总结2015
2015/04/27 职场文书
农村环境卫生倡议书
2015/04/29 职场文书
劳动合同变更协议书范本
2019/04/18 职场文书
SQL Server 中的事务介绍
2022/05/20 SQL Server
Apache POI操作批量导入MySQL数据库
2022/06/21 Servers
Win11 Beta 预览版 22621.575 和 22622.575更新补丁KB5016694发布(附更新内容大全)
2022/08/14 数码科技