em算法python代码_EM算法的python实现的方法步骤

导读热词

前言:前一篇文章大概说了EM算法的整个理解以及一些相关的公式神马的,那些数学公式啥的看完真的是忘完了,那就来用代码记忆记忆吧!接下来将会对python版本的EM算法进行一些分析。

EM的python实现和解析

引入问题(双硬币问题)

假设有两枚硬币A、B,以相同的概率随机选择一个硬币,进行如下的抛硬币实验:共做5次实验,每次实验独立的抛十次,结果如图中a所示,例如某次实验产生了H、T、T、T、H、H、T、H、T、H,H代表正面朝上。

假设试验数据记录员可能是实习生,业务不一定熟悉,造成a和b两种情况

a表示实习生记录了详细的试验数据,我们可以观测到试验数据中每次选择的是A还是B

b表示实习生忘了记录每次试验选择的是A还是B,我们无法观测实验数据中选择的硬币是哪个

问在两种情况下分别如何估计两个硬币正面出现的概率?

以上的针对于b实习生的问题其实和三硬币问题类似,只是这里把三硬币中第一个抛硬币的选择换成了实习生的选择。

对于已知是A硬币还是B硬币抛出的结果的时候,可以直接采用概率的求法来进行求解。对于含有隐变量的情况,也就是不知道到底是A硬币抛出的结果还是B硬币抛出的结果的时候,就需要采用EM算法进行求解了。如下图:

7ccc8a74f0cc229c8b70d528d36b3b15.png

其中的EM算法的第一步就是初始化的过程,然后根据这个参数得出应该产生的结果。

构建观测数据集

针对这个问题,首先采集数据,用1表示H(正面),0表示T(反面):

#硬币投掷结果

observations = numpy.array([[1,1,1],[1,0],[0,1]])

第一步:参数的初始化

参数赋初值

5a6a8f35cbbfa84c1037821642a0d0f0.png

第一个迭代的E步

抛硬币是一个二项分布,可以用scipy中的binom来计算。对于第一行数据,正反面各有5次,所以:

#二项分布求解公式

contribution_A = scipy.stats.binom.pmf(num_heads,len_observation,theta_A)

contribution_B = scipy.stats.binom.pmf(num_heads,theta_B)

将两个概率正规化,得到数据来自硬币A,B的概率:

weight_A = contribution_A / (contribution_A + contribution_B)

weight_B = contribution_B / (contribution_A + contribution_B)

这个值类似于三硬币模型中的μ,只不过多了一个下标,代表是第几行数据(数据集由5行构成)。同理,可以算出剩下的4行数据的μ。

有了μ,就可以估计数据中AB分别产生正反面的次数了。μ代表数据来自硬币A的概率的估计,将它乘上正面的总数,得到正面来自硬币A的总数,同理有反面,同理有B的正反面。

#更新在当前参数下A,B硬币产生的正反面次数

counts['A']['H'] += weight_A * num_heads

counts['A']['T'] += weight_A * num_tails

counts['B']['H'] += weight_B * num_heads

counts['B']['T'] += weight_B * num_tails

第一个迭代的M步

当前模型参数下,AB分别产生正反面的次数估计出来了,就可以计算新的模型参数了:

new_theta_A = counts['A']['H']/(counts['A']['H'] + counts['A']['T'])

new_theta_B = counts['B']['H']/(counts['B']['H'] + counts['B']['T'])

于是就可以整理一下,给出EM算法单个迭代的代码:

def em_single(priors,observations):

"""

EM算法的单次迭代

Arguments

------------

priors:[theta_A,theta_B]

observation:[m X n matrix]

Returns

---------------

new_priors:[new_theta_A,new_theta_B]

:param priors:

:param observations:

:return:

"""

counts = {'A': {'H': 0,'T': 0},'B': {'H': 0,'T': 0}}

theta_A = priors[0]

theta_B = priors[1]

#E step

for observation in observations:

len_observation = len(observation)

num_heads = observation.sum()

num_tails = len_observation-num_heads

#二项分布求解公式

contribution_A = scipy.stats.binom.pmf(num_heads,theta_A)

contribution_B = scipy.stats.binom.pmf(num_heads,theta_B)

weight_A = contribution_A / (contribution_A + contribution_B)

weight_B = contribution_B / (contribution_A + contribution_B)

#更新在当前参数下A,B硬币产生的正反面次数

counts['A']['H'] += weight_A * num_heads

counts['A']['T'] += weight_A * num_tails

counts['B']['H'] += weight_B * num_heads

counts['B']['T'] += weight_B * num_tails

# M step

new_theta_A = counts['A']['H'] / (counts['A']['H'] + counts['A']['T'])

