EM算法实现双硬币模型(python实现)

EM(Expectation-Maximization)算法可以对结果进行预测参数的信息,在一些含有隐变量的参数中使用它可以对模型参数进行一定的估计,并且它在机器学习的很多领域都会运用,这里我用python实现双硬币模型。

在这里插入图片描述

import numpy as np
import mathmp = math.powclass EM:def __init__(self, theta):self.theta_ap,self.theta_bp = thetaself.theta_an = 1 - self.theta_apself.theta_bn = 1 - self.theta_bpinfo_array = 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]])    #硬币正反的信息#计算时为了方便加入的算子self.assist_array = np.ones(10)  self.add_array = np.ones(5)  self.help_array = np.array([10,-1])  #计算向下硬币的矩阵算子self.mul = np.array([0.1])   #向上或向下的概率矩阵算子self.up_array=np.matmul(info_array,self.assist_array.T)   #向上的硬币个数矩阵self.calc_array = np.column_stack((self.add_array,self.up_array))self.down_array = np.inner(self.calc_array,self.help_array)    #向下的硬币个数矩阵self.probility_array_a = np.zeros(5) #属于A的概率self.probility_array_b = np.zeros(5) #属于B的概率self.pa = np.zeros(5)    #P(z = A|y1,theta_a)self.pb = np.zeros(5)    #P(z = B|y1,theta_a)self.proportion_up = np.zeros(5)  #向上的硬币占比self.proportion_down = np.zeros(5)    #向下的硬币占比self.upgrade_array = np.zeros((2,2)) #概率更新矩阵self.proportion_up = self.up_array.T*self.mul      #向上的硬币占比self.proportion_down = self.down_array.T*self.mul  #向下的硬币占比def e_step(self):for i in range(5):self.pa[i]=mp(self.theta_ap,self.up_array[i])*mp(self.theta_an,self.down_array[i])self.pb[i]=mp(self.theta_bp,self.up_array[i])*mp(self.theta_bn,self.down_array[i])for i in range(5):self.probility_array_a[i] = self.pa[i]/(self.pa[i]+self.pb[i])self.probility_array_b[i] = 1 - self.probility_array_a[i]mul_unit = np.row_stack((self.proportion_up,self.proportion_down))probility_unit = np.column_stack((self.probility_array_a,self.probility_array_b))self.upgrade_array = np.dot(mul_unit,probility_unit) #更新概率矩阵def m_step(self):self.theta_ap = self.upgrade_array[0,0]/(self.upgrade_array[0,0]+ self.upgrade_array[1,0])  #更新theta_aself.theta_an = 1 - self.theta_apself.theta_bp = self.upgrade_array[0,1]/(self.upgrade_array[0,1]+ self.upgrade_array[1,1])  #更新theta_bself.theta_bn = 1 - self.theta_bp#进行下一轮迭代print(self.upgrade_array)print(self.theta_ap)print(self.theta_bp)def em_algo(self):for i in range(20):self.e_step()self.m_step()def main():f = EM(theta=[0.6,0.5])f.em_algo()if __name__ == "__main__":main()

这里尽量使用矩阵运算来代替循环,因此涉及到矩阵运算,而且矩阵运算可以利用GPU进行加速,在大型项目中使用较多。
结果为:

[[2.12974819 1.17025181][0.85722466 0.84277534]]
0.7130122354005162
0.5813393083136625
[[1.92093824 1.37906176][0.65649201 1.04350799]]
0.7452920360819947
0.5692557501718727
[[1.94102768 1.35897232][0.5860269  1.1139731 ]]
0.7680988343673211
0.5495359141383477
[[1.97538329 1.32461671][0.54692598 1.15307402]]
0.7831645842999735
0.5346174541475203
[[1.99753285 1.30246715][0.52761677 1.17238323]]
0.7910552458637526
0.5262811670299319
[[2.00879016 1.29120984][0.51947654 1.18052346]]
0.7945325379936993
0.5223904375178747
[[2.01398202 1.28601798][0.5163729  1.1836271 ]]
0.7959286672497985
0.5207298780860258
[[2.01628374 1.28371626][0.51525515 1.18474485]]
0.7964656379225264
0.5200471890029876
[[2.0172865  1.2827135 ][0.51486707 1.18513293]]
0.7966683078984393
0.5197703896938074
[[2.01771917 1.28228083][0.51473641 1.18526359]]
0.7967441494752115
0.5196586622041123

最终结果为A向上的概率为0.79,B向上的概率为0.52.


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部