混合高斯聚类的一种实现方法

[R][源码]EM算法实现基于高斯混合模型(GMM)的聚类 要求:用EM算法实现基于GMM的聚类算法。一、实验数据参考[1] 3.3.2章节。由两个二维高斯分布混合生成1000个数据,混合系数分别是0.4、0.6,均值和方差如下:mu1=[-2,-2]sigma1=[1.2, 0.5, 0.5, 1]mean2=[2,2]sigma2=[1.5, 0.7, 0.7, 1]二、实验过程、结果与分析2.1 数据散点图 2.2 用mclust包实现R语言自带mc... 阅读详情

近来看了一篇文章《Hierarchical Clustering of a Mixture Model》【1】,它是一篇比较早的文章了,2005年,Jacob Goldberger Sam Roweis,Department of Computer Science, University of Toronto。文中讲到一种简单的高斯聚类方法,近来有文章将它用于目标检测(Object Detection)最后阶段,以代替NMS(non maximum suppression,非极大值抑制),获得更好的bbox预测。我试了一下,这种方法有其独到之处,经它处理后的bbox相互重叠的情况有很大改善,而且较NMS要“软”一些,没那么“硬”,生成的box样子要比NMS能更好地覆盖目标。接下来,我将结合自己的代码和实验进行小结。

一、高斯聚类

