混合高斯(1)
混合高斯
单一高斯模型无法应对如老忠实间歇喷泉这些实际的问题,而高斯混合模型提供了一类比单独的高斯分布更强大的概率模型。我们将高斯混合模型看成高斯分量的简单线性叠加,其公式为[注0]:
引入一个K维的二值随机变量,这个变量采取"1-of-K"表示方法,其中一个特定元素等于1,其余所有的元素等于0.于是的值满足。因此我们可以根据哪个元素非零,判断向量有K个可能的状态。现在做出如下假设:向量的概率分布根据混合系数 进行赋值,即
其中系数 满足 ,使得上述概率是合法的。由于向量采用了“1-of-K”表示方法,因此可以将这个概率分布写成
类似地,给定一个特定的值,x的条件概率分布是一个高斯分布
于是
因此向量的联合概率分布为, 而的边缘概率分布可以通过将联合概率分布对所有可能的求和得到,即[注1]
上面一顿操作下来是要干什么啊?用混合高斯分布来表示变量的分布,然后通过引入一个新的变量,通过这两个变量联合分布对新变量所有可能求和,又得到这个混合高斯分布。转了一圈又回来了。
- 如果可以通过对联合概率关于某个变量所有可能求和可以表示边缘概率分布,即存在 的表示形式,那么对于每个观测数据点,存在一个与之对应的潜在变量
- 潜在变量可以显式写出?
- 我们能够对联合概率分布操作,而不是对边缘概率分布操作,这会极大地简化计算
- 给定x的条件下,z的条件概率可以求出,使用贝叶斯定理得到
我们用 表示 。如果将 看成 的先验概率,则 就是观测到x之后,对应的后验概率。对应混合模型, 也可以被看着第k个分量对应"解释"观测值x的"责任"[注2]。(等价于变量z的第k分量是1,其余分量是0.即)
最大似然
假设我们有一个观测的数据集 , 我们希望使用混合高斯模型来对数据进行建模。这个数据可以表示为一个 的矩阵,其中第n行为。类似地对应的潜在变量被表示为一个 的矩阵,它的行为。我们假定数据点独立地从概率分布中取样。根据公式(9.7),对数似然函数为
求解最大似然函数面临的问题:
(1)奇异性的存在。假设混合高斯模型,它的分量的协方差矩阵为 ,混合模型的第k分量均值和某个数据点完全相同,即对于某个n值,,那么这个数据点为似然函数贡献一项,形式为
如果考虑这个方差很小,趋于0,那么对数似然函数也会趋于无穷大。因此对数似然函数的最大化不是一个良好定义的问题[注3]。
(2)最大化高斯混合模型的对数似然函数,比单一的高斯分布更加复杂。困难源自在公式(9.14)中,对k的求和出现在对数计算的内部,从而对数函数无法之间作用于高斯分布,也就无法简化计算。我们令对数似然函数的导数等于零,也不会得到一个解析解。
用于GM的EM
有一种优雅的且强大的求解带有潜在变量的模型的最大似然解的方法被称为期望最大化算法,expectation-maximization algorithm,或者简称EM算法。
首先,令公式(9.14)中关于高斯分量的均值导数等于零[注4],得到
用上文提到的后验概率(9.13)代替简化公式得
再对上述公式两侧同时乘以
可以看到第k个高斯分量的均值可以通过对数据集中所有的数据点加权平均的方式得到,其中数据点的权重因子由后验概率给出。
令公式(9.14)中关于高斯分布的协方差矩阵的导数等于零[注5],得到
最大化公式 (9.14)需考虑限制条件,混合系数之和等于1. 使用拉格朗日乘法,最大化下面的量
求导得到
上式两边同时乘以,然后再对k 求和得到
从而推导得到
再代入公式(9.21)并同时乘以得到
附录
[注0] 为了便于大家与原文进行对比,这里的公式索引,仍采用和书本一样的索引号。
[注1]
由于z取值是"1-of-K",因此只1有个是1其余都等于零,即
对向量的所有可能求和就可以得到
[注2]
原文中是这么描述的: can also be viewed as the responsibility that component takes for 'explaining' the observation . 直白点讲,能观察到数据点,高斯混合分布中第k个分布贡献占比是,所有的分量贡献比之和等于1.
设变量z的取值分别是,依次对应着颜色red,green,blue。变量z的概率分布,以及x的条件分布依次为
使用如下代码画出的类似书中图9.5图形如下:
- 图左:随机从概率分布取样得到,再由条件概率分布取样得到二维点。二维点可以直接在直角坐标系用点画出,但是不好直接在绘制在坐标系中,于是映射为一种颜色,然后涂在二维坐标点上,即一一对应又完整了展示了联合变量的取样。
- 图中:忽略变量的取值。(实际自然界现象可能很多都是复杂的多元分布,能直观观察到可能就是单个变量的取样,而背后隐藏着无法观察或者未知的,但与当前观察一一对应的某个变量值。)
- 图右:观察到数据点后,按照后验概率公式求出,各个分量贡献占比,然后给数据点着色。可以看出位置点越靠近左右两侧的高斯分布的,其颜色越是接近红色或者蓝色。说明对应分量的影响越大。
import matplotlib.pyplot as plt
import numpy as np
from numpy.linalg import det, inv
global colors
colors = ['red', 'green', 'blue'] # 颜色值:红、绿、蓝
global prob_colors
prob_colors = np.array([0.1, 0.3, 0.6]) # 颜色变量Z取值的概率
# 条件概率 prob(x|z=red)
global mu_red
mu_red = np.array([-2, -1])
global sigma_red
sigma_red = np.array([[1,-1],[-1,2]])
# 条件概率 prob(x|z=green)
global mu_green
mu_green = np.array([1, 1])
global sigma_green
sigma_green = np.array([[1,1],[1,2]])
# 条件概率 prob(x|z=green)
global mu_blue
mu_blue = np.array([4.5, 2.5])
global sigma_blue
sigma_blue = np.array([[1,-1],[-1,2]])
def prob_value(x, mu, sigma):
diff_term = (x - mu).reshape(2,1)
D = len(x)
den = (2 * np.pi) ** (D / 2) * np.sqrt(det(sigma))
num = np.einsum("ij,jk->ik", np.einsum("ij,jk->ik", diff_term.T, inv(sigma)), diff_term)
num = np.exp(-num / 2).squeeze()
return num / den
def gamma_z(x):
x_red = prob_value(x, mu_red, sigma_red)
x_green = prob_value(x, mu_green, sigma_green)
x_blue = prob_value(x, mu_blue, sigma_blue)
den = prob_colors[0] * x_red + prob_colors[1] * x_green + prob_colors[2] * x_blue
return (prob_colors[0]*x_red/den, prob_colors[1]*x_green/den, prob_colors[2]*x_blue/den)
num = 1000 # 总样本点数
x_red = []
x_green = []
x_blue = []
for i in range(num):
rands = np.random.choice(colors, 1, p=prob_colors)
if rands[0] == 'red':
prob_norm = np.random.multivariate_normal(mu_red, sigma_red, size=1)
x_red.append(prob_norm[0])
if rands[0] == 'green':
prob_norm = np.random.multivariate_normal(mu_green, sigma_green, size=1)
x_green.append(prob_norm[0])
if rands[0] == 'blue':
prob_norm = np.random.multivariate_normal(mu_blue, sigma_blue, size=1)
x_blue.append(prob_norm[0])
x_red=np.array(x_red)
x_green=np.array(x_green)
x_blue=np.array(x_blue)
x_all = np.concatenate((x_red, x_green, x_blue), axis=0)
gamma_zk = []
for i in range(num):
xi = x_all[i]
gamma_zk.append(gamma_z(xi))
plt.figure(figsize=(9,3))
plt.subplot(1,3,1)
plt.plot(x_red[:,0], x_red[:,1], '.', alpha=1, color='r')
plt.plot(x_green[:,0], x_green[:,1], '.', alpha=1, color='g')
plt.plot(x_blue[:,0], x_blue[:,1], '.', alpha=1, color='b')
plt.subplot(1,3,2)
x_all = np.concatenate((x_red, x_green, x_blue), axis=0)
plt.plot(x_all[:,0], x_all[:,1], '.', alpha=1, color='pink')
tt = np.array([[1,0,0], [0,1,1]])
plt.subplot(1,3,3)
for ind in range(num):
x = x_all[ind]
plt.plot(x[0], x[1], '.', alpha=1, c=gamma_zk[ind])
plt.show()
[注3]:为什么单一高斯分布不会出现奇异性问题?
[注4]:如何推导这个(9.14)关于高斯分量均值的导数
首先,设
因此等于下面矩阵的各个元素相加
此时假设矩阵是对称矩阵, 表示矩阵A的第j列, 现在求关于中第k个分量的导数,而中关于包含与的,对应上述矩阵的第k行和第k列。再考虑A的对称性,可以得到
上式关于求导得到
从而求得
因此,关于向量的导数为
多元高斯分布的概率密度函数为
因此关于的导数为
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)