高斯混合模型中的奇点问题


15

在模式识别和机器学习这本书的第9章中,有关于高斯混合模型的这一部分:

在此处输入图片说明 在此处输入图片说明 老实说,我并不真正理解为什么会产生奇异之处。谁能向我解释一下?抱歉,我只是一个本科生,并且是机器学习的新手,所以我的问题听起来有点愚蠢,但请帮助我。非常感谢你


像看起来真实容易固定太,重新参数化到σk2=τ2γk然后违法处罚γķ用于优化时过于接近零。
概率

1
@probabilityislogic不知道我是否在这里关注:(
Dang Manh Truong

Answers:


11

如果我们想使用最大似然将高斯拟合到单个数据点,我们将得到一个非常尖刻的高斯,它会“崩溃”到该点。当只有一个点时,方差为零,这在多元高斯情况下会导致奇异协方差矩阵,因此将其称为奇点问题。

当方差变为零时,高斯分量(公式9.15)的可能性变为无穷大,并且模型变得过拟合。当我们仅将一个高斯拟合到多个点时,不会发生这种情况,因为方差不能为零。但是,当我们混合使用高斯时,可能会发生这种情况,如PRML的同一页所示。

在此处输入图片说明

更新
这本书提出了两种解决奇点问题的方法,分别是

1)发生奇点时重置均值和方差 在此处输入图片说明

2)通过添加先验使用MAP而不是MLE。 在此处输入图片说明


