복붙노트

[PYTHON] 가우스 혼합 모델 이해하기

PYTHON

가우스 혼합 모델 이해하기

나는 scikit-learn 가우스 혼합 모델 구현의 결과를 이해하려고 노력하고있다. 다음 예제를 살펴보십시오.

#!/opt/local/bin/python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture

# Define simple gaussian
def gauss_function(x, amp, x0, sigma):
    return amp * np.exp(-(x - x0) ** 2. / (2. * sigma ** 2.))

# Generate sample from three gaussian distributions
samples = np.random.normal(-0.5, 0.2, 2000)
samples = np.append(samples, np.random.normal(-0.1, 0.07, 5000))
samples = np.append(samples, np.random.normal(0.2, 0.13, 10000))

# Fit GMM
gmm = GaussianMixture(n_components=3, covariance_type="full", tol=0.001)
gmm = gmm.fit(X=np.expand_dims(samples, 1))

# Evaluate GMM
gmm_x = np.linspace(-2, 1.5, 5000)
gmm_y = np.exp(gmm.score_samples(gmm_x.reshape(-1, 1)))

# Construct function manually as sum of gaussians
gmm_y_sum = np.full_like(gmm_x, fill_value=0, dtype=np.float32)
for m, c, w in zip(gmm.means_.ravel(), gmm.covariances_.ravel(), 
               gmm.weights_.ravel()):
    gmm_y_sum += gauss_function(x=gmm_x, amp=w, x0=m, sigma=np.sqrt(c))

# Normalize so that integral is 1    
gmm_y_sum /= np.trapz(gmm_y_sum, gmm_x)

# Make regular histogram
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=[8, 5])
ax.hist(samples, bins=50, normed=True, alpha=0.5, color="#0070FF")
ax.plot(gmm_x, gmm_y, color="crimson", lw=4, label="GMM")
ax.plot(gmm_x, gmm_y_sum, color="black", lw=4, label="Gauss_sum")

# Annotate diagram
ax.set_ylabel("Probability density")
ax.set_xlabel("Arbitrary units")

# Draw legend
plt.legend()
plt.show()

여기서는 먼저 가우시안 (gaussians)으로 구성된 샘플 배포판을 생성 한 다음 이들 데이터에 가우스 혼합 모델을 적용합니다. 다음으로, 주어진 입력에 대한 확률을 계산하려고합니다. 편리하게 scikit 구현은 score_samples 메소드를 제공합니다. 이제 나는이 결과를 이해하려고 노력하고 있습니다. 저는 GMM 적합성에서 가우시안의 매개 변수를 취해서 합계를 구한 다음 적분을 1로 정규화하여 매우 똑같은 분포를 만들 수 있다고 항상 생각했습니다. 그러나 그림에서 볼 수 있듯이 score_samples 메소드가 원본 데이터 (파란색 막대 그래프)에 완벽하게 (빨간색 선) 적합하게 맞춰지면 수동으로 생성 된 분포 (검은 선)는 그렇지 않습니다. 내 생각이 잘못되어 왜 GMM에 맞춰 가우스를 합산하여 배포본을 만들지 못하는지 이해하고 싶습니다. 모든 입력에 대해 감사드립니다.

해결법

  1. ==============================

    1.미래의 누군가가 똑같은 것에 대해 궁금해하는 경우를 위해 : 하나는 합계가 아닌 개별 구성 요소를 표준화해야합니다.

    미래의 누군가가 똑같은 것에 대해 궁금해하는 경우를 위해 : 하나는 합계가 아닌 개별 구성 요소를 표준화해야합니다.

    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.mixture import GaussianMixture
    
    # Define simple gaussian
    def gauss_function(x, amp, x0, sigma):
        return amp * np.exp(-(x - x0) ** 2. / (2. * sigma ** 2.))
    
    # Generate sample from three gaussian distributions
    samples = np.random.normal(-0.5, 0.2, 2000)
    samples = np.append(samples, np.random.normal(-0.1, 0.07, 5000))
    samples = np.append(samples, np.random.normal(0.2, 0.13, 10000))
    
    # Fit GMM
    gmm = GaussianMixture(n_components=3, covariance_type="full", tol=0.001)
    gmm = gmm.fit(X=np.expand_dims(samples, 1))
    
    # Evaluate GMM
    gmm_x = np.linspace(-2, 1.5, 5000)
    gmm_y = np.exp(gmm.score_samples(gmm_x.reshape(-1, 1)))
    
    # Construct function manually as sum of gaussians
    gmm_y_sum = np.full_like(gmm_x, fill_value=0, dtype=np.float32)
    for m, c, w in zip(gmm.means_.ravel(), gmm.covariances_.ravel(), gmm.weights_.ravel()):
        gauss = gauss_function(x=gmm_x, amp=1, x0=m, sigma=np.sqrt(c))
        gmm_y_sum += gauss / np.trapz(gauss, gmm_x) * w
    
    # Make regular histogram
    fig, ax = plt.subplots(nrows=1, ncols=1, figsize=[8, 5])
    ax.hist(samples, bins=50, normed=True, alpha=0.5, color="#0070FF")
    ax.plot(gmm_x, gmm_y, color="crimson", lw=4, label="GMM")
    ax.plot(gmm_x, gmm_y_sum, color="black", lw=4, label="Gauss_sum", linestyle="dashed")
    
    # Annotate diagram
    ax.set_ylabel("Probability density")
    ax.set_xlabel("Arbitrary units")
    
    # Make legend
    plt.legend()
    
    plt.show()
    

  2. from https://stackoverflow.com/questions/41631161/understanding-gaussian-mixture-models by cc-by-sa and MIT license