摘要: 本文通过用Python中的马尔可夫链蒙特卡罗实现了睡眠模型项目,并教会如何使用MCMC。

在过去的几个月里,我在数据科学领域里遇到一个术语:马尔可夫链蒙特卡罗(MCMC)。在博客或文章里,每次看到这个语,我都会摇摇头,有几次我试着学习MCMC和贝叶斯推理,但每次一开始,就很快放弃了。我学习新技术的方式都是把它应用到一个实际问题上。

通过使用一些数据和一本应用实战的书(Bayesian Methods for Hackers),我终于通过一个实际项目弄懂了MCMC。像往常一样,当把这些技术概念应用到实际问题中时,理解它们要比阅读书上的抽象概念更容易。本文通过介绍Python中的MCMC实现过程,最终教会了我使用这个强大的建模和分析工具。

本项目的完整代码和相关数据在GitHub上可以找到。本文重点讨论了应用程序和结果,涵盖了很多有深度的内容。

介绍

实际生活中的数据永远不是完美的,但我们仍然可以通过正确的模型从噪音数据中提取有价值的信息。

典型睡眠数据

本项目的目的是使用睡眠数据创建一个模型,该模型指定了睡眠的后验概率作为一个时间函数。由于时间是一个连续变量,因为指定整个后验分布是比较困难的,所以我们转向接近于分布的方法-MCMC。

概率分布的选择

在使用MCMC之前,我们需要确定适当的函数来给睡眠的后验概率分布建模。最简单方法是通过可视化的方式进行数据检查,入睡的时间函数的观察结果如下图所示:

睡眠数据

在图上,每个数据节点被标记为一个点,点的强度表明了在指定时间的观测次数。我的表只记录入睡的时间,所以为了扩大数据量,我在时间点两边的每一分钟都加上了节点。如果手表记录我在晚上10:05分睡着了,那么之前的每分钟都被表示为0(清醒),之后的每分钟都表示为1(入睡)。这将会把大约60个晚上的观测扩展到11340个数据节点。

可以看到,我总是于晚上10:00之后入睡,我们想要创建一个获取从醒到睡的概率转换的模型。当模型在一个精确的时间从清醒(0)到入睡(1)转换的时候,我们可以给模型用一个简单的阶梯函数,因为我不会每晚都在同一时间入睡,所以我们需要一个函数来把转换过程建模为渐变过程。给定数据的最佳选择是一个在0和1之间平稳转换的逻辑函数。以下是入睡概率作为时间函数的逻辑方程。

β(beta)和α(alpha)是我们在MCMC过程中必须学习的模型参数。如下所示具有不同参数的逻辑函数:

逻辑函数适合这些数据,因为入睡转换的概率是逐渐的,同时获取了我的睡眠样本的变化。我们希望能为函数增加一个时间变量t,并找出入睡的概率,它必须在0和1之间。为了创建这个模型,我们通过一个分类的技术作为MCMC,用数据来找到最佳的α和β参数。

马尔可夫链蒙特卡罗(MCMC)

MCMC是从概率分布中抽样以构造最可能分布的一类方法。我们不能直接计算逻辑分布,所以我们为函数的参数(α和β)生成数千个称为样本的数值,以创建分布的近似值。MCMC背后的思想是,随着生成更多的样本,近似值会越来越接近实际的分布。

MCMC方法有两个部分,蒙特卡罗是指使用重复随机样本来获得数值结果的通用技术。蒙特卡罗可以被认为是进行很多次的实验,每次改变模型中的变量并观察反应。通过选择随机值,我们可以研究参数空间的一大部分,可能的变量值的范围。参数空间,如下图所示:

很显然,我们不能尝试图中的每个点,但是通过从较高概率(红色)的区域随机抽样,我们可以创建最可能的模型。

马尔可夫链(Markov Chain)

MCMC结合了马尔可夫链和蒙特卡罗的思想,是一种基于当前值对分布的参数重复抽取随机值的方法。每个值的样本都是随机的,但是这些值的选择受到当前状态和参数的假定先验分布的限制。MCMC可以看作是逐渐收敛到实际分布的随机游动。

