混合高斯模型算法

来源:互联网 发布:皮鞋品牌 知乎 编辑:程序博客网 时间:2024/06/05 15:41

下面介绍一下高斯混合模型算法:

高斯模型有单高斯模型(SGM)和混合高斯模型(GMM)两种。

(1)单高斯模型:

为简单起见,阈值t的选取一般靠经验值来设定。通常意义下,我们一般取t=0.7-0.75之间。

二维情况如下所示:

(2)混合高斯模型:

 

      对于(b)图所示的情况,很明显,单高斯模型是无法解决的。为了解决这个问题,人们提出了高斯混合模型(GMM)。

在介绍GMM之前,先来介绍一下k-means方法。

聚类的方法有很多种,k-means 要数最简单的一种聚类方法了,其大致思想就是把数据分为多个堆,每个堆就是一类。每个堆都有一个聚类中心(学习的效果就是获得这k个聚类中心),这个中心就是这个类中所有数据的均值,而这个堆中所有的点到该类的聚类中心都小于到其他类的聚类中心(分类的过程就是将未知数据对这k个聚类中心进行比较的过程,离哪个近就是谁)。其实k-means算得上是最直观、最方便理解的一种聚类方式了。原则就是把最像的数据分在一起,而“像”这个定义由我们来完成,比如欧式距离的最小等等。

GMM和k-means其实是十分相似的,区别仅仅在于对GMM来说,我们引入了概率。说到这里,我想先补充一点东西。统计学习的模型有两种,一种是概率模型,一种是非概率模型。所谓概率模型,就是指训练模型的形式是P(Y|X).输入是X,输出是Y,训练后模型得到的输出不是一个具体的值,而是一系列概率值(对应于分类问题来说,就是输入X对应于各个不同的Y(类)的概率),然而我们选取概率最大的那个类作为判决对象(软分类--soft assignment)。所谓非概率模型,就是指训练模型是一个决策函数Y=f(X),输入数据X是多少就可以投影得到惟一的Y,即判决结果(硬分类--hard assignment)。回到GMM,学习的过程就是训练出几个概率分布,所谓混合高斯模型就是指对样本的概率密度分布进行估计,而估计采用的模型(训练模型)是几个高斯模型的加权和。每个高斯模型就代表了一个类。对样本中的数据分别在几个高斯模型上投影,就会分别得到在各个类上的概率。

顾名思义,就是数据可以看作是从数个高斯分布中生成出来的。虽然我们可以用不同的分布来随意地构造 XX Mixture Model ,但是 GMM是 最为流行。另外,Mixture Model 本身其实也是可以变得任意复杂的,通过增加 Model 的个数,我们可以任意地逼近任何连续的概率密分布。

    每个 GMM 由 K 个 Gaussian 分布组成,每个 Gaussian 称为一个“Component”,这些 Component 线性加成在一起就组成了 GMM 的概率密度函数:

 

                (1)

其中,πk表示选中这个component部分的概率,我们也称其为加权系数。

根据上面的式子,如果我们要从 GMM 的分布中随机地取一个点的话,实际上可以分为两步:

(1)首先随机地在这 K 个 Component 之中选一个,每个 Component 被选中的概率实际上就是它的系数 πk,选中了 Component 之后,再单独地考虑从这个 Component 的分布中选取一个点就可以了──这里已经回到了普通的 Gaussian 分布,转化为了已知的问题。假设现在有 N 个数据点,我们认为这些数据点由某个GMM模型产生,现在我们要需要确定 πk,μk,σk 这些参数。很自然的,我们想到利用最大似然估计来确定这些参数,

最大似然估计就是使样本点在估计的概率密度函数上的概率值最大。由于概率值一般都很小,N很大的时候,连乘的结果非常小,容易造成浮点数下溢。所以我们通常取log,将目标函数改写成:

                                                       

也就是最大化对数似然函数,完整形式为:

                                                               (2)

 

一般在做参数估计时,我们都是通过对待求变量进行求导来求极值,在上式中,log函数中又有求和操作,你想用求导的方法来算会非常复杂,没有闭合解。可以采用的求解方法是EM算法--

将求解分为两步:第一步,假设知道各个高斯模型的参数(可以初始化一个,或者基于上一步迭代结果),去估计每个高斯模型的权值;第二步,基于估计的权值,回过头再去确定高斯模型的参数。重复这两个步骤,直到波动很小,近似达到极值(注意这里是极值不是最值,EM算法会陷入局部最优)。具体表达如下:

     1、(E step)

    对于第i个样本xi 来说,它由第k model 生成的概率为:

   

    在这一步,假设高斯模型的参数是已知的(由上一步迭代而来或由初始值决定)。

    2、(M step)

 高斯混合模型--GMM(Gaussian <wbr>Mixture <wbr>Model)

    3、重复上述两步骤直到算法收敛。

