Bu cevap, bir GMM'nin bir veri kümesine takılması sırasında tekil bir kovaryans matrisine yol açan şeyin ne olduğu, bunun neden olduğu ve bunu önlemek için neler yapabileceğimiz hakkında bir fikir verecektir.
Bu nedenle, Gauss Karışım Modelinin veri kümesine takılması sırasındaki adımları yeniden özetleyerek en iyi şekilde başlarız.
0. Verilerinize kaç kaynak / küme (c) sığdırmak istediğinize karar verin
1. Küme başına
ortalama , kovaryans Σ c ve fraction_per_class π c parametrelerini başlatınμcΣcπc
E- St e p---------
- Her bir veri noktası için hesaplama olasılık r ı c veri noktası olduğunu x i küme c ait:
r ı c = π c N ( x i | u c , Σ c )xbenrben cxben
buradaN(x|μ,Σ)çok değişkenli Gaussian'ı aşağıdakilerle tanımlar:
N(xi,μc,Σc)=1rben c= πcN-( xben | μ c, Σc)ΣKk = 1πkN-( xben | μ k, Σk)
N-( x | μ , Σ )
ricbize her veri noktası içinxi'ninölçümünü verir:ProbabilitythatxibelongstoclasN-( xben, μc, Σc) = 1 ( 2 π)n2| Σc|12e x p ( - 12( xben- μc)TΣ- 1c( xben- μc) )
rben cxben , eğer bu nedenlexıçok yakın bir Gauss c için yüksek bir alacak,Ricdeğerine aksi takdirde bu gauss ve nispeten düşük değerler için.
M-Step_
Her küme için c: Toplam ağırlığı hesaplamcPr o b a b i l i t y t h a t x ben b , e l O , n gs t o c l a s s c Pr o b a b i l i t y o f xben o v e r a l l c l a s s e s xbenrben c
M- St e p----------
mc(gevşek küme c tahsis nokta kısmını konuşma) ve güncelleme , μ c ve Σ C kullanılarak R ı c : ile
m c = Σ ı r ı c π c = m CπcμcΣcrben c
mc = Σ benrbenc
μc=1πc = m cm
Σc=1μc = 1 mcΣbenrben cxben
Bu son formülde güncellenmiş araçları kullanmanız gerektiğini unutmayın.
Modelimizin log olabilirlik fonksiyonu log olasılığının hesaplandığı yerle birleşene kadar E ve M adımını tekrarlayın:
l n p ( X | π , μ , Σ ) = Σ N i = 1 l n ( Σ KΣc = 1 mcΣbenrben c( xben- μc)T( xben- μc)
l n p ( X | π,μ,Σ)= Σ N-i = 1 l n ( ΣKk = 1πkN-( xben | μ k, Σk) )
XA X= XA = I
[ 0000]
birXbenΣ- 1c0Çok Değişkenli Gauss E ve M adımı arasındaki yineleme sırasında bir noktaya düşerse yukarıdaki kovaryans matrisi. Bu, örneğin, 3 gaussian'a uymak istediğimiz ancak aslında sadece iki sınıftan (kümelerden) oluşan bir veri setimiz varsa, gevşek bir şekilde konuşursak, bu üç gaussiandan ikisi kendi kümesini yakalarken son gaussian sadece onu yönetir oturduğu tek bir noktayı yakalamak için. Bunun nasıl göründüğünü göreceğiz. Ancak adım adım: İki kümeden oluşan iki boyutlu bir veri kümeniz olduğunu varsayın, ancak bunu bilmiyorsunuz ve üç gauss modelini c = 3 olarak ayarlamak istiyorsunuz. E adımında ve grafiğinde parametrelerinizi başlattınız. verilerinizin üstündeki gausslular gibi (belki sol altta ve sağ üstte nispeten dağınık iki kümeyi görebilirsiniz):
μcπc
rben cc o vrben c
rben c= πcN-( xben | μ c, Σc)ΣKk = 1πkN-( xben | μ k, Σk)
rben crben cxbenxbenxbenrben cxbenrben crben cΣc = Σ benrben c( xben- μc)T( xben- μc)
rben cxben( xben- μc)μcxbenjμjμj= xnrben c
[ 0000]
00matris. Bu, kovaryans matrisinin digonaline çok az bir değer (
sklearn'in GaussianMixture değerinde bu değer 1e-6 olarak ayarlanır) eklenerek yapılır. Bir gaussun çöktüğünü fark etmek ve ortalama ve / veya kovaryans matrisini yeni, keyfi olarak yüksek bir değere ayarlamak gibi tekilliği önlemenin başka yolları da vardır. Bu kovaryans düzenlenmesi, aşağıda açıklanan sonuçları aldığınız kodda da uygulanır. Belki de söylendiği gibi tekil kovaryans matrisi elde etmek için kodu birkaç kez çalıştırmanız gerekir. bu her seferinde olmamalı, aynı zamanda gaussianların ilk kurulumuna da bağlıdır.
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()