为了抽取α和β的随机值,我们需要假设这些值的先验分布。由于我们没有预先给参数假设,所以可以使用一个正态分布。正态分布或高斯分布由平均值定义,表明了数据的位置、方差和分布范围。下图是具有不同平均值和范围的几个正态分布:

我们使用的特定MCMC算法称为Metropolis Hastings。为了将观测数据与模型联系起来,每次绘制一组随机值时,该算法都会根据数据进行评估。如果这些随机值与数据不一致,则会被拒绝,并且模型保持在当前状态。反之,如果与数据一致,则将这些随机值分配给参数并变成当前状态。这个过程持续一定数量的迭代,那么模型的精确度就会随着迭代数量的增加而提高。

综上所述,用MCMC解决问题的基本步骤如下:

(1)选择α和β以及逻辑函数的参数初始值集合;

(2)根据当前状态给α和β随机分配新的值;

(3)检查新的随机值是否符合观测值。如果不符合,则拒绝这些随机值,并返回到先前状态,反之,要是符合,则接受,并更新为新的当前状态;

(4)如需迭代,则重复步骤2和3;

算法返回其生成的所有α和β的值。然后,我们可以使用这些值的平均值作为逻辑函数中最有可能的α和β最终值。MCMC不能返回“True”值,而是返回一个分布的近似值。由已有数据得到的睡眠概率,其最终模型是具有α和β平均值的逻辑函数。

Python的实现

为了在Python中实现MCMC,我们将使用贝叶斯推理库PyMC3,它对大部分细节进行了抽象,使我们能够创建模型而不是空有理论。

下面的代码创建了具有参数α和β、概率p和观察值的完整模型。步骤变量引用特定的算法,并且变量sleep_trace保存了由模型生成的所有参数值。

withpm.Model() as sleep_model:

# Create the alpha and beta parameters

# Assume a normal distribution

alpha=pm.Normal('alpha', mu=0.0, tau=0.05, testval=0.0)

beta=pm.Normal('beta', mu=0.0, tau=0.05, testval=0.0)

# The sleep probability is modeled as a logistic function

p=pm.Deterministic('p', 1. / (1. +tt.exp(beta * time + alpha)))

# Create the bernoulli parameter which uses observed data to inform the algorithm

observed=pm.Bernoulli('obs', p, observed=sleep_obs)

# Using Metropolis Hastings Sampling

step=pm.Metropolis()

# Draw the specified number of samples

sleep_trace=pm.sample(N_SAMPLES, step=step);

为了更好地了解代码的运行,我们可以看下所有的模型运行过程中所产生的α和β值。

上图被称为轨迹图。我们可以看到,每个状态都与先前的马尔可夫链相关,但其值在蒙特卡罗抽样中振荡明显。

在MCMC中,很常见的做法是丢弃多达90%的轨迹。算法不立即收敛到真实分布,而且初始值往往也不准确。之后的参数值通常会更好一些,这意味着应该用它们来构建模型。我们使用了10000个样本,并丢弃了前面的50%,但是在企业级应用中可能会使用成百上千个或数百万个样本。

MCMC收敛到真实值,但评估收敛可能是很困难的。如果我们想要最精确的结果,这是一个重要的因素。PyMC3库已经创建了用于评估模型质量的函数,包括轨迹图和自相关图。

pm.traceplot(sleep_trace, ['alpha', 'beta'])pm.autocorrplot(sleep_trace, ['alpha', 'beta'])

轨迹图(上) 和自相关图(下)

睡眠模型

在最终建立和运行模型之后,现在应该使用了。我们将最后5000个α和β样本的平均值作为最有可能的参数值,这允许我们创建单个曲线图来模拟指定时间之后的入睡概率:

该模型能很好地表示数据,还获取了我入睡模式固有的变化,它不是给出一个结果,而是给出一个概率。例如,可以查询该模型以找出我在指定时间入睡的概率,并找到概率超过50%的时间点:

晚上9点半入睡概率: 4.80%.

晚上9点半入睡概率: 27.44%.

晚上10点入睡概率: 73.91%.

在晚上10点14分,入睡概率提高到了50%以上。

