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修改字典内key对应值的方法
Jul 11 Python
改进Django中的表单的简单方法
Jul 17 Python
Python正则抓取网易新闻的方法示例
Apr 21 Python
Python数据分析之如何利用pandas查询数据示例代码
Sep 01 Python
让Python更加充分的使用Sqlite3
Dec 11 Python
Python使用Phantomjs截屏网页的方法
May 17 Python
python 产生token及token验证的方法
Dec 26 Python
python 应用之Pycharm 新建模板默认添加编码格式-作者-时间等信息【推荐】
Jun 17 Python
python3.7 使用pymssql往sqlserver插入数据的方法
Jul 08 Python
Python基于smtplib模块发送邮件代码实例
May 29 Python
PyQt中使用QtSql连接MySql数据库的方法
Jul 28 Python
Python 游戏大作炫酷机甲闯关游戏爆肝数千行代码实现案例进阶
Oct 16 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
第九节 绑定 [9]
2006/10/09 PHP
php遍历树的常用方法汇总
2015/06/18 PHP
ThinkPHP中html:list标签用法分析
2016/01/09 PHP
php实现获取农历(阴历)、节日、节气的类与用法示例
2017/11/20 PHP
javascript 动态加载 css 方法总结
2009/07/11 Javascript
clientX,pageX,offsetX,x,layerX,screenX,offsetLeft区别分析
2010/03/12 Javascript
jquery CSS选择器笔记
2010/03/29 Javascript
基于编写jQuery的无缝滚动插件
2014/08/02 Javascript
JavaScript数据结构和算法之二叉树详解
2015/02/11 Javascript
jquery制作多功能轮播图插件
2015/04/02 Javascript
jquery实现表格中点击相应行变色功能效果【实例代码】
2016/05/09 Javascript
基于jQuery实现的打字机效果
2017/01/16 Javascript
详解nodejs微信公众号开发——5.素材管理接口
2017/04/11 NodeJs
vue.js实现价格格式化的方法
2017/05/23 Javascript
webpack v4 从dev到prd的方法
2018/04/02 Javascript
使用 electron 实现类似新版 QQ 的登录界面效果(阴影、背景动画、窗体3D翻转)
2018/10/23 Javascript
node实现mock-plugin中间件的方法
2019/12/25 Javascript
vue中实现动态生成二维码的方法
2020/02/21 Javascript
python使用在线API查询IP对应的地理位置信息实例
2014/06/01 Python
编程语言Python的发展史
2014/09/26 Python
Python脚本实现虾米网签到功能
2016/04/12 Python
Windows上使用virtualenv搭建Python+Flask开发环境
2016/06/07 Python
python学习笔记之列表(list)与元组(tuple)详解
2017/11/23 Python
python web.py开发httpserver解决跨域问题实例解析
2018/02/12 Python
python实现聚类算法原理
2018/02/12 Python
Python使用matplotlib和pandas实现的画图操作【经典示例】
2018/06/13 Python
浅谈Django的缓存机制
2018/08/23 Python
python爬取内容存入Excel实例
2019/02/20 Python
python单例模式的多种实现方法
2019/07/26 Python
使用Python制作一个打字训练小工具
2019/10/01 Python
python获取网络图片方法及整理过程详解
2019/12/20 Python
HTML5 新标签全部总汇(推荐)
2016/06/13 HTML / CSS
国际旅客访问北美最大的汽车租赁提供商:Alamo Rent A Car
2018/06/13 全球购物
C#的几个面试问题
2016/05/22 面试题
股东授权委托书范文
2014/09/13 职场文书
2015年房产经纪人工作总结
2015/05/15 职场文书