我们采用EM算法,分布迭代求解最大值:

EM算法的步骤这里不作详细的介绍,可以参见博客:

http://blog.pluskid.org/?p=39

最后总结一下,用GMM的优点是投影后样本点不是得到一个确定的分类标记,而是得到每个类的概率,这是一个重要信息。GMM每一步迭代的计算量比较大,大于k-means。GMM的求解办法基于EM算法,因此有可能陷入局部极值,这和初始值的选取十分相关了。GMM不仅可以用在聚类上,也可以用在概率密度估计上。

贴出代码:

复制代码
  1 function varargout = gmm(X, K_or_centroids)
2 % ============================================================
3 % Expectation-Maximization iteration implementation of
4 % Gaussian Mixture Model.
5 %
6 % PX = GMM(X, K_OR_CENTROIDS)
7 % [PX MODEL] = GMM(X, K_OR_CENTROIDS)
8 %
9 % - X: N-by-D data matrix.
10 % - K_OR_CENTROIDS: either K indicating the number of
11 % components or a K-by-D matrix indicating the
12 % choosing of the initial K centroids.
13 %
14 % - PX: N-by-K matrix indicating the probability of each
15 % component generating each point.
16 % - MODEL: a structure containing the parameters for a GMM:
17 % MODEL.Miu: a K-by-D matrix.
18 % MODEL.Sigma: a D-by-D-by-K matrix.
19 % MODEL.Pi: a 1-by-K vector.
20 % ============================================================
21
22 threshold = 1e-15;
23 [N, D] = size(X);
24
25 if isscalar(K_or_centroids)
26 K = K_or_centroids;
27 % randomly pick centroids
28 rndp = randperm(N);
29 centroids = X(rndp(1:K), :);
30 else
31 K = size(K_or_centroids, 1);
32 centroids = K_or_centroids;
33 end
34
35 % initial values
36 [pMiu pPi pSigma] = init_params();
37
38 Lprev = -inf;
39 while true
40 Px = calc_prob();
41
42 % new value for pGamma
43 pGamma = Px .* repmat(pPi, N, 1);
44 pGamma = pGamma ./ repmat(sum(pGamma, 2), 1, K);
45
46 % new value for parameters of each Component
47 Nk = sum(pGamma, 1);
48 pMiu = diag(1./Nk) * pGamma' * X;
49 pPi = Nk/N;
50 for kk = 1:K
51 Xshift = X-repmat(pMiu(kk, :), N, 1);
52 pSigma(:, :, kk) = (Xshift' * ...
53 (diag(pGamma(:, kk)) * Xshift)) / Nk(kk);
54 end
55
56 % check for convergence
57 L = sum(log(Px*pPi'));
58 if L-Lprev < threshold
59 break;
60 end
61 Lprev = L;
62 end
63
64 if nargout == 1
65 varargout = {Px};
66 else
67 model = [];
68 model.Miu = pMiu;
69 model.Sigma = pSigma;
70 model.Pi = pPi;
71 varargout = {Px, model};
72 end
73
74 function [pMiu pPi pSigma] = init_params()
75 pMiu = centroids;
76 pPi = zeros(1, K);
77 pSigma = zeros(D, D, K);
78
79 % hard assign x to each centroids
80 distmat = repmat(sum(X.*X, 2), 1, K) + ...
81 repmat(sum(pMiu.*pMiu, 2)', N, 1) - ...
82 2*X*pMiu';
83 [dummy labels] = min(distmat, [], 2);
84
85 for k=1:K
86 Xk = X(labels == k, :);
87 pPi(k) = size(Xk, 1)/N;
88 pSigma(:, :, k) = cov(Xk);
89 end
90 end
91
92 function Px = calc_prob()
93 Px = zeros(N, K);
94 for k = 1:K
95 Xshift = X-repmat(pMiu(k, :), N, 1);
96 inv_pSigma = inv(pSigma(:, :, k));
97 tmp = sum((Xshift*inv_pSigma) .* Xshift, 2);
98 coef = (2*pi)^(-D/2) * sqrt(det(inv_pSigma));
99 Px(:, k) = coef * exp(-0.5*tmp);
100 end
101 end
102 end
复制代码


    函数返回的 Px 是一个  的矩阵,对于每一个  ,我们只要取该矩阵第  行中最大的那个概率值所对应的那个 Component 为  所属的 cluster 就可以实现一个完整的聚类方法了。

 

参考资料:

【C++代码】

http://www.cppblog.com/Terrile/archive/2011/01/19/120051.html

http://www.autonlab.org/tutorials/gmm.html

http://bubblexc.com/y2011/8/

http://blog.pluskid.org/?p=39&cpage=1#comments

0 0
原创粉丝点击