关于单一高斯情况,为什么方差不能为零?教科书说:“回想一下,在单个高斯分布的情况下并没有出现这个问题。要理解这种差异,请注意,如果单个高斯分布崩溃到一个数据点上,它将对由另一个引起的似然函数产生乘法因子数据点和这些因素将以指数级速度快速变为零,从而使总体可能性变为零,而不是无穷大。”但我不太了解:(
Dang Manh Truong 2016年

@DangManhTruong,这是因为根据方差的定义,,除非所有点都具有相同的值,否则我们始终具有非零方差。v一种[RX=Ë[X-μ2]
dontloo

我知道了!谢谢:D那么在实践中我们应该怎么做以避免它?这本书没有解释。
Dang Manh Truong

@DangManhTruong嗨,我将其添加到了答案中,请看一下:)
dontloo

@DangManhTruong不客气
dontloo

3

回想一下,在单个高斯分布的情况下不会出现此问题。要理解差异,请注意,如果单个高斯坍缩到一个数据点上,它将对其他数据点产生的似然函数贡献乘性因子,并且这些因子将以指数方式快速变为零,从而使总体似然性变为零,而不是比无限

我也对此部分感到困惑,这是我的解释。为简单起见,以一维盒为例。

当单个高斯“崩溃”在数据点,即μ = x i时,总似然变为:X一世μ=xi

p(x)=p(xi)p(xi)=(12πσ)(niN12πσe(xnμ)22σ2)

您会看到,左边的项p x i,与GMM中的病理情况类似,而右边的项是其他数据点p xiσ0p(xi)仍包含类似术语 ë - X ñ - μ 2p(xi其中0指数地快,σ0,所以上的可能性的整体效果是它去零。Ë-Xñ-μ22σ20σ0

这里的要点是,当拟合单个高斯时,所有数据点必须共享一组参数,而在混合情况下,一个分量可以“聚焦”于一个数据点而不会损害整体数据的可能性。μσ


2

该答案将深入了解在将GMM拟合到数据集期间导致奇异协方差矩阵发生的情况,为什么会发生这种情况以及我们可以采取哪些措施来防止这种情况的发生。

因此,我们最好从概括高斯混合模型到数据集的步骤开始。


0决定要多少源/集群(三)以适应您的数据
1.初始化参数均值,协方差Σ ÇμCΣC,并fraction_per_class 每个集C πC

Ë-小号ŤËp_

  1. 计算每个数据点的概率ř Ç该数据点X 属于群集c相: [R Ç = π Ç Ñ X | μ ÇX一世[R一世CX一世

    其中ÑX|μΣ描述了mulitvariate高斯: ÑXμÇΣc ^=1
    [R一世C=πCñX一世 | μCΣCΣķ=1个ķπķñX一世 | μķΣķ
    ñX | μΣ

    - [RÇ给了我们对每个数据点X该措施的:P- [Røb一个býħXbëöñ小号öç一个小号
    N(xi,μc,Σc) = 1(2π)n2|Σc|12exp(12(xiμc)TΣc1(xiμc))


    ricxi因此如果X是非常接近高斯C,它会得到一个高- [RÇ值对于这个高斯,相对较低的值。 MStep_ 对于每个群集c:计算总权重mcProbability that xi belongs to class cProbability of xi over all classesxiric

    MStep_

    mc(严格意义上分配给集C点的级分)和更新πcμcΣcric

    mc = Σiric

    πc = mcm

    μc = 1mcΣiricxi

    Σc = 1mcΣiric(xiμc)T(xiμc)





    ln p(X | π,μ,Σ) = Σi=1N ln(Σk=1KπkN(xi | μk,Σk))



因此,现在我们已经得出了计算过程中的单个步骤,我们必须考虑矩阵奇异意味着什么。如果矩阵是不可逆的,则它是奇异的。如果存在矩阵,则矩阵是可逆的X 这样 一种X=X一种=一世。如果未给出,则称矩阵为奇异的。也就是说,像这样的矩阵:

[0000]


是不可逆的,并且遵循单数形式。如果我们假设上面的矩阵是矩阵,这也是合理的。一种 不可能有矩阵 X 这给点缀此矩阵的单位矩阵 一世(简单地获取这个零矩阵,并将其与任何其他2x2矩阵进行点积,您将看到总是得到零矩阵)。但是为什么这对我们来说是一个问题?好吧,考虑上面的多元法线的公式。在那里你会发现ΣC-1个这是协方差矩阵的可逆 由于奇异矩阵是不可逆的,因此在计算过程中会引发错误。
因此,既然我们知道了一个奇异的,不可逆的矩阵,以及为什么这对我们在GMM计算中很重要,那么我们怎么会遇到这个问题?首先,我们得到这个0协方差矩阵,如果在E和M步骤之间的迭代过程中多元高斯落入一个点。例如,如果我们有一个我们要适合3个高斯的数据集,但实际上它仅包含两个类(集群),以至于粗略地说,这三个高斯中的两个捕获了自己的聚类,而最后一个高斯只对其进行管理,则可能会发生这种情况。抓住它所在的一个点。我们将在下面看到它的样子。但是要分步进行:假设您有一个包含两个聚类的二维数据集,但您不知道该数据并想为其拟合三个高斯模型,即c =3。您可以在E步骤中初始化参数并绘制数据之上的高斯函数,看起来很模糊。例如(也许您可以在左下方和右上方看到两个相对分散的群集): 在此处输入图片说明 初始化参数后,您将迭代执行E,T步骤。在此过程中,三个高斯人都在四处游荡并寻找自己的最佳位置。如果您观察模型参数,即μCπC您将观察到它们会收敛,经过多次迭代后它们将不再改变,并且相应的高斯也已找到其在空间中的位置。在具有奇点矩阵的情况下,您会遇到smth。像: 在此处输入图片说明 我用红色圈出第三高斯模型的地方。因此,您会看到,这个高斯位于一个数据点上,而其他两个则占据了其余部分。在这里,我必须注意,为了能够像我已经使用协方差正则化一样绘制图形,这是一种防止奇异矩阵的方法,下面将进行描述。

好的,但是现在我们仍然不知道为什么以及如何遇到奇点矩阵。因此,我们必须看一下[R一世CCØv在E和M步骤中。如果你看[R一世C 再次公式:
[R一世C=πCñX一世 | μCΣCΣķ=1个ķπķñX一世 | μķΣķ
你看到那里 [R一世C如果在簇c下很有可能具有较大的值,否则将具有较低的值。为了使这一点更加明显,请考虑以下情况:我们有两个相对散布的高斯和一个非常紧密的高斯,我们计算[R一世C 对于每个数据点 X一世如图所示: 在此处输入图片说明 因此从左到右浏览数据点,并想象您会写下每个数据点的概率X一世它属于红色,蓝色和黄色高斯。您可以看到的是,对于大多数X一世它属于黄色高斯的概率很小。在上述情况下,第三高斯位于一个数据点上,[R一世C 此数据点仅大于零,而其他数据点均为零 X一世。(折叠到该数据点上->如果所有其他点很可能是高斯一或二的一部分,就会发生这种情况,因此这是高斯三点剩下的唯一点->发生这种情况的原因可以在数据集本身在高斯的初始化中。也就是说,如果我们为高斯选择了其他初始值,则我们将看到另一幅图,而第三个高斯可能不会崩溃)。如果您进一步加深此高斯,就足够了。的[R一世C桌子然后看起来很薄。如: 在此处输入图片说明 如您所见,[R一世C第三列的值,即第三高斯为零而不是这一行。如果我们在此处查找表示哪个数据点,则会得到该数据点:[23.38566343 8.07067598]。好的,但是为什么在这种情况下我们得到一个奇异矩阵呢?好吧,这是我们的最后一步,因此,我们必须再次考虑协方差矩阵的计算,即:
ΣC = Σ一世[R一世CX一世-μCŤX一世-μC
我们已经看到了所有 [R一世C 是零而不是一个 X一世与[23.38566343 8.07067598]。现在公式要我们计算X一世-μC。如果我们看一下μC对于第三高斯,我们得到[23.38566343 8.07067598]。哦,等等,那和X一世 这就是Bishop写道:“假设混合模型的组成部分之一,让我们说 Ĵ 第一部分,有其平均值 μĴ 完全等于其中一个数据点,以便 μĴ=Xñ对于n的某个值(Bishop,2006,p.434)。那么会发生什么呢?那么,这个项将为零,因此该数据点是协方差矩阵不为零的唯一机会(因为该数据点为唯一的地方[R一世C> 0),现在变为零,看起来像:

[0000]


因此,如上所述,这是一个奇异矩阵,将在多元高斯计算中导致误差。那么我们如何防止这种情况。好吧,我们已经看到,如果协方差矩阵是0矩阵。因此,为了防止奇异性,我们只需要防止协方差矩阵变为0矩阵。这是通过在协方差矩阵的对角线上添加一个很小的值(在sklearn的GaussianMixture中将该值设置为1e-6)来完成的。还有其他防止奇异性的方法,例如在高斯崩溃时注意并将其均值和/或协方差矩阵设置为新的任意高值。下面的代码中也实现了这种协方差正则化,您可以通过该代码获得所描述的结果。如前所述,也许您必须多次运行代码才能获得奇异的协方差矩阵。这绝不能每次都发生,还取决于高斯人的初始设置。
import matplotlib.pyplot as plt
from matplotlib import style
style.use('fivethirtyeight')
from sklearn.datasets.samples_generator import make_blobs
import numpy as np
from scipy.stats import multivariate_normal


# 0. Create dataset
X,Y = make_blobs(cluster_std=2.5,random_state=20,n_samples=500,centers=3)

# Stratch dataset to get ellipsoid data
X = np.dot(X,np.random.RandomState(0).randn(2,2))


class EMM:

    def __init__(self,X,number_of_sources,iterations):
        self.iterations = iterations
        self.number_of_sources = number_of_sources
        self.X = X
        self.mu = None
        self.pi = None
        self.cov = None
        self.XY = None



    # Define a function which runs for i iterations:
    def run(self):
        self.reg_cov = 1e-6*np.identity(len(self.X[0]))
        x,y = np.meshgrid(np.sort(self.X[:,0]),np.sort(self.X[:,1]))
        self.XY = np.array([x.flatten(),y.flatten()]).T


        # 1. Set the initial mu, covariance and pi values
        self.mu = np.random.randint(min(self.X[:,0]),max(self.X[:,0]),size=(self.number_of_sources,len(self.X[0]))) # This is a nxm matrix since we assume n sources (n Gaussians) where each has m dimensions
        self.cov = np.zeros((self.number_of_sources,len(X[0]),len(X[0]))) # We need a nxmxm covariance matrix for each source since we have m features --> We create symmetric covariance matrices with ones on the digonal
        for dim in range(len(self.cov)):
            np.fill_diagonal(self.cov[dim],5)


        self.pi = np.ones(self.number_of_sources)/self.number_of_sources # Are "Fractions"
        log_likelihoods = [] # In this list we store the log likehoods per iteration and plot them in the end to check if
                             # if we have converged

        # Plot the initial state    
        fig = plt.figure(figsize=(10,10))
        ax0 = fig.add_subplot(111)
        ax0.scatter(self.X[:,0],self.X[:,1])
        for m,c in zip(self.mu,self.cov):
            c += self.reg_cov
            multi_normal = multivariate_normal(mean=m,cov=c)
            ax0.contour(np.sort(self.X[:,0]),np.sort(self.X[:,1]),multi_normal.pdf(self.XY).reshape(len(self.X),len(self.X)),colors='black',alpha=0.3)
            ax0.scatter(m[0],m[1],c='grey',zorder=10,s=100)


        mu = []
        cov = []
        R = []


        for i in range(self.iterations):               

            mu.append(self.mu)
            cov.append(self.cov)


            # E Step
            r_ic = np.zeros((len(self.X),len(self.cov)))

            for m,co,p,r in zip(self.mu,self.cov,self.pi,range(len(r_ic[0]))):
                co+=self.reg_cov
                mn = multivariate_normal(mean=m,cov=co)
                r_ic[:,r] = p*mn.pdf(self.X)/np.sum([pi_c*multivariate_normal(mean=mu_c,cov=cov_c).pdf(X) for pi_c,mu_c,cov_c in zip(self.pi,self.mu,self.cov+self.reg_cov)],axis=0)
            R.append(r_ic)

            # M Step

            # Calculate the new mean vector and new covariance matrices, based on the probable membership of the single x_i to classes c --> r_ic
            self.mu = []
            self.cov = []
            self.pi = []
            log_likelihood = []

            for c in range(len(r_ic[0])):
                m_c = np.sum(r_ic[:,c],axis=0)
                mu_c = (1/m_c)*np.sum(self.X*r_ic[:,c].reshape(len(self.X),1),axis=0)
                self.mu.append(mu_c)

                # Calculate the covariance matrix per source based on the new mean
                self.cov.append(((1/m_c)*np.dot((np.array(r_ic[:,c]).reshape(len(self.X),1)*(self.X-mu_c)).T,(self.X-mu_c)))+self.reg_cov)
                # Calculate pi_new which is the "fraction of points" respectively the fraction of the probability assigned to each source 
                self.pi.append(m_c/np.sum(r_ic)) 



            # Log likelihood
            log_likelihoods.append(np.log(np.sum([k*multivariate_normal(self.mu[i],self.cov[j]).pdf(X) for k,i,j in zip(self.pi,range(len(self.mu)),range(len(self.cov)))])))



        fig2 = plt.figure(figsize=(10,10))
        ax1 = fig2.add_subplot(111) 
        ax1.plot(range(0,self.iterations,1),log_likelihoods)
        #plt.show()
        print(mu[-1])
        print(cov[-1])
        for r in np.array(R[-1]):
            print(r)
        print(X)

    def predict(self):
        # PLot the point onto the fittet gaussians
        fig3 = plt.figure(figsize=(10,10))
        ax2 = fig3.add_subplot(111)
        ax2.scatter(self.X[:,0],self.X[:,1])
        for m,c in zip(self.mu,self.cov):
            multi_normal = multivariate_normal(mean=m,cov=c)
            ax2.contour(np.sort(self.X[:,0]),np.sort(self.X[:,1]),multi_normal.pdf(self.XY).reshape(len(self.X),len(self.X)),colors='black',alpha=0.3)




EMM = EMM(X,3,100)     
EMM.run()
EMM.predict()

0

恕我直言,所有答案都错过了一个基本事实。如果人们查看高斯混合模型的参数空间,则该空间沿子空间是奇异的,在子空间中,混合中的组分少于全部。这意味着导数自动为零,通常整个子空间将显示为mle。从哲学上讲,小于满秩协方差的子空间是参数空间的边界,当边界上出现mle时,该子空间应始终是可疑的-它通常表示存在一个较大的参数空间,在其中可以找到“真正的” MLE。Drton,Sturmfeld和Sullivant有一本书叫做“代数统计”。该书对此进行了详细讨论。如果您真的很好奇,那么应该看看。


-2

对于单个高斯,均值可能等于数据点之一(Xñ 例如),然后在似然函数中包含以下术语:

ñXñ|XñσĴ1个1个σĴXñ1个2π1个/2σĴ经验值-1个σĴ|Xñ-σĴ|2=1个2π1个/2σĴ
限制 σĴ0 自从指数论证消失之后,现在显然变得分歧了。

但是对于数据点 X 与均值不同 σĴ, 我们将有

ñX|XσĴ1个1个=1个2π1个/2σĴ经验值-1个σĴ|X-σĴ|2
现在,指数的参数在极限处发散(并且为负) σĴ0。结果,这两个项在似然函数中的乘积将消失。

该答案是错误的,因为没有理由确定均值 μĴ 和标准偏差 σĴ
西安
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.