May*_*ybe 6 python random plot montecarlo
我添加了三个正态分布以获得如下所示的新分布,如何在 python 中根据此分布进行采样?
import matplotlib.pyplot as plt
import scipy.stats as ss
import numpy as np
x = np.linspace(0, 10, 1000)
y1 = [ss.norm.pdf(v, loc=5, scale=1) for v in x]
y2 = [ss.norm.pdf(v, loc=1, scale=1.3) for v in x]
y3 = [ss.norm.pdf(v, loc=9, scale=1.3) for v in x]
y = np.sum([y1, y2, y3], axis=0)/3
plt.plot(x, y, '-')
plt.xlabel('$x$')
plt.ylabel('$P(x)$')
Run Code Online (Sandbox Code Playgroud)
顺便说一句,有没有更好的方法来绘制这样的概率分布?
您似乎在问两个问题:如何从分布中采样以及如何绘制 PDF?
假设您正在尝试从代码中显示的 3 个正态分布的混合分布中进行采样,以下代码片段以天真、直接的方式执行这种采样,作为概念验证。
基本上,这个想法是
i在成分的指数中选择一个指数,即0, 1, 2 ...根据它们的概率权重。i,选择相应的分布并从中获得一个样本点。但是,要绘制 PDF,在这种情况下您实际上并不需要样本,因为理论上的解决方案非常简单。在更一般的情况下,PDF 可以通过样本的直方图来近似。
下面的代码使用理论 PDF 执行采样和 PDF 绘图。
import numpy as np
import numpy.random
import scipy.stats as ss
import matplotlib.pyplot as plt
# Set-up.
n = 10000
numpy.random.seed(0x5eed)
# Parameters of the mixture components
norm_params = np.array([[5, 1],
[1, 1.3],
[9, 1.3]])
n_components = norm_params.shape[0]
# Weight of each component, in this case all of them are 1/3
weights = np.ones(n_components, dtype=np.float64) / 3.0
# A stream of indices from which to choose the component
mixture_idx = numpy.random.choice(len(weights), size=n, replace=True, p=weights)
# y is the mixture sample
y = numpy.fromiter((ss.norm.rvs(*(norm_params[i])) for i in mixture_idx),
dtype=np.float64)
# Theoretical PDF plotting -- generate the x and y plotting positions
xs = np.linspace(y.min(), y.max(), 200)
ys = np.zeros_like(xs)
for (l, s), w in zip(norm_params, weights):
ys += ss.norm.pdf(xs, loc=l, scale=s) * w
plt.plot(xs, ys)
plt.hist(y, normed=True, bins="fd")
plt.xlabel("x")
plt.ylabel("f(x)")
plt.show()
Run Code Online (Sandbox Code Playgroud)