вектор sampe точек из усеченного экспоненциального распределения с определенным средним - PullRequest
0 голосов
/ 06 ноября 2018

Я создаю усеченное экспоненциальное распределение:

from scipy.stats import truncexpon
truncexp = truncexpon(b = 8)

Теперь я хочу взять 8 точек из этого распределения, чтобы их среднее значение составляло приблизительно 4. Каков наилучший способ сделать это без создания огромной петли для случайной выборки, пока среднее значение не станет достаточно близким?

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Распределение truncexpon имеет три параметра: форму b, местоположение loc и масштаб scale. Поддержка дистрибутива: [x1, x2], где x1 = loc и x2 = shape*scale + loc. Решите последнее уравнение для shape, чтобы получить shape = (x2 - x1)/scale. Мы выберем параметр scale, чтобы среднее значение распределения было равно 4. Для этого мы можем использовать scipy.optimize.fsolve, примененный к функции шкалы, которая равна нулю, когда truncexpon.mean((x2 - x1)/scale, loc, scale) равно 4 .

Вот короткий сценарий для демонстрации:

import numpy as np
from scipy.optimize import fsolve
from scipy.stats import truncexpon


def func(scale, desired_mean, x1, x2):
    return truncexpon.mean((x2 - x1)/scale, loc=x1, scale=scale) - desired_mean


x1 = 1
x2 = 9

desired_mean = 4.0

# Numerically solve for the scale parameter of the truncexpon distribution
# with support [x1, x2] for which the expected mean is desired_mean.
scale_guess = 2.0
scale = fsolve(func, scale_guess, args=(desired_mean, x1, x2))[0]

# This is the shape parameter of the desired truncexpon distribution.
shape = (x2 - x1)/scale

print("Expected mean of the distribution is %6.3f" %
      (truncexpon.mean(shape, loc=x1, scale=scale),))
print("Expected standard deviation of the distribution is %6.3f" %
      (truncexpon.std(shape, loc=x1, scale=scale),))

# Generate a sample of size 8, and compute its mean.
sample = truncexpon.rvs(shape, loc=x1, scale=scale, size=8)
print("Mean of the sample of size %d is %6.3f" %
      (len(sample), sample.mean(),))

bigsample = truncexpon.rvs(shape, loc=x1, scale=scale, size=100000)
print("Mean of the sample of size %d is %6.3f" %
      (len(bigsample), bigsample.mean(),))

Типичный вывод:

Expected mean of the distribution is  4.000
Expected standard deviation of the distribution is  2.178
Mean of the sample of size 8 is  4.694
Mean of the sample of size 100000 is  4.002
0 голосов
/ 06 ноября 2018

Среднее значение является характеристикой вашего распределения. Если вы продолжите выборку значений, то эмпирическое среднее просто станет все ближе и ближе к аналитическому среднему.

Сципи может сказать вам среднее значение вашей усеченной экспоненты:

b = 8
truncexp = truncexpon(b)
truncexp.mean() # 0.99731539839326999

Вы можете использовать распределение для выборки и расчета эмпирического среднего значения:

num_samples = 100000
np.mean(truncexp.rvs(num_samples)) # 0.99465816346645264

Аналитическая формула для расчета среднего значения такова (вторая строка):

b = np.linspace(0.1, 20, 100)
m = 1/ ((1 - np.exp(-b)) / ((1 - (b + 1)*np.exp(-b))))

Если вы построите график, вы увидите, как ведет себя среднее значение для разных значений b.

enter image description here

Для b -> inf среднее значение будет стремиться к 1. Вы не найдете b со средним значением 4.

Если вы хотите произвести выборку из усеченной экспоненты со средним значением 4, вы можете просто масштабировать выборки. Это не даст вам сэмплы из исходного дистрибутива, но опять же, сэмплы из оригинального дистрибутива никогда не дадут вам среднее значение 4.

truncexp.rvs(num_samples) * 4 / truncexp.mean()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...