Если вы хотите, чтобы усеченная норма поддерживалась на [lower, upper]
, используйте
X = stats.truncnorm(
(lower - mu) / sigma, (upper - mu) / sigma, loc=mu, scale=sigma)
Например, если вы хотите, чтобы усеченная норма поддерживалась на [31.399904, np.inf]
со средним значением 32 и стандартным отклонением 0,822358, тогда вы должны использовать
import scipy.stats as stats
import matplotlib.pyplot as plt
lower, upper = 31.399904, np.inf
mu, sigma = 32, 0.822358
X = stats.truncnorm(
(lower - mu) / sigma, (upper - mu) / sigma, loc=mu, scale=sigma)
N = stats.norm(loc=mu, scale=sigma)
data = X.rvs(10000)
fig, ax = plt.subplots(2, sharex=True)
ax[0].hist(data, density=True)
ax[1].hist(N.rvs(10000), density=True)
plt.show()
Верхняя гистограмма показывает распределение образца по усеченной норме, нижняя гистограмма показывает распределение образца по стандартной нормали сто же самое среднее и стандартное отклонение.
Если вы также хотите, чтобы среднее значение mu
равнялось левой конечной точке опоры, вы должны использовать
lower, upper = 31.399904, np.inf
mu, sigma = lower, 0.822358
Z = stats.truncnorm.rvs((lower - mu) / sigma, (upper - mu) / sigma, loc=mu, scale=sigma)
, что эквивалентнона
Z = stats.truncnorm.rvs(0, np.inf, loc=31.399904, scale=0.822358)
Например,
In [47]: np.random.seed(1234)
In [49]: stats.truncnorm.rvs(0, np.inf, loc=31.399904, scale=0.822358)
Out[49]: 31.599232630594255
Проблема с
Z = truncnorm.rvs(a = 31.399904/0.822358, b = np.inf, loc = 31.399904, scale = 0.822358)
состоит в том, что среднее значение находится в loc = 31.3999904, но слеваконечная точка составляет около 38,2:
In [51]: a = 31.399904/0.822358; a
Out[51]: 38.18276711602489
Наиболее вероятное значение усеченного элемента должно быть средним, но среднее значение выходит за пределы опоры [38.2, np.inf]
.Это противоречие приводит к странному поведению.