new_theta_B = counts['B']['H'] / (counts['B']['H'] + counts['B']['T'])

return [new_theta_A,new_theta_B]

EM算法主循环

给定循环的两个终止条件:模型参数变化小于阈值;循环达到最大次数,就可以写出EM算法的主循环了

def em(observations,prior,tol = 1e-6,iterations=10000):

"""

EM算法

:param observations :观测数据

:param prior:模型初值

:param tol:迭代结束阈值

:param iterations:最大迭代次数

:return:局部最优的模型参数

"""

iteration = 0;

while iteration < iterations:

new_prior = em_single(prior,observations)

delta_change = numpy.abs(prior[0]-new_prior[0])

if delta_change < tol:

break

else:

prior = new_prior

iteration +=1

return [new_prior,iteration]

给定数据集和初值,就可以调用EM算法了:

print em(observations,[0.6,0.5])

得到

[[0.72225028549925996,0.55543808993848298],36]

我们可以改变初值,试验初值对EM算法的影响。

print em(observations,[0.5,0.6])

结果:

[[0.55543727869042425,0.72225099139214621],37]

看来EM算法还是很健壮的。如果把初值设为相等会怎样?

print em(observations,[0.3,0.3])

输出:[[0.64000000000000001,0.64000000000000001],1]

显然,两个值相加不为1的时候就会破坏这个EM函数。

换一下初值:

print em(observations,[0.99999,0.00001])

输出:[[0.72225606292866507,0.55543145006184214],33]

EM算法对于参数的改变还是有一定的健壮性的。

以上是根据前人写的博客进行学习的~可以自己动手实现以下,对于python练习还是有作用的。希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

相关文章

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365468.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第一阶段·Linux运维基础-第2章·Linux系统目录结构介绍

01 变量与PS1 02 添加用户 03 关闭SELinux 04 关闭iptables 05 显示中文乱码排查过程 06 总结 07 目录结构课程内容 08 Linux目录结构特点 09 Linux核心目录简介 10 Linux目录文件之配置文件 11 Linux核心目录文件之DNS及屌丝逃离洗浴中心之路 12 Linux核心目录文件…

使用junit-drools进行JBoss Drools单元测试

最近&#xff0c;我一直在大量使用JBoss Drools进行项目。 我不是Drools专家-我也不太相信这个框架&#xff0c;或者可能不是只相信该项目中的特定用例-我发现很难为基于Drools的业务规则编写简单&#xff0c;可维护的单元测试 。 这就是junit-drools诞生的方式-简单的帮助程序…

scrapy 采集网页出现丢失url的问题

