ガウス混合モデルの特異点の問題


15

本「パターン認識と機械学習」の第9章には、ガウス混合モデルに関する次の部分があります。

ここに画像の説明を入力してください ここに画像の説明を入力してください 正直に言うと、なぜこれが特異性を生み出すのか、私にはよくわかりません。誰も私にこれを説明できますか?申し訳ありませんが、私は学部生であり、機械学習の初心者なので、私の質問は少しばかげているように聞こえるかもしれませんが、助けてください。どうもありがとうございました


簡単に修正できるように見えるので、化し、最適化時にゼロに近づきすぎるとにペナルティーを科します。γ Kσk2=τ2γkγk
確率

1
@probabilityislogicここをフォローしているかどうかわからない:(
ダンマンチュオン

回答:


11

最尤法を使用してガウス分布を単一のデータポイントに適合させたい場合、そのポイントに「崩壊する」非常に尖ったガウス分布を取得します。多変量ガウスの場合、特異共分散行列につながる点が1つだけの場合、分散はゼロになるため、特異点問題と呼ばれます。

分散がゼロになると、ガウス成分(式9.15)の尤度は無限になり、モデルはオーバーフィットします。これは、分散がゼロになることはないため、複数のポイントに1つのガウス分布のみを当てはめると発生しません。ただし、PRMLの同じページに示されているように、ガウス分布が混在している場合に発生する可能性があります。

ここに画像の説明を入力してください

更新
この本は、特異点の問題に対処するための2つの方法を提案しています。

1)特異点が発生した場合の平均と分散のリセット ここに画像の説明を入力してください

2)事前を追加することにより、MLEの代わりにMAPを使用します。 ここに画像の説明を入力してください


単一のガウスの場合について、なぜ分散をゼロにすることはできませんか?教科書には、「この問題は単一のガウス分布の場合には発生しなかったことを思い出してください。違いを理解するために、単一のガウス分布がデータ点に崩壊すると、他のデータポイントとこれらの要因は、ゼロではなく、無限大になり、全体的な可能性を与えて、指数関数的に速くゼロに行きます」しかし、私はそれを非常:(を理解していない。
ダンManhチュオン

分散の定義によれば、そのため@DangManhTruong すべての点が同じ値である場合を除き、我々は常に非ゼロの分散を有します。var(x)=E[(xμ)2]
dontloo

そうですか!ありがとう:Dそれでは、実際にはそれを避けるために何をすべきでしょうか?本はそれについて説明しません。
ダンマンチュオン

@DangManhTruongこんにちは、私は答えにそれを追加しました、見てください:)
dontloo

あなたにしているの歓迎を@DangManhTruong
dontloo

3

この問題は、単一のガウス分布の場合には発生しなかったことを思い出してください。違いを理解するために、単一のガウスがデータ点に崩壊すると、他のデータ点から生じる尤度関数に乗法因子が寄与し、これらの因子は指数関数的に速くゼロになり、全体的な尤度がむしろゼロになることに注意してください無限よりも。

また、私はこの部分にちょっと混乱しています。これが私の解釈です。簡単にするために1Dのケースを取り上げます。

単一のガウス分布がデータポイントで「崩壊する」、つまりμ = x iの場合、全体的な尤度は次のようになります。xiμ=xi

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

あなたが見るように、左の用語P X I GMMにおける病的場合と同様であるが、他のデータ点の尤度である右、上の用語P XI、依然としてような用語含まEは- X N - μ 2σ0p(xi)p(xi)どの0飛躍的に速くとしてσ0、それがゼロに行くの可能性に対する全体的な影響があるそう。e(xnμ)22σ20σ0

ここでの主なポイントは、1つのコンポーネントが全体的なデータ尤度を損なうことなく1つのデータポイントに「焦点を合わせる」ことができる混合ケースとは異なり、単一のガウス分布をフィッティングするとき、すべてのデータポイントが1つのパラメーターセットを共有する必要があることです。μ,σ


2

