繁体   English   中英

生成峰度大于 3 的随机正态分布

[英]Generate random normal distribution with kurtosis greater than 3

正态分布的峰度为 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

在此处输入图片说明

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

在此处输入图片说明

随机法线,肥尾在 0.01-0.10 之间

???

由于峰度不是正态分布函数的参数之一,因此您必须使用另一种方法来生成近似正态分布的函数。 它变得复杂。 看看这个: https : //stats.stackexchange.com/questions/43482/transformation-to-increase-kurtosis-and-skewness-of-normal-rv

上面的链接给出了使用 R (sigh) 代码的示例,但我认为它足够简单,可以让您在 Python 中编写等效代码。 这是我所知道的几种扩展(即功能分层)之一,可以让您实现这一目标。

不幸的是,我知道没有简单的解决方案。

正态分布的峰度始终为 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM