使用Scipy生成偏斜分布的随机变量

4
尝试从SciPy中的分布中随机抽取一个数字,就像使用stats.norm.rvs一样。但是,我想从我拥有的经验分布中获取数字-它是一个偏斜的数据集,我想将偏斜和峰度纳入我正在绘制的分布中。理想情况下,我想只调用stats.norm.rvs(loc = blah,scale = blah,size = blah),然后除了平均值和方差之外还设置偏斜和峰度。norm函数需要一个'moments'参数,其中包含一些排列方式的'mvsk',其中s和k代表偏斜和峰度,但显然这只是要求从rv计算出s和k,而我想首先将s和k建立为分布的参数。
无论如何,我不是任何统计专家,也许这是一个简单或误导人的问题。感激任何帮助。
编辑:如果四个矩不足以很好地定义分布,是否有其他方法可以绘制与看起来像这样的经验分布一致的值:http://i.imgur.com/3yB2Y.png
4个回答

1
正态分布只有两个参数,即均值和方差。有一些正态分布的扩展,具有4个参数,包括偏度和峰度。一个例子是Gram-Charlier扩展,但据我所知,scipy中只提供了pdf而没有rvs。
作为替代方案,scipy.stats中有一些具有4个参数的分布,如johnsonsu,它们是灵活的,但具有不同的参数化。
然而,在您的示例中,分布是针对大于零的值,因此近似正态分布效果不佳。正如安德鲁建议的那样,我认为您应该查看scipy.stats中具有下限为零的分布,例如gamma,您可能会找到类似的东西。
另一种选择是,如果您的样本足够大,可以使用gaussian_kde,它也可以创建随机数。但是,gaussian_kde也不适用于具有有限边界的分布。

1

如果您不担心进入分布的尾部,并且数据是浮点数,则可以从经验分布中进行采样。

  • 对数据进行排序。
  • 在数据前面添加一个0。
  • 令N表示此数据数组的长度
  • 计算q=scipy.rand()*N
  • idx=int(q); di=q-idx
  • xlo=data_array[idx], xhi=data_array[idx+1];
  • 返回xlo+(xhi-xlo)*di

基本上,这是在线性插值经验CDF以获得随机变量。

两个潜在问题是(1)如果您的数据集很小,则可能无法很好地表示分布,(2)您将无法生成大于现有数据集中最大值的值。

要超越这些限制,您需要查看参数分布,例如上面提到的伽马分布。


0

0

如果需要的话,可以将短答案替换为其他发行版:

n = 100
a_b = [rand() for i in range(n)]
a_b.sort()
# len(a_b[:int(n*.8)])
c = a_b[int(n*.8)]
print c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接