混合高斯模型(MoG,Gaussian Mixture Model)是一种常见的参数化概率模型,其表达形式如下:
f(y)=∑i=1kαiN(y;μi,Σi)=∑i=1kαifi(y)(1) f(y) = \sum^k_{i=1}\alpha_iN(y;\mu_i,\Sigma_i)= \sum^k_{i=1}\alpha_i f_i(y)\qquad (1) f(y)=i=1∑k​αi​N(y;μi​,Σi​)=i=1∑k​αi​fi​(y)(1)
f(y)f(y)f(y)是由 kkk 个d维高斯分布构成的混合分布,各高斯分布 fi(y)f_i(y)fi​(y) 的期望和方差分别为 μi,Σi\mu_i,\Sigma_iμi​,Σi​。可将每个独立的高斯分布称为一个高斯核,所谓高斯聚类就是将多个高斯核进行聚类,用较少的高斯核来近似表达它,此过程描述如下:
f(y)=∑i=1kαifi(y)≈∑j=1mβjgj(y), and k>m(2) f(y) =\sum^k_{i=1}\alpha_i f_i(y)\approx \sum^m_{j=1}\beta_j g_j(y)\quad \text{, and }k\gt m\qquad(2) f(y)=i=1∑k​αi​fi​(y)≈j=1∑m​βj​gj​(y), and k>m(2)
(2)式中 gj(y)g_j(y)gj​(y) 也是与fi(y)f_i(y)fi​(y) 同维度的高斯分布,且约等于式左边的高斯核数量要大于右边的高斯核数量。所谓高斯聚类,指的就是用较少的高斯核混合分布来拟合较多核的高斯混合分布。
要完成 G(y)=∑j=1mβjgj(y)G(y)= \sum^m_{j=1}\beta_j g_j(y)G(y)=∑j=1m​βj​gj​(y) 对 F(y)=∑i=1kαifi(y)F(y)=\sum^k_{i=1}\alpha_i f_i(y)F(y)=∑i=1k​αi​fi​(y) 的拟合即求使分布 G(y)G(y)G(y) 与分布 F(y)F(y)F(y) 距离最小的参数,设 θ\thetaθ 是 G(y)G(y)G(y) 的可调参数集,于是 G(y)G(y)G(y) 可写为 Gθ(y)G_{\theta}(y)Gθ​(y),于是拟合问题就是:
θ=arg⁡min⁡θDistance(Gθ,F)(3) \theta=\arg\min_{\theta} {Distance}(G_{\theta},F)\qquad (3) θ=argθmin​Distance(Gθ​,F)(3)
G(y)G(y)G(y) 与 F(y)F(y)F(y) 是两个分布,衡量概率分布的距离可以用KL散度:
KL(G,F)=EF(log⁡pgpf)(4) KL(G,F)=\mathbb E_{F}(\log\frac{p_g}{p_f})\qquad(4) KL(G,F)=EF​(logpf​pg​​)(4)
有了衡量拟合效果的距离定义(KL),有了可控参数模型(G(y)G(y)G(y)),似乎拟合问题就可以直接转化为最优化问题了:将 Gθ(y)G_{\theta}(y)Gθ​(y) 和 F(y)F(y)F(y) 是代入(3)、(4),距离KL对参数集(θ={β,μ,Σ}\theta=\{\beta,\mu,\Sigma\}θ={β,μ,Σ})求偏导,偏导置零求解最优参数集。但不幸的是Gθ(y)G_{\theta}(y)Gθ​(y) 和 F(y)F(y)F(y) 都是混合高斯模型,这个过程没有闭式解,直接求最优解的方法行不通。怎么办?
突破点1:
两个混合高斯的KL没有闭式,但两个高斯的KL却是有闭式形式的:
设两个高斯分布分别为 N1(μ1,Σ1)N_1(\mu_1,\Sigma_1)N1​(μ1​,Σ1​) 和 N2(μ2,Σ2)\N_2(\mu_2,\Sigma_2)N2​(μ2​,Σ2​),则它们的KL距离为:
KL(N1∣∣N2)=12(log⁡∣Σ2∣∣Σ1∣+Tr(Σ2−1Σ1)+(μ1−μ2)T(Σ2)−1(μ1−μ2)+d) KL(N_1||N_2) = \frac 12 \left( \log\frac {|\Sigma_2|}{|\Sigma_1|}+Tr(\Sigma_2^{-1}\Sigma_1)+(\mu_1-\mu_2)^T(\Sigma_2)^{-1}(\mu_1-\mu_2)+d\right) KL(N1​∣∣N2​)=21​(log∣Σ1​∣∣Σ2​∣​+Tr(Σ2−1​Σ1​)+(μ1​−μ2​)T(Σ2​)−1(μ1​−μ2​)+d)
证明:
d维高斯分布:
N(x∣u,Σ)=1(2π)n/2∣Σ∣1/2exp⁡{−12(x−u)TΣ−1(x−u)} N(x|u,\Sigma ) = {1 \over {{{(2\pi )}^{n/2}}{{\left| \Sigma \right|}^{1/2}}}}\exp \{ - {1 \over 2}{(x - u)^T}{\Sigma ^{ - 1}}(x - u)\} N(x∣u,Σ)=(2π)n/2∣Σ∣1/21​exp{−21​(x−u)TΣ−1(x−u)}
则两个高斯分布的KL散度为:
DKL(P1∣∣P2)=EP1[log⁡P1−log⁡P2] =12EP1[−log⁡∣Σ1∣−(x−u1)TΣ1−1(x−u1)+log⁡∣Σ2∣+(x−u2)TΣ2−1(x−u2)] =12log⁡∣Σ2∣∣Σ1∣+12EP1[−(x−u1)TΣ1−1(x−u1)+(x−u2)TΣ2−1(x−u2)] =12log⁡∣Σ2∣∣Σ1∣+12EP1{−tr[Σ1−1(x−u1)(x−u1)T]+tr[Σ2−1(x−u2)(x−u2)T]} {D_{KL}}({P_1}||{P_2}) = {E_{{P_1}}}\left[ {\log {P_1} - \log {P_2}} \right] \\ \ \\ = {1 \over 2}{E_{{P_1}}}\left[ { - \log \left| {{\Sigma _1}} \right| - {{(x - {u_1})}^T}\Sigma _1^{ - 1}(x - {u_1}) + \log \left| {{\Sigma _2}} \right| + {{(x - {u_2})}^T}\Sigma _2^{ - 1}(x - {u_2})} \right] \\ \ \\ = {1 \over 2}\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} + {1 \over 2}{E_{{P_1}}}\left[ { - {{(x - {u_1})}^T}\Sigma _1^{ - 1}(x - {u_1}) + {{(x - {u_2})}^T}\Sigma _2^{ - 1}(x - {u_2})} \right] \\ \ \\ = {1 \over 2}\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} + {1 \over 2}{E_{{P_1}}}\left\{ { - tr\left[ {\Sigma _1^{ - 1}(x - {u_1}){{(x - {u_1})}^T}} \right] + tr\left[ {\Sigma _2^{ - 1}(x - {u_2}){{(x - {u_2})}^T}} \right]} \right\} DKL​(P1​∣∣P2​)=EP1​​[logP1​−logP2​] =21​EP1​​[−log∣Σ1​∣−(x−u1​)TΣ1−1​(x−u1​)+log∣Σ2​∣+(x−u2​)TΣ2−1​(x−u2​)] =21​log∣Σ1​∣∣Σ2​∣​+21​EP1​​[−(x−u1​)TΣ1−1​(x−u1​)+(x−u2​)TΣ2−1​(x−u2​)] =21​log∣Σ1​∣∣Σ2​∣​+21​EP1​​{−tr[Σ1−1​(x−u1​)(x−u1​)T]+tr[Σ2−1​(x−u2​)(x−u2​)T]}
这是因为 (x−u1)TΣ1−1(x−u1)(x - {u_1})^T\Sigma _1^{ - 1}(x - {u_1})(x−u1​)TΣ1−1​(x−u1​) 是一个标量,因此有:
(x−u1)TΣ1−1(x−u1)=tr((x−u1)TΣ1−1(x−u1)) =tr(Σ1−1(x−u1)(x−u1)T) (x - {u_1})^T\Sigma _1^{ - 1}(x - {u_1}) = tr\left((x - {u_1})^T\Sigma _1^{ - 1}(x - {u_1})\right)\\ \ \\ =tr\left(\Sigma _1^{ - 1}(x - {u_1})(x - {u_1})^T\right) (x−u1​)TΣ1−1​(x−u1​)=tr((x−u1​)TΣ1−1​(x−u1​)) =tr(Σ1−1​(x−u1​)(x−u1​)T)
=12log⁡∣Σ2∣∣Σ1∣+12EP1{−tr[Σ1−1(x−u1)(x−u1)T]}+12EP1{tr[Σ2−1(x−u2)(x−u2)T]} =12log⁡∣Σ2∣∣Σ1∣−12tr{EP1[Σ1−1(x−u1)(x−u1)T]}+12tr{EP1[Σ2−1(x−u2)(x−u2)T]} =12log⁡∣Σ2∣∣Σ1∣−12tr{Σ1−1EP1[(x−u1)(x−u1)T]}+12tr{EP1[Σ2−1(xxT−u2xT−xu2T+u2u2T)]} =12log⁡∣Σ2∣∣Σ1∣−12tr{Σ1−1Σ1}+12tr{Σ2−1EP1(xxT−u2xT−xu2T+u2u2T)} =12log⁡∣Σ2∣∣Σ1∣−12d+12tr{Σ2−1(Σ1+u1u1T−u2u1T−u1u2T+u2u2T)} = {1 \over 2}\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} + {1 \over 2}{E_{{P_1}}}\left\{ { - tr\left[ {\Sigma _1^{ - 1}(x - {u_1}){{(x - {u_1})}^T}} \right]} \right\} + {1 \over 2}{E_{{P_1}}}\left\{ {tr\left[ {\Sigma _2^{ - 1}(x - {u_2}){{(x - {u_2})}^T}} \right]} \right\} \\ \ \\ = {1 \over 2}\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} - {1 \over 2}tr\left\{ {{E_{{P_1}}}\left[ {\Sigma _1^{ - 1}(x - {u_1}){{(x - {u_1})}^T}} \right]} \right\} + {1 \over 2}tr\left\{ {{E_{{P_1}}}\left[ {\Sigma _2^{ - 1}(x - {u_2}){{(x - {u_2})}^T}} \right]} \right\} \\ \ \\ = {1 \over 2}\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} - {1 \over 2}tr\left\{ {\Sigma _1^{ - 1}{E_{{P_1}}}\left[ {(x - {u_1}){{(x - {u_1})}^T}} \right]} \right\} + {1 \over 2}tr\left\{ {{E_{{P_1}}}\left[ {\Sigma _2^{ - 1}(x{x^T} - {u_2}{x^T} - xu_2^T + {u_2}u_2^T)} \right]} \right\} \\ \ \\ = {1 \over 2}\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} - {1 \over 2}tr\left\{ {\Sigma _1^{ - 1}{\Sigma _1}} \right\} + {1 \over 2}tr\left\{ {\Sigma _2^{ - 1}{E_{{P_1}}}(x{x^T} - {u_2}{x^T} - xu_2^T + {u_2}u_2^T)} \right\} \\ \ \\ = {1 \over 2}\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} - {1 \over 2}d + {1 \over 2}tr\left\{ {\Sigma _2^{ - 1}({\Sigma _1} + {u_1}u_1^T - {u_2}u_1^T - {u_1}u_2^T + {u_2}u_2^T)} \right\} =21​log∣Σ1​∣∣Σ2​∣​+21​EP1​​{−tr[Σ1−1​(x−u1​)(x−u1​)T]}+21​EP1​​{tr[Σ2−1​(x−u2​)(x−u2​)T]} =21​log∣Σ1​∣∣Σ2​∣​−21​tr{EP1​​[Σ1−1​(x−u1​)(x−u1​)T]}+21​tr{EP1​​[Σ2−1​(x−u2​)(x−u2​)T]} =21​log∣Σ1​∣∣Σ2​∣​−21​tr{Σ1−1​EP1​​[(x−u1​)(x−u1​)T]}+21​tr{EP1​​[Σ2−1​(xxT−u2​xT−xu2T​+u2​u2T​)]} =21​log∣Σ1​∣∣Σ2​∣​−21​tr{Σ1−1​Σ1​}+21​tr{Σ2−1​EP1​​(xxT−u2​xT−xu2T​+u2​u2T​)} =21​log∣Σ1​∣∣Σ2​∣​−21​d+21​tr{Σ2−1​(Σ1​+u1​u1T​−u2​u1T​−u1​u2T​+u2​u2T​)}
这是因为x∼N1(u1,Σ1)x \sim N_1(u_1,\Sigma_1)x∼N1​(u1​,Σ1​):
EP1[xxT]=Σ1+u1u1T E_{P_{1}}\left[ {x{x^T}} \right] = \Sigma_1 + u_1{u_1^T} EP1​​[xxT]=Σ1​+u1​u1T​
=12{log⁡∣Σ2∣∣Σ1∣−d+tr(Σ2−1Σ1)+tr{Σ2−1(u1u1T−u2u1T−u1u2T+u2u2T)}} =12{log⁡∣Σ2∣∣Σ1∣−d+tr(Σ2−1Σ1)+tr{Σ2−1u1u1T−Σ2−1u2u1T−Σ2−1u1u2T+Σ2−1u2u2T}} =12{log⁡∣Σ2∣∣Σ1∣−d+tr(Σ2−1Σ1)+tr{u1TΣ2−1u1−2u1TΣ2−1u2+u2TΣ2−1u2}} =12{log⁡∣Σ2∣∣Σ1∣−d+tr(Σ2−1Σ1)+(u2−u1)TΣ2−1(u2−u1)} = {1 \over 2}\left\{ {\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} - d + tr(\Sigma _2^{ - 1}{\Sigma _1}) + tr\left\{ {\Sigma _2^{ - 1}({u_1}u_1^T - {u_2}u_1^T - {u_1}u_2^T + {u_2}u_2^T)} \right\}} \right\} \\ \ \\ = {1 \over 2}\left\{ {\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} - d + tr(\Sigma _2^{ - 1}{\Sigma _1}) + tr\left\{ {\Sigma _2^{ - 1}{u_1}u_1^T - \Sigma _2^{ - 1}{u_2}u_1^T - \Sigma _2^{ - 1}{u_1}u_2^T + \Sigma _2^{ - 1}{u_2}u_2^T} \right\}} \right\} \\ \ \\ = {1 \over 2}\left\{ {\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} - d + tr(\Sigma _2^{ - 1}{\Sigma _1}) + tr\left\{ {u_1^T\Sigma _2^{ - 1}{u_1} - 2u_1^T\Sigma _2^{ - 1}{u_2} + u_2^T\Sigma _2^{ - 1}{u_2}} \right\}} \right\} \\ \ \\ = {1 \over 2}\left\{ {\log {{\left| {{\Sigma _2}} \right|} \over {\left| {{\Sigma _1}} \right|}} - d + tr(\Sigma _2^{ - 1}{\Sigma _1}) + {{({u_2} - {u_1})}^T}\Sigma _2^{ - 1}({u_2} - {u_1})} \right\} =21​{log∣Σ1​∣∣Σ2​∣​−d+tr(Σ2−1​Σ1​)+tr{Σ2−1​(u1​u1T​−u2​u1T​−u1​u2T​+u2​u2T​)}} =21​{log∣Σ1​∣∣Σ2​∣​−d+tr(Σ2−1​Σ1​)+tr{Σ2−1​u1​u1T​−Σ2−1​u2​u1T​−Σ2−1​u1​u2T​+Σ2−1​u2​u2T​}} =21​{log∣Σ1​∣∣Σ2​∣​−d+tr(Σ2−1​Σ1​)+tr{u1T​Σ2−1​u1​−2u1T​Σ2−1​u2​+u2T​Σ2−1​u2​}} =21​{log∣Σ1​∣∣Σ2​∣​−d+tr(Σ2−1​Σ1​)+(u2​−u1​)TΣ2−1​(u2​−u1​)}
这是因为 x∼N(u,Σ)x \sim N(u,\Sigma)x∼N(u,Σ) 有:
E(xTAx)=tr(AΣ)+uTAu E\left( {{x^T}Ax} \right) = tr(A\Sigma ) + {u^T}Au E(xTAx)=tr(AΣ)+uTAu
证毕。

