从数据中绘制具有正态分布叠加的直方图

时间:2014-11-25 18:28:28

标签: c# statistics oxyplot

我被要求在我们的数据上绘制一个正态分布覆盖的直方图。我们的数据是一系列无限范围的双打。接下来的想法是:

  1. 将我的所有值拆分为存储桶(我称之为代码中的步骤)
  2. 查找恰好位于每个存储桶中的所有值
  3. 计算存储桶中的项目数,并将其除以总体项目数
  4. 将mu计算为平均值(值)
  5. 将方差计算为avg([(每个值-mu)^ 2])
  6. 使用公式绘制叠加层:1. / Sqrt(2 * Pi * var)* e ^(( - (x - mean)^ 2/2 / var)
  7. 这是我到目前为止所写的内容:

    double[] values;
    const int StepsNumber = 30;
    // Choosing the size of each bucket
    double step = (values.Max() - values.Min())/StepsNumber;
    
    double mean = values.Average();
    double deviationSq = values.Select(x => Math.Pow(x - mean, 2)).Average();
    
    var bucketeer = new Dictionary<double, double>();
    for (double curr = values.Min(); curr <= values.Max(); curr += step)
    {
            // Counting the values that can be put in the bucket and dividing them on values.Count()
            var count = values.Where(x => x >= fromVal && x < fromVal + step).Count();
            bucketeer.Add(fromVal, count / values.Count());
    }
    
    // Then I build normal distribution overlay 
    var overlayData = new LineSeries();
    int x0 = values.Min();
    int x1 = values.Max();
    for (int i = 0; i < n; i++)
            {
                double x = x0 + (x1 - x0) * i / (n - 1);
                double f = 1.0 / Math.Sqrt(2 * Math.PI * varianceSq) * Math.Exp(-(x - mean) * (x - mean) / 2 / varianceSq);
                overlayData .Points.Add(new DataPoint(x, f));
            }
    
    // And draw everything
    
    plotModel.Series.Add(overlayData);
            foreach (var pair in bucketeer.OrderBy(x => x.Key))
            {
                columnSeries.Items.Add(new RectangleBarItem(pair.Key, 0, pair.Key + step, pair.Value));
            }
    plotModel.Series.Add(columnSeries);
    

    但结果看起来有点奇怪: My chart

    直方图似乎与叠加层不匹配。感觉我错过了什么 - 要么计算错误的桶,要么在数学上有错误。

2 个答案:

答案 0 :(得分:1)

这个问题现在很陈旧,但我在尝试做类似的事情时发现了这个问题,所以我会提出这个建议:

首先,varianceSq变量实际上应该是方差(或标准偏差的平方)。

其次,从平均值和标准偏差计算f的标准公式使得曲线的面积比其低1。要匹配直方图,您需要将值向上缩放直方图矩形的总面积

即。 y = f * (bar width * total of bar heights)

答案 1 :(得分:0)

嘿,谢谢你指出了正确的类型,以便首先建立一个像样的直方图。

我想说通过逐步通过数据库而不是单步执行值来对覆盖代码进行另一次破解。