この回答は、GMMをデータセットに適合させる際に特異な共分散行列をもたらす、何が起こっているのか、なぜ起こっているのか、それを防ぐためにできることについての洞察を与えます。

そのため、ガウス混合モデルをデータセットに適合させる際の手順を繰り返すことから始めるのが最適です。


あなたがあなたのデータに合うようにしたいどのように多くのソース/クラスター(C)を決め0.
1.初期化パラメータの平均、共分散Σ C、およびfraction_per_class π CあたりのクラスタC μcΣcπc

EStep_

  1. 各データポイントのための計算は、確率のR IのCデータポイントは、そのxは、私は:とクラスタcに属する R I C = π C N X I | μ CΣ C)をxiricxi

    NはX|μΣ:でmulitvariateガウス分布を記述する NXIμCΣC=1
    ric=πcN(xi | μc,Σc)Σk=1KπkN(xi | μk,Σk)
    N(x | μ,Σ)

    、RICの各データポイントのための私達を与えるxはIを尺度の:PRO、B、B、I、L、ITのY軸のTHTxibelongstoclas
    N(xi,μc,Σc) = 1(2π)n2|Σc|12exp(12(xiμc)TΣc1(xiμc))


    ricxしたがって、xiが1つのガウスcに非常に近い場合、高いric値を取得しますそれ以外の場合、このガウスおよび比較的低い値に対して。 MStep_ 各クラスターcについて:総重量mcを計算するProbablty that バツ belongs to class cProbablty of バツ over all classesバツrc

    MStep_

    mc(緩くクラスタcに割り当てられたポイントの一部を話す)、更新μ C、およびΣ cを使用してのR のI Cを有する: M C = Σ I 、R I C π C = M CπcμcΣcrc

    mc = Σrc

    μC=1
    πc = mcm

    ΣC=1
    μc = 1mcΣrcバツ

    マインドあなたは、この最後の式で更新手段を使用する必要があること。 :反復対数尤度を用いて計算された我々のモデルの収束の対数尤度関数まで、EおよびMステップを繰り返し 、L、N、PX|πμΣ=Σ N iは= 1、LをNΣ K
    Σc = 1mcΣrcバツμcTバツμc





    ln pバツ | πμΣ = Σ=1N lnΣk=1KπkNバツ | μkΣk



バツAX=XA=I

[0000]


AXIΣc1
0EとMのステップ間の反復中に多変量ガウスが1つのポイントに該当する場合、上記の共分散行列。これは、たとえば3つのガウス分布に適合させたいが実際には2つのクラス(クラスター)のみで構成されるデータセットがあり、大まかに言うと、これら3つのガウス分布の2つが最後のガウス分布のみを管理するのに自分のクラスターをキャッチする場合に発生する可能性があります座っている1つのポイントをキャッチします。これが以下のように見えることを確認します。しかし、ステップバイステップ:2つのクラスターで構成される2次元データセットがあり、それがわからず、3つのガウスモデルをc = 3に適合させたいと仮定します。Eステップでパラメーターを初期化し、プロットします。データの上にあるガウス分布。次のようになります(おそらく、左下と右上に2つの比較的散在するクラスターが表示されます) ここに画像の説明を入力してくださいμcπcここに画像の説明を入力してください

riccovric
ric=πcN(xi | μc,Σc)Σk=1KπkN(xi | μk,Σk)
ricricxiここに画像の説明を入力してくださいxixiricxiricここに画像の説明を入力してくださいric
Σc = Σiric(xiμc)T(xiμc)
ricxi(xiμc)μcxijμjμj=xnric

[0000]


00マトリックス。これは、共分散行列の対角線にごくわずかな値(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

xn

N(xn|xn,σj11)limσjxn1(2π)1/2σjexp(1σj|xnσj|2)=1(2π)1/2σj
σj0

xmσj

N(xm|xm,σj11)=1(2π)1/2σjexp(1σj|xmσj|2)
σj0

μjσj
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.