如何在numpy范围内获得正态分布?

map*_*ple 28 python random numpy normal-distribution machine-learning

在机器学习任务中.我们应该得到一组带有约束的随机wrt正态分布.我们可以获得正态分布数,np.random.normal()但它不提供任何绑定参数.我想知道怎么做?

tot*_*ico 40

的参数化truncnorm是复杂的,所以这里是转换参数化的东西更直观的功能:

from scipy.stats import truncnorm

def get_truncated_normal(mean=0, sd=1, low=0, upp=10):
    return truncnorm(
        (low - mean) / sd, (upp - mean) / sd, loc=mean, scale=sd)
Run Code Online (Sandbox Code Playgroud)

如何使用它?

  1. 使用参数实例生成器:均值,标准偏差截断范围:

    >>> X = get_truncated_normal(mean=8, sd=2, low=1, upp=10)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 然后,您可以使用X生成值:

    >>> X.rvs()
    6.0491227353928894
    
    Run Code Online (Sandbox Code Playgroud)
  3. 或者,具有N个生成值的numpy数组:

    >>> X.rvs(10)
    array([ 7.70231607,  6.7005871 ,  7.15203887,  6.06768994,  7.25153472,
            5.41384242,  7.75200702,  5.5725888 ,  7.38512757,  7.47567455])
    
    Run Code Online (Sandbox Code Playgroud)

一个可视化示例

以下是三种不同截断正态分布的图:

X1 = get_truncated_normal(mean=2, sd=1, low=1, upp=10)
X2 = get_truncated_normal(mean=5.5, sd=1, low=1, upp=10)
X3 = get_truncated_normal(mean=8, sd=1, low=1, upp=10)

import matplotlib.pyplot as plt
fig, ax = plt.subplots(3, sharex=True)
ax[0].hist(X1.rvs(10000), normed=True)
ax[1].hist(X2.rvs(10000), normed=True)
ax[2].hist(X3.rvs(10000), normed=True)
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • +1。但值得注意的是,如果在函数内部立即使用 get_truncated_normal.rvs( ) ,而不是在外部调用它,则该函数会变得更快。当然,这仅在您想要随机抽奖时才有用 (2认同)

bak*_*kal 12

如果您正在寻找截断的正态分布,SciPy会为其调用一个函数truncnorm

该分布的标准形式是截断到[a,b]范围的标准法线 - 注意a和b是在标准法线的域上定义的.要转换特定均值和标准差的剪辑值,请使用:

a,b =(myclip_a - my_mean)/ my_std,(myclip_b - my_mean)/ my_std

truncnorm将a和b作为形状参数.

>>> from scipy.stats import truncnorm
>>> truncnorm(a=-2/3., b=2/3., scale=3).rvs(size=10)
array([-1.83136675,  0.77599978, -0.01276925,  1.87043384,  1.25024188,
        0.59336279, -0.39343176,  1.9449987 , -1.97674358, -0.31944247])
Run Code Online (Sandbox Code Playgroud)

上面的例子以-2和2为界,并返回10个随机变量(使用该.rvs()方法)

>>> min(truncnorm(a=-2/3., b=2/3., scale=3).rvs(size=10000))
-1.9996074381484044
>>> max(truncnorm(a=-2/3., b=2/3., scale=3).rvs(size=10000))
1.9998486576228549
Run Code Online (Sandbox Code Playgroud)

这是-6,6的直方图:

在此输入图像描述

  • 只是为了清楚地表明a和b是形状参数,否则读者可能会尝试使用比例不同于1的-2,2,然后获得[-2,2]之外的随机值 (3认同)