可以看到我入睡的平均时间是晚上10点14分左右。

这些值是给定数据的最可能的估计值。然而,会有这些概率相关的不确定性,因为模型是近似的。为了表示这种不确定性,我们可以在一个给定的时间点使用所有α和β的样本来进行入睡概率预测,然后根据结果绘制柱状:

上述结果给出了一个更好的MCMC模型能实际做到的指标。这个方法并没有找到一个正确答案,而是可能值的一个样本。贝叶斯推理是有实际用处的,因为它以概率的形式表示预测的结果。我们可以说得到一个最有可能的答案,但是更准确的说法应该是任何预测都是一系列值的范围。

睡醒模型

可以用我早上睡醒的相关数据来找到一个类似的模型。我通常在早上6点起床,下图根据观察结果显示了从睡觉到睡醒的最终模型。

可以通过模型来发现我在某一指定时间入睡的概率和最有可能睡醒的时间。

早上5点半睡醒的概率: 14.10%.

早上6点睡醒的概率: 37.94%.

早上6点半睡醒的概率: 69.49%.

在早上6点11分睡醒的概率超过50%。

入睡持续时间

最后一个我想创建的是入睡时间模型。首先,我们需要找到一个函数来模拟数据的分布,但只能通过检查数据来找到。

一个普通的分布即可实现,但它不会获取右边的离群点。可以使用两个相互独立的正态分布来表示这两种模式,但是,我会使用一个偏态分布。偏态分布有三个参数,平均值、方差、偏差,并且这三个参数必须从MCMC算法中进行学习。下面的代码创建模型并实现Metropolis Hastings抽样:

withpm.Model() asduration_model:

# Three parameters to sample

alpha_skew=pm.Normal('alpha_skew', mu=0, tau=0.5, testval=3.0)

mu_ =pm.Normal('mu', mu=0, tau=0.5, testval=7.4)

tau_ =pm.Normal('tau', mu=0, tau=0.5, testval=1.0)

# Duration is a deterministic variable

duration_ =pm.SkewNormal('duration', alpha=alpha_skew, mu= mu_,

sd=1/tau_, observed= duration)

# Metropolis Hastings for sampling

step=pm.Metropolis()

duration_trace=pm.sample(N_SAMPLES, step=step)

现在,我们可以使用三个参数的平均值来构造最有可能的分布。下图表示数据的最终偏态分布:

上图看起来很合乎实际情况,通过查询模型可以发现我至少获得一定的入睡持续时间,和最可能的入睡时间范围的概率:

入睡至少持续6.5小时的概率= 99.16%.

入睡至少持续8小时的概率= 44.53%.

入睡至少持续9小时的概率= 10.94%.

入睡最可能持续的时间是7.67小时

结论

通过完成这个项目,告诉我们解决问题的重要性是最好解决实际生活中的问题。数据科学需要不断地进行知识积累,最有效的方法就是有了问题尽快开始。

以上为译文,由

文章原标题《Markov Chain Monte Carlo in Python》

作者:William Koehrsen

译者:奥特曼,审校:袁虎。

文章为简译,更为详细的内容,请查看

更多技术干货敬请关注云栖社区知乎机构号:阿里云云栖社区 - 知乎

本文为云栖社区原创内容,未经允许不得转载。

