EM算应用:两硬币、三硬币

本文详细介绍了EM算法在处理含有隐变量的两硬币和三硬币模型中的应用。通过E步计算隐变量的期望,M步更新模型参数,逐步逼近最优解。文中给出了具体的推导过程和Python代码实现,展示了如何求解硬币正面向上的概率。
摘要由CSDN通过智能技术生成

参考了很多资料弄明白了EM算法在两硬币和三硬币中的算法以及代码。

0 EM算法

关于EM算法定义、使用场景、EM算法推导、收敛性证明直接看《统计学习方法》即可。
EM算法应用于有隐变量的场景。例如投掷2枚硬币,每次记录抛掷的硬币是A还是B,记录是正面还是反面。根据投掷结果计算2枚硬币的正面的概率是很好计算的。如果在记录过程中,没有记录抛掷的硬币是A还是B,这就是包含隐变量。这个时候没有解析解,只能通过迭代的方法求解。这也就是EM算法发挥作用的地方。

1 三硬币模型

有三枚硬币A,B,C,先投掷A,如果是正面就投掷B,如果是反面就投掷C,若我们只能观测到最后的投掷结果(B或者C的结果)而不能知道投掷的过程,如何估算三颗硬币的正面率?

1.1 定义

  • 参数 θ = ( π , p , q ) \theta=(\pi,p,q) θ=(π,p,q), π , p , q \pi,p,q π,p,q分别表示硬币A,B,C是正面的概率。
  • 观测到了n次投掷结果,记为 Y = ( y 1 , y 2 , . . . y n ) Y=(y_1,y_2,...y_n) Y=(y1,y2,...yn),每次投掷10次, y i ∈ [ 0 , 10 ] y_i \in [0,10] yi[0,10],表示本次试验中硬币正面朝上的次数
  • 隐变量设为 Z = ( z 1 , z 2 , . . . z n ) Z=(z_1,z_2,...z_n) Z=(z1,z2,...zn) z i = 0 z_i=0 zi=0表示硬币A正面朝上,将选择硬币B投掷; z i = 1 z_i=1 zi=1表示硬币A背面朝上,将选择硬币C投掷。

1.2 推导

1.2.1 E步

EM算法的E步是为隐变量建期望。

Q ( θ , θ ( i ) ) = ∑ z P ( z ∣ Y , θ ( i ) ) l o g P ( Y , z ∣ θ ) = ∑ j = 1 n ∑ k = 1 K P ( z = l k ∣ y j , θ ( i ) ) l o g P ( y j , z = l k ∣ θ ) = ∑ j = 1 n [ P ( z = 0 ∣ y j , θ ( i ) ) l o g P ( y j , z = 0 ∣ θ ) + P ( z = 1 ∣ y j , θ ( i ) ) l o g P ( y j , z = 1 ∣ θ ) ] Q(\theta, \theta^{(i)})=\sum_zP(z|Y,\theta^{(i)})logP(Y,z|\theta)\\ =\sum_{j=1}^n\sum_{k=1}^K P(z=l_k|y_j,\theta ^{(i)})logP(y_j,z=l_k|\theta)\\ =\sum_{j=1}^n[P(z=0|y_j,\theta ^{(i)}) logP(y_j,z=0|\theta) + P(z=1|y_j,\theta ^{(i)}) logP(y_j,z=1|\theta)] Q(θ,θ(i))=zP(zY,θ(i))logP(Y,zθ)=j=1nk=1KP(z=lkyj,θ(i))logP(yj,z=lkθ)=j=1n[P(z=0∣yj,θ(i))logP(yj,z=0∣θ)+P(z=1∣yj,θ(i))logP(yj,z=1∣θ)]
这里我们认为z的取值有k个。

