使用组件参数的 GaussianMixture 初始化 - sklearn
GaussianMixture initialization using component parameters - 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 旨在使用高斯混合来拟合样本,但有没有办法为其提供最终值并从那里继续?
它似乎有一个检查来确保模型已经过训练。您可以通过在设置参数之前在非常小的数据集上训练 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
你太棒了,J.P.Petersen!
看到您的回答后,我比较了使用 fit
方法引入的变化。似乎初始实例化并没有创建 gmix
的所有属性。具体来说,它缺少以下属性,
covariances_
means_
weights_
converged_
lower_bound_
n_iter_
precisions_
precisions_cholesky_
前三个是在分配给定输入时引入的。其中,对于我的应用程序,我唯一需要的属性是 precisions_cholesky_
,它是逆协方差矩阵的 cholesky 分解。作为最低要求,我将其添加如下,
gmix.precisions_cholesky_ = np.linalg.cholesky(np.linalg.inv(sigma)).transpose((0, 2, 1))
要了解发生了什么,先GaussianMixture
checks that it has been fitted:
self._check_is_fitted()
哪个触发 the following check:
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更新它的约束,@J.P.Petersen的解决方案可能是最好的干得好。
作为@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)
并且根据您的协方差类型,您应该相应地更改 full
作为 _compute_precision_cholesky
的输入(将是 full
、diag
、tied
之一, spherical
).
我想使用 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 旨在使用高斯混合来拟合样本,但有没有办法为其提供最终值并从那里继续?
它似乎有一个检查来确保模型已经过训练。您可以通过在设置参数之前在非常小的数据集上训练 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
你太棒了,J.P.Petersen!
看到您的回答后,我比较了使用 fit
方法引入的变化。似乎初始实例化并没有创建 gmix
的所有属性。具体来说,它缺少以下属性,
covariances_
means_
weights_
converged_
lower_bound_
n_iter_
precisions_
precisions_cholesky_
前三个是在分配给定输入时引入的。其中,对于我的应用程序,我唯一需要的属性是 precisions_cholesky_
,它是逆协方差矩阵的 cholesky 分解。作为最低要求,我将其添加如下,
gmix.precisions_cholesky_ = np.linalg.cholesky(np.linalg.inv(sigma)).transpose((0, 2, 1))
要了解发生了什么,先GaussianMixture
checks that it has been fitted:
self._check_is_fitted()
哪个触发 the following check:
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更新它的约束,@J.P.Petersen的解决方案可能是最好的干得好。
作为@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)
并且根据您的协方差类型,您应该相应地更改 full
作为 _compute_precision_cholesky
的输入(将是 full
、diag
、tied
之一, spherical
).