突破点2:
经聚类后,fif_ifi​ 必对应于一个 gjg_jgj​,一个 gjg_jgj​ 可以对应多个 fif_ifi​,这是一个多对一的映射,该映射可定义为:
π:i→j, i∈{1,2,⋯ ,k}, j∈{1,2,⋯ ,m}, and k>m \pi:i\to j,\ i\in \{1,2,\cdots,k\}, \ j\in \{1,2,\cdots, m\},\ \text{and} \ k\gt m π:i→j, i∈{1,2,⋯,k}, j∈{1,2,⋯,m}, and k>m
由上,定义一个具有闭式形式的混合高斯分布F和G的距离:
d(F,G,π)=∑i=1kαiKL(fi∥gπ(i))(5) d(F,G,\pi)=\sum_{i=1}^k \alpha_i KL(f_{i} \Vert g_{\pi(i)}) \qquad (5) d(F,G,π)=i=1∑k​αi​KL(fi​∥gπ(i)​)(5)
高斯聚类的结果就是使(5)最小。

二、聚类迭代

设F有k个高斯核,是需要拟合的混合高斯分布;G有m个高斯核,是参数化混合高斯分布模型。
1、初始化G的m个高斯核;
2、计算 fif_ifi​ 与 gjg_jgj​ 之间距离,根据最近邻原则,构造映射关系 j=π(i)j = \pi(i)j=π(i),i=π−1(j)i=\pi^{-1}(j)i=π−1(j) 是它的反函数。
3、计算 group_j 对应的高斯核
uj′=1βj∑i∈π−1(j)αiui(6a) Σj′=1βj∑i∈π−1(j)αi(Σi+(ui−uj′)(ui−uj′)T)(6b) βj=∑i∈π−1(j)αi(6c) u_j'={1 \over {\beta_j}}\sum_{i\in \pi^{-1}(j)} \alpha_i u_i \qquad (6a) \\ \ \\ \Sigma_j'= {1 \over \beta_j}\sum_{i\in \pi^{-1}(j)}\alpha_i\left(\Sigma_i+(u_i-u_j') (u_i-u_j')^T\right) \qquad (6b) \\ \ \\ \beta_j = \sum_{i\in \pi^{-1}(j)}\alpha_i \qquad (6c) uj′​=βj​1​i∈π−1(j)∑​αi​ui​(6a) Σj′​=βj​1​i∈π−1(j)∑​αi​(Σi​+(ui​−uj′​)(ui​−uj′​)T)(6b) βj​=i∈π−1(j)∑​αi​(6c)
4、重复2、3步骤,至收敛。