我们先看下 P ( z = 0 ∣ y j , θ ( i ) ) P(z=0|y_j,\theta ^{(i)}) P(z=0∣yj,θ(i))应该怎么计算,这是一个条件概率,可以转为联合概率与全概率相除。
P ( z = 0 ∣ y j , θ ( i ) ) = P ( z = 0 , y j ∣ θ ( i ) ) ∑ z P ( z = z , y j ∣ θ ( i ) ) = P ( z = 0 , y j ∣ θ ( i ) ) P ( z = 0 , y j ∣ θ ( i ) ) + P ( z = 1 , y j ∣ θ ( i ) ) = π ( i ) ( p ( i ) ) ( y j ) ( 1 − p ( i ) ) 10 − y j π ( i ) ( p ( i ) ) ( y j ) ( 1 − p ( i ) ) 10 − y j + ( 1 − π ( i ) ) ( q ( i ) ) ( y j ) ( 1 − q ( i ) ) 10 − y j = μ j ( i + 1 ) P(z=0|y_j,\theta ^{(i)})=\dfrac{P(z=0,y_j|\theta ^{(i)})}{\sum_zP(z=z,y_j|\theta ^{(i)})}\\ =\dfrac{P(z=0,y_j|\theta ^{(i)})}{P(z=0,y_j|\theta ^{(i)})+P(z=1,y_j|\theta ^{(i)})}\\ =\dfrac{\pi^{(i)}(p^{(i)})^{(y_j)}(1-p^{(i)})^{10-y_j}}{\pi^{(i)}(p^{(i)})^{(y_j)}(1-p^{(i)})^{10-y_j} +(1- \pi^{(i)})(q^{(i)})^{(y_j)}(1-q^{(i)})^{10-y_j}}\\ =\mu_j^{(i+1)} P(z=0∣yj,θ(i))=zP(z=z,yjθ(i))P(z=0,yjθ(i))=P(z=0,yjθ(i))+P(z=1,yjθ(i))P(z=0,yjθ(i))=π(i)(p(i))(yj)(1p(i))10yj+(1π(i))(q(i))(yj)(1q(i))10yjπ(i)(p(i))(yj)(1p(i))10yj=μj(i+1)

10- y j y_j yj表示硬币反面朝上的次数。在有些公式中写的是1- y j y_j yj。这是因为要解决的问题是投一次硬币的问题。或者说一次试验只投一次硬币。

我们再看 P ( y j , z = 0 ∣ θ ) P(y_j,z=0|\theta) P(yj,z=0∣θ)的计算方式,它表示用硬币B,并且正面朝上的次数为 y j y_j yj
P ( y j , z = 0 ∣ θ ) = π p y j ( 1 − p ) 10 − y j P(y_j,z=0|\theta)=\pi p^{y_j}(1-p)^{10-y_j} P(yj,z=0∣θ)=πpyj(1p)10yj
P ( y j , z = 1 ∣ θ ) = ( 1 − π ) q y j ( 1 − q ) 10 − y j P(y_j,z=1|\theta)=(1-\pi)q^{y_j}(1-q)^{10-y_j} P(yj,z=1∣θ)=(1π)qyj(1q)10yj

