在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中列表生成式和生成器的区别
Aug 03 Python
Python中的字符串查找操作方法总结
Jun 27 Python
Python 数据处理库 pandas进阶教程
Apr 21 Python
在python中以相同顺序shuffle两个list的方法
Dec 13 Python
详解python读取和输出到txt
Mar 29 Python
Python pandas.DataFrame 找出有空值的行
Sep 09 Python
pygame库实现移动底座弹球小游戏
Apr 14 Python
python 使用opencv 把视频分割成图片示例
Dec 12 Python
使用Python给头像加上圣诞帽或圣诞老人小图标附源码
Dec 25 Python
PyQT5速成教程之Qt Designer介绍与入门
Nov 02 Python
python 实现Harris角点检测算法
Dec 11 Python
Python探索生命起源 matplotlib细胞自动机动画演示
Apr 21 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获取当前页面完整URL的实现代码
2013/06/10 PHP
Laravel 4.2 中队列服务(queue)使用感受
2014/10/30 PHP
在PHP站点的页面上添加Facebook评论插件的实例教程
2016/01/08 PHP
php简单检测404页面的方法示例
2019/08/23 PHP
javascript 写的一个简单的timer
2009/07/30 Javascript
关于可运行代码无法正常执行的使用说明
2010/05/13 Javascript
Javascript操作cookie的函数代码
2012/10/03 Javascript
JavaScript中的匀速运动和变速(缓冲)运动详细介绍
2012/11/11 Javascript
IE浏览器中图片onload事件无效的解决方法
2014/04/29 Javascript
Javascript的严格模式strict mode详细介绍
2014/06/06 Javascript
程序员必知35个jQuery 代码片段
2015/11/05 Javascript
Jquery实现简单的轮播效果(代码管用)
2016/03/14 Javascript
javascript中利用柯里化函数实现bind方法
2016/04/29 Javascript
深入理解Ajax的get和post请求
2016/06/02 Javascript
简单实现js悬浮导航效果
2017/02/05 Javascript
浅谈js-FCC算法Friendly Date Ranges(详解)
2017/04/10 Javascript
Angular2+国际化方案(ngx-translate)的示例代码
2017/08/23 Javascript
nodejs使用redis作为缓存介质实现的封装缓存类示例
2018/02/07 NodeJs
详解Python中for循环是如何工作的
2017/06/30 Python
python中requests和https使用简单示例
2018/01/18 Python
Pytorch加载部分预训练模型的参数实例
2019/08/18 Python
浅谈对python中if、elif、else的误解
2020/08/20 Python
python语言time库和datetime库基本使用详解
2020/12/25 Python
利用Bootstrap实现漂亮简洁的CSS3价格表实例源码
2017/03/02 HTML / CSS
CAT鞋美国官网:CAT Footwear
2017/11/27 全球购物
客服工作职责
2013/12/11 职场文书
公积金单位接收函
2014/01/11 职场文书
学生会干部自荐信
2014/02/04 职场文书
消防先进事迹材料
2014/02/10 职场文书
小学三八妇女节活动方案
2014/03/16 职场文书
公务员群众路线专题民主生活会发言材料
2014/09/17 职场文书
个人先进材料范文
2014/12/30 职场文书
本溪关门山导游词
2015/02/09 职场文书
2015小学教师德育工作总结
2015/05/12 职场文书
python实现简单区块链结构
2021/04/25 Python
教你在 Java 中实现 Dijkstra 最短路算法的方法
2022/04/08 Java/Android