贝叶斯分类器(二)贝叶斯网和EM算法
贝叶斯网(Bayesian network)亦称“信念网”(belief network),它借助于有向无环图(Directed Acyclic Graph, DAG)来刻画属性之间的依赖关系,并使用条件概率表(Conditional Probability Table, CPT)来描述属性的联合概率分布。
一个贝叶斯网
贝叶斯网有效地表达了属性间的条件独立性。给定父结点集,贝叶斯网假设每个属性与它的非后裔属性独立,于是
以上图为例,联合概率分布定义为:
贝叶斯网中三个变量之间的典型依赖关系:
在“同父”结构中,给定父结点
事实上,一个变量取值的确定与否,能对另两个变量间的独立性发生影响,这个现象并非
“有向分离”(D-separation),分析有向图中变量之间的条件独立性。先把有向图转变为一个无向图:
找出有向图中的所有
将所有有向边改为无向边。
由此产生的无向图称为“道德图”(moral graph),令父结点相连的过程称为“道德化”(moralization)。
贝叶斯网学习的首要任务就是根据训练数据集找出结构最“恰当”的贝叶斯网。“评分搜索”是求解这一问题的常用方法。具体来说,先定义一个评分函数,评估贝叶斯网域训练数据的契合程度,然后基于评分函数寻找结构最优的贝叶斯网。
每个贝叶斯网描述了一个训练数据上的概率分布,自有一套编码机制能使那些经常出现的样本有更短的编码。“最小长度描述”(Minimal Description Length, MDL)准则:选择综合编码长度(包括描述网络和编码数据)最短的贝叶斯网。
给定训练集
其中
显然,
若
若
若
若贝叶斯网
其中
通过已知变量观测值来推测待查询变量的过程称为“推断”(inference),已知变量观测值称为“证据”(evidence)。
现实应用中,贝叶斯网的近似推断常使用吉布斯采样(Gibbs sampling)来完成,这是一种随机采样方法。
令
下图为吉布斯采样算法:
实质上,吉布斯采用是在贝叶斯网所有变量的联合状态空间与证据
需要注意的是,由于马尔科夫链通常需要很长时间才能趋于平稳分布,因此,吉布斯采样算法的收敛速度较慢。此外,若贝叶斯网中存在极端概率“0”或“1”,则不能保证马尔科夫链存在平稳分布,此时吉布斯采样会给出错误的估计结果。
概率模型有时含有观测变量(observable variable),又含有隐变量或潜在变量(latent variable)。如果概率模型的变量都是观测数据,那么给定数据,可以直接用极大似然估计或贝叶斯估计法估计模型的参数。但当模型含有隐变量时,就不能简单地使用这些估计方法。
EM算法是一种迭代方法,用于含有隐变量(hidden variable)的概率模型参数的极大似然估计,或极大后验概率估计。
EM算法的每次迭代由两步组成:E步,求期望(expectation);M步,求极大(maximization),故称为期望极大算法(expectation maximization algorithm),简称EM算法。
例(三硬币模型):假设有3枚硬币,分别记作A,B,C。这些硬币正面出现的概率分别是
EM算法与初值的选择有关,选择不同的初值可能得到不同的参数估计值。
一般地,用
假设给定观测数据
EM算法通过迭代求
import numpy as np
def expectation_maximization(obs_value, theta, tol, max_iter):
"""
EM算法
obs_value: 观测值
theta: 模型参数
tol: 精度要求
max_iter: 最大迭代次数
"""
m, n = obs_value.shape
for it in range(max_iter):
theta_old = np.copy(theta) # 用于精度判断,退出迭代
for i in range(m):
mu_array = np.zeros(n) # 存储每个观测值yi的mu值
for j in range(n):
# 计算模型参数pi^i,p^i,q^i下观测数据y_i来自掷硬币B的概率
yi = obs_value[i, j]
p_bcoin = theta[0] * theta[1] ** yi * (1 - theta[1]) ** (1 - yi)
p_ccoin = (1 - theta[0]) * theta[2] ** yi * (1 - theta[2]) ** (1 - yi)
mu_array[j] = p_bcoin / (p_bcoin + p_ccoin)
# 更新参数值
theta[0] = np.mean(mu_array)
theta[1] = mu_array.dot(obs_value[i]) / mu_array.sum()
theta[2] = (1 - mu_array).dot(obs_value[i]) / (1 - mu_array).sum()
# 满足精度,迭代退出
print("iter: ", it + 1, " model args: ", theta)
if abs(theta - theta_old).max() <= tol:
break
def random_sample_observations(m, n):
"""
随机产生m轮,每轮n次实验
"""
random_obs = np.zeros((m, n))
for i in range(m):
for j in range(n):
random_obs[i, j] = np.random.randint(0, 2)
return random_obs
observations = np.array([[1, 1, 0, 1, 0, 0, 1, 0, 1, 1]])
theta = np.array([0.5, 0.5, 0.5])
expectation_maximization(observations, theta, 1e-15, 10)
EM算法的描述:
输入:观测变量数据
输出:模型参数
(1)选择模型的初值
(2)E步:记
这里
(3)M步:求使
(4)重复第(2)和第(3)步,直到收敛。
函数
步骤(1),参数的初值可以任意选择,但需要注意EM算法对初值是敏感的。
步骤(2),E步求
步骤(3),M步求
步骤(4)给出停止迭代的条件,一般是对较小的正数
则停止迭代。
在现实应用中往往会遇到“不完整”的训练样本,这种存在“未观测”变量的情形下,是否仍能对模型参数进行估计呢?
未观测变量的学名是“隐变量”(latent variable)。令
EM(Expectation-Maximization)算法是常用的估计参数隐变量的利器,它是一种迭代式的方法,其基本思想是:若参数
基于
基于已观测变量
这就是EM算法的原型。
进一步,若不是取
E步(Expectation):以当前参数
M步(Maximization):寻找参数最大化期望似然,即:
简单来说,EM算法使用两个步骤交替计算:第一步是期望(E)步,利用当前估计的参数值来计算对数似然的期望值;第二步是最大化(M)步,寻找能使E步产生似然期望最大化的参数值。然后,新得到的参数值重新被用于E步,.......直到收敛到局部最优解。
隐变量估计问题也可以通过梯度下降法等优化算法求解,但由于求和的项数将随着隐变量的数目以指数级上升,会给梯度计算带来麻烦;而EM算法则可看做是一种非梯度优化方法。