python做马尔科夫模型预测法_用Python实现马尔可夫链蒙特卡罗相关推荐

  1. python做马尔科夫模型预测法_通过Python的Networkx和Sklearn来介绍隐性马尔科夫模型...

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 文章梗概 马尔科夫是何人? 马尔科夫性质是什么? 马尔科夫模型是什么? 是什么让马尔科夫模型成为隐性的? ...

  2. python做马尔科夫模型预测法_李航《统计学习方法》第十章——用Python实现隐马尔科夫模型...

    相关文章: 李航<统计学习方法>第二章--用Python实现感知器模型(MNIST数据集) 李航<统计学习方法>第三章--用Python实现KNN算法(MNIST数据集) 李航 ...

  3. python做马尔科夫模型预测法_隐马尔可夫模型的前向算法和后向算法理解与实现(Python)...

    前言 隐马尔可夫模型(HMM)是可用于标注问题的统计学习模型,描述由隐藏的马尔可夫链随机生成观测序列的过程,属于生成模型. 马尔可夫模型理论与分析 参考<统计学习方法>这本书,书上已经讲得 ...

  4. python做马尔科夫模型预测法_python 日常笔记 hmmlearn 隐性马尔科夫模型案例分析...

    问题: 什么是马尔科夫模型?用来干什么? 大家可以参考这篇简书 python 实现 关于HMM有两个主要问题: 已知上述三个参数,和当前观测序列,求解隐藏状态的变化 所有参数未知,只有数据,如何获得三 ...

  5. python做马尔科夫模型预测法_Python实现HMM(隐马尔可夫模型)

    1. 前言 隐马尔科夫HMM模型是一类重要的机器学习方法,其主要用于序列数据的分析,广泛应用于语音识别.文本翻译.序列预测.中文分词等多个领域.虽然近年来,由于RNN等深度学习方法的发展,HMM模型逐 ...

  6. python做马尔科夫模型预测法_python实现隐马尔科夫模型HMM

    #coding=utf8 ''''' Created on 2017-8-5 里面的代码许多地方可以精简,但为了百分百还原公式,就没有精简了. @author: adzhua ''' import n ...

  7. 【转】隐马尔科夫模型(HMM)及其Python实现

    原文链接https://applenob.github.io/hmm.html 隐马尔科夫模型(HMM)及其Python实现 目录 1.基础介绍 形式定义 隐马尔科夫模型的两个基本假设 一个关于感冒的 ...

  8. matlab求马尔可夫转移矩阵,求马尔科夫模型的转移矩阵_马尔科夫转移矩阵

    求马尔科夫模型的转移矩阵 用Matlab解决如下: clc,clear,format rat a=[ 4 3 2 1 4 3 1 1 2 3 2 1 2 3 4 4 3 3 1 1 1 3 3 2 1 ...

  9. 隐马尔科夫模型HMM之Baum-Welch算法Python代码实现

    ☕️ 本文系列文章汇总: (1)HMM开篇:基本概念和几个要素 (2)HMM计算问题:前后向算法 代码实现 (3)HMM学习问题:Baum-Welch算法 (4)  HMM预测问题:维特比算法 本篇算 ...

最新文章

  1. Moocryption
  2. ViewPage+Fragment的使用例子
  3. QT简介及QT环境搭建
  4. awesome字体图标库
  5. oracle提供的有用函数(待续)
  6. html里空间顺序,按空间顺序写我的房间作文
  7. 线性分组码的最小汉明距为6_第二章 线性代数
  8. oracle迁移至gaussdb,GaussDB for DWS 数据融合系列第九期:Oracle数据迁移到GaussDB(DWS)...
  9. Android书页翻页设计:android-flip
  10. iOS音频播放 (一):概述 转
  11. 记录一次项目中代码大致优化方向
  12. linux用dd命令刻录u盘,巧用linux dd命令刻录启动U盘
  13. opencv 毛星云c++版本复习
  14. 百度CTO李一男:未来五年电子商务是关注重点
  15. word整个表格首行缩进_Word段落首行无法缩进、不能输入空格与表格首行缩进的解决方法...
  16. 如何知道php是32位还是64位,怎么看电脑是32位还是64位详细介绍
  17. IE浏览器打不开jupyter notebook网页的解决办法
  18. 彻底解决Word中子标题变黑块问题
  19. ArcGIS Server Rest 认证过程分析
  20. 康耐视InSight相机的连接与仿真的使用

热门文章

  1. sql查看数据库线程数_SQL Server始终在可用性组数据库上的最大辅助线程
  2. sql docker容器_了解SQL Server Docker容器中的备份和还原操作
  3. sql server 面试_SQL Server审核面试问题
  4. mysql屏蔽_MySQL中的企业数据屏蔽
  5. P1273 有线电视网 树形dp
  6. 正则表达式学习(2)
  7. handler 和 intent用法
  8. 【windows核心编程】线程局部存储TLS
  9. 《Image Effects 》第一章学习笔记(2)
  10. @Scope(prototype)