我尝试使用numpy.random.multivariate_normal
生成多个样本,其中每个样本都是从具有不同mean
和cov
的多元正态分布中提取的。例如,如果我想提取2个样本,我尝试
from numpy import random as rand
means = np.array([[-1., 0.], [1., 0.]])
covs = np.array([np.identity(2) for k in xrange(2)])
rand.multivariate_normal(means, covs)
但是这会导致ValueError: mean must be 1 dimensional
,我必须为此做一个for循环吗?我认为对于像rand.binomial
这样的函数来说这是可能的。
2条答案
按热度按时间pn9klfpd1#
正如@hpaulj建议的那样,可以从标准多元正态分布生成样本,然后使用
einsum
和/或broadcasting来转换样本。缩放是通过将标准样本点乘以协方差矩阵的平方根来完成的。在下面,我使用scipy.linalg.sqrtm
来计算矩阵平方根,使用numpy.einsum
来执行矩阵乘法。与循环遍历
means
和covs
数组并为每对数组调用一次multivariate_normal
相比,此方法可能不会更快(mean,cov)。这种方法最给予好处的情况是当你有 * 许多 * 不同的均值和协方差,并且每对生成少量样本时。即使这样,它也可能不会更快,因为脚本使用Python循环遍历covs
数组,为每个协方差矩阵调用sqrtm
。如果性能很关键,请使用实际数据进行测试。stszievb2#
由于我在任何地方都没有找到答案,我只需要为每个
mean, std
对计算一次pdf(X)
。我直接从公式中矢量化(所以它只适用于
pdf
(但其他函数也可以类似地编写):其中,
所有
X
、means
、stds
的形状均为[N, d]
(N个多变量数据点,每个数据点具有d个值)并且输出是
[N]
我已经验证了它给出了正确的答案(在1e-14的小误差范围内,我不知道为什么它不相等,也许他们在除法中添加了一个小ε,从而使用了一些数值稳定性问题)
并且快得多(在大小仅为10^4的情况下,我获得了**~4300倍**的加速比):
这对于像高斯混合模型这样应用于图像的应用来说是至关重要的,因为我们需要为每个像素处理多个高斯,所以对于非常小/低分辨率的240 * 320图像,它是76800个高斯。
注意,这不处理协方差矩阵,但通常您可以只使用标准差而不是整个矩阵