那么我们把这三个式子代入到Q函数中得到:
Q ( θ , θ ( i ) ) = ∑ j = 1 n [ μ j ( i + 1 ) l o g ( π p y j ( 1 − p ) 10 − y j ) + ( 1 − μ j ( i + 1 ) ) l o g ( ( 1 − π ) q y j ( 1 − q ) 10 − y j ) = ∑ j = 1 n [ μ j ( i + 1 ) ( l o g π + y j l o g + ( 10 − y j ) l o g ( 1 − p ) ) + ( 1 − μ j ( i + 1 ) ) ( l o g ( 1 − π ) + y j l o g q + ( 10 − y j ) l o g ( 1 − q ) ) ] Q(\theta, \theta^{(i)})=\sum_{j=1}^n[\mu_j^{(i+1)}log(\pi p^{y_j}(1-p)^{10-y_j})+(1-\mu_j^{(i+1)})log((1-\pi)q^{y_j}(1-q)^{10-y_j})\\ =\sum_{j=1}^n[\mu_j^{(i+1)}(log\pi + {y_j}log+ (10-y_j)log(1-p))+(1-\mu_j^{(i+1)})(log(1-\pi)+y_jlogq+(10-y_j)log(1-q))] Q(θ,θ(i))=j=1n[μj(i+1)log(πpyj(1p)10yj)+(1μj(i+1))log((1π)qyj(1q)10yj)=j=1n[μj(i+1)(logπ+yjlog+(10yj)log(1p))+(1μj(i+1))(log(1π)+yjlogq+(10yj)log(1q))]

这样就将Q函数中的隐变量消除了,用模型参数θ来表示

1.2.1 M步

EM算法的M步是求下一轮参数。
有了Q函数,分别对θ中的具体参数求导,推导出参数更新公式。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

π = 1 n ∑ j = 1 n μ j ( i + 1 ) \pi=\dfrac{1}{n}\sum_{j=1}^n\mu _{j}^{(i+1)} π=n1j=1nμj(i+1)
p = ∑ j = 1 n μ j ( i + 1 ) y j ∑ j = 1 n 10 ∗ μ j ( i + 1 ) p=\dfrac{\sum_{j=1}^n\mu _j^{(i+1)}y_j}{\sum_{j=1}^n10*\mu _j^{(i+1)}} p=j=1n10μj(i+1)j=1nμj(i+1)yj

q = ∑ j = 1 n ( 1 − μ j ( i + 1 ) ) y j ∑ j = 1 n 10 ( 1 − ∗ μ j ( i + 1 ) ) q=\dfrac{\sum_{j=1}^n(1-\mu _j^{(i+1)})y_j}{\sum_{j=1}^n10(1-*\mu _j^{(i+1)})} q=j=1n10(1μj(i+1))j=1n(1μj(i+1))yj

1.3 代码

class EM3Coins:
    def __init__(self, thetas, data):
        self.thetas = thetas
        self.data = data

    def em_algo(self,  max_iter=30, eps=1e-3):
        pi, p, q = self.thetas
        pi = pi[:, None]
        thetas = np.array([p, q])
        ll_old = -np.infty
        n = len(self.data)
        sum = np.sum(self.data[0])
        for i in range(max_iter):
            like = pi * np.array([np.prod(np.power(theta, self.data), axis=1) for theta in thetas])
            p_coin = like / np.sum(like, axis=0)  # 2x5
            new_pi = 1/n * np.sum(p_coin, axis=1)
            p_coin_data = self.data[:, 0].dot(p_coin.T)  # 2x5
            new_thetas = p_coin_data / (sum * np.sum(p_coin, axis=1))
            new_thetas = np.array([[theta, 1 - theta] for theta in new_thetas])
            ll_new = np.sum(p_coin * np.log(like))
            if np.abs(ll_new - ll_old) < eps:
                break
            ll_old = ll_new
            thetas = new_thetas
            pi = new_pi[:,None]
        return pi.T, thetas
def main2():
    observed_data = np.array([(5, 5), (9, 1), (8, 2), (4, 6), (7, 3)])
    theta = np.array([[0.5, 0.5], [0.8, 0.2], [0.6, 0.4]])
    em = EM3Coins(thetas=theta, data=observed_data)
    pi, thetas = em.em_algo()
    print(pi)
    print(thetas)

最后得到pi=[[0.51950478 0.48049522]],p=[0.79406571 0.20593429],q=[0.51505001 0.48494999]

2 两硬币

假设现在有两个硬币A和B,我们想要知道两枚硬币各自为正面的概率即模型的参数。我们先随机从A,B中选一枚硬币,然后扔10次并记录下相应的结果,H代表正面T代表反面。对以上的步骤重复进行5次。如果在记录的过程中我们记录下来每次是哪一枚硬币(即知道每次选的是A还是B),那可以直接根据结果进行估计(见下图a)。
在这里插入图片描述
但是如果数据中没记录每次投掷的硬币是A还是B(隐变量),只观测到5次循环共50次投币的结果,这时就没法直接估计A和B的正面概率。这时就该轮到EM算法大显身手了,EM算法特别适用于这种含有隐变量的参数求解问题(见下图b)。
在这里插入图片描述
先初始化输入参数,如上图1步给了一个初始值0.6(A硬币正面的概率),0.5(B硬币正面的概率)。接下来先进行E步(对隐变量求期望),如上图2步:以第一条数据为例,5H5T,为A的概率为 p A = 0. 6 5 × 0. 4 5 p_A=0.6^5\times0.4^5 pA=0.65×0.45 ,为B的概率 p B = 0. 5 5 × 0. 5 5 p_B=0.5^5\times0.5^5 pB=0.55×0.55 ,归一化后得P(A)=0.45,P(B)=0.55,剩下几条数据同理可得。而后通过M-step可计算重新迭代的概率值。如上图第一次迭代后
,循环上面的E、M步骤直至收敛我们就可以得到最终的答案,如上图进过10次迭代后得到了最终的结果。

用术语描述。

2.1 定义

  • 参数 θ = ( p , q ) \theta=(p,q) θ=(p,q), p , q p,q p,q分别表示硬币A,B是正面的概率。
  • 观测到了n次投掷结果,记为 Y = ( y 1 , y 2 , . . . y n ) Y=(y_1,y_2,...y_n) Y=(y1,y2,...yn),每次投掷10次, y i ∈ [ 0 , 10 ] y_i \in [0,10] yi[0,10],表示本次试验中硬币正面朝上的次数
  • 隐变量设为 Z = ( z 1 , z 2 , . . . z n ) Z=(z_1,z_2,...z_n) Z=(z1,z2,...zn) z i = 0 z_i=0 zi=0表示选择硬币A投掷; z i = 1 z_i=1 zi=1表示选择硬币B投掷。

2.2 推导

2.2.1 E步

EM算法的E步是为隐变量建期望。

Q ( θ , θ ( i ) ) = ∑ z P ( z ∣ Y , θ ( i ) ) l o g P ( Y , z ∣ θ ) = ∑ j = 1 n ∑ k = 1 K P ( z = l k ∣ y j , θ ( i ) ) l o g P ( y j , z = l k ∣ θ ) = ∑ j = 1 n [ P ( z = 0 ∣ y j , θ ( i ) ) l o g P ( y j , z = 0 ∣ θ ) + P ( z = 1 ∣ y j , θ ( i ) ) l o g P ( y j , z = 1 ∣ θ ) ] Q(\theta, \theta^{(i)})=\sum_zP(z|Y,\theta^{(i)})logP(Y,z|\theta)\\ =\sum_{j=1}^n\sum_{k=1}^K P(z=l_k|y_j,\theta ^{(i)})logP(y_j,z=l_k|\theta)\\ =\sum_{j=1}^n[P(z=0|y_j,\theta ^{(i)}) logP(y_j,z=0|\theta) + P(z=1|y_j,\theta ^{(i)}) logP(y_j,z=1|\theta)] Q(θ,θ(i))=zP(zY,θ(i))logP(Y,zθ)=j=1nk=1KP(z=lkyj,θ(i))logP(yj,z=lkθ)=j=1n[P(z=0∣yj,θ(i))logP(yj,z=0∣θ)+P(z=1∣yj,θ(i))logP(yj,z=1∣θ)]
这里我们认为z的取值有k个。

我们先看下 P ( z = 0 ∣ y j , θ ( i ) ) P(z=0|y_j,\theta ^{(i)}) P(z=0∣yj,θ(i))应该怎么计算,这是一个条件概率,可以转为联合概率与全概率相除。
P ( z = 0 ∣ y j , θ ( i ) ) = P ( z = 0 , y j ∣ θ ( i ) ) ∑ z P ( z = z , y j ∣ θ ( i ) ) = P ( z = 0 , y j ∣ θ ( i ) ) P ( z = 0 , y j ∣ θ ( i ) ) + P ( z = 1 , y j ∣ θ ( i ) ) = ( p ( i ) ) ( y j ) ( 1 − p ( i ) ) 10 − y j ( p ( i ) ) ( y j ) ( 1 − p ( i ) ) 10 − y j + ( q ( i ) ) ( y j ) ( 1 − q ( i ) ) 10 − y j = μ j ( i + 1 ) P(z=0|y_j,\theta ^{(i)})=\dfrac{P(z=0,y_j|\theta ^{(i)})}{\sum_zP(z=z,y_j|\theta ^{(i)})}\\ =\dfrac{P(z=0,y_j|\theta ^{(i)})}{P(z=0,y_j|\theta ^{(i)})+P(z=1,y_j|\theta ^{(i)})}\\ =\dfrac{(p^{(i)})^{(y_j)}(1-p^{(i)})^{10-y_j}}{(p^{(i)})^{(y_j)}(1-p^{(i)})^{10-y_j} +(q^{(i)})^{(y_j)}(1-q^{(i)})^{10-y_j}}\\ =\mu_j^{(i+1)} P(z=0∣yj,θ(i))=zP(z=z,yjθ(i))P(z=0,yjθ(i))=P(z=0,yjθ(i))+P(z=1,yjθ(i))P(z=0,yjθ(i))=(p(i))(yj)(1p(i))10yj+(q(i))(yj)(1q(i))10yj(p(i))(yj)(1p(i))10yj=μj(i+1)

10- y j y_j yj表示硬币反面朝上的次数。在有些公式中写的是1- y j y_j yj。这是因为要解决的问题是投一次硬币的问题。或者说一次试验只投一次硬币。

我们再看 P ( y j , z = 0 ∣ θ ) P(y_j,z=0|\theta) P(yj,z=0∣θ)的计算方式,它表示用硬币A,并且正面朝上的次数为 y j y_j yj
P ( y j , z = 0 ∣ θ ) = p y j ( 1 − p ) 10 − y j P(y_j,z=0|\theta)=p^{y_j}(1-p)^{10-y_j} P(yj,z=0∣θ)=pyj(1p)10yj
P ( y j , z = 1 ∣ θ ) = q y j ( 1 − q ) 10 − y j P(y_j,z=1|\theta)=q^{y_j}(1-q)^{10-y_j} P(yj,z=1∣θ)=qyj(1q)10yj

那么我们把这三个式子代入到Q函数中得到:
Q ( θ , θ ( i ) ) = ∑ j = 1 n [ μ j ( i + 1 ) l o g ( p y j ( 1 − p ) 10 − y j ) + l o g ( ( 1 − π ) q y j ( 1 − q ) 10 − y j ) = ∑ j = 1 n [ μ j ( i + 1 ) ( y j l o g + ( 10 − y j ) l o g ( 1 − p ) ) + ( 1 − μ j ( i + 1 ) ) ( y j l o g q + ( 10 − y j ) l o g ( 1 − q ) ) ] Q(\theta, \theta^{(i)})=\sum_{j=1}^n[\mu_j^{(i+1)}log( p^{y_j}(1-p)^{10-y_j})+log((1-\pi)q^{y_j}(1-q)^{10-y_j})\\ =\sum_{j=1}^n[\mu_j^{(i+1)}( {y_j}log+ (10-y_j)log(1-p))+(1-\mu_j^{(i+1)})(y_jlogq+(10-y_j)log(1-q))] Q(θ,θ(i))=j=1n[μj(i+1)log(pyj(1p)10yj)+log((1π)qyj(1q)10yj)=j=1n[μj(i+1)(yjlog+(10yj)log(1p))+(1μj(i+1))(yjlogq+(10yj)log(1q))]

这样就将Q函数中的隐变量消除了,用模型参数θ来表示

2.2.1 M步

EM算法的M步是求下一轮参数。
有了Q函数,分别对θ中的具体参数求导,推导出参数更新公式。过程不再详细写了,参考三硬币模型,应该可以推出来。
p = ∑ j = 1 n μ j y j ∑ j = 1 n 10 μ j p=\dfrac{\sum_{j=1}^n\mu_jy_j}{\sum_{j=1}^n10\mu_j} p=j=1n10μjj=1nμjyj
q = ∑ j = 1 n ( 1 − μ j ) y j ∑ j = 1 n 10 ( 1 − μ j ) q=\dfrac{\sum_{j=1}^n(1 - \mu_j)y_j}{\sum_{j=1}^n10(1-\mu_j)} q=j=1n10(1μj)j=1n(1μj)yj

2.3 代码

class EM2Coins:

    def __init__(self, thetas, data):
        self.thetas = thetas
        self.data = data  # 5x2

    def em_algo(self, max_iter=30, eps=1e-3):
        ll_old = -np.infty
        sum = np.sum(self.data[0])
        for i in range(max_iter):
            like = np.array([np.prod(np.power(theta, self.data), axis=1)for theta in self.thetas])  # 2x5
            p_coin = like / np.sum(like, axis=0)  # 2x5,表示概率 p_coin[i][j]表示第j次试验选择硬币i的概率
            p_coin_data = self.data[:, 0].dot(p_coin.T)
            new_thetas = p_coin_data / (sum * np.sum(p_coin, axis=1))
            # 这里不够优雅
            new_thetas = np.array([[theta, 1 - theta] for theta in new_thetas])

            #p_coin_data = np.array([p[:, None] * self.data for p in p_coin])
            #new_thetas = np.array([pd.sum(0) / pd.sum() for pd in p_coin_data])
            #print(new_thetas)

            ll_new = np.sum(p_coin * np.log(like))
            if np.abs(ll_new - ll_old) < eps:
                break
            ll_old = ll_new
            self.thetas = new_thetas
        return self.thetas
 def main():
    observed_data = np.array([(5, 5), (9, 1), (8, 2), (4, 6), (7, 3)])
    theta = np.array([[0.4, 0.6], [0.6, 0.4], [0.5, 0.5]])
    em = EM2Coins(thetas=theta, data=observed_data)
    theta = em.em_algo()
    print(theta)

最终结果:p=[0.7967724 0.2032276 ], q=[0.51961361 0.48038639]

3 参考链接

为了弄明白代码中的每一步的含义,为了弄清楚E和M分别做了什么事情,参考了很多内容。主要参考内容是《统计学习方法》、《机器学习公式推导与代码实现》、知乎链接1链接2

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值