三、实验

问题:设F是3个高斯核的混合分布,G有两个高斯核,用G来拟合F。
1、定义高斯核

class guassian_component:
    def __init__(self, miu1, miu2, var1, var2, co12=0, co21=0):
        self.miu = np.asarray([[miu1], [miu2]])
        self.sigma = np.zeros((2,2))
        self.sigma[0][0] = var1
        self.sigma[1][1] = var2
        self.sigma[0][1] = co12
        self.sigma[1][0] = co21
        
    def getMiu(self):
        return self.miu
    
    def getSigma(self):
        return self.sigma
    
    def sigmaDet(self):
        #return self.sigma[0][0]*self.sigma[1][1]
        return np.linalg.det(self.sigma)
    
    def sigmaInv(self):
        '''
        inv = np.zeros((2,2))
        inv[0][0] = 1/self.sigma[0][0]
        inv[1][1] = 1/self.sigma[1][1]
        '''
        inv = np.linalg.inv(self.sigma)
        return inv

def Gaussian2D(x, gaussian_ker):
    y = x-gaussian_ker.getMiu()
    y = np.exp(-0.5*np.matmul(np.matmul(y.transpose(),gaussian_ker.sigmaInv()),y))
    y = 1/(2*np.pi)/np.sqrt(np.abs(gaussian_ker.sigmaDet()))*y
    return y

def f_contour(x,y, guassian_ker):#定义函数生成对于(x,y)的高值
    z = []
    for _y in y:
        for _x in x:
            _xy = np.asarray([[_x],[_y]])
            z.append(Gaussian2D(_xy,guassian_ker))
    z = np.asarray(z)
    return z.reshape((x.shape[0],y.shape[0]))

dx=0.01;dy=0.01
x=np.arange(-2.0,2.0,dx)
y=np.arange(-2.0,2.0,dx)
X,Y=np.meshgrid(x,y)#生成网格矩阵
    
c1 = guassian_component(0,0,0.1,0.2)
z = f_contour(x,y, c1)

fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(1,1,1)
C=ax.contour(X,Y,z,8,colors='black')#绘制等高线,为等高线设置为黑色
ax.contourf(X,Y,z,8)#添加颜色(颜色区分等高线)
ax.clabel(C,inline=1,fontsize=10)#0闭合添加数字,1表示开口添加等高线。等高线字体大小
plt.show()

在这里插入图片描述
2、混合高斯分布

c_a = guassian_component(1,0,0.1,0.3) # miu_x, miu_y, var_x, var_y
c_b = guassian_component(0,0,0.2,0.2)
c_c = guassian_component(0,0.5,0.2,0.1)

