如何使用boost正态分布类?

24

我正在尝试使用boost::normal_distribution来生成均值为0,标准差为1的正态分布。

以下代码不起作用,因为一些值超过了-1和1的范围(而且不应该超出)。请问有人可以指出我做错了什么吗?

#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>

int main()
{
  boost::mt19937 rng; // I don't seed it on purpouse (it's not relevant)

  boost::normal_distribution<> nd(0.0, 1.0);

  boost::variate_generator<boost::mt19937&, 
                           boost::normal_distribution<> > var_nor(rng, nd);

  int i = 0; for (; i < 10; ++i)
  {
    double d = var_nor();
    std::cout << d << std::endl;
  }
}

我的电脑上的结果是:

0.213436
-0.49558
1.57538
-1.0592
1.83927
1.88577
0.604675
-0.365983
-0.578264
-0.634376

正如您所看到的,所有值都不在-1和1之间。

提前感谢大家!

编辑: 当你有截止日期并且避免在实践之前学习理论时,就会发生这种情况。


7
我已经忘记了大部分统计学知识,但是方差(是分布构造函数的第二个参数)肯定没有指定范围的绝对截止点?它是衡量事物分散程度的一种度量。 - anon
@Neil Butterworth:构造函数中的第二个参数是标准差(方差的平方根)。 - jason
好吧,我确实说过我几乎什么都忘了! - anon
感谢提供这个示例!它对于开始使用boost::normal_distribution类非常有帮助。我很高兴下面解释了统计问题。 - solvingPuzzles
1
这个例子非常有帮助!但我可以问一下,在 boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > var_nor(rng, nd); 中为什么要使用 &?我也在学习使用 boost。谢谢! - Vokram
@Vokram 我猜模板中的 boost::mt19937& 意味着使用对现有对象的引用,而不是复制它。 - William
2个回答

29
以下代码不起作用,因为某些值超过了-1和1(不应该超过)。有人能指出我做错了什么吗?
不是的,这是对正态分布标准差(构造函数中的第二个参数1)的误解。
正态分布是熟悉的钟形曲线。该曲线有效地告诉您值的分布情况。接近钟形曲线峰值的值比远离峰值的值更可能出现(分布的尾部)。
标准差告诉您值的分散程度。数字越小,值就越集中在平均值周围。数字越大,值就越分散。在下面的图像中,您可以看到红色曲线的方差(方差是标准差的平方)为0.2。将其与具有相同平均值但方差为1.0的绿色曲线进行比较。您可以看到绿色曲线中的值相对于红色曲线更分散。紫色曲线的方差为5.0,值甚至更分散。
因此,这就解释了为什么值不限于[-1, 1]。然而,一个有趣的事实是,68%的值始终在平均值的一个标准差内。因此,作为一个有趣的测试,请编写一个程序从具有平均值0和方差1的正态分布中绘制大量值,并计算在平均值的一个标准差内的数量。您应该得到一个接近68%的数字(更精确地说是68.2689492137%)。

alt text

1: 来自boost documentation:

normal_distribution(RealType mean = 0, RealType sd = 1);

构造一个均值为mean,标准差为sd的正态分布。


分析非常有帮助和有用。 - user4764898

8

您没有做错任何事情。对于正态分布,sigma指定了标准差,而不是范围。如果您生成足够的样本,您将看到约68%的样本落在区间[均值-标准差,均值+标准差]内,约95%在2个标准差内,而超过99%则在3个标准差内。


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