您好,欢迎来到步遥情感网。
搜索
您的当前位置:首页em算法 三硬币模型

em算法 三硬币模型

来源:步遥情感网

三硬币模型

设有3枚硬币记作a,b,c。出现正面的概率分别为π,p,q。先掷硬币a,若a为正面选硬币b,反面选c。

E步

观测数据y来自硬币b的概率

M步

p = m μ 1 m μ 1 + ( n − m ) μ 2 p=\dfrac{m\mu_1}{m\mu_1+(n-m)\mu_2} p=mμ1+(nm)μ2mμ1
q = m ( 1 − μ 1 ) m ( 1 − μ 1 ) + ( n − m ) ( 1 − μ 2 ) q=\dfrac{m(1-\mu_1)}{m(1-\mu_1)+(n-m)(1-\mu_2)} q=m(1μ1)+(nm)(1μ2)m(1μ1)
此时计算下一步的 μ 1 ( 1 ) = π p π p + ( 1 − π ) q \mu_1^{(1)}=\dfrac{\pi p}{\pi p +(1-\pi)q} μ1(1)=πp+(1π)qπp
带入 π \pi π,p,q后:
μ 1 ( 1 ) = m n μ 1 m n μ 1 + ( 1 − 1 n [ m μ 1 + ( n − m ) μ 2 ] ) m ( 1 − μ 1 ) m ( 1 − μ 1 ) + ( n − m ) ( 1 − μ 2 ) \mu_1^{(1)}=\cfrac{\cfrac m n \mu_1}{\cfrac m n \mu_1+\big( 1-\frac 1 n[m\mu_1+(n-m)\mu_2] \big)\cfrac{m(1-\mu_1)}{m(1-\mu_1)+(n-m)(1-\mu_2)}} μ1(1)=nmμ1+(1n1[mμ1+(nm)μ2])m(1μ1)+(nm)(1μ2)m(1μ1)nmμ1
μ 1 ( 1 ) = μ 1 μ 1 + ( n − [ m μ 1 + ( n − m ) μ 2 ] ) 1 − μ 1 m ( 1 − μ 1 ) + ( n − m ) ( 1 − μ 2 ) \mu_1^{(1)}=\cfrac{ \mu_1}{ \mu_1+\big( n-[m\mu_1+(n-m)\mu_2] \big)\cfrac{1-\mu_1}{m(1-\mu_1)+(n-m)(1-\mu_2)}} μ1(1)=μ1+(n[mμ1+(nm)μ2])m(1μ1)+(nm)(1μ2)1μ1μ1
μ 1 ( 1 ) = μ 1 μ 1 + ( n − n μ 2 + m μ 2 − m μ 1 ) 1 − μ 1 m − m + n − n μ 2 + m μ 2 − m μ 1 \mu_1^{(1)}=\cfrac{ \mu_1}{ \mu_1+\big(n-n\mu_2+m\mu_2-m\mu_1 \big)\cfrac{1-\mu_1}{m-m+n-n\mu_2+m\mu_2-m\mu_1 }} μ1(1)=μ1+(nnμ2+mμ2mμ1)mm+nnμ2+mμ2mμ11μ1μ1
μ 1 ( 1 ) = μ 1 μ 1 + 1 − μ 1 \mu_1^{(1)}=\cfrac{ \mu_1}{\mu_1+1-\mu_1} μ1(1)=μ1+1μ1μ1
μ 1 ( 1 ) = μ 1 \mu_1^{(1)}=\mu_1 μ1(1)=μ1

个人觉得书上三硬币的例子并不是迭代算法,第二次迭代生成的 μ 1 \mu_1 μ1等于第一次生成的 μ 1 \mu_1 μ1。所以后续迭代产生的 π \pi πpq都等于第一次计算得到的 π \pi πpq。

#include<bits/stdc++.h>
using namespace std;
const int n=10000;
int l[n]={0};
long double u[n]={0};
int main(){
	int seed = time(0);
    srand(seed);
    for(int i=0;i<n;++i){
    	if(rand()%10000<4123){
    		l[i]=rand()%10000<5201;
		}else{
			l[i]=rand()%10000<7321;
		}
	}
	
	long double a=0.1231,b=0.2319,c=0.123;
	for(int i=0;i<10;++i){
		long double sumu=0,sumuy=0,sumnuy=0,sumnu=0;
		long double i1=a*b/(a*b+(1-a)*c),i2=a*(1-b)/(a*(1-b)+(1-a)*(1-c));
		cout<<"------"<<i1<<' '<<i2<<endl;
		for(int j=0;j<n;++j){
			if(l[j]){
				u[j]=i1;
				sumuy+=u[j];
				sumnuy+=1-u[j];
			}
			else{
				u[j]=i2;
				
			}
			sumu+=u[j];
			sumnu+=1-u[j];
		}
		cout<<"***"<<endl;
		cout<<sumu<<endl;
		cout<<sumuy<<endl;
		cout<<sumnuy<<endl;
		cout<<sumnu<<endl;
		cout<<"***"<<endl;
		a=sumu/n;
		b=sumuy/sumu;
		c=sumnuy/sumnu;
		cout<<a<<"\t"<<b<<"\t"<<c<<"\t"<<endl;
	}
	
	
	
	return 0;
} 

使用代码模拟十次迭代

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- obuygou.com 版权所有 赣ICP备2024042798号-5

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务