dx=0.01;dy=0.01
x=np.arange(-2.0,2.0,dx)
y=np.arange(-2.0,2.0,dx)

z_a = f_contour(x,y, c_a)
z_b = f_contour(x,y, c_b)
z_c = f_contour(x,y, c_c)

z = 0.4*z_a + 0.1*z_b + 0.5*z_c

fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(1,1,1)
C=ax.contour(X,Y,z,8,colors='black')#绘制等高线,为等高线设置为黑色
ax.contourf(X,Y,z,8)#添加颜色(颜色区分等高线)
ax.clabel(C,inline=1,fontsize=10)#0闭合添加数字,1表示开口添加等高线。等高线字体大小
plt.show()

在这里插入图片描述
3、高斯聚类

def gaussian_KL(f_ker, g_ker):
    y = np.log(np.abs(g_ker.sigmaDet())/np.abs(f_ker.sigmaDet()))+ \
        np.matmul(np.matmul((f_ker.getMiu()-g_ker.getMiu()).transpose(),g_ker.sigmaInv()), \
                  (f_ker.getMiu()-g_ker.getMiu())) + \
        np.trace(np.matmul(g_ker.sigmaInv(),f_ker.getSigma()))
    return 0.5*y

def new_GaussianComp(kernels, weights):
    '''
    args:
        kernels: (list) [#num_kernels, ]
        weights: (list) [#num_kernels, ]
        
    returns:
        guassian_component
    '''
    if weights == None:
        raise Exception("group is empty!")
        
    if len(weights)==1:
        #print('group is 1.')
        return kernels[0]
    
    
    miu = np.zeros((2,1))
    sigma = np.zeros((2,2))
    beta = 0
    for w,ker in zip(weights, kernels):
        miu += w*ker.getMiu()
        beta += w
    miu /= beta
    
    for w, ker in zip(weights, kernels):
        y = ker.getSigma()+np.matmul((ker.getMiu()-miu),(ker.getMiu()-miu).transpose())
        #print(ker.getSigma())
        #print(ker.getMiu()-miu)
        #print(y)
        #print()
        y *= w
        sigma += y
        
    sigma /= beta
    return guassian_component(miu[0][0],miu[1][0], sigma[0][0], sigma[1][1], sigma[0][1], sigma[1][0])


class GaussianCluster:
    def __init__(self, group_num, original_gaussians, weights):
        '''
        args:
            orginal_gaussians: (list) each of orginal_gaussian is guassian_component
            weights: (list) the sum of all weights is 1.
        '''
        self.original = original_gaussians
        self.weights = weights
        self.group_num = group_num
        
        self.match_grid = np.zeros((group_num, len(weights)))   # one-hot, one result to serveral original
        self.distance_grid = np.zeros((group_num, len(weights)))   # distance between original-kernels and result-kernels
        
        # initialize group_kers by some selected original-kernels
        idx = np.arange(len(weights))
        np.random.shuffle(idx)
        idx = idx[:group_num]
        
        self.group_kers = []     # new groups
        self.group_betas = []    # new mixture weights
        for i in idx:
            var1 = original_gaussians[i].getSigma()[0][0]
            var2 = original_gaussians[i].getSigma()[1][1]
            miu1 = original_gaussians[i].getMiu()[0][0]+np.random.randn()*np.sqrt(var1)
            miu2 = original_gaussians[i].getMiu()[1][0]+np.random.randn()*np.sqrt(var2)
            ker = guassian_component(miu1, miu2, var1*2,var2*2)
            
            self.group_kers.append(ker)
            
    def cal_distance(self):
        for i,g in enumerate(self.group_kers):
            for j,f in enumerate(self.original):
                self.distance_grid[i][j] = gaussian_KL(f,g)
                
    def cal_pie(self):
        self.match_grid = np.zeros((self.group_num, len(self.weights))) 
        self.cal_distance()
        pie = np.argmin(self.distance_grid, axis=0)
        for i,grp_idx in enumerate(pie):
            self.match_grid[grp_idx][i]=1
    
    def cal_kernels(self):
        self.group_kers = []
        self.group_betas = []
        for i in range(self.group_num):
            group_j = self.match_grid[i]
            #print(group_j)
            index = np.asarray([idx for idx in range(len(self.weights))])
            j_i = index[group_j>0]
            
            if (len(j_i)==0):
                print('j_i is Empty!') 
                # reinitialize the kernel:
                # initialize group_kers by some selected original-kernels
                idx = np.arange(len(self.weights))
                np.random.shuffle(idx)
                idx = idx[0]
                var1 = self.original[i].getSigma()[0][0]
                var2 = self.original[i].getSigma()[1][1]
                miu1 = self.original[i].getMiu()[0][0]+np.random.randn()*np.sqrt(var1)
                miu2 = self.original[i].getMiu()[1][0]+np.random.randn()*np.sqrt(var2)
                ker = guassian_component(miu1, miu2, var1*2,var2*2)
                
                self.group_kers.append(ker)
                self.group_betas.append(0)
                #break
                
            else:
                #print(j_i)
                gau = []
                wgt = []
                for idx in j_i:
                    gau.append(self.original[idx])
                    wgt.append(self.weights[idx])
                c_new = new_GaussianComp(gau,wgt)
                self.group_kers.append(c_new)
                self.group_betas.append(sum(wgt))
            
    def iteration(self, times):
        for _ in range(times):
            self.cal_pie()
            self.cal_kernels()
        return self.group_kers
    
    def getGroupKers(self):
        return self.group_kers
    
    def getGroupBetas(self):
        return self.group_betas

