白话机器学习算法(十一) EM(附三个硬币模型代码)
2014-03-30 19:39
676 查看
EM有很多公式推导,这里还是先说下EM思想,前面说过EM是最大似然估计的思路,但是他的方法是用 参数与数据 去估计 参数,直到估计出的参数基本正确;
很多初学的对EM感到困惑,常常被一堆公式所迷惑,这样不利于深入理解EM,在此我也不想用一堆公式去推倒这个思想的数学证明;我只想给初学EM的读者一个感性的认识以及一些学习建议:
拿K-means来做个例子,我们要求的是聚类中心,我们是怎么做的呢?我们假设若一个聚类中心,然后通过这些聚类中心去得到某些东西,然后我们通过得到这些东西再去更新聚类中心;放到GMM模型中,就是我们假设某个参数,然后通过这个参数得到某个中间变量,再用这个中间变量去更新参数!
如果你还不能理解?
在概率中我们一个数据的期望是不是可以用成我们观测数据的均值去估计,如果两者一致,就叫无偏估计,好了,这是一个统计与估计相互验证的问题,GMM中就是这样一个思路:数据的统计与估计相互验证,我猜个参数,用参数去进行统计,再用统计值对参数进行估计!(再次强调我这里说的不是EM的证明,EM的证明指的的为什么我这么做最后能趋向于正确!是一个收敛性证明!)
如果你想从感性到理性逐渐理解:
建议你首先看看三个硬币模型,再去看下GMM的实际执行过程,再去看下EM的证明,结合起来,相信很快就能理解!
下面是EM算法在三个硬币模型中的代码
很多初学的对EM感到困惑,常常被一堆公式所迷惑,这样不利于深入理解EM,在此我也不想用一堆公式去推倒这个思想的数学证明;我只想给初学EM的读者一个感性的认识以及一些学习建议:
拿K-means来做个例子,我们要求的是聚类中心,我们是怎么做的呢?我们假设若一个聚类中心,然后通过这些聚类中心去得到某些东西,然后我们通过得到这些东西再去更新聚类中心;放到GMM模型中,就是我们假设某个参数,然后通过这个参数得到某个中间变量,再用这个中间变量去更新参数!
如果你还不能理解?
在概率中我们一个数据的期望是不是可以用成我们观测数据的均值去估计,如果两者一致,就叫无偏估计,好了,这是一个统计与估计相互验证的问题,GMM中就是这样一个思路:数据的统计与估计相互验证,我猜个参数,用参数去进行统计,再用统计值对参数进行估计!(再次强调我这里说的不是EM的证明,EM的证明指的的为什么我这么做最后能趋向于正确!是一个收敛性证明!)
如果你想从感性到理性逐渐理解:
建议你首先看看三个硬币模型,再去看下GMM的实际执行过程,再去看下EM的证明,结合起来,相信很快就能理解!
下面是EM算法在三个硬币模型中的代码
#include <iostream> #include <math.h> using namespace std; typedef struct theta { double pi; double p; double q; theta(double piInput,double pInput,double qInput):pi(piInput),p(pInput),q(qInput) { } }Theta; void threeCoins(int *pData,int nSize,int nNum,Theta &thetaStart); int main() { int pData[10]={1,1,0,1,0,0,1,0,1,1}; Theta thetaStart(0.5,0.5,0.5); threeCoins(pData,10,10,thetaStart); getchar(); return 0; } //nNum是迭代次数 void threeCoins(int *pData,int nSize,int nNum,Theta &thetaStart) { double *u=new double[nSize]; memset(u,0,sizeof(double)*nSize); Theta thetaTemp=thetaStart; int iNum=0; while(iNum<nNum) { for (int i=0;i<nSize;i++) { u[i]=thetaTemp.pi*pow(thetaTemp.p,pData[i])*pow(1-thetaTemp.p,pData[i]) /(thetaTemp.pi*pow(thetaTemp.p,pData[i])*pow(1-thetaTemp.p,pData[i])+(1-thetaTemp.pi)*pow(thetaTemp.q,pData[i])*pow(1-thetaTemp.q,1-pData[i])); } double uSum=0; for (int i=0;i<nSize;i++) { uSum+=u[i]; } thetaTemp.pi=uSum/nSize; double uSum2=0; for (int i=0;i<nSize;i++) { uSum2+=u[i]*pData[i]; } thetaTemp.p=uSum2/uSum; double uSum3=0; for (int i=0;i<nSize;i++) { uSum3+=pData[i]; } thetaTemp.q=(uSum3-uSum2)/(nSize-uSum); cout<<thetaTemp.pi<<'\t'<<thetaTemp.p<<'\t'<<thetaTemp.q<<endl; iNum++; } delete []u; }
相关文章推荐
- 白话机器学习算法(十一) EM(附三个硬币模型代码)
- 无公式无代码白话机器学习算法之决策树
- 最大熵,三硬币模型的R语言代码
- 【机器学习算法模型】聚类算法——EM
- 白话机器学习算法(十一) GMM
- R语言实现SOM(自组织映射)模型(三个函数包+代码)
- 《第一行代码-Android》学习笔记(十一)
- 借助 ptpython 三个命令实现终端下 PySpark 代码高亮和代码补全:
- [全程建模]三个问题的对话之一——RUP中的阶段与代码问题
- TensorFlow全流程样板代码:以ai challenger 场景分类和slim预训练模型为例
- 嵌入式 linux下kernel代码中设备驱动模型之device
- Android Studio(十一):代码混淆及打包apk
- Windows Socket五种I/O模型——代码全攻略
- server模型代码示例
- 设计模式讲解与代码实践(十一)——外观
- 十一、用工具生成代码
- Rails3入门之十一 建立一个多模型的form
- 平台总线设备驱动模型——代码分析
- 可重复使用程序代码 + 可重复使用模型 = 更高的生产力
- LDA主题模型的java代码实现