如何从已裁剪的正态分布中采样?

我想从N(0, 1)进行采样。但我希望这些值来自[-1, +1]。我无法应用np.clip,因为那样会增加-1+1的可能性。我可以进行随机裁剪,但不能保证它会超出范围。

#standard
s = np.random.normal(0, 1, [10,10])
s = np.clip(s)

#stochastic
for j in range(10)
    edge1 = np.where(s[j] >= 1.)[0]
    edge2 = np.where(s[j] <= -1)[0]

    if edge1.shape[0] > 0:
        rand_el1 = np.random.normal(0, 1, size=(1, edge1.shape[0]))
        s[j,edge1] = rand_el1
    if edge2.shape[0] > 0:
        rand_el2 = np.random.normal(0, 1, size=(1, edge2.shape[0]))
        s[j,edge2] = rand_el2

最佳答案

scipy库将截断的正态分布实现为scipy.stats.truncnorm。您可以使用sample = truncnorm.rvs(-1, 1, size=sample_size)

例如,

In [55]: import matplotlib.pyplot as plt

In [56]: from scipy.stats import truncnorm, norm


正态分布的样本100000点被截断为[-1,1]:

In [57]: sample = truncnorm.rvs(-1, 1, size=100000)


绘制直方图,然后绘制理论PDF曲线。可以使用truncnorm.pdf或缩放后的版本norm.pdf计算PDF。

In [58]: _ = plt.hist(sample, bins=51, normed=True, facecolor='g', edgecolor='k', alpha=0.4)

In [59]: x = np.linspace(-1, 1, 101)

In [60]: plt.plot(x, truncnorm.pdf(x, -1, 1), 'k', alpha=0.4, linewidth=5)
Out[60]: [<matplotlib.lines.Line2D at 0x11f78c160>]

In [61]: plt.plot(x, norm.pdf(x)/(norm.cdf(1) - norm.cdf(-1)), 'k--', linewidth=1)
Out[61]: [<matplotlib.lines.Line2D at 0x11f779f60>]


这是情节:

python - 从修剪的正态分布中采样-LMLPHP

关于python - 从修剪的正态分布中采样,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44803744/

10-10 04:24