def mixture_for_contour(kernels, weights):
    dx=0.01;dy=0.01
    x=np.arange(-2.0,2.0,dx)
    y=np.arange(-2.0,2.0,dx)

	def f(x,y, guassian_kers, weights):#定义函数生成对于(x,y)的高值
        z = []
        for _y in y:
            for _x in x:
                mix = 0
                for ker,wgt in zip(guassian_kers, weights):
                    _xy = np.asarray([[_x],[_y]])
                    mix += wgt*Gaussian2D(_xy,ker)
                z.append(mix)
        z = np.asarray(z)
        return z.reshape((x.shape[0],y.shape[0]))

    z = f(x,y, kernels, weights)
    return x,y,z

kernels = [c_a, c_b, c_c]
weights = [0.4, 0.1, 0.5]
gCluster = GaussianCluster(2, kernels, weights)

kernels = gCluster.iteration(5)
weights = gCluster.getGroupBetas()
print(weights)

X,Y,Z = mixture_for_contour(kernels, weights)
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(1,1,1)
C=ax.contour(X,Y,Z,8,colors='black')#绘制融合后等高线
C=ax.contour(X0,Y0,Z0,8,colors='black') #绘制原图等高线
ax.contourf(X,Y,Z,8)#添加颜色(颜色区分等高线)
ax.clabel(C,inline=1,fontsize=10)#0闭合添加数字,1表示开口添加等高线。等高线字体大小
plt.show()

在这里插入图片描述

四、小结

该方法能够很好地实现高斯聚类,一般的迭代次数仅为5~6次,但它也有一些局限:
1、初始化对结果有很大的影响;
2、需要设定唯一的超级参数,即聚类的数量。
3、以上实现方法在聚类数量较大的时候,运行速度还是慢一些,可以再做一些优化,比如在期望相差较远的高斯核之间就不用计算其距离了,另外在设定被抛出的高斯核的初始值时,可以更科学一些。
最后,这种方法可以用来合并Object Detection产生的bbox,它的效果与NMS各有千秋,将其复合起来用,效果会更好。


【1】《Hierarchical Clustering of a Mixture Model》

聚类模型-模型聚类-高斯混合 聚类模型 1、层次聚类 2、原型聚类-K-means 3、模型聚类-GMM 4、EM算法-LDA主题模型 5、密度聚类-DBSCAN 6、图聚类-谱聚类 三、模型聚类-高斯混合 高斯混合的类表示是一个高斯模型,相似性度量定义为服从类cjcjc_{j}高斯分布μ,Σμ,Σ\mu,\Sigma的概率(Kmeans的相似度量是聚距离度量),所以高斯混合聚类也可... 阅读详情

相关推荐

高斯混合模型和软聚类

通过给出每个样本属于每个成分的概率分布,高斯混合模型提供了一种模糊的聚类分配方式。硬聚类将样本分配到一个确定的聚类中,而软聚类则提供了更灵活的方法,可以对样本进行模糊的聚类分配。高斯混合模型通过给出每个样本属于每个成分的概率分布,提供了一种软聚类的方式。在高斯混合模型中,每个样本都被分配到每个成分的概率被称为聚类的隶属度(membership),表示样本属于每个成分的程度。在高斯混合模型中,每个样本的生成过程分为两个步骤:首先,选择一个成分作为生成该样本的成分;库,它提供了高斯混合模型的实现。

AlianBlank的博客 268

通信基础 2——高斯分布及归一化、标准化、零均值化

目录高斯变量基础高斯分布概率密度函数性质复高斯分布概率密度函数应用零均值循环对称复高斯随机变量零均值化卡方分布补充归一化标准化 高斯变量基础 高斯分布 概率密度函数 性质 复高斯分布 若复高斯分布Z=X+iY, 且满足 则有 概率密度函数 注:复高斯随机变量的密度函数,分母已经没有根号 应用 零均值循环对称复高斯随机变量 特殊的,当μ=μx=μy=0时,Z称为零均值循环对称复高斯随机变量(zero mean circle symmetric complex gaussian,ZMCSCG),σ2称为

Paul 的笔记库 1万+

PCL 点云高斯混合聚类

其中,点云聚类是点云数据处理中的重要任务之一,它的目标是将点云数据划分为不同的类别或簇。综上所述,本文介绍了一种基于高斯混合模型的点云聚类方法,并给出了相应的源代码实现。在点云聚类中,我们可以将每个点看作是从一个高斯分布中采样得到的。在本文中,我们将使用点云库(Point Cloud Library,简称PCL)来处理点云数据,以及numpy和matplotlib库来进行数据处理和可视化。上述代码中,我们首先获取每个点的聚类标签,并根据聚类标签和颜色映射关系,将点云按簇进行可视化展示。函数来加载点云数据。

. 437

【机器学习】聚类算法——高斯混合聚类(理论+图解)

  简 介:下面是我在学习时候的记录并加上自己的理解。本文意在记录自己近期学习过程中的所学所得,如有错误,欢迎大家指正。   关键词:高斯混合聚类、机器学习、极大似然估计 在讲高斯混合聚类算法之前先补充以下相关的数学知识,由于篇幅原因,只是简单叙述,如需详细内容,请查阅相关资料 一、正态分布 在概率论中我们学过某些数值在一定情况下是符合正态分布的。 我们经常见到某某数据符合正态分布,那么它到底是什么意思呢? 正态曲线呈钟型,两头低,中间高,左右对称因其曲线呈钟形,因此人们又经常称之..

优快云 精品推荐 1万+

高斯混合聚类算法

我们还可以使用predict_proba方法获取数据点属于每个簇的概率,使用means_属性获取聚类的均值向量,使用covariances_属性获取聚类的协方差矩阵。高斯混合聚类算法(Gaussian Mixture Clustering)是一种基于概率模型的聚类方法,它假设数据集由若干个高斯分布组成,每个高斯分布代表一个簇。对于每个数据点xi和每个簇k,计算其属于簇k的后验概率P(z=k|xi)。在本文中,我们将探讨高斯混合聚类算法的原理和实现,同时提供相应的源代码。首先,我们来介绍算法的基本原理。