url_list ["http://www.icoat.cc/news/list_18_3.html", "http://www.icoat.cc/news/list_18.html", "http://www.icoat.cc/news/list_18_2.html", ] for ls in url_list:   yield scrapy.Request(urlls, headersheader, callbackself.parseL…

java中重新加载指定文件_java-更改后重新加载属性文件

我将属性文件加载到一个类中,然后在整个应用程序中使用该类来获取它们.public class PropertiesUtil extends PropertyPlaceholderConfigurer {private static Map properties new HashMap();Overrideprotected void loadProperties(final Properties props) throws IOExcepti…

plsql 为空显示 0 的函数_不加班只加薪!从0到1教你制作出入库进销存表格

出入库表应用十分广泛&#xff0c;是每个公司都用到的表格&#xff0c;下面我们来看看怎么从一张空白表一步一步实现《出入库表》的制作&#xff0c;目的是做到只需要记录出库入库流水&#xff0c;自动对库存及累计出入库数量进行计算、实时统计。出入库表构成做一个出入库表&a…

eShopOnContainers学习系列(一):Swagger的使用

最近在看eShopOnContainer项目&#xff0c;抽取一下其中的基础知识点&#xff0c;做个记录&#xff0c;有兴趣的可以看下。 新建一个.net core API项目&#xff0c;添加Nuget包 Swashbuckle.AspNetCore.SwaggerGen、Swashbuckle.AspNetCore.SwaggerUI&#xff1a; 然后在启动文…

结合WebSocket编写WebGL综合场景示例

在WebGL场景中导入多个Babylon骨骼模型&#xff0c;在局域网用WebSocket实现多用户交互控制。 首先是场景截图&#xff1a; 上图在场景中导入一个Babylon骨骼模型&#xff0c;使用asdw、空格、鼠标控制加速度移动&#xff0c;在移动时播放骨骼动画。 上图在场景中加入更多的骨…

awk----基本用法

awk具体的请看这个 https://www.cnblogs.com/bwbfight/p/9402738.html awk 竟然自诩一种语言&#xff0c;ok.... 牛 既然这样就学习一下吧 awk -F‘[指定多个分隔符]’ 比如 awk -F[ :]表示指定&#xff1a;空格为分隔符 涉及多个重复分割符可以这样指定 awk -F[ :] 表示多个空…

java按条件查询结果为空_mybatis中查询结果为空时不同返回类型对应返回值问题...

今天在别人的代码基础上实现新需求&#xff0c;看到对于mybatis查询结果的判断不是很正确&#xff0c;如果查询结果为空就会异常&#xff0c;不知道大家有没有这样的疑惑&#xff1a;mybatis中resultType有多种返回类型&#xff0c;对于每种不同类型&#xff0c;查询结果为空时…

object picker 微信小程序_微信小程序 demo分享

选择器示例demo&#xff1a;1.普通选择器 2.多列选择器 3.时间选择器 4.日期选择器 5.省市区选择器wxml普通选择器&#xff1a;(普通数组)当前选择&#xff1a;{{array[index]}}普通选择器2&#xff1a;(普通json格式数组)当前选择&#xff1a;{{objectArray[objectIndex].name…

项目学生:分片集成测试数据

这是Project Student的一部分。 其他职位包括带有Jersey的 Web服务 客户端&#xff0c;带有Jersey的 Web服务服务器 &#xff0c; 业务层和带有Spring Data的持久性 。 到目前为止&#xff0c;所有集成测试都使用了内存嵌入式数据库&#xff0c;该数据库无法一次又一次地保留信…

BZOJ1036 树的统计(树链剖分+线段树)

【题目描述】 一棵树上有n个节点&#xff0c;编号分别为1到n&#xff0c;每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作&#xff1a; I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问…

Unity插件Gaia使用介绍

零基础创建Unity精美场景地形&#xff08;使用插件Gaia&#xff09;一、先上最终效果图二、软件环境搭建1.Unity5.6.0下载链接https://unity3d.com/cn/get-unity/download/archive?_ga2.110664517.1175563345.1516068066-173539005.15020707552.Gaia Unity地形制作插件下载链…

java http 压缩_解压HTTP API的GZIP压缩数据

1.对Java后端的请求HttpURLConnection对象中的消息头设置压缩connection.setRequestProperty("Accept-Encoding", "gzip, deflate");2.发送请求后获取response中的content-encodingconnection.getContentEncoding(); // 获取content-encoding3.如果content…

20151208_使用windows2012配置weblogic节点管理器

经过实践&#xff0c;weblogic节点管理器的作用主要有两点&#xff1a; 1、可通过weblogic控制台远程控制被管server启停。 2、可以自动重启被管server的进程&#xff0c;并且对spring框架提供比直接启动更快的重启速度。 配置步骤&#xff1a; 在管理电脑上&#xff1a; …

python各种包安装顺序_史上最全的Python包管理工具:Anaconda教程

事实上Anaconda 和 Jupyter notebook已成为数据分析的标准环境。简单来说&#xff0c;Anaconda是包管理器和环境管理器&#xff0c;Jupyter notebook 可以将数据分析的代码、图像和文档全部组合到一个web文档中。接下来我详细介绍下Anaconda&#xff0c;并在最后给出Jupyter no…

在Spring MVC中使用多个属性文件

每个人都听说过将单个Web应用程序组合成一个大型应用程序的门户。 门户软件的工作原理类似于mashup &#xff0d;来自多个来源的内容在单个服务中被拾取&#xff0c;大部分显示在单个网页中。 门户软件还允许在嵌入到门户软件中的所有单个Web应用程序&#xff08;独立模块&…

汇编语言实验一

实验任务 &#xff08;1&#xff09;使用debug&#xff0c;将程序段写入内存&#xff0c;逐条执行&#xff0c;观察cpu中相关寄存器内容变化。 完成此实验&#xff0c;可用e命令或a命令。 e命令改写内存的内容&#xff0c;如图&#xff1a; 我没有一气喝成&#xff0c;一开始便…

python学习 day6 (3月7日)

#__author : liuyang #date : 2019/3/7 0007 a [a , b , c] b [] print(a is b ) # 空元组 可以 空列表 不可以 print(tuple(a))题目&#xff1a; l1 [11, 22, 33, 44, 55] #将此列表索引为奇数的对应元素全部删除 # 错误示例 for l in range(len(l1)):print(l)if l % 2…

java jni helloword_JNI入门教程之HelloWorld篇

JNI入门教程之HelloWorld篇来源:互联网 宽屏版 评论2008-05-31 09:07:11本文讲述如何使用JNI技术实现HelloWorld&#xff0c;目的是让读者熟悉JNI的机制并编写第一个HelloWorld程序。java Native Interface(JNI)是Java语言的本地编程接口&#xff0c;是J2SDK的一部分。在java…