3 回答
TA贡献1779条经验 获得超6个赞
虽然平方和算法在大多数情况下都可以正常工作,但是如果您要处理非常大的数字,可能会造成很大的麻烦。您基本上可能最终会得到负方差...
另外,永远不要永远将a ^ 2计算为pow(a,2),几乎可以肯定a * a更快。
到目前为止,计算标准差的最佳方法是韦尔福德方法。我的C非常生锈,但是看起来可能像这样:
public static double StandardDeviation(List<double> valueList)
{
double M = 0.0;
double S = 0.0;
int k = 1;
foreach (double value in valueList)
{
double tmpM = M;
M += (value - tmpM) / k;
S += (value - tmpM) * (value - M);
k++;
}
return Math.Sqrt(S / (k-2));
}
如果您拥有全部人口(而不是样本人口),请使用return Math.Sqrt(S / (k-1));。
编辑:我已经根据杰森的言论更新了代码...
编辑:我还根据亚历克斯的言论更新了代码...
TA贡献1836条经验 获得超13个赞
解决方案比Jaime的解决方案快10倍,但是请注意,正如Jaime指出的那样:
“虽然平方和算法在大多数情况下都可以正常工作,但是如果要处理非常大的数字,可能会造成很大的麻烦。基本上,您最终可能会得到负方差”
如果您认为要处理的是非常大的数字或数量非常大的数字,则应使用两种方法进行计算,如果结果相等,则可以确定可以使用“我的”方法。
public static double StandardDeviation(double[] data)
{
double stdDev = 0;
double sumAll = 0;
double sumAllQ = 0;
//Sum of x and sum of x²
for (int i = 0; i < data.Length; i++)
{
double x = data[i];
sumAll += x;
sumAllQ += x * x;
}
//Mean (not used here)
//double mean = 0;
//mean = sumAll / (double)data.Length;
//Standard deviation
stdDev = System.Math.Sqrt(
(sumAllQ -
(sumAll * sumAll) / data.Length) *
(1.0d / (data.Length - 1))
);
return stdDev;
}
TA贡献1777条经验 获得超3个赞
Jaime接受的答案很好,除了您需要在最后一行除以k-2(您需要除以“ number_of_elements-1”)。更好的是,将k从0开始:
public static double StandardDeviation(List<double> valueList)
{
double M = 0.0;
double S = 0.0;
int k = 0;
foreach (double value in valueList)
{
k++;
double tmpM = M;
M += (value - tmpM) / k;
S += (value - tmpM) * (value - M);
}
return Math.Sqrt(S / (k-1));
}
- 3 回答
- 0 关注
- 1476 浏览
添加回答
举报