在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中利用xml.dom模块解析xml的方法教程
May 24 Python
详解tensorflow训练自己的数据集实现CNN图像分类
Feb 07 Python
Python实现合并两个列表的方法分析
May 28 Python
Python使用Selenium爬取淘宝异步加载的数据方法
Dec 17 Python
Python 3.6 -win64环境安装PIL模块的教程
Jun 20 Python
python实现简单聊天室功能 可以私聊
Jul 12 Python
python读取指定字节长度的文本方法
Aug 27 Python
Python实现微信机器人的方法
Sep 06 Python
Python 支持向量机分类器的实现
Jan 15 Python
Python类如何定义私有变量
Feb 03 Python
在django admin详情表单显示中添加自定义控件的实现
Mar 11 Python
Python干货实战之八音符酱小游戏全过程详解
Oct 24 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作的文本留言本的例子(六)
2006/10/09 PHP
PHP实现MVC开发得最简单的方法――模型
2007/04/10 PHP
PHP面向对象五大原则之依赖倒置原则(DIP)详解
2018/04/08 PHP
PHP检查文件是否存在,不存在自动创建及读取文件内容操作示例
2020/01/23 PHP
JavaScript Eval 函数使用
2010/03/23 Javascript
jquery ajax post提交数据乱码
2013/11/05 Javascript
JavaScript中的slice()方法使用详解
2015/06/06 Javascript
JavaScript中关键字 in 的使用方法详解
2016/10/17 Javascript
EasyUI学习之Combobox下拉列表(1)
2016/12/29 Javascript
javascript事件的绑定基础实例讲解(34)
2017/02/14 Javascript
详解如何在Angular中快速定位DOM元素
2017/05/17 Javascript
详解react-webpack2-热模块替换[HMR]
2017/08/03 Javascript
NodeJS实现不可逆加密与密码密文保存的方法
2018/03/16 NodeJs
bing Map 在vue项目中的使用详解
2018/04/09 Javascript
vue项目如何刷新当前页面的方法
2018/05/18 Javascript
vue使用vuex实现首页导航切换不同路由的方法
2019/05/08 Javascript
JS代码屏蔽F12,右键,粘贴,复制,剪切,选中,操作实例
2019/09/17 Javascript
在layui框架中select下拉框监听更改事件的例子
2019/09/20 Javascript
jQuery实现手风琴效果(蒙版)
2020/01/11 jQuery
微信小程序之导航滑块视图容器功能的实现代码(简单两步)
2020/06/19 Javascript
addEventListener()和removeEventListener()追加事件和删除追加事件
2020/12/04 Javascript
uniapp微信小程序:key失效的解决方法
2021/01/20 Javascript
[01:07:17]EG vs Optic Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
PyQt5利用QPainter绘制各种图形的实例
2017/10/19 Python
用Python实现KNN分类算法
2017/12/22 Python
python笔记之mean()函数实现求取均值的功能代码
2019/07/05 Python
Python matplotlib修改默认字体的操作
2020/03/05 Python
python pymysql链接数据库查询结果转为Dataframe实例
2020/06/05 Python
如何解决cmd运行python提示不是内部命令
2020/07/01 Python
基于python requests selenium爬取excel vba过程解析
2020/08/12 Python
CSS3自定义滚动条样式 ::webkit-scrollbar的示例代码详解
2020/06/01 HTML / CSS
APM Monaco中国官网:来自摩纳哥珠宝品牌
2017/12/27 全球购物
Mamaearth官方网站:印度母婴护理产品公司
2019/10/06 全球购物
饮料业务员岗位职责
2013/12/15 职场文书
Java输出Hello World完美过程解析
2021/06/13 Java/Android
nginx.conf配置文件结构小结
2022/04/08 Servers