EM学习-思想和代码
EM算法的简明实现
当然是教学用的简明实现了,这份实现是针对双硬币模型的。
双硬币模型
假设有两枚硬币A、B,以相同的概率随机选择一个硬币,进行如下的抛硬币实验:共做5次实验,每次实验独立的抛十次,结果如图中a所示,例如某次实验产生了H、T、T、T、H、H、T、H、T、H,H代表正面朝上。
假设试验数据记录员可能是实习生,业务不一定熟悉,造成a和b两种情况
a表示实习生记录了详细的试验数据,我们可以观测到试验数据中每次选择的是A还是B
b表示实习生忘了记录每次试验选择的是A还是B,我们无法观测实验数据中选择的硬币是哪个
问在两种情况下分别如何估计两个硬币正面出现的概率?

a情况相信大家都很熟悉,既然能观测到试验数据是哪枚硬币产生的,就可以统计正反面的出现次数,直接利用最大似然估计即可。
b情况就无法直接进行最大似然估计了,只能用EM算法,接下来引用nipunbatra博主的简明EM算法Python实现。
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 4 18:23:28 2017 @author: Administrator
""" import numpy as np
from scipy import stats priors = [0.6, 0.5]
observations = np.array([[1,0,0,0,1,1,0,1,0,1],
[1,1,1,1,0,1,1,1,1,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]]) def em_single(priors, observations):
"""
input:
priors:[theta_A, theta_B]
obvervations:m*n matrix output: """
theta_A = priors[0]
theta_B = priors[1]
counts = {'A':{'H':0,'T':0}, 'B':{'H':0,'T':0}} # 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 iteration: 最大迭代数
return: 局部最优的模型参数
"""
import math
iter = 0
while iter < iterations:
new_prior = em_single(prior, observations)
delta_change = np.abs(new_prior[0]-prior[0])
if delta_change < tol:
break
else:
prior = new_prior
iter += 1
print (iter) return [new_prior, iter] y = em(observations, priors)
参考自:http://www.hankcs.com/ml/em-algorithm-and-its-generalization.html
EM学习-思想和代码的更多相关文章
- javascript 模块化 (切记:学习思想)
模块化(切记:学习思想) 如果不用模块化编写代码,那么会具有以下问题: 代码杂乱无章,没有条理性,不便于维护,不便于复用 很多代码重复.逻辑重复 全局变量污染 不方便保护私有数据(闭包) 模块化的基本 ...
- 简要介绍Active Learning(主动学习)思想框架,以及从IF(isolation forest)衍生出来的算法:FBIF(Feedback-Guided Anomaly Discovery)
1. 引言 本文所讨论的内容为笔者对外文文献的翻译,并加入了笔者自己的理解和总结,文中涉及到的原始外文论文和相关学习链接我会放在reference里,另外,推荐读者朋友购买 Stephen Boyd的 ...
- 从bug中学习怎么写代码
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:从bug中学习怎么写代码.
- 20145335郝昊 Java学习心得 密码学代码复写
20145335郝昊 Java学习心得 密码学代码复写 本学期我们学习了现代密码学这门课程,在上课的时候接触到了很多种类型的密码体制,对于一些典型很通用的密码体制有自己的学习和设计.不论是从密码体制还 ...
- FPGA学习中的代码阅读
不管是学FPGA还是C语言,任何一种代码的学习都离不开大量的代码阅读,也就是多看,多学习别人的代码.初学者在学习的过程中更为重要的是模仿,模仿别人的代码算法怎么去处理的,模仿多了,代码看的多了,能力自 ...
- 前端学习:JS(面向对象)代码笔记
前端学习:JS(面向对象)代码笔记 前端学习:JS面向对象知识学习(图解) 创建类和对象 创建对象方式1调用Object函数 <body> </body> <script ...
- IOS学习4——block代码块
本文转载自:iOS开发-由浅至深学习block 一.关于block 在iOS 4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调.这不免让我们想 ...
- 机器学习:集成学习(集成学习思想、scikit-learn 中的集成分类器)
一.集成学习的思想 集成学习的思路:一个问题(如分类问题),让多种算法参与预测(如下图中的算法都可以解决分类问题),在多个预测结果中,选择出现最多的预测类别做为该样本的最终预测类别: 生活中的集成思维 ...
- [python]进阶学习之阅读代码
起因 最近在公司的任务是写一些简单的运营工具,因为是很小的工具,所以就用了github上面的一个开源项目flask-admin,可以省去很多的事情. 但是,这个开源项目是个人维护的项目,所以文档相对简 ...
随机推荐
- MySQL 5.6新特性 -- crash-safe replication
在slave上有两个线程:io线程和sql线程io线程接收master的二进制日志信息并写入到本地的relay log中:sql线程执行本地relay log中的信息.io线程读取到的二进制日志当前位 ...
- Effective Java 第三版——61. 基本类型优于装箱的基本类型
Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...
- 将csv的数据导入mysql
手头有一份8MB的CSV文件需要分析,对于程序员来说,还有比在数据库里分析更愉快的事情吗? 所以让我们把CSV导入MYSQL吧. 一.首先按照文件列数创建相应的SQL表 例如: DROP TABLE ...
- Jason 和 Java 对象转化示例
1.工程 2.代码: JsonUtil.java package com.my.json; import java.util.ArrayList; import java.util.List; imp ...
- 运行第一个Docker容器-Docker for Web Developers(1)
1. Docker介绍 Docker由dotCloud公司发起的一个内部项目,后来Docker火了,dotCloud公司改名为Docker了: Docker使用了Go语言开发,基于 Linux 内核的 ...
- numpy数组(4)-二维数组
python创建二维 list 的方法是在 list 里存放 list : l = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]] numpy可以直接 ...
- 【Spark深入学习-11】Spark基本概念和运行模式
----本节内容------- 1.大数据基础 1.1大数据平台基本框架 1.2学习大数据的基础 1.3学习Spark的Hadoop基础 2.Hadoop生态基本介绍 2.1Hadoop生态组件介绍 ...
- 去除partner页面消息 自动添加关注者的功能
某些公司希望在partner页面说些partner的坏话,可是odoo居然自动添加了partner关注,这就尴尬了.... 如果恰搭建了邮件服务器,很有可能就自动发到了客户邮箱里,等着炸锅吧.... ...
- Unity5 AssetBundle系列——简单的AssetBundleManager
一个AssetBundle同时只能加载一次,所以实际使用中一般会伴随着AssetBundle包的管理. 下面是一个简单的AssetBundle管理器,提供了同步和异步加载函数: using Unity ...
- PCL中使用FLANN库(2)
接着上一篇的介绍继续 关于在使用readHeader函数读取点云数据头的类型的代码(Read a point cloud data header from a PCD file.) pcl::PCLP ...