>

클러스터 (정지 위치)가있는 2D 데이터 (GPS 데이터)가 있는데, 이는 표준 표준 편차 (GPS 샘플의 고유 노이즈에 비례)를 갖는 가우시안과 유사합니다. 아래 그림은 두 개의 클러스터가 있다고 예상되는 샘플을 보여줍니다. 이미지의 폭은 25 미터, 높이는 13 미터입니다.

sklearn  모듈에는 sklearn.mixture.GaussianMixture 기능이 있습니다 를 사용하면 가우스 혼합을 데이터에 맞출 수 있습니다. 이 함수에는 covariance_type 매개 변수가 있습니다 가우스 모양에 대해 다른 것을 가정 할 수 있습니다. 예를 들어, 'tied' 를 사용하여 균일하다고 가정 할 수 있습니다  인수.

그러나 공분산 행렬이 일정하게 유지되는 것으로 가정 할 수는 없습니다. sklearn 에서  소스 코드 이것을 가능하게하는 수정을하는 것은 사소한 것처럼 보이지만 이것을 허용하는 업데이트로 풀 요청을하기에는 약간 과도한 느낌이 있습니다 (우연히 sklearn 에서 버그를 추가하고 싶지는 않습니다. ). 각 가우시안의 공분산 행렬이 고정 된 데이터에 혼합을 더 잘 적용 할 수있는 방법이 있습니까?

SD는 각 구성 요소에 대해 약 3 미터로 일정하게 유지되어야한다고 가정하고 싶습니다. 이는 GPS 샘플의 소음 수준이기 때문입니다.

  • 답변 # 1

    EM 알고리즘을 직접 구현할 수있을 정도로 간단합니다. 또한 프로세스에 대한 직관적 인 이해도 제공합니다. 공분산이 알려져 있고 성분의 사전 확률이 같고 수단에만 적합하다고 가정합니다.

    이 클래스는 다음과 같습니다 (Python 3에서) :

    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.stats import multivariate_normal
    class FixedCovMixture:
        """ The model to estimate gaussian mixture with fixed covariance matrix. """
        def __init__(self, n_components, cov, max_iter=100, random_state=None, tol=1e-10):
            self.n_components = n_components
            self.cov = cov
            self.random_state = random_state
            self.max_iter = max_iter
            self.tol=tol
        def fit(self, X):
            # initialize the process:
            np.random.seed(self.random_state)
            n_obs, n_features = X.shape
            self.mean_ = X[np.random.choice(n_obs, size=self.n_components)]
            # make EM loop until convergence
            i = 0
            for i in range(self.max_iter):
                new_centers = self.updated_centers(X)
                if np.sum(np.abs(new_centers-self.mean_)) < self.tol:
                    break
                else:
                    self.mean_ = new_centers
            self.n_iter_ = i
        def updated_centers(self, X):
            """ A single iteration """
            # E-step: estimate probability of each cluster given cluster centers
            cluster_posterior = self.predict_proba(X)
            # M-step: update cluster centers as weighted average of observations
            weights = (cluster_posterior.T / cluster_posterior.sum(axis=1)).T
            new_centers = np.dot(weights, X)
            return new_centers
    
        def predict_proba(self, X):
            likelihood = np.stack([multivariate_normal.pdf(X, mean=center, cov=self.cov) 
                                   for center in self.mean_])
            cluster_posterior = (likelihood / likelihood.sum(axis=0))
            return cluster_posterior
        def predict(self, X):
            return np.argmax(self.predict_proba(X), axis=0)
    
    

    귀하와 같은 데이터에서 모델이 빠르게 수렴됩니다.

    np.random.seed(1)
    X = np.random.normal(size=(100,2), scale=3)
    X[50:] += (10, 5)
    model = FixedCovMixture(2, cov=[[3,0],[0,3]], random_state=1)
    model.fit(X)
    print(model.n_iter_, 'iterations')
    print(model.mean_)
    plt.scatter(X[:,0], X[:,1], s=10, c=model.predict(X))
    plt.scatter(model.mean_[:,0], model.mean_[:,1], s=100, c='k')
    plt.axis('equal')
    plt.show();
    
    

    및 출력

    11 iterations
    [[9.92301067 4.62282807]
     [0.09413883 0.03527411]]
    
    

    추정 센터 ( (9.9, 4.6)  그리고 (0.09, 0.03) )은 실제 센터 ( (10, 5) )에 가깝습니다  그리고 (0, 0) ).

  • 답변 # 2

    최고의 옵션은 " GaussianMixture 에서 상속받은 새로운 scikit-learn 클래스를 정의하여 나만의 GMM 모델을 구현하십시오.  원하는 동작을 얻기 위해 메소드를 덮어 씁니다. 이렇게하면 구현을 직접 수행 할 수 있으며 scikit-learn 코드를 변경하거나 풀 요청을 만들 필요가 없습니다.

    또 다른 옵션은 scikit-learn에서 베이지안 GMM 버전을 보는 것입니다. 공분산이 고정되도록 공분산 행렬에 대한 사전을 설정할 수 있습니다. 공분산의 사전으로 Wishart 분포를 사용하는 것 같습니다. 그러나이 배포판에 익숙하지 않아서 더 많은 정보를 얻을 수 있습니다.

  • 답변 # 3

    먼저 spherical 를 사용할 수 있습니다.  옵션을 사용하면 각 구성 요소마다 단일 분산 값이 제공됩니다. 이렇게하면 자신을 확인할 수 있고, 수신 된 분산 값이 너무 다른 경우 무언가 잘못되었습니다.

    분산을 미리 설정하려는 경우 구성 요소에 가장 적합한 중심 만 찾는 문제가 발생합니다. 당신은 k-means 를 사용하여 그것을 할 수 있습니다 예를 들어. 구성 요소의 수를 모르는 경우 모든 논리 값 (예 : 1-20)을 스윕하고 피팅 오류 감소를 평가할 수 있습니다. 또는 자체 EM 기능을 최적화하여 중심과 구성 요소 수를 동시에 찾을 수 있습니다.

  • 이전 c# - LVM_GETCOLUMN은 첫 번째 열에 대한 정보 만 반환합니다
  • 다음 node.js - supertest를 사용하여 응답 본문을 확인하려고합니다오류가 발생했습니다