EM-高斯混合模型
认识
前面为了直观认识 EM 算法, 用的"扔硬币"的案例, 是为了简化和直观, 而稍微偏应用和深入一点是高斯模型分类,这样一个话题.
就好比我们现在有一堆的数据点, 已经知道是来自于不同的 k 个类别, 每个类别又服从各自的高斯分布, 即k个不同的 (μ,σ)
需求: 求解出这 k 个高斯模型的参数
但现实是, 对于某一个点, 我们并不知道是来自于哪个类别, 因此只能认为任何一个点是这 k 个类别(模型) 的混合(Mixture) 结果.
对某一个点 xi, 它可能有 0.3的概率来自A类, 0.2概率来自B类, 0.1概率来自C类.... 这也是一个概率分布
Mixture of Gaussian 定义
给定一个有 n 个训练数据的集合, D={x1,x2,x3,..xn} 使用联合概率分布来建模:
p(xi,zi)=p(zi)p(xi|zi), 其中, 假设有 k 个类别分布.
-
zi→多元正态分布(ϕ) 其中 ϕ 是一个向量
-
ϕj=p(zi=j)且p(zi|xi=j)→N(μj,Σj)
-
k∑j=1ϕj=1
即在一共有 k 个高斯模型下, ϕj 为混合模型中的第 j 个高斯模型占的权重. 设 k 为 zi 的可能取值上限即每个xi 的产生:
-
随机从 {1,2,3,....k} 中选择一个 zi
-
然后从 zi 对应的高斯分布中产生 xi
-
zi 为不能直接观测到的 隐含变量, ϕ,μ,Σ 为需要预测的参数
E步: 让 μ,Σ 不变, 更新 ϕ
M步: 让 ϕ 不变, 更新 μ,Σ
对应的对数似然函数如下:
l(ϕ,μ,Σ)=n∑i=1 p(xi;ϕ,μ,Σ)
=n∑i=1log k∑zi=1p(xi|zi;μ,Σ)p(zi;ϕ)
这是个全概率分布: ϕ→zi→xi
给定 ϕ 下, zi 的分布; 给定 zi 下, xi的分布
参数估计
核心还是似然函数和贝叶斯公式
**E 步: ** 为第 i 个数据, 其所属 k 个类别中的 第 j 个类别的概率分布 (有点绕哈):
w(i)j=Qi(zi=j)=P(zi=j|xi;ϕ,Σ,μ)
即给定 ϕ,μ,Σ,xi 的条件下, P(zi=j) 的概率有多大
M 步: 最大化似然函数:
n∑i=1k∑zi=1Qi(zi) logp(xi,zi;ϕ,μ,Σ)Qi(zi)
即已知 xi,zi 的条件下, 去更新 μ,Σ
=n∑i=1k∑j=1Qi(zi=j) logp(xi|zi=j;μ,Σ)p(zi=j;ϕ)Qi(zi=j)
=n∑i=1k∑j=1w(i)j log1(2π)0.5n|Σ|0.5exp(−0.5(xi−μj)TΣ−1j(xi−μj))∗ϕjw(i)j
w(i)j 是非常容易算的, 就是之前的扔硬币嘛
但更新 Σj,μj 就麻烦了
只能分别对 Σ,μ 来求偏导了呀, 于是, 对期望 μl 求偏导( μl 表示 j=l 的时候哦:
∇μl=n∑i=1k∑j=1w(i)j log1(2π)0.5n|Σ|0.5exp(−0.5(xi−μj)TΣ−1j(xi−μj))∗ϕjw(i)j
化繁为简单, 利用 log 性质
上式相当于 log(abcd)=loga+logb+logc−logd
即原式对 μj 求导, 只跟中间的那项有关, 跟 exp 前面的高斯项, 还是 ϕj 没有任何关系滴
∇μl=n∑i=1k∑zi=1w(i)j log−0.5(xi−μj)TΣ−1j(xi−μj)
只是对 μl 求导, 只有当 j = l 的时候呢, 才会考虑 这 ∑求和, 即求和是没有真正起作用的, 可以直接去掉
=n∑i=1w(i)j∇μl log−0.5(xi−μj)TΣ−1j(xi−μj)
$=0.5 \sum \limits {i=1}^n w_l^{(i)} \nabla2\mu_l^T \Sigma_l ^{-1}x_i - \mu_l^T \Sigma_l^{-1}\mu_l $
=n∑i=1w(i)l(Σ−1lxi−Σ−1lμl)
令其等于 0 即:
μl=n∑i=1w(i)lxin∑i=1w(i)l
同理 再对 Σ 偏导, 令其为零, 跟上面是一样的.
Σj=n∑i=1w(i)j(xi−μj)(xi−μj)Tn∑i=1w(i)j
同理 对 ϕj 求偏导, 只保留包含 ϕj 的项, 即:
n∑i=1k∑j=1w(i)jlog(ϕj)
回顾上文, ϕj=p(zi=j;ϕ) 是一个概率分布, ∑kj=1ϕj=1 即是一个求条件极值的经典问题, 那很自然要引入到拉格朗日函数啦.
l(ϕ)=n∑i=1k∑j=1w(i)jlog(ϕj)−β(k∑j=1ϕj−1)
对 ϕj 求偏导, 令值为0:
同样对于 j = 1,2..k 来说, 其实 求和只是对满足条件的一项, 并未对其他产生作用
∇ϕjl(ϕ)=n∑i=1w(i)jϕj+β = 0
这里的 求和 是对 i 哦, 跟 j 是没有关系滴
ϕj=n∑i=1w(i)j−β
又因为 所有的 ϕ 的和是 1,可得到:
k∑j=1n∑i=1w(i)j−β=1
β 是常数, 可以提出来
1−βk∑j=1n∑i=1w(i)j=1
又因为 w(i)j=Qi(zi=j) 因此得到:
1−βn∑i=11=1
则: −β=n 这样一来, 最终化简得出:
ϕj=1nn∑i=1w(i)j
小结
重复执行 E, M 步骤, 直到收敛...
while True:
E-步: (即给定 ϕ,μ,Σ,xi 的条件下, P(zi=j) 的概率有多大)
w(i)j=Qi(zi=j)=P(zi=j|xi;ϕ,Σ,μ)
M-步: (更新参数 Σ,μ)
μl=n∑i=1w(i)lxin∑i=1w(i)l
Σj=n∑i=1w(i)j(xi−μj)(xi−μj)Tn∑i=1w(i)j
ϕj=1nn∑i=1w(i)j
IF 收敛:
break
总体上, 还是有点难度的感觉, 就是 大小类的层级关系 加上 条件概率, 真的是挺容易晕的, 也不太确定, 是否一定正确, 还是过后再来仔细检查一波.
耐心和恒心, 总会获得回报的.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通