Gaussian Karışım Modelleri (Mixtüre Models / GMM) [1]’de işlendi. O yazı her biri \(d\) boyutlu olabilecek \(G\) tane Gaussian’dan oluşan bir karışım ile veriyi temsil edebilmekten bahsediyordu. Bu tür bir modelde bilinmeyenler \(G\) tane Gaussian’ın parametreleriydi, yani her Gaussian için D x 1 boyutunda bir \(\mu\), D x D boyutunda bir \(\Sigma\), ve tüm karışım için karışım seviyelerini gösteren D x 1 boyutunda bir \(\pi\) bulunması gerekiyordu. Eğer [2] notasyonu ile gösterirsek, karışım olasılık dağılım fonksiyonu,
\[ p(x) = \sum _{g=1}^{G} \pi_g N(x | \mu_g, \Sigma_g) \]
oluyordu, ki \(x \in R^{D}\).
Dikkat edersek [1] yazısı veriyi toptan (batch) işleyen bir yaklaşım gösterdi, bu yaklaşım, ki Beklenti-Maksimizasyon (Expectation-Maximization / EM) adıyla bilinir, döngüsünün her adımında verinin tamamını işler. Bu yazıda veriyi azar azar, artımsal şekilde işleyerek yaklaşık EM yapmanın tekniğini göreceğiz. Eğer her veri noktası aynı şekilde dağılmış, bağımsız şekilde geliyorsa uzun vadede bu artımsal öğrenim tekniği normal toptan EM’in bulduğu sonuca yaklaşacaktır.
Notasyon şöyle, veriler \(x_i\) olarak geliyor, \(i\) bir indistir, ve \(i = 1,..,m,m+1\) olarak gider. Bizi ilgilendiren önemli an \(m\) anından \(m+1\) anına geçiş, yani \(m\)’ye kadar olan model parametrelerini \(m+1\)’inci veri gelince ona göre güncellemek.
Bu bağlamda ilk varsayımı, yaklaşıksallamayı şöyle yapalım, tek bir veri noktası eklediğimizde GMM modelinin parametrelerinin çok fazla değişmesini beklemeyiz, o zaman GMM karışımının içindeki \(g\)’inci Gaussian \(x_{i+1}\) verisi üzerinde hesapladığı olasılık / sorumluluk (responsibility) şöyle gösterilebilir,
\[ p^{(m+1)}(C_g | \mathbf{x}_i) \approx p^{(m)}(C_g | \mathbf{x}_i) \qquad (1) \]
Karışım Ağırlıkları \(\pi_g\)
Her \(g\) bileşeni için karışım ağırlığı tüm \(m\) verileri üzerinden hesaplanan ortalama sorumluluktur. Bu hesap tabii ki toptan EM mantığından geliyor, referans için [2],
\[ \pi_g^{(m)} = \frac{1}{m} \sum_{i=1}^{m} p^{(m)}(C_g | \mathbf{x}_i) \]
Yeni \(x_{m+1}\) verisi gelince üstteki formül doğal olarak alttaki gibi olur,
\[ \pi_g^{(m+1)} = \frac{1}{m+1} \sum_{i=1}^{m+1} p^{(m+1)}(C_g | \mathbf{x}_i) \]
Şimdi (1)’deki yaklaşıksallamayı kullanırız,
\[ \pi_g^{(m+1)} \approx \frac{1}{m+1} \left( \sum_{i=1}^{m} p^{(m)}(C_g | \mathbf{x}_i) + p^{(m)}(C_g | \mathbf{x}_{m+1}) \right) \]
Hatırlarsak,
\[ \sum_{i=1}^{m} p^{(m)}(C_g | \mathbf{x}_i) = m \pi_g^{(m)} \]
O zaman,
\[ \pi_g^{(m+1)} \approx \frac{1}{m+1} \left( m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) \right) \]
Burada bir tekrar düzenleme daha yapalım. Eşitliğin sağ tarafını mevcut kestirme hesabı \(\pi_g^{(m)}\) artı bir düzeltme terimi olarak düşünelim. Bunu ortaya çıkartmak için şöyle yazabiliriz,
\[ \pi_g^{(m+1)} \approx \pi_g^{(m)} + \left[ \frac{1}{m+1} \left( m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) \right) - \pi_g^{(m)} \right] \]
Üstte bir \(\pi_g^{(m)}\) ekledik ve bir tane de çıkarttık, böylece aslında hiçbir değişim yapmamış olduk. Formül hala aynı şey söylüyor. Şimdi köşeli parantez içindekiler için ortak bir bölen \((m+1)\) yaratalım,
\[ \pi_g^{(m+1)} \approx \pi_g^{(m)} + \frac{1}{m+1} \left( m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) - (m+1)\pi_g^{(m)} \right) \]
Parantez icindeki ifadeleri basitlestirelim,
\[ m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) - m\pi_g^{(m)} - \pi_g^{(m)} = p^{(m)}(C_g | \mathbf{x}_{m+1}) - \pi_g^{(m)} \]
Geri sokalım,
\[ \pi_g^{(m+1)} \approx \pi_g^{(m)} + \frac{1}{m+1} \left( p^{(m)}(C_g | \mathbf{x}_{m+1}) - \pi_g^{(m)} \right) \]
Böylece karışım ağırlıkları için özyineli güncelleme formülüne erişmiş olduk.
Ortalama \(\mu_g\) Güncellemesi
Bileşen \(g\)’nin ortalaması şöyle tanımlıdır,
\[ \mu_g^{(m)} = \frac{1}{m \pi_g^{(m)}} \sum_{i=1}^{m} p^{(m)}(C_g | \mathbf{x}_i) \mathbf{x}_i \]
Bu ifade toptan EM matematiğinden geliyor [1].
\(m \pi_g^{(m)}\) ile bölüm ifadesini eşitliğin sol tarafına geçirip ona \(S_g^{(m)}\) diyebiliriz,
\[ S_g^{(m)} = \sum_{i=1}^{m} p^{(m)}(C_g | \mathbf{x}_i) \mathbf{x}_i = m \pi_g^{(m)} \mu_g^{(m)} \qquad{(2)} \]
Yeni veri noktası \(\mathbf{x}_{m+1}\) geldiğinde üstteki toplama bir terim daha eklenmiş olacaktır, yani mevcut toplam \(S_g^{(m)}\) artı yeni veri için gereken terim,
\[ S_g^{(m+1)} = S_g^{(m)} + p^{(m+1)}(C_g | \mathbf{x}_{m+1}) \mathbf{x}_{m+1} \]
Bu noktada yine (1)’deki aynı yaklaşıksallamayı kullanabiliriz,
\[ S_g^{(m+1)} \approx S_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) \mathbf{x}_{m+1} \]
Şimdi (2) formülündeki eşitliğin sol tarafını baz alırsak, ve bunu \(m+1\) için adapte edersek,
\[ S_g^{(m+1)} = (m+1) \pi_g^{(m+1)} \mu_g^{(m+1)} \]
Ya da
\[ \mu_g^{(m+1)} = \frac{S_g^{(m+1)}}{(m+1) \pi_g^{(m+1)}} \]
Üstteki formüle üç formül ustteki formülü sokalim,
\[ \mu_g^{(m+1)} \approx \frac{ S_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) \mathbf{x}_{m+1} }{ (m+1) \pi_g^{(m+1)} } \]
Şimdi \(S_g^{(m)} = m \pi_g^{(m)} \mu_g^{(m)}\) ifadesini ve daha önceki \(\pi_g^{(m+1)}\) eşitliğini sok,
\[ \mu_g^{(m+1)} \approx \frac{ m \pi_g^{(m)} \mu_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) \mathbf{x}_{m+1} }{ (m+1) \left[ \pi_g^{(m)} + \frac{1}{m+1} \left( p^{(m)}(C_g | \mathbf{x}_{m+1}) - \pi_g^{(m)} \right) \right] } \]
Böleni basitleştir,
\[ (m+1) \pi_g^{(m+1)} = m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) \]
O zaman
\[ \mu_g^{(m+1)} \approx \frac{ m \pi_g^{(m)} \mu_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) \mathbf{x}_{m+1} }{ m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) } \]
Şöyle de yazılabilir,
\[ \mu_g^{(m+1)} = \mu_g^{(m)} + \frac{ p^{(m)}(C_g | \mathbf{x}_{m+1}) }{ m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) } \left( \mathbf{x}_{m+1} - \mu_g^{(m)} \right) \]
Şimdi, alttaki ifadenin doğru olduğunu bildiğimize göre
\[ m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) \approx (m+1) \pi_g^{(m+1)} \]
Büyük \(m\) için alttaki de doğru olmalıdır.
\[ \mu_g^{(m+1)} \approx \mu_g^{(m)} + \frac{1}{m+1} \cdot \frac{ p^{(m)}(C_g | \mathbf{x}_{m+1}) }{ \pi_g^{(m)} } \left( \mathbf{x}_{m+1} - \mu_g^{(m)} \right) \]
Böylece \(\mu_g\) güncellemesini elde etmiş oluyoruz.
Kovaryans \(\Sigma_g\) Güncellemesi
Bileşen \(g\) için kovaryans
\[ \Sigma_g^{(m)} = \frac{1}{m \pi_g^{(m)}} \sum_{i=1}^{m} p^{(m)}(C_g | \mathbf{x}_i) (\mathbf{x}_i - \mu_g^{(m)}) (\mathbf{x}_i - \mu_g^{(m)})^T \]
Şu tanımı öne sürelim,
\[ T_g^{(m)} = \sum_{i=1}^{m} p^{(m)}(C_g | \mathbf{x}_i) (\mathbf{x}_i - \mu_g^{(m)}) (\mathbf{x}_i - \mu_g^{(m)})^T = m \pi_g^{(m)} \Sigma_g^{(m)} \]
Yeni veri noktası için
\[ T_g^{(m+1)} \approx T_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) (\mathbf{x}_{m+1} - \mu_g^{(m+1)}) (\mathbf{x}_{m+1} - \mu_g^{(m+1)})^T \]
Şimdi \(\mu_g^{(m+1)}\) güncellemesi üzerinden de bir yaklaşıksallama tanımlayacağız,
\[ (\mathbf{x}_{m+1} - \mu_g^{(m+1)}) \approx (\mathbf{x}_{m+1} - \mu_g^{(m)}) \]
O zaman
\[ T_g^{(m+1)} \approx T_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) (\mathbf{x}_{m+1} - \mu_g^{(m)}) (\mathbf{x}_{m+1} - \mu_g^{(m)})^T \]
Yani
\[ \Sigma_g^{(m+1)} = \frac{T_g^{(m+1)}}{(m+1) \pi_g^{(m+1)}} \]
Yerine geçir
\[ \Sigma_g^{(m+1)} \approx \frac{ T_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) (\mathbf{x}_{m+1} - \mu_g^{(m)}) (\mathbf{x}_{m+1} - \mu_g^{(m)})^T }{ (m+1) \pi_g^{(m+1)} } \]
\(T_g^{(m)} = m \pi_g^{(m)} \Sigma_g^{(m)}\) eşitliğini kullanarak ve \(\pi_g^{(m+1)}\) formülü ile alttakini elde ederiz,
\[ \Sigma_g^{(m+1)} \approx \frac{ m \pi_g^{(m)} \Sigma_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) (\mathbf{x}_{m+1} - \mu_g^{(m)}) (\mathbf{x}_{m+1} - \mu_g^{(m)})^T }{ m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) } \]
Bu şöyle de yazılabilir
\[ \Sigma_g^{(m+1)} = \Sigma_g^{(m)} + \frac{ p^{(m)}(C_g | \mathbf{x}_{m+1}) }{ m \pi_g^{(m)} + p^{(m)}(C_g | \mathbf{x}_{m+1}) } \left[ (\mathbf{x}_{m+1} - \mu_g^{(m)}) (\mathbf{x}_{m+1} - \mu_g^{(m)})^T - \Sigma_g^{(m)} \right] \]
Tekrar büyük \(m\) için yaklaşıksallama yapıyoruz
\[ \Sigma_g^{(m+1)} \approx \Sigma_g^{(m)} + \frac{1}{m+1} \cdot \frac{ p^{(m)}(C_g | \mathbf{x}_{m+1}) }{ \pi_g^{(m)} } \left[ (\mathbf{x}_{m+1} - \mu_g^{(m)}) (\mathbf{x}_{m+1} - \mu_g^{(m)})^T - \Sigma_g^{(m)} \right] \]
Böylece kovaryans güncellemesini elde etmiş olduk.
Örnek
Alttaki kodda 2 boyutlu veri baz alındı, iki Gaussian tepesini karışımından rasgele örneklem alıyoruz.
from scipy.stats import multivariate_normal
def generate_gmm_data(weights, means, covs, n_samples):
= len(weights)
n_components = np.zeros((n_samples, 2))
data = np.random.choice(n_components, size=n_samples, p=weights)
component_choices for i in range(n_components):
= np.where(component_choices == i)[0]
indices = len(indices)
n_points_to_sample if n_points_to_sample > 0:
= np.random.multivariate_normal(
data[indices, :] =means[i],
mean=covs[i],
cov=n_points_to_sample
size
)
= np.arange(len(data))
shuffle_indices
np.random.shuffle(shuffle_indices)= data[shuffle_indices]
res_data return res_data
def gmm_pdf(x, y, weights, means, covs):
"""(x,y) noktasinda GMM olasilik yogunlugunu hesapla"""
= 0
z for i in range(len(weights)):
= multivariate_normal(means[i], covs[i])
rv += weights[i] * rv.pdf([x, y])
z return z
= [0.7, 0.3]
weights = [
means 0, 5],
[5, -2]
[
]= [
covs 2, 1.5], [1.5, 3]],
[[10, -3], [-3, 5]]
[[
]
= 1000
n_points
# Generate data points
= generate_gmm_data(weights, means, covs, n_points)
gmm_data
=(8, 6))
plt.figure(figsize0], gmm_data[:, 1], alpha=0.6, s=10)
plt.scatter(gmm_data[:, "X-coordinate")
plt.xlabel("Y-coordinate")
plt.ylabel(True)
plt.grid('stat_112_gmminc_01.png') plt.savefig(
Grafikte iki tepenin aşağı yukarı nerede olduğu görülüyor. Şimdi artımsal olarak üstteki veriyi temsil eden GMM’i bulmaya uğraşalım.
def responsibilities(x, weights, means, covs):
= np.zeros(len(weights))
p for k in range(len(weights)):
= weights[k] * multivariate_normal(mean=means[k], cov=covs[k]).pdf(x)
p[k] = p.sum()
denom if denom == 0:
return np.ones_like(p) / len(p)
return p / denom
def log_likelihood(X, weights, means, covs):
= 0.0
ll for x in X:
= sum(weights[k] *
px =means[k], cov=covs[k]).pdf(x)
multivariate_normal(meanfor k in range(len(weights)))
+= np.log(px + 1e-12) # guard against log(0)
ll return ll
= generate_gmm_data(weights, means, covs, n_points)
data = 2
n_components = data.shape[1]
d = np.ones(n_components) / n_components
weights_tmp = np.random.randn(n_components, d) * 5
means_tmp = np.array([np.eye(d) for _ in range(n_components)])
covs_tmp
= 1
m_total = weights * m_total
cumulative_r
for idx in range(len(data)):
= data[idx]
x = responsibilities(x, weights_tmp, means_tmp, covs_tmp)
r += 1.0
m_total for k in range(n_components):
# Update cumulative responsibilities
+= r[k]
cumulative_r[k]
= cumulative_r[k] / m_total
weights_tmp[k]
= means_tmp[k].copy()
mu_old = (1.0 / m_total) * (r[k] / (weights_tmp[k] + 1e-12))
coef = mu_old + coef * (x - mu_old)
means_tmp[k]
= (x - mu_old).reshape(-1, 1)
diff_var = covs_tmp[k] + coef * (diff_var @ diff_var.T - covs_tmp[k])
covs_tmp[k]
= log_likelihood(data, weights_tmp, means_tmp, covs_tmp)
ll print (ll)
-4373.507980537245
print (weights_tmp)
print (means_tmp)
print (covs_tmp)
[0.29698269 0.70301731]
[[ 4.95850944 -1.96333327]
[-0.09937333 4.98941925]]
[[[12.4988802 -3.52676769]
[-3.52676769 4.98789128]]
[[ 2.01466638 1.36292997]
[ 1.36292997 3.1163339 ]]]
= np.linspace(-10, 15, 120)
xs = np.linspace(-10, 15, 120)
ys = np.meshgrid(xs, ys)
Xg, Yg = np.zeros_like(Xg)
Z_true = np.zeros_like(Xg)
Z_learned
for i in range(Xg.shape[0]):
for j in range(Xg.shape[1]):
= np.array([Xg[i, j], Yg[i, j]])
pt = sum(weights[k] *
Z_true[i, j] =means[k], cov=covs[k]).pdf(pt)
multivariate_normal(meanfor k in range(len(weights)))
= sum(weights_tmp[k] *
Z_learned[i, j] =means_tmp[k], cov=covs_tmp[k]).pdf(pt)
multivariate_normal(meanfor k in range(n_components))
= plt.subplots(1, 2, figsize=(12, 5), constrained_layout=True)
fig, axes = axes
ax1, ax2 = ax1.contourf(Xg, Yg, Z_true, levels=40, cmap='viridis')
cf1 0], data[:, 1], c='white', s=8, alpha=0.6,
ax1.scatter(data[:, ='k', linewidth=0.2)
edgecolors"Veri")
ax1.set_title("x")
ax1.set_xlabel("y")
ax1.set_ylabel(=ax1, fraction=0.046, pad=0.04)
fig.colorbar(cf1, ax
= ax2.contourf(Xg, Yg, Z_learned, levels=40, cmap='viridis')
cf2 0], data[:, 1], c='white', s=8, alpha=0.6,
ax2.scatter(data[:, ='k', linewidth=0.2)
edgecolorsu'Artımsal GMM ile Öğrenilmiş PDF')
ax2.set_title("x")
ax2.set_xlabel("y")
ax2.set_ylabel(
ax2.legend()=ax2, fraction=0.046, pad=0.04)
fig.colorbar(cf2, ax'stat_112_gmminc_02.png') plt.savefig(
Şimdiye kadar gördüklerimiz artımsal güncelleme yapıyor olsa bile görülen tüm verilere aynı ağırlığı / önemi veriyordu. Fakat son görülen verilere daha fazla ağırlık veren ve eskileri (bir parametreye bağlı olarak) yavaş yavaş “unutan” bir yaklaşım bazen daha faydalı olabilir. EWMA yaklaşımı burada devreye girebilir, [5] yazısında gösterildiği gibi EWMA’nın kabaca bir kaydırılan pencere içindeki verileri işleme mantığı vardır (ve bu ‘etkili pencere’ büyüklüğü hesaplanabilir) böylece eski verilerin yavaşça unutulması sağlanabilir.
EWMA yaklaşımında bir \(\lambda\) parametresi vardır, o zaman önceki güncelleme formüllerini bir \(\lambda\) içerecek şekilde tekrar düzenlersek [2],
\[ \pi_g^{m+1} = \pi_g^{m} + \lambda [ p^{(m)} (C_g | x_{m+1}) - \pi_g^{m} ] \]
\[ \mu_g^{(m+1)} = \mu_g^{(m)} + \lambda \frac{ p^{(m)}(C_g | \mathbf{x}_{m+1}) }{ \pi_g^{(m)} } \left( \mathbf{x}_{m+1} - \mu_g^{(m)} \right) \]
\[ \Sigma_g^{(m+1)} = \Sigma_g^{(m)} + \lambda \frac{ p^{(m)}(C_g | \mathbf{x}_{m+1}) }{ \pi_g^{(m)} } \left[ (\mathbf{x}_{m+1} - \mu_g^{(m)}) (\mathbf{x}_{m+1} - \mu_g^{(m)})^T - \Sigma_g^{(m)} \right] \]
Üstteki formüller aslında daha önceki güncelleme formüllerinin genelleşmiş halidir denebilir, eğer \(\lambda = \frac{1}{m+1}\) dersek, ve sürekli artan \(m\) bağlamında önceki formüllerin aynısını elde ederiz. Fakat farklı bir unutma faktörü \(\lambda\) verirsek, mesela \(\lambda=0.999\), o zaman EWMA usulü bir GMM güncellemesi elde etmiş oluyoruz.
EWMA güncellemesi kodu,
from scipy.stats import multivariate_normal
def generate_gmm_data(weights, means, covs, n_samples):
= np.random.RandomState()
rng = len(weights)
n_components = len(means[0])
d = np.zeros((n_samples, d))
data = rng.choice(n_components, size=n_samples, p=weights)
comps for k in range(n_components):
= np.where(comps == k)[0]
idx if len(idx) > 0:
= rng.multivariate_normal(mean=means[k], cov=covs[k], size=len(idx))
data[idx]
rng.shuffle(data)return data
def responsibilities(x, weights, means, covs, eps=1e-12):
= np.zeros(len(weights))
p for k in range(len(weights)):
# enforce SPD-ish covariance
= (covs[k] + covs[k].T) / 2.0
cov = cov + np.eye(cov.shape[0]) * 1e-6
cov = multivariate_normal(mean=means[k], cov=cov, allow_singular=True)
rv = weights[k] * rv.pdf(x)
p[k] = p.sum()
denom if denom < eps:
return np.ones_like(p) / len(p)
return p / denom
def log_likelihood(X, weights, means, covs, eps=1e-12):
= 0.0
ll for x in X:
= 0.0
px for k in range(len(weights)):
= (covs[k] + covs[k].T) / 2.0
cov = cov + np.eye(cov.shape[0]) * 1e-6
cov = multivariate_normal(mean=means[k], cov=cov, allow_singular=True)
rv += weights[k] * rv.pdf(x)
px += np.log(px + eps)
ll return ll
if __name__ == "__main__":
= 1000
n_points = generate_gmm_data(weights, means, covs, n_points)
data = data.shape[1]
d = 0.1
lambda_forget = 2
n_components
= np.ones(n_components) / n_components
weights_tmp = np.random.randn(n_components, d) * 5
means_tmp = np.array([np.eye(d) for _ in range(n_components)])
covs_tmp = 1e-6
min_covar = 1e-12
eps
for idx, x in enumerate(data):
= responsibilities(x, weights_tmp, means_tmp, covs_tmp)
r
= weights_tmp + lambda_forget * (r - weights_tmp)
weights_tmp = np.maximum(weights_tmp, eps)
weights_tmp /= np.sum(weights_tmp)
weights_tmp
for k in range(n_components):
= max(weights_tmp[k], eps)
pi_k = means_tmp[k].copy()
mu_old = mu_old + lambda_forget * (r[k] / pi_k) * (x - mu_old)
means_tmp[k] = (x - mu_old).reshape(-1, 1)
diff = diff @ diff.T
outer = covs_tmp[k] + lambda_forget * (r[k] / pi_k) * (outer - covs_tmp[k])
covs_tmp[k] = (covs_tmp[k] + covs_tmp[k].T) / 2.0
covs_tmp[k] = np.diag(covs_tmp[k])
diag = np.maximum(diag, min_covar)
diag = covs_tmp[k] - np.diag(np.diag(covs_tmp[k])) + np.diag(diag)
covs_tmp[k]
if (idx + 1) % 200 == 0:
= log_likelihood(data[:200], weights_tmp, means_tmp, covs_tmp)
ll print(f"iter {idx+1}: partial log-likelihood = {ll:.3f}")
= log_likelihood(data, weights_tmp, means_tmp, covs_tmp)
ll_final print(f"Nihai log olurluk: {ll_final:.3f}")
print("Hesaplanan Karisim Agirliklari:", weights_tmp)
print("Hesaplanan Ortalama:\n", means_tmp)
print("Hesaplanan Kovaryans:\n", covs_tmp)
print("Unutma Faktoru:", lambda_forget)
print("Orneklem:", n_points)
iter 200: partial log-likelihood = -976.455
iter 400: partial log-likelihood = -937.786
iter 600: partial log-likelihood = -955.248
iter 800: partial log-likelihood = -999.386
iter 1000: partial log-likelihood = -936.467
Nihai log olurluk: -4604.283
Hesaplanan Karisim Agirliklari: [0.70080574 0.29919426]
Hesaplanan Ortalama:
[[-0.35565126 4.74680112]
[ 4.33770918 -1.21072193]]
Hesaplanan Kovaryans:
[[[ 1.67484021 0.68862933]
[ 0.68862933 1.41498905]]
[[ 9.57519709 -2.98166738]
[-2.98166738 4.51008999]]]
Unutma Faktoru: 0.1
Orneklem: 1000
Kaynaklar
[1] Bayramli, Istatistik, Gaussian Karışım Modeli (GMM) ile Kümelemek
[2] Zheng, Recursive Gaussian Mixture Models for Adaptive Process Monitoring
[3] Titterington, Recursive Parameter Estimation using Incomplete Data
[4] Zivkovic, Recursive unsupervised learning of finite mixture models
[5] Bayramli, Zaman Serileri - ARIMA, ARCH, GARCH, Periyotlar, Yürüyen Ortalama