Инициализация GaussianMixture с использованием параметров компонента - sklearn

Я хочу использовать sklearn.mixture.GaussianMixture для хранения модели гауссовой смеси, чтобы впоследствии я мог использовать ее для генерации выборок или значений в точке выборки, используя score_samples метод. Вот пример, где компоненты имеют следующий вес, среднее значение и ковариации

import numpy as np
weights = np.array([0.6322941277066596, 0.3677058722933399])
mu = np.array([[0.9148052872961359, 1.9792961751316835], 
               [-1.0917396392992502, -0.9304220945910037]])
sigma = np.array([[[2.267889129267119, 0.6553245618368836], 
                        [0.6553245618368835, 0.6571014653342457]], 
                       [[0.9516607767206848, -0.7445831474157608], 
                        [-0.7445831474157608, 1.006599716443763]]])

Затем я инициализировал смесь следующим образом

from sklearn import mixture
gmix = mixture.GaussianMixture(n_components=2, covariance_type='full')
gmix.weights_ = weights   # mixture weights (n_components,) 
gmix.means_ = mu          # mixture means (n_components, 2) 
gmix.covariances_ = sigma  # mixture cov (n_components, 2, 2) 

Наконец, я попытался создать образец на основе параметров, которые привели к ошибке:

x = gmix.sample(1000)
NotFittedError: This GaussianMixture instance is not fitted yet. Call 'fit' with appropriate arguments before using this method.

Как я понимаю, GaussianMixture предназначен для подбора образца с использованием смеси гауссов, но есть ли способ предоставить ему окончательные значения и продолжить с этого момента?

4 ответа

Решение

Вы качаетесь, JPPetersen! После просмотра вашего ответа я сравнил внесенные изменения с помощью fit метод. Кажется, что первоначальная реализация не создает все атрибуты gmix, В частности, отсутствуют следующие атрибуты,

covariances_
means_
weights_
converged_
lower_bound_
n_iter_
precisions_
precisions_cholesky_

Первые три вводятся, когда заданные входы назначены. Среди прочего, для моего приложения единственный атрибут, который мне нужен, это precisions_cholesky_ которое является холеским разложением обратных коваринационных матриц. В качестве минимального требования я добавил его следующим образом:

gmix.precisions_cholesky_ = np.linalg.cholesky(np.linalg.inv(sigma)).transpose((0, 2, 1))

Кажется, что у него есть проверка, которая проверяет, что модель была обучена. Вы можете обмануть это, обучив GMM на очень маленьком наборе данных перед настройкой параметров. Как это:

gmix = mixture.GaussianMixture(n_components=2, covariance_type='full')
gmix.fit(rand(10, 2))  # Now it thinks it is trained
gmix.weights_ = weights   # mixture weights (n_components,) 
gmix.means_ = mu          # mixture means (n_components, 2) 
gmix.covariances_ = sigma  # mixture cov (n_components, 2, 2)
x = gmix.sample(1000)  # Should work now

Чтобы понять, что происходит, что GaussianMixture Сначала проверяет, что это было установлено:

self._check_is_fitted()

Что вызывает следующую проверку:

def _check_is_fitted(self):
    check_is_fitted(self, ['weights_', 'means_', 'precisions_cholesky_'])

И, наконец, последний вызов функции:

def check_is_fitted(estimator, attributes, msg=None, all_or_any=all):

который только проверяет, что классификатор уже имеет атрибуты.


Короче говоря, единственное, что вам не хватает, чтобы это работало (без необходимости fit это) установить precisions_cholesky_ атрибут:

gmix.precisions_cholesky_ = 0

должен сделать трюк (не могу попробовать, так что не уверен на 100%:P)

Однако, если вы хотите играть безопасно и иметь последовательное решение в случае, если scikit-learn обновляет свои противоречия, решение @JPPetersen, вероятно, является лучшим способом.

В качестве небольшой альтернативы ответу @hashmuke вы можете использовать вычисление точности, которое используется внутри GaussianMixture напрямую:

      import numpy as np
from scipy.stats import invwishart as IW
from sklearn.mixture import GaussianMixture as GMM
from sklearn.mixture._gaussian_mixture import _compute_precision_cholesky

n_dims = 5
mu1 = np.random.randn(n_dims)
mu2 = np.random.randn(n_dims)
Sigma1 = IW.rvs(n_dims, 0.1 * np.eye(n_dims))
Sigma2 = IW.rvs(n_dims, 0.1 * np.eye(n_dims))
gmm = GMM(n_components=2)
gmm.weights_ = np.array([0.2, 0.8])
gmm.means_ = np.stack([mu1, mu2])
gmm.covariances_ = np.stack([Sigma1, Sigma2])
gmm.precisions_cholesky_ = _compute_precision_cholesky(gmm.covariances_, 'full')
X, y = gmm.sample(1000)

И в зависимости от вашего типа ковариации вы должны соответственно измениться в качестве входных данных для _compute_precision_cholesky(будет одним из full, diag, tied, spherical).

Другие вопросы по тегам