Python 具有最小值和最大值的正态分布内的随机数生成器
Python Random Number Generator within a normal distribution with Min and Max values
顺便说一句,有人向我建议我可以在 python 中使用半正态分布来设置最小和最大点,使用 0 到无穷大:
halfnorm.rvs()
0 似乎截断了最小值,但是我不知道如何处理无穷大。
我想在正态分布中生成 0 - 15 的数字生成器,但由于分布限制的性质,很难找到一个不超过最大值或低于最小值的函数。
我会尝试使用 beta 分布:https://en.wikipedia.org/wiki/Beta_distribution。它非常简单(例如集成)并且能够拟合典型的反应时间分布。
现在的问题是如何针对固定的 α 和 β 参数有效地进行采样……scipy
已经为我们完成了:https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.beta.html
编辑:出于评论和好奇心,这里是一个示例,绘制了 10 个样本和 1000 个值的直方图:
from scipy.stats import beta
from numpy import histogram
import pylab
max_time = 3
min_time = 0.5
a, b = 2, 7
dist = beta(a, b)
for _ in range(10):
sample = min_time + dist.rvs(size=1000) * (max_time - min_time)
his, bins = histogram(sample, bins=20, density=True)
pylab.plot(bins[:-1], his, ".")
pylab.xlabel("Reaction time [s]")
pylab.ylabel("Probability density [1/s]")
pylab.grid()
pylab.show()
我刚刚回答了类似的问题here。我会在此处复制答案,因为我认为这个问题标题的信息量更大:
您可以使用均匀分布,边界从正态“转换”为均匀分布space(使用误差函数)并使用反误差函数将其转换为正态分布。
import matplotlib.pyplot as plt
import numpy as np
from scipy import special
mean = 0
std = 7
min_value = 0
max_value = 15
min_in_standard_domain = (min_value - mean) / std
max_in_standard_domain = (max_value - mean) / std
min_in_erf_domain = special.erf(min_in_standard_domain)
max_in_erf_domain = special.erf(max_in_standard_domain)
random_uniform_data = np.random.uniform(min_in_erf_domain, max_in_erf_domain, 10000)
random_gaussianized_data = (special.erfinv(random_uniform_data) * std) + mean
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].hist(random_uniform_data, 30)
axes[1].hist(random_gaussianized_data, 30)
axes[0].set_title('uniform distribution samples')
axes[1].set_title('erfinv(uniform distribution samples)')
plt.show()
我最近 运行 遇到了类似的问题。
为了解决这个问题并使我的 min/max 保持在合理的范围内,我刚刚创建了一些 if 语句来捕获任何超过实际最小值和最大值的数字。
if value <0:
value = abs(value)
elif value >15:
value - 15 = diff
value = 15-diff
这对我来说足够接近了。
顺便说一句,有人向我建议我可以在 python 中使用半正态分布来设置最小和最大点,使用 0 到无穷大: halfnorm.rvs()
0 似乎截断了最小值,但是我不知道如何处理无穷大。
我想在正态分布中生成 0 - 15 的数字生成器,但由于分布限制的性质,很难找到一个不超过最大值或低于最小值的函数。
我会尝试使用 beta 分布:https://en.wikipedia.org/wiki/Beta_distribution。它非常简单(例如集成)并且能够拟合典型的反应时间分布。
现在的问题是如何针对固定的 α 和 β 参数有效地进行采样……scipy
已经为我们完成了:https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.beta.html
编辑:出于评论和好奇心,这里是一个示例,绘制了 10 个样本和 1000 个值的直方图:
from scipy.stats import beta
from numpy import histogram
import pylab
max_time = 3
min_time = 0.5
a, b = 2, 7
dist = beta(a, b)
for _ in range(10):
sample = min_time + dist.rvs(size=1000) * (max_time - min_time)
his, bins = histogram(sample, bins=20, density=True)
pylab.plot(bins[:-1], his, ".")
pylab.xlabel("Reaction time [s]")
pylab.ylabel("Probability density [1/s]")
pylab.grid()
pylab.show()
我刚刚回答了类似的问题here。我会在此处复制答案,因为我认为这个问题标题的信息量更大:
您可以使用均匀分布,边界从正态“转换”为均匀分布space(使用误差函数)并使用反误差函数将其转换为正态分布。
import matplotlib.pyplot as plt
import numpy as np
from scipy import special
mean = 0
std = 7
min_value = 0
max_value = 15
min_in_standard_domain = (min_value - mean) / std
max_in_standard_domain = (max_value - mean) / std
min_in_erf_domain = special.erf(min_in_standard_domain)
max_in_erf_domain = special.erf(max_in_standard_domain)
random_uniform_data = np.random.uniform(min_in_erf_domain, max_in_erf_domain, 10000)
random_gaussianized_data = (special.erfinv(random_uniform_data) * std) + mean
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].hist(random_uniform_data, 30)
axes[1].hist(random_gaussianized_data, 30)
axes[0].set_title('uniform distribution samples')
axes[1].set_title('erfinv(uniform distribution samples)')
plt.show()
我最近 运行 遇到了类似的问题。
为了解决这个问题并使我的 min/max 保持在合理的范围内,我刚刚创建了一些 if 语句来捕获任何超过实际最小值和最大值的数字。
if value <0:
value = abs(value)
elif value >15:
value - 15 = diff
value = 15-diff
这对我来说足够接近了。