GMM与K-means的那些事
来源:互联网 发布:安卓常用的布局优化 编辑:程序博客网 时间:2024/06/12 18:55
- GMM算法
- GMM 与 K-means
- GMM 模型
- GMM 聚类
- 参数与似然函数
- 算法流程
- Matlab 实现
- Python版本代码
- GMM与K-means对比
- 关于GMM算法中奇异矩阵的问题
转载请注明出处【CSDN】http://blog.csdn.net/llp1992
GMM算法
GMM ,Gaussian Mixture Model,顾名思义,就是说该算法由 多个高斯模型线性叠加 混合而成。每个高斯模型我们称之为 component 。GMM算法描述的是数据的本身存在的一种分布,如果component足够多的话,GMM可以逼近任意一种概率密度分布,但是此时的GMM模型就太过复杂了。
GMM 与 K-means
GMM算法跟K-means算法很像,它也是被用来聚类。在GMM中,component的个数我们定义为 K ,这跟K-means中的K一样,需要另外的方式去确定K值得大小。
在K-means中,每个聚类中心的初始化都会影响聚类效果,同样的,GMM算法对每个component的质心的初始化也很敏感。
解决方案
在K-means中,二分K-means算法就是为了弱化初始点对聚类效果的影响而提出来的,具体思路如下:
首先将所有点作为一个簇,然后将该簇一分为二。之后选择能最大程度降低聚类代价函数(也就是误差平方和)的簇划分为两个簇。以此进行下去,直到簇的数目等于用户给定的数目k为止
伪代码如下:
将所有数据点看成一个簇
当簇数目小于k时
对每一个簇
计算总误差
在给定的簇上面进行k-均值聚类(k=2)
计算将该簇一分为二后的总误差
选择使得误差最小的那个簇进行划分操作
同样的,GMM也可以有类似的二分GMM算法,关于二分K-means算法的具体流程以及代码请参考博客:
机器学习实战ByMatlab(四)二分K-means算法
GMM 模型
GMM由K个Gaussian分布线性叠加而成,先看看GMM的概率密度函数:
该函数可以这么理解,假设我们有一个数据集,然后我们现在用GMM模型来描述这个数据集的分布。在已知数据集由component k 描述的情况下,数据集的概率密度函数为:
当然,总共有 K 个component,每个component 对生成数据集的贡献为
如果我们要从 GMM 的分布中随机地取一个点的话,实际上可以分为两步:首先随机地在这 K个Gaussian Component 之中选一个,每个 Component 被选中的概率实际上就是它的系数 pi(k) ,选中了 Component 之后,再单独地考虑从这个 Component 的分布中选取一个点就可以了──这里已经回到了普通的 Gaussian 分布,转化为了已知的问题。
GMM 聚类
假设现在有一个大数据集,为什么要大数据集?待会会说。只要我们能用GMM算法来描述这个“客观存在”的数据集,那么GMM的K个component也就是对应的K个cluster了。根据数据来推算概率密度通常被称作 density estimation ,特别地,当我们在已知(或假定)了概率密度函数的形式,而要估计其中的参数的过程被称作“参数估计”。
每个component k 都是一个Gaussian分布,其均值设定为
参数与似然函数
现在假设我们有 N 个数据点,并假设它们服从某个分布(记作
我们的想法是,找到这样一组参数,它所确定的概率分布生成这些给定的数据点的概率最大,而这个概率实际上就等于
接下来我们只要将这个函数最大化(通常的做法是求导并令导数等于零,然后解方程),亦即找到这样一组参数值,它让似然函数取得最大值,我们就认为这是最合适的参数,这样就完成了参数估计的过程。
由于在对数函数里面又有加和,我们没法直接用求导解方程的办法直接求得最大值。为了解决这个问题,我们采取之前从 GMM 中随机选点的办法:分成两步,E步和M步,这就是用EM算法求解GMM的过程。其实这跟K-means的求解思想很像,或者说,K-means算法的求解中就是EM算法的精髓。
算法流程
1.估计数据由每个 Component 生成的概率(并不是每个 Component 被选中的概率):对于每个数据 来说,它由第 个 Component 生成的概率为:
其中
2.通过极大似然估计可以通过求到令参数=0得到参数
其中,
3.重复迭代前面两步,直到似然函数的值收敛为止。
Matlab 实现
GMM函数,来自 pluskid
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
注意这句代码
- 1
- 1
乍看之下好像跟我们的后验概率公式很不符合啊!后验概率公式如下:
代码中的实现是 乘以协方差矩阵的逆矩阵的行列式的开根号后的值,根据线性代数的知识可以得到:
测试代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
效果如下
采用同样的数据集: GMM聚类效果如下:
K-means效果如下:
Python版本代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
效果如下:
奇怪的是,用Python实现的时候,并没有出现协方差矩阵是奇异矩阵的现象,这是什么原因我也不是很清楚。
GMM与K-means对比
- 聚类效果差不多,初始值敏感的缺点也差不多,解决方案也差不多,二分法。
- 不同点:GMM输出的是数据点属于每个每类的概率,我们用最大似然方法去确定分类。就严谨性来说,用概率进行描述数据点的分类,GMM显然要比K-mean好很多。
关于GMM算法中奇异矩阵的问题
这个问题应该说是GMM算法的一个瑕疵,如果运行上面的代码可以发现在求协方差矩阵的逆矩阵的时候,有时候会报错,说协方差矩阵是奇异矩阵(singular),此时求解矩阵的行列式就会报错,关于这个问题,pluskid在 一篇博客
中已经说的很清楚。这里总结一下解决方法:
- 假设有N个D维的样本数据,如果协方差矩阵是奇异矩阵,那么要检查一下N是否足够大,D是否可以减少几维
- 最简单的解决方法之一,在协方差矩阵上加上一个对角线矩阵
λI ,其中λ 要足够小 ,不过如果数据集太小,这样也只是减少发生协方差矩阵是奇异矩阵的概率而已。
代码和数据都已近存放到 GitHub ,可以提供下载,如果觉得有用就请给个star吧。
参考文献:漫谈 Clustering (3): Gaussian Mixture Model
- GMM与K-means的那些事
- 机器学习算法原理与实践(五)、GMM与K-means的那些事
- GMM&K-means&EM
- GMM 和 K-means
- EM算法(期望最大化)——从EM算法角度理解K-Means与GMM的区别
- 【机器学习】K-means和GMM
- k-means、GMM聚类、KNN原理概述
- K-means 与 K-means++
- K-Means, K-Medoids, GMM, Spectral clustering,Ncut
- K-Means, K-Medoids, GMM, Spectral clustering,Ncut
- KNN与K-Means的区别
- KNN与K-Means的区别
- KNN与K-Means的区别
- KNN与K-Means的区别
- K-means与EM的关系
- KNN与K-Means的区别
- KNN与K-Means的区别
- 聚类算法——K-means, K-means++, KNN, GMM,
- lua文件操作详解
- 多层前馈神经网络的后向传播算法推导
- python idle更改样式
- [vijos1139] 小胖办证
- 实现全选功能三种方法
- GMM与K-means的那些事
- HashMap学习(一)
- Activity生命周期个人理解
- Mac Sierra Matlab2016a中文乱码解决
- 绘制幸福笑脸
- 习题七
- 读《魔鬼经济学02》
- 朴素贝叶斯 VS 逻辑回归 区别
- Redis 事务 命令