以下是我的学习笔记,以及总结,如有错误之处请不吝赐教。
本文主要介绍最大熵模型与EM算法相关内容及相关代码案例。
关于熵之前的文章中已经学习过,具体可以查看:ml课程:决策树、随机森林、GBDT、XGBoost相关(含代码实现),补充一些
基本概念:
信息量:信息的度量,即一件事情发生的概率。那么熵既可以表示为信息量的期望,也就是。
联合熵(joint entropy):是联合概率分布或者多个变量的熵。
条件熵(conditionam):公式如下:
变换一下:
互信息(mutual information):是衡量两个随机变量之间的相关性,常用来特征选择或者降维;他与的区别是可以衡量非线性的相关性,具体公式表示:
推倒一下得到:
我们可以根据VN图来表示以上三个概念的
相对熵(relative entropy),即KL散度(kullback-leibler divergence):是衡量两个概率分布的差异。具体表示为:
性质:
- 是一个非对称的近似度量;
- 值越大分布之间的差异越大;
- 始终存在
关于性质3具体证明如下:
证明:假设,,同时由于log函数为凹函数,根据琴生不等式得到:E(f(x))f(E(X)):
将上述几个式子代入得到:
交叉熵(cross entropy):是衡量两个概率分布间的差异性信息,公式如下:
变化一下得到:
隐变量:表示不可观测变量Y={y1,y2,y3...,yn};
显变量:表示可观测变量Z={z1,z2,z3...,zn},两个变量的性质有:
最大似然(极大似然)估计:N个误差的联合概率密度为:p(y1,y2,...,yN),由于它们相互独立,故有:
那么条件概率的最大似然可以表示为:
这个概率反映了,在概率密度函数的参数是θ时,得到y这组样本的概率。 需要找到一个参数θ,其对应的似然函数L(θ)最大,这个叫做θ的最大似然估计量,记为:
由于似然函数连乘求导无法求解,因此对其取对数:
最后求导令其为0,得到似然方程参数。
最大熵模型(max entropy model):
在学习概率模型的时候,在所有可能的概率模型中,熵最大的模型是最好的模型;通俗说就是承认已知事物,对未知事物没有任何偏见。
目标函数:
然后通过最大熵求解得到以此来分类:
我们要求解以上的目标函数,需要构建一个特征函数:
同时通过概率的条件知:
同时我们定义理想状态的概率为,那么可以得到:
总结以上得到最大熵模型:
因此我们构造拉格朗日乘子:
其中:.
对其求偏导数:
令其为0,得到:
因此最终得到:
其中:
但是上式很难求得解析解,因此我们使用近似逼近解:
IIS(improved iterative scaling)方法:该方法类似坐标上升法,是假设最大熵模型下不断迭代使得:
EM算法(Expection Maximization):
用迭代方式交替求解优化值,这个算法可以从两个方向求解,如下图:
下面我们先从右边爬山,从最大似然的方向推到EM算法:
根据前面基本概念,将含有隐变量的极大似然估计的方法写为:
对其两边取对数:
我们迭代进行求解,使得,即:
即:
分别对前后两项进行凑项和琴生不等式得到:
令等于后面的式子,则:
具体推推倒过程如下图:
因此我们得到EM算法流程为:
- 随机生成,以此来迭代
- E-step:令为已经求得的数,根据前面得到的式子求,也就是其下边界函数,也是熵值。
- M-step:求导=0,最大化
- 重复2,3两步,直至为止。
下面我们从左边上山,从K-means(参考:ml课程:聚类概述及K-means讲解(含代码实现))方向推到EM算法:
K-means算法可以表示为:
- 随机选择k个点作为,即簇类的中心点;
- E-step:,其中表示一个隐变量概率为0或者1的硬分类;
- M-step:对上式求导=0,最小化。
- 重复2,3两步,直至为止。
EM算法应用:
高斯混合模型(GMM):
核心代码:
######################################################
# E 步:计算每个模型对样本的响应度
# Y 为样本矩阵,每个样本一行,只有一个特征时为列向量
# mu 为均值多维数组,每行表示一个样本各个特征的均值
# cov 为协方差矩阵的数组,alpha 为模型响应度数组
######################################################
def getExpectation(Y, mu, cov, alpha):
# 样本数
N = Y.shape[0]
# 模型数
K = alpha.shape[0]
# 为避免使用单个高斯模型或样本,导致返回结果的类型不一致
# 因此要求样本数和模型个数必须大于1
assert N > 1, "There must be more than one sample!"
assert K > 1, "There must be more than one gaussian model!"
# 响应度矩阵,行对应样本,列对应响应度
gamma = np.mat(np.zeros((N, K)))
# 计算各模型中所有样本出现的概率,行对应样本,列对应模型
prob = np.zeros((N, K))
for k in range(K):
prob[:, k] = phi(Y, mu[k], cov[k])
prob = np.mat(prob)
# 计算每个模型对每个样本的响应度
for k in range(K):
gamma[:, k] = alpha[k] * prob[:, k]
for i in range(N):
gamma[i, :] /= np.sum(gamma[i, :])
return gamma
######################################################
# M 步:迭代模型参数
# Y 为样本矩阵,gamma 为响应度矩阵
######################################################
def maximize(Y, gamma):
# 样本数和特征数
N, D = Y.shape
# 模型数
K = gamma.shape[1]
#初始化参数值
mu = np.zeros((K, D))
cov = []
alpha = np.zeros(K)
# 更新每个模型的参数
for k in range(K):
# 第 k 个模型对所有样本的响应度之和
Nk = np.sum(gamma[:, k])
# 更新 mu
# 对每个特征求均值
for d in range(D):
mu[k, d] = np.sum(np.multiply(gamma[:, k], Y[:, d])) / Nk
# 更新 cov
cov_k = np.mat(np.zeros((D, D)))
for i in range(N):
cov_k += gamma[i, k] * (Y[i] - mu[k]).T * (Y[i] - mu[k]) / Nk
cov.append(cov_k)
# 更新 alpha
alpha[k] = Nk / N
cov = np.array(cov)
return mu, cov, alpha
######################################################
# 高斯混合模型 EM 算法
# 给定样本矩阵 Y,计算模型参数
# K 为模型个数
# times 为迭代次数
######################################################
def GMM_EM(Y, K, times):
Y = scale_data(Y) #定义scale_data()数据预处理,将其缩放至0和1之间
mu, cov, alpha = init_params(Y.shape, K) #定义init_params()初始化模型参数
for i in range(times):
gamma = getExpectation(Y, mu, cov, alpha)
mu, cov, alpha = maximize(Y, gamma)
debug("{sep} Result {sep}".format(sep="-" * 20)) #定义debug()表示调试输出变量
debug("mu:", mu, "cov:", cov, "alpha:", alpha, sep="\n")
return mu, cov, alpha
具体实现欢迎关注:我的github
后续将继续介绍EM算法相关的应用,To be continue...