YovcGit的博客 376

高斯混合模型是什么?什么是软聚类?高斯混合模型还能做什么?

sklearn.mixture.BayesianGaussianMixture sklearn.mixture.GaussianMixture from sklearn.mixture import GaussianMixture from sklearn.mixture import BayesianGaussianMixture from sklearn.datasets.samples_generator import make_blobs X, y = make_blobs(n_sam

data+scenario+science+insight 838

numpy实现周志华机器学习 9.4.3 高斯混合聚类(GMM算法)

本文主要参考周志华《机器学习》的9.4.3章节,对高斯混合聚类的原理做简单介绍,并使用numpy实现GMM。 要想很好得理解掌握高斯混合聚类算法,以我的学习经验来看,需要掌握两方面背景知识。 多维正态分布 EM算法 关于上述两方面知识,我只做简单的介绍。首先,什么是多维正态分布?就是多变量的正态分布。我们所熟知的正态分布往往是一维的,但在现实中,我们所获得的数据往往是多维的。这就需要用到多维正...

weixin_42217488的博客 2133

高斯混合模型(GMM)及其在数据挖掘中的应用

概率密度函数(PDF)是指对于连续型随机变量X,其取值于区间 [a, b] 上的概率密度函数f(x)满足以下条件:对于任意实数x,有f(x) >= 0。X落在任意区间 [c, d] 上的概率等于该区间内f(x)的定积分,即。在整个实数线上,f(x)的积分值等于1,即。对于高斯分布来说,概率密度函数不仅描述了分布的形状,而且还可以用来计算随机变量落在任意区间的概率。计算如下:通过积分运算,可以求得该区间内的概率值,这在数据分析中非常有用。

weixin_36173034的博客 1867

【机器学习】聚类分析(三)——高斯混合模型

我们介绍一种用统计混合模型进行聚类的方法——高斯聚类模型(Gaussian Misture Model, GMM)。这种聚类方法得到的是每个样本点属于各个类的概率,而不是判定它完全属于一个类,所以有时也会被称为软聚类。

HerosOfEarth的博客 1万+

了解随机振动疲劳分析中 Ansys nCode DesignLife 的平均应力校正

通过选择静态环境,我们可以将其结果视为疲劳计算的平均应力,如图 3 所示,因此从静态偏移载荷工况中提取的平均应力用于转移预测雨流计数中所有循环的平均值。您可以通过观看下面的教学视频获得宝贵的见解,该视频将指导您完成利用 Ansys nCode DesignLife 分析平均应力对随机振动载荷下结构的影响的过程。它基于 R 比率或平均应力水平。另一方面,平均应力校正可以帮助消除平均应力的负面影响,提高结果的保真度。Ansys nCode 提供先进的平均应力校正技术,使工程师能够考虑平均应力对疲劳寿命的影响。

jkh920184196的博客 1519

LayaBox CommandBuffer描边使用详细

项目需要使用LayaBox做一个给3D物体动态描边的一个功能,前前后后踩了一些坑算是把这个东西给做出来了把我改好的代码贴上,分享给大家。 (1)想要使用描边你的引擎版本必须 >=2.9.0 (2)你必须下载 Laya官方的BlurShader库才能使用这个功能,下载地址:https://github.com/layabox/layaair-demo/tree/master/h5/3d/ts/LayaAir3D_PostProcess/BlurShader 下载完之后把BlurShader放到自己项目的

小智队长 1735

【机器学习笔记】通俗易懂解释高斯混合聚类原理

最近在看周志华《机器学习》中聚类这一章。其它聚类方法都比较容易看懂,唯有高斯混合聚类这种方法看上去比较复杂,有点难理解。但是,当将它的原理和过程看懂之后,其实这节书所讲的内容并不复杂,只是将高斯分布、贝叶斯公式、极大似然法和聚类的思路混合在这一种方法中,所以理解起来有点绕。 作为入门初学者,我尽量按我的理解用通俗易懂的方法来说清楚高斯混合聚类做了什么、能做什么和为什么可以这么做。希望能让同样对高...

lotusng 3万+

AI 模型训练核心方法论:零基础也能落地的 8 个关键阶段

本文是为 AI 零基础学习者打造的模型训练入门指南,以生活化语言拆解核心概念,规避专业术语壁垒。内容先通俗阐释模型训练、监督学习、数据集划分等基础概念,再按问题定义、数据准备、模型选择、环境搭建、训练、评估、调参、部署 8 个阶段,拆解完整训练流程,搭配 PyTorch 代码示例与实战案例,同时提供资源预算、常见问题解决方案及学习路径。指南强调数据的核心重要性,推荐新手优先使用迁移学习和免费 GPU 资源,兼顾理论与实操,帮助学习者快速上手,避开训练误区,独立完成从模型搭建到部署的全流程。

weixin_52741870的博客 469

基于模型的聚类和R语言中的高斯混合模型

原文链接:http://tecdat.cn/?p=6105 介绍 聚类模型是一个概念,用于表示我们试图识别的聚类类型。四种最常见的聚类方法模型是层次聚类,k均值聚类,基于模型的聚类和基于密度的聚类 可以基于两个主要目标评估良好的聚类算法: 高级内相似性 低级间相似性 基于模型的聚类是迭代方法,通过优化聚类中数据集的分布,将一组数据集拟合到聚类中。高斯分布只不过是正态分......

大数据部落 2724

基于STM32的宠物智能照护嵌入式系统设计

嵌入式系统是实现物联网终端设备本地化感知、决策与执行的核心技术载体,其关键在于多传感器融合、低功耗执行控制与轻量级云边协同。本文围绕环境监测(温湿度、烟雾、余粮)、机电执行(步进电机食盘、继电器风扇)和可靠通信(MQTT+ESP8266)三大技术主线,深入解析STM32F103在资源约束下的外设调度策略、ADC采样抗干扰设计、DHT11时序精准控制及HX711称重滤波算法等工程实践要点。系统强调本地闭环优先原则,确保离线基础功能可用,同时通过阿里云IoT平台实现远程监控与告警联动,为中小型智能硬件项目提供可

weixin_29155599的博客 294

机器学习【学校智慧食堂及其应用】

本文主要介绍机器学习【智慧食堂及其应用】

qq_201729558 2571

高斯混合模型GMM理论和Python实现

简述 高斯混合模型,就是说用多个高斯函数去描述不同的元素分布。 通过EM方法来迭代生成不同的高斯模型的各个参数。 具体的EM算法的理论网上很多,但推荐各位先看完这个算法思路之后,再去看理论推导就更加好了。 更新方法 μi′=∑j=1mηji∗xj∑j=1mηji\mu_i^{'} = \frac{\sum_{j=1}^m{\eta_{ji} * x_j}}{\sum_{j=1}...

gc.collect() 5391

VC Spyglass CDC验证避坑指南:如何正确配置同步复位信号(实验二重点解析)

本文深入解析VC Spyglass CDC验证中同步复位信号的正确配置方法,通过实验二案例详细展示错误配置的典型表现及修正过程。文章提供同步复位的最佳实践方案,包括约束文件修改指南、验证流程优化建议和高级调试技巧,帮助工程师有效避免CDC验证中的常见陷阱。

rock5的博客 678

C++高斯混合型GMM实现

#ifndef MYGMM_H #define MYGMM_H #include <iostream> #include <Eigen/Dense> #include <math.h> #include <vector> #define EPS 0.00000001 using namespace std; using namespace Eigen; Eigen::MatrixXf getCov(Eigen::MatrixXf input) {

random_repick的专栏 372

从量子兔AlphaPi硬件拆解到ESP32-C3库开发实战

本文详细拆解了量子兔AlphaPi开发板的硬件构成,重点分析了其核心ESP32-C3芯片及外围传感器。通过逆向工程揭示了GPIO引脚定义与通信协议,并实战演示了如何从零开发MicroPython库,驱动按键、加速度计及LED点阵,最终整合成一个互动平衡球游戏项目,展现了开源硬件在教育与二次开发中的潜力。

weixin_29164497的博客 460

28、基准剂量法:原理、应用与计算详解

本文详细介绍了基准剂量法(BMD)的原理、在监管机构中的应用以及具体的计算方法。内容涵盖样本量与BMD的关系、主要监管机构如EPA对BMD的应用、BMD的模型选择与数据拟合过程、拟合优度评估、下置信限(BMDL)计算,以及实验设计对BMD结果的影响。同时,还讨论了剂量指标和响应选择的关键问题,为理解和应用基准剂量法提供了全面的参考。

info6的博客 280

高斯混合模型的解释及Python实现

https://www.toutiao.com/a6698235653743706632/ 在机器学习领域,我们可以区分为两个主要领域:监督学习和无监督学习。两者的主要区别在于数据的性质以及处理数据的方法。聚类是一种无监督学习问题,我们希望在数据集中找到具有某些共同特征的点的聚类。假设我们有这样一个机器学习数据集: 我们的工作是找到一组看起来很接近的点。在这种情况下,我们可以清...

喜欢打酱油的老鸟 5723

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

使用sklearn实现混合高斯聚类

from sklearn.mixture import GaussianMixture 参数 n_components高斯模型的数量,也是聚类的数量,相当于k-means中的k。 covariance_type方差类型,具体的差异性没有研究过。 tol停止迭代的阈值 reg_covar防止为零的增加数,使用默认即可。 max_iter最大的迭代次数 n_init随机次数,因为GMM算法手随机数影响较大,所以需要多随机几次。算法会保存最优的随机作为最优解。 random_state随机数 属性 **weig

weixin_44414593的博客 2338

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

聚类的高斯混合模型研究附Matlab代码

在无监督学习领域,聚类算法通过挖掘数据内在分布规律实现样本分组,是数据挖掘、图像分割、用户画像等场景的核心技术。高斯混合模型(Gaussian Mixture Model, GMM)作为概率型聚类方法的典型代表,突破了传统硬聚类(如 K-means)“非此即彼” 的归属限制,通过多个高斯分布分量的线性组合拟合数据分布,既能输出样本属于各簇的概率(软聚类结果),又能处理非球形、不同密度的复杂数据簇,在高维数据与不确定性场景中具有显著优势。

j_jinger的博客 891

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

聚类的高斯混合模型研究(Matlab代码实现)

关于高斯混合模型(Gaussian Mixture Model, GMM)的研究文档可以包括以下内容:1. **基本原理和数学基础**:- GMM 是一种概率模型,用于描述多个高斯分布混合而成的复合概率分布。- 包括高斯分布的定义、参数和密度函数形式。- 描述如何通过多个高斯分布的加权和来建模复杂数据分布。2. **模型参数的估计**:- 最常见的估计方法是期望最大化(Expectation-Maximization, EM)算法。- EM 算法的步骤和推导过程。

weixin_46039719的博客 677

高斯混合模型GMM

这周突发兴致,拿起“西瓜书”啃了啃,没按照书上的目录来,结合目前正在做的,看到了高斯混合模型(Gaussian mixture model——GMM)。这个模型与原型聚类稍有区别,是 采用概率模型来聚类。 1.高斯分布 既然有“高斯”两字,那就跟高斯分布有关吧~然而我连概率密度表达式都记不太清了,赶紧复习一下! 一元高斯分布: 多元高斯分布: 我使用的是多元高斯分布,是均值...

Code Wang的博客 2754
上一篇: 近年来目标检测方面值得一看的论文(到CVPR 2019)
下一篇: 通过代码学习 VQ-VAE
田神
博客等级 码龄17年 217粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值