■高斯混合模型(GMM):理念、数学、EM算法和python实现
本文插图
高斯混合模型是一种流行的无监督学习算法 。 GMM方法类似于K-Means聚类算法 , 但是由于其复杂性 , 它更健壮 , 因此更有用 。
K-means聚类使用欧式距离函数来发现数据中的聚类 。 只要数据相对于质心呈圆形分布 , 此方法就可以很好地工作 。 但是 , 如果数据是非线性的呢?或者数据具有非零的协方差呢?如果聚类具有不同的均值和协方差怎么办?
这就要用到高斯混合模型了!
GMM假设生成数据的是一种混合的高斯分布 。 与将数据点硬分配到聚类的K-means方法(假设围绕质心的数据呈圆形分布)相比 , 它使用了将数据点软分配到聚类的方法(即概率性 , 因此更好) 。
简而言之 , GMM效果更好 , 因为:(A)通过使用软分配捕获属于不同聚类的数据点的不确定性 , (B)对圆形聚类没有偏见 。 即使是非线性数据分布 , 它也能很好地工作 。
GMM
GMM的目标函数是最大化数据X、p(X)或对数似然值L的似然值(因为对数是单调递增函数) 。 通过假设混合了K个高斯来生成数据 , 我们可以将p(X)写为边缘概率 , 对所有数据点的K个聚类求和 。
本文插图
似然值
本文插图
对数似然值
利用上面对数函数的求和 , 我们不能得到解析解 。 看起来很讨厌 , 但这个问题有一个很好的解决方案:Expectation-Maximization(EM)算法 。
数学
EM算法是一种迭代算法 , 用于在无法直接找到参数的情况下寻找模型的最大似然估计(MLE) 。 它包括两个步骤:期望步骤和最大化步骤 。
1.期望步骤:计算成员值r_ic 。 这是数据点x_i属于聚类c的概率 。
本文插图
2. 最大化步骤:计算一个新参数mc , 该参数确定属于不同聚类的点的分数 。通过计算每个聚类c的MLE来更新参数μ , π , Σ 。
本文插图
重复EM步骤 , 直到对数似然值L收敛 。
Python编码
让我们从头开始用python编写GMM的基本实现 。
生成一维数据 。
x = np.linspace(-5, 5, 20) x1 = x*np.random.rand(20) x2 = x*np.random.rand(20) + 10 x3 = x*np.random.rand(20) - 10 xt = np.hstack((x1,x2,x3))初始化GMM的参数:μ , π , Σ 。
max_iterations = 10 pi = np.array([1/3, 1/3, 1/3]) mu = np.array([5,6,-3]) var = np.array([1,3,9]) r = np.zeros((len(xt), 3))运行EM算法的第一次迭代
import matplotlib.pyplot as plt import numpy as np from scipy.stats import norm gauss1 = norm(loc=mu[0], scale=var[0]) gauss2 = norm(loc=mu[1], scale=var[1]) gauss3 = norm(loc=mu[2], scale=var[2]) # E-Step for c,g,p in zip(range(3), [gauss1, gauss2, gauss3], pi): r[:,c] = p*g.pdf(xt[:]) for i in range(len(r)): r[i,:] /= np.sum(r[i,:]) fig = plt.figure(figsize=(10,10)) ax0 = fig.add_subplot(111) for i in range(len(r)): ax0.scatter(xt[i],0,c=r[i,:],s=100) for g,c in zip([gauss1.pdf(np.linspace(-15,15)),gauss2.pdf(np.linspace(-15,15)),gauss3.pdf(np.linspace(-15,15))],['r','g','b']): ax0.plot(np.linspace(-15,15),g,c=c,zorder=0) ax0.set_xlabel('X-axis') ax0.set_ylabel('Gaussian pdf value') ax0.legend(['Gaussian 1', 'Gaussian 2', 'Gaussian 3']) plt.show() # M-Step mc = np.sum(r, axis=0) pi = mc/len(xt) mu = np.sum(r*np.vstack((xt, xt, xt)).T, axis=0)/mc var = [] for c in range(len(pi)): var.append(np.sum(np.dot(r[:,c]*(xt[i] - mu[c]).T, r[:,c]*(xt[i] - mu[c])))/mc[c])
推荐阅读
- 初中数学@初中数学三角形倒角模型专题“8字模型”(含经典练习附答案)
- 体坛夏洛克称双方有代沟,没比赛“嘴仗”却不断!纳达尔回绝克耶高斯聊天邀请
- 智东西OpenAI追踪AI模型效率:每16个月翻一番!超越摩尔定律
- 科学家@人类寿命的极限是多少?科学家建立模型,这个数字你能接受吗?
- 量子位AI就能让它动起来!再也不怕3D动画拖更了,只要做出角色3D模型
- 购车小助理将搭载e-Power混合动力系统,日产发布新劲客预告图
- #王者荣耀#王者荣耀:马可波罗“高达”皮肤火了!模型霸气,有点像千手观音
- 大哥说事我们是认真的!导弹是模型,官方:涉及机密不能透露,搞笑
- 混合动力:混动车电池坏了,可以当燃油车来开吗?比亚迪和丰田的差距有点大
- 快科技Intel酷睿i5-L15G7处理器现身:10nm 3D封装、5核x86混合架构
