在机器学习任务中,我们需要获取一组符合正态分布且有边界的随机数。我们可以使用np.random.normal()
获取一个符合正态分布的随机数,但是它并没有提供任何边界参数。我想知道如何实现这个功能?
在机器学习任务中,我们需要获取一组符合正态分布且有边界的随机数。我们可以使用np.random.normal()
获取一个符合正态分布的随机数,但是它并没有提供任何边界参数。我想知道如何实现这个功能?
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)
使用参数 平均数(mean)、标准差(standard deviation) 和 截断范围(truncation range) 来实例化生成器:
>>> X = get_truncated_normal(mean=8, sd=2, low=1, upp=10)
然后,您可以使用 X 生成一个值:>>> X.rvs()
6.0491227353928894
或者,一个包含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])
下面是三个不同的截断正态分布的图形:
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()
get_truncated_normal.rvs()
而不是在外部调用它,该函数会更快。当然,这只有在您需要随机抽样时才有帮助。 - KenHBStruncnorm
的函数。>>> 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])
>>> 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
这是一个-6到6的直方图绘图:
您可以将目标范围(按照惯例)细分为相等的分区,然后计算每个区域的积分,然后根据表面在每个分区上调用均匀方法。
这是Python实现的:
quad_vec(eval('scipy.stats.norm.pdf'), 1, 4,points=[0.5,2.5,3,4],full_output=True)