Генерация случайного нормального распределения с эксцессом больше 3 - PullRequest
2 голосов
/ 14 января 2020

В нормальном распределении эксцесс равен 3. При увеличении выбросов в распределении хвосты становятся "жирными", а эксцесс увеличивается более чем на 3.

Как создать случайное распределение между двумя числами с эксцессом больше 3 (предпочтительно около 5-7)?

Импорт

import numpy as np
import scipy.stats import kurtosis

Случайная единообразная между 0,01-0,10

# Random Uniform Distribution
runif = np.random.uniform(0.01, 0.10, 10000)

kurtosis(runif, fisher=False)

1.8124891901330156

enter image description here

Случайная норма между 0,01-0,10

lower = 0.01
upper = 0.10
mu = (upper)/2
sigma = 0.01
N = 10000
retstats = scipy.stats.truncnorm.rvs((lower-mu)/sigma,(upper-mu)/sigma,loc=mu,scale=sigma,size=N)

mean = .05
stdev = .01  # 99.73% chance the sample will fall in your desired range

values = [gauss(mean, stdev) for _ in range(10000)]

kurtosis(values, fisher=False)

3.015004351756201

enter image description here

Случайный Нормальный с толстыми хвостами в диапазоне 0,01-0,10

???

Ответы [ 2 ]

2 голосов
/ 14 января 2020

Нормальное распределение всегда имеет эксцесс 3. Равномерное распределение имеет эксцесс 9/5. Длиннохвостые распределения имеют эксцесс, превышающий 3. Например, у Лапласа эксцесс 6. [Обратите внимание, что обычно эти распределения определяются в терминах избыточного эксцесса, который равен фактическому эксцессу минус 3.] См. Таблицу здесь: http://mathworld.wolfram.com/KurtosisExcess.html

Однако, отрезав хвосты, вы только уменьшите эксцесс. Обрезая хвосты, невозможно создать нормальное распределение с эксцессом выше 3. Чтобы создать распределение с ограниченным диапазоном и высоким эксцессом, вам необходимо убедиться, что срез имеет минимальное влияние на хвосты, и начать с длиннохвостый (ненормальный) распределение. В разговорной речи вам понадобится очень остроконечный дистрибутив. Я создаю один ниже, используя Лапласа с небольшим параметром экспоненциального затухания.

import numpy as np                                                                       
from scipy.stats import kurtosis                                                         

min_range = 0.01                                                                         
max_range = 0.10                                                                         
midpoint = (max_range + min_range)/2                                                     
samples = 10000                                                                          

def filter_tails(x):                                                                     
    return x[(x >= min_range) & (x <= max_range)]                                        

runif = np.random.uniform(min_range, max_range, samples)                                 
value = kurtosis(filter_tails(runif), fisher=False)                                      
print(f"uniform kurtosis = {value}")                                                     

sigma = 0.01                                                                             
runif = np.random.normal(midpoint, sigma, samples)                                       
value = kurtosis(filter_tails(runif), fisher=False)                                      
print(f"gaussian kurtosis = {value}")                                                    

exponential_decay = 0.001                                                                
runif = np.random.laplace(midpoint, exponential_decay, samples)                          
value = kurtosis(filter_tails(runif), fisher=False)                                      
print(f"laplace kurtosis = {value}")

Запустив скрипт, я получаю:

uniform kurtosis = 1.8011863970680828
gaussian kurtosis = 3.0335178694177785
laplace kurtosis = 5.76290423111418
2 голосов
/ 14 января 2020

Поскольку эксцесс не является одним из параметров функции нормального распределения, необходимо использовать другой метод, который генерирует функцию, аппроксимирующую нормальное распределение. Это становится сложным. Взгляните на это: https://stats.stackexchange.com/questions/43482/transformation-to-increase-kurtosis-and-skewness-of-normal-r-v

Ссылка выше дает примеры с использованием кода R (вздох), но я думаю, что это достаточно просто, чтобы позволить вам кодировать эквивалент в Python. Это одно из нескольких расширений (т. Е. Многоуровневых функций), которые, как мне известно, позволяют вам достичь этого.

К сожалению, я не знаю простого решения, о котором мне известно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...