【问题标题】:How to create a vector containing a (artificially generated) Guassian (normal) distribution?如何创建包含(人工生成的)高斯(正态)分布的向量?
【发布时间】:2012-06-15 02:01:24
【问题描述】:

如果我有数据(每日股票图表是一个很好的例子,但它可以是任何东西),其中我只知道 X 单位销售的范围(高 - 低),但我不知道确切的价格出售的任何给定物品。为简单起见,假设价格范围包含足够的桶(例如,40 美分范围内的 41 美分增量)以使这种分布可行。如何分配这些项目以形成存储在向量中的正常钟形曲线?它不必是完美的,而是现实的。

我(非常)天真的想法是假设由于随机数应该形成正态分布,我可以做一些像二进制 RNG 这样的事情。例如,如果有 40 个存储桶,那么如果 '0' 出现 40 次,则第 0 个存储桶会递增,如果连续出现 '1' 次,则第 39 个存储桶会递增。如果“1”出现 20 次,则它位于向量的中间。对每个项目执行此操作,直到计算完 X 个单位。这可能是正确的,也可能不是正确的,并且在任何情况下似乎都比必要的效率低得多。我正在寻找更明智的东西。

这不是作业,只是一直困扰着我的一个问题,我的统计数据达不到标准。大多数文献似乎都在分析已经存在的分布,而不是关于如何人为地创建分布。

我想用 C++ 写这个,所以用 R 或 matlab 或其他东西预先打包的解决方案对我来说不是太有用。

谢谢。我希望这是有道理的。

【问题讨论】:

  • “我(非常)幼稚的想法是假设随机数应该形成正态分布” - 这真的不是真的。但是,您可以使用算法从正态分布(实际上是从许多统计分布)生成值。
  • 您是否有可能尝试创建一个高斯分布的直方图,其中每个 bin 的频率计数存储为向量的元素??
  • 为什么不使用 Boost 随机生成器库?还是新的 C++11 随机库?
  • 查看Boost.Random docs - C++11 版本应该相同,但在std 命名空间中。
  • 顺便说一句,在我看来,二项式分布更适合您的问题。二项式“大致”呈正态,但比正态更适合您的桶模型,因为它表示一组离散值的概率。

标签: c++ algorithm math statistics


【解决方案1】:

大多数文献似乎都是关于分析已经存在的分布,而不是关于如何人为地创建分布。

有大量关于如何创建的文献。 Box-Muller 变换、Marsaglia 极坐标法(Box-Muller 的一种变体)和 Ziggurat 算法是三个。 (谷歌这些条款)。两种 Box-Muller 方法都易于实现。

更好的是,只需使用已经存在的随机生成器来实现这些算法之一。 boost 和新的 C++11 都有这样的包。

【讨论】:

  • 留给 Boost 吧!快速浏览后,这似乎可以满足我的需要。非常感谢!
【解决方案2】:

您描述的算法依赖于中心极限定理,该定理说定义为属于 相同 分布的n 随机变量之和的随机变量在以下情况下趋于接近正态分布n 增长到无穷大。来自计算机 PRNG 的均匀分布的伪随机变量构成了这个一般定理的一个特例。

要获得更有效的算法,您可以将概率密度函数视为某种空间扭曲,它在中间扩展实轴并将其收缩到末端。

令 F: R -> [0:1] 是正态分布的累积函数,invF 是它的逆函数,x 是均匀分布在 [0:1] 上的随机变量,那么 invF(x) 将是一个正态分布分布随机变量。

实现这一点只需能够计算 invF(x)。不幸的是,这个函数不能用初等函数来表达。实际上,它是非线性微分方程的解。但是,您可以使用牛顿法有效地求解方程 x = F(y)。

我所描述的是逆变换方法的简化表示。这是一种非常通用的方法。有更有效的从正态分布采样的专门算法。 David Hammen 的回答中提到了这些。

【讨论】:

  • 谢谢德米特里。我可能要在夏天剩下的时间里才能完全理解你的回答,但我期待着回报。
猜你喜欢
  • 2010-12-13
  • 1970-01-01
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-16
相关资源
最近更新 更多