Python实现EM算法实例代码


Posted in Python onOctober 04, 2020

EM算法实例

通过实例可以快速了解EM算法的基本思想,具体推导请点文末链接。图a是让我们预热的,图b是EM算法的实例。

这是一个抛硬币的例子,H表示正面向上,T表示反面向上,参数θ表示正面朝上的概率。硬币有两个,A和B,硬币是有偏的。本次实验总共做了5组,每组随机选一个硬币,连续抛10次。如果知道每次抛的是哪个硬币,那么计算参数θ就非常简单了,如

下图所示:

Python实现EM算法实例代码

如果不知道每次抛的是哪个硬币呢?那么,我们就需要用EM算法,基本步骤为:

  1、给θ_AθA​和θ_BθB​一个初始值;

  2、(E-step)估计每组实验是硬币A的概率(本组实验是硬币B的概率=1-本组实验是硬币A的概率)。分别计算每组实验中,选择A硬币且正面朝上次数的期望值,选择B硬币且正面朝上次数的期望值;

  3、(M-step)利用第三步求得的期望值重新计算θ_AθA​和θ_BθB​;

  4、当迭代到一定次数,或者算法收敛到一定精度,结束算法,否则,回到第2步。

Python实现EM算法实例代码

计算过程详解:初始值θ_A^{(0)}θA(0)​=0.6,θ_B^{(0)}θB(0)​=0.5。

由两个硬币的初始值0.6和0.5,容易得出投掷出5正5反的概率是p_A=C^5_{10}*(0.6^5)*(0.4^5)pA​=C105​∗(0.65)∗(0.45),p_B=C_{10}^5*(0.5^5)*(0.5^5)pB​=C105​∗(0.55)∗(0.55), p_ApA​/(p_ApA​+p_BpB​)=0.449, 0.45就是0.449近似而来的,表示第一组实验选择的硬币是A的概率为0.45。然后,0.449 * 5H = 2.2H ,0.449 * 5T = 2.2T ,表示第一组实验选择A硬币且正面朝上次数和反面朝上次数的期望值都是2.2,其他的值依次类推。最后,求出θ_A^{(1)}θA(1)​=0.71,θ_B^{(1)}θB(1)​=0.58。重复上述过程,不断迭代,直到算法收敛到一定精度为止。

这篇博客对EM算法的推导非常详细,链接如下:

https://blog.csdn.net/zhihua_oba/article/details/73776553

Python实现

#coding=utf-8
from numpy import *
from scipy import stats
import time
start = time.perf_counter()

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 = stats.binom.pmf(num_heads,len_observation,theta_A)
  contribution_B = stats.binom.pmf(num_heads,len_observation,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]


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 = abs(prior[0]-new_prior[0])
  if delta_change < tol:
   break
  else:
   prior = new_prior
   iteration +=1
 return [new_prior,iteration]

#硬币投掷结果
observations = array([[1,0,0,0,1,1,0,1,0,1],
      [1,1,1,1,0,1,1,1,0,1],
      [1,0,1,1,1,1,1,0,1,1],
      [1,0,1,0,0,0,1,1,0,0],
      [0,1,1,1,0,1,1,1,0,1]])
print (em(observations,[0.6,0.5]))
end = time.perf_counter()
print('Running time: %f seconds'%(end-start))

总结

到此这篇关于Python实现EM算法实例的文章就介绍到这了,更多相关Python实现EM算法实例内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
使用 Python 获取 Linux 系统信息的代码
Jul 13 Python
python web框架学习笔记
May 03 Python
Python实现基于二叉树存储结构的堆排序算法示例
Dec 08 Python
Python装饰器简单用法实例小结
Dec 03 Python
解决py2exe打包后,总是多显示一个DOS黑色窗口的问题
Jun 21 Python
Flask模板引擎之Jinja2语法介绍
Jun 26 Python
Django实现发送邮件找回密码功能
Aug 12 Python
Python pyautogui模块实现鼠标键盘自动化方法详解
Feb 17 Python
python对数组进行排序,并输出排序后对应的索引值方式
Feb 28 Python
让Django的BooleanField支持字符串形式的输入方式
May 20 Python
Python虚拟环境venv用法详解
May 25 Python
Python如何实现后端自定义认证并实现多条件登陆
Jun 22 Python
python em算法的实现
Oct 03 #Python
浅析Python中字符串的intern机制
Oct 03 #Python
Python实现AES加密,解密的两种方法
Oct 03 #Python
python实现AdaBoost算法的示例
Oct 03 #Python
Django创建一个后台的基本步骤记录
Oct 02 #Python
Python中qutip用法示例详解
Oct 02 #Python
如何利用Python给自己的头像加一个小国旗(小月饼)
Oct 02 #Python
You might like
[FAQ]PHP中的一些常识:类篇
2006/10/09 PHP
PHP中动态显示签名和ip原理
2007/03/28 PHP
php实现数组筛选奇数和偶数示例
2014/04/11 PHP
php封装的smarty类完整实例
2016/10/19 PHP
php操作access数据库的方法详解
2017/02/22 PHP
js实现字符串的16进制编码不加密
2014/04/25 Javascript
我的Node.js学习之路(二)NPM模块管理
2014/07/06 Javascript
js实现对table动态添加、删除和更新的方法
2015/02/10 Javascript
chrome不支持form.submit的解决方案
2015/04/28 Javascript
javascript中checkbox使用方法实例演示
2015/11/19 Javascript
jQuery抛物线运动实现方法(附完整demo源码下载)
2016/01/08 Javascript
JS实现CheckBox复选框全选、不选或全不选功能
2020/07/28 Javascript
vue2.0 如何把子组件的数据传给父组件(推荐)
2018/01/15 Javascript
解决Webpack 热部署检测不到文件变化的问题
2018/02/22 Javascript
jQuery实现仿京东防抖动菜单效果示例
2018/07/06 jQuery
关于Vue项目跨平台运行问题的解决方法
2018/09/18 Javascript
微信小程序设置全局请求URL及封装wx.request请求操作示例
2019/04/02 Javascript
微信网页登录逻辑与实现方法
2019/04/29 Javascript
详解小程序云开发攻略(解决最棘手的问题)
2019/09/30 Javascript
Python使用chardet判断字符编码
2015/05/09 Python
详解MySQL数据类型int(M)中M的含义
2016/11/20 Python
Python基于列表模拟堆栈和队列功能示例
2018/01/05 Python
对PyTorch torch.stack的实例讲解
2018/07/30 Python
Python定时任务APScheduler的实例实例详解
2019/07/22 Python
python pandas cumsum求累计次数的用法
2019/07/29 Python
Python编程快速上手——强口令检测算法案例分析
2020/02/29 Python
应届大学生自荐信格式
2013/09/21 职场文书
优秀党员主要事迹
2014/01/19 职场文书
统计专业自荐书
2014/07/06 职场文书
敬老月活动总结
2014/08/28 职场文书
绿色校园广播稿
2014/10/13 职场文书
2014年小学工作总结
2014/11/26 职场文书
2015年幼儿园中班开学寄语
2015/05/27 职场文书
小学学习委员竞选稿
2015/11/20 职场文书
java调用Restful接口的三种方法
2021/08/23 Java/Android
oracle重置序列从0开始递增1
2022/02/28 Oracle