《统计学习方法(第二版)》-李航-第九章EM算法及其推广 思维导图笔记及课后练习题目答案(使用python3编写EM算法及在高斯混合模型中的应用)

第九章思维导图总结:

请添加图片描述

import numpy as np

9.1

y = np.array([[1, 1, 0, 1, 0, 0, 1, 0, 1, 1]]).T
m = y.shape[0]
theta = np.array([[0.46, 0.55, 0.67]]).T  # initialization

for i in range(100):
    theta_old = theta.copy()
    q_theta = (theta[0] * theta[1] ** y * (1 - theta[1]) ** (1 - y)) / (theta[0] * theta[1] ** y * (1 - theta[1]) ** (1 - y) + 
        ((1 - theta[0]) * theta[2] ** y * (1 - theta[2]) ** (1 - y)))
    theta[0] = q_theta.sum() / m
    theta[1] = (q_theta.T @ y) / q_theta.sum()
    theta[2] = ((1 - q_theta.T) @ y) / (1 - q_theta).sum()
    print(f'iteration {i} with theta:',theta.T)
    if np.linalg.norm(theta - theta_old) < 0.000001:
        print(f'converge at iteragtion: {i}')
        break
print(f'final theta: {theta.T}')
iteration 0 with theta: [[0.46186284 0.534595   0.65613464]]
iteration 1 with theta: [[0.46186284 0.534595   0.65613464]]
converge at iteragtion: 1
final theta: [[0.46186284 0.534595   0.65613464]]

9.2

F ( P ~ , θ ) = E p [ log ⁡ P ( Y , Z ∣ θ ) ] + H ( P ~ ) = E p [ log ⁡ P ( Y , Z ∣ θ ) ] − E P ~ log ⁡ P ~ ( Z ) = ∑ z P ~ θ ( Z ) log ⁡ P ( Y , Z ∣ θ ) − ∑ Z P ~ ( Z ) log ⁡ P ~ ( Z ) = ∑ z P ( Z ∣ Y , θ ) log ⁡ P ( Y , Z ∣ θ ) − ∑ Z P ( Z ∣ Y , θ ) log ⁡ P ( Z ∣ Y , θ ) = ∑ z P ( Z ∣ Y , θ ) log ⁡ P ( Y , Z ∣ θ ) P ( Z ∣ Y , θ ) = ∑ z P ( Z ∣ Y , θ ) log ⁡ P ( Y ∣ θ ) = log ⁡ P ( Y ∣ θ ) \begin{array}{l}F(\tilde{P}, \theta) \\ =E_{p}[\log P(Y, Z \mid \theta)]+H(\tilde{P}) \\ =E_{p}[\log P(Y, Z \mid \theta)]-E_{\tilde{P}} \log \tilde{P}(Z) \\ =\sum_{z} \tilde{P}_{\theta}(Z) \log P(Y, Z \mid \theta)-\sum_{Z} \tilde{P}(Z) \log \tilde{P}(Z) \\ =\sum_{z} P(Z \mid Y, \theta) \log P(Y, Z \mid \theta)-\sum_{Z} P(Z \mid Y, \theta) \log P(Z \mid Y, \theta) \\ =\sum_{z} P(Z \mid Y, \theta) \log \frac{P(Y, Z \mid \theta)}{P(Z \mid Y, \theta)} \\ =\sum_{z} P(Z \mid Y, \theta) \log P(Y \mid \theta) \\ =\log P(Y \mid \theta)\end{array} F(P~,θ)=Ep[logP(Y,Zθ)]+H(P~)=Ep[logP(Y,Zθ)]EP~logP~(Z)=zP~θ(Z)logP(Y,Zθ)ZP~(Z)logP~(Z)=zP(ZY,θ)logP(Y,Zθ)ZP(ZY,θ)logP(ZY,θ)=zP(ZY,θ)logP(ZY,θ)P(Y,Zθ)=zP(ZY,θ)logP(Yθ)=logP(Yθ)

