【发布时间】:2017-05-25 07:21:16
【问题描述】:
如果我使用从this SO question 修改的代码对样本进行标准偏差计算:
public double CalculateStandardDeviation(List<double> values, bool sample = false)
{
double mean = 0.0;
double sum = 0.0;
double stdDev = 0.0;
int count = 0;
foreach (double val in values)
{
count++;
double delta = val - mean;
mean += delta / count;
sum += delta * (val - mean);
}
if (1 < count)
stdDev = Math.Sqrt(sum / (count - (sample ? 1 : 0)));
return stdDev;
}
使用这个单元测试:
[Test]
public void Sample_Standard_Deviation_Returns_Expected_Value()
{
//original cite: http://warrenseen.com/blog/2006/03/13/how-to-calculate-standard-deviation/
double expected = 2.23606797749979;
double tolerance = 1.0 / System.Math.Pow(10, 13);
var cm = new CommonMath();//a library of math functions we use a lot
List<double> values = new List<double> { 4.0, 2.0, 5.0, 8.0, 6.0 };
double actual = cm.CalculateStandardDeviation(values, true);
Assert.That(actual, Is.EqualTo(expected).Within(tolerance));
}
测试通过,结果值在指定的容差范围内。
但是,如果我使用这个 Linq-ified 代码,它会失败,返回一个 2.5 的值(好像它是一个总体标准差):
double meanOfValues = values.Average();
double sumOfValues = values.Sum();
int countOfValues = values.Count;
double standardDeviationOfValues =
Math.Sqrt(sumOfValues / (countOfValues - (sample ? 1 : 0)));
return standardDeviationOfValues;
由于我从未统计过(所以请保持温和),列表中值的 Linq 化(这是一个词)似乎应该给我同样的结果,但他们没有,我不明白我做错了什么。 N 和 N-1 之间的决定动作在两者中是相同的,那为什么答案不一样呢?
【问题讨论】:
-
这里的样品有什么用?
-
你错过了一步:
var standardDeviationOfValues = Math.Sqrt(values.Select(v=>Math.Pow(v - meanOfValues,2)).Average());或者你不能使用sumOfValues但sumOfDeltasSquared,这是你没有计算出来的。无论哪种情况,当样本为假时,您当前的公式都会计算平均值/平均值,而不是标准偏差。 -
啊,感谢您的洞察力,这并不像我想象的那么简单。
标签: c# linq unit-testing statistics standard-deviation