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实现ssh批量登录并执行命令
Oct 25 Python
Python序列操作之进阶篇
Dec 08 Python
Python编写Windows Service服务程序
Jan 04 Python
python批量设置多个Excel文件页眉页脚的脚本
Mar 14 Python
numpy判断数值类型、过滤出数值型数据的方法
Jun 09 Python
flask中过滤器的使用详解
Aug 01 Python
Python 旋转打印各种矩形的方法
Jul 09 Python
pycharm新建一个python工程步骤
Jul 16 Python
python使用socket实现的传输demo示例【基于TCP协议】
Sep 24 Python
Python3.7基于hashlib和Crypto实现加签验签功能(实例代码)
Dec 04 Python
pandas 数据类型转换的实现
Dec 29 Python
python os.listdir()乱码解决方案
Jan 31 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
PHP提取中文首字母
2008/04/09 PHP
php异步多线程swoole用法实例
2014/11/14 PHP
PHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIF
2016/02/19 PHP
PHP实现的简单路由和类自动加载功能
2018/03/13 PHP
php fread函数使用方法总结
2019/05/28 PHP
javascript学习笔记(十四) window对象使用介绍
2012/06/20 Javascript
js数组转json并在后台对其解析具体实现
2013/11/20 Javascript
JavaScript实现简单Tip提示框效果
2016/04/20 Javascript
bootstrap table小案例
2016/10/21 Javascript
javascript设置文本框光标的方法实例小结
2016/11/04 Javascript
移动开发之自适应手机屏幕宽度
2016/11/23 Javascript
原生js实现下拉框功能(支持键盘事件)
2017/01/13 Javascript
Vue.js对象转换实例
2017/06/07 Javascript
微信小程序 转发功能的实现
2017/08/04 Javascript
vue使用axios实现文件上传进度的实时更新详解
2017/12/20 Javascript
element-ui 设置菜单栏展开的方法
2018/08/22 Javascript
JS使用H5实现图片预览功能
2019/09/30 Javascript
详解Python3中yield生成器的用法
2015/08/20 Python
Python学习笔记整理3之输入输出、python eval函数
2015/12/14 Python
使用Python &amp; Flask 实现RESTful Web API的实例
2017/09/19 Python
Python格式化日期时间操作示例
2018/06/28 Python
python计算两个矩形框重合百分比的实例
2018/11/07 Python
Django Rest framework之认证的实现代码
2018/12/17 Python
在pycharm中设置显示行数的方法
2019/01/16 Python
python元组和字典的内建函数实例详解
2019/10/22 Python
python 中的命名空间,你真的了解吗?
2020/08/19 Python
LocalStorage记住用户和密码功能
2017/07/24 HTML / CSS
string = null 和string = ''的区别
2013/04/28 面试题
网络工程与软件技术毕业生自荐信
2013/09/24 职场文书
法制宣传月活动总结
2014/04/29 职场文书
副处级干部考察材料
2014/05/17 职场文书
公司离职证明范本(5篇)
2014/09/17 职场文书
工作检讨书怎么写
2015/01/23 职场文书
redis 查看所有的key方式
2021/05/07 Redis
go语言基础 seek光标位置os包的使用
2021/05/09 Golang
MySql数据库触发器使用教程
2022/06/01 MySQL