9.3

from scipy.stats import norm as Gaussian


y = np.array([[-67, -48, 6, 8, 14, 16, 23, 24, 28, 29, 41, 49, 56, 60, 75]]).T
m = y.shape[0]
k = 2  # number of sub_distribution
alpha = np.array([1.0 / k for _ in range(k)]).T # initialize parameters
miu = np.array([[y.mean() for _ in range(k)]]).T
sigma = np.array([[np.sqrt(y.var()) for _ in range(k)]]).T


for i in range(100):
    alpha_old = alpha.copy()
    miu_old = miu.copy()
    sigma_old = sigma.copy()
    gamma_hat = np.zeros((m, k))
    for j in range(k):
        gamma_hat[:, j, None] = alpha[j] * Gaussian.pdf(y, miu[j], sigma[j]**2)
    gamma_hat = gamma_hat / gamma_hat.sum(axis=1).reshape((-1, 1))
    miu = (gamma_hat.T @ y) / gamma_hat.sum(axis=0).T
    sigma = (gamma_hat * (y - miu_old.T)**2).sum(axis=0).T / gamma_hat.sum(axis=0).T
    sigma = np.sqrt(sigma)
    alpha = gamma_hat.sum(axis=0).T / m
    if np.sum((miu - miu_old)**2 + (sigma - sigma_old)**2 + (alpha - alpha_old)**2) < 1e-15:
        print(f'converge at iteragtion: {i}')
        break
print(f'final alpha: {alpha.T} \nfinal miu: {miu.T} \nfinal sigma:{sigma.T}')
converge at iteragtion: 0
final alpha: [0.5 0.5] 
final miu: [[20.93333333 20.93333333]
 [20.93333333 20.93333333]] 
final sigma:[36.46453376 36.46453376]

看一下10个子模型(高斯分布)的结果:

from scipy.stats import norm as Gaussian


y = np.array([[-67, -48, 6, 8, 14, 16, 23, 24, 28, 29, 41, 49, 56, 60, 75]]).T
m = y.shape[0]
k = 10  # number of sub_distribution
alpha = np.array([1.0 / k for _ in range(k)]).T # initialize parameters
miu = np.array([[y.mean() for _ in range(k)]]).T
sigma = np.array([[np.sqrt(y.var()) for _ in range(k)]]).T


for i in range(100):
    alpha_old = alpha.copy()
    miu_old = miu.copy()
    sigma_old = sigma.copy()
    gamma_hat = np.zeros((m, k))
    for j in range(k):
        gamma_hat[:, j, None] = alpha[j] * Gaussian.pdf(y, miu[j], sigma[j]**2)
    gamma_hat = gamma_hat / gamma_hat.sum(axis=1).reshape((-1, 1))
    miu = (gamma_hat.T @ y) / gamma_hat.sum(axis=0).T
    sigma = (gamma_hat * (y - miu_old.T)**2).sum(axis=0).T / gamma_hat.sum(axis=0).T
    sigma = np.sqrt(sigma)
    alpha = gamma_hat.sum(axis=0).T / m
    if np.sum((miu - miu_old)**2 + (sigma - sigma_old)**2 + (alpha - alpha_old)**2) < 1e-15:
        print(f'converge at iteragtion: {i}')
        break
print(f'final alpha: {alpha.T} \nfinal miu: {miu.T} \nfinal sigma:{sigma.T}')
converge at iteragtion: 0
final alpha: [0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1] 
final miu: [[20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]
 [20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]
 [20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]
 [20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]
 [20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]
 [20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]
 [20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]
 [20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]
 [20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]
 [20.93333333 20.93333333 20.93333333 20.93333333 20.93333333 20.93333333
  20.93333333 20.93333333 20.93333333 20.93333333]] 
final sigma:[36.46453376 36.46453376 36.46453376 36.46453376 36.46453376 36.46453376
 36.46453376 36.46453376 36.46453376 36.46453376]

9.4

还没看非监督呢

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ML--小小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值