一、预备知识
极大似然估计
Jensen不等式
二、EM算法
问题描述
我们这里不再具体推导EM算法,太南了~~~
EM算法流程
三、EM算法实例
四、EM算法的Python实现
# coding:UTF-8
'''
Created on 2019年12月24日
@author: NanShan
'''
from __future__ import division
import numpy as np
import math as mt
# 首先生成一些用于测试的样本
# 指定参数(均值)
sigma = 5
miu_1 = 45
miu_2 = 60
# 随机均匀选择两个高斯分布,用于生成样本值
N = 1000
X = np.zeros((1, N))
for i in range(N):
if np.random.random() > 0.5: # 使用的是numpy模块中的random
X[0, i] = np.random.randn() * sigma + miu_1
else:
X[0, i] = np.random.randn() * sigma + miu_2
# 上述步骤已经生成样本
# 对生成的样本,使用EM算法计算其均值miu
# 取miu的初始值
k = 2
miu = np.random.random((1, k))
Expectations = np.zeros((N, k))
for step in range(500): # 设置迭代次数
# 步骤1,E步
for i in range(N):
# 计算分母
denominator = 0
for j in range(k):
denominator = denominator + mt.exp(-1 / (2 * sigma ** 2) * (X[0, i] - miu[0, j]) ** 2)
# 计算分子
for j in range(k):
numerator = mt.exp(-1 / (2 * sigma ** 2) * (X[0, i] - miu[0, j]) ** 2)
Expectations[i, j] = numerator / denominator
# 步骤2,M步
oldMiu = np.zeros((1, k))
for j in range(k):
oldMiu[0, j] = miu[0, j]
numerator = 0
denominator = 0
for i in range(N):
numerator = numerator + Expectations[i, j] * X[0, i]
denominator = denominator + Expectations[i, j]
miu[0, j] = numerator / denominator
# 判断是否满足要求(这个精度已经相当可以啦)
epsilon = 0.000000001
if np.sum(np.abs(miu-oldMiu)) < epsilon:
print('退出时训练的轮数:', step)
print('最后预测的均值为:', miu)
break
print('最后预测的均值为:', miu)
输出结果:
五、应用
如果将样本看作观察值,潜在类别看作是隐藏变量,那么聚类问题也就是参数估计问题,只不过聚类问题中参数分为隐含类别变量和其他参数。