如何计算标准差[数组]

时间:2011-03-17 08:11:31

标签: c# .net algorithm

double[] someDoubles = { 34.6, 45.1, 55.5, 78.5, 84.66, **1400.32**, 99.04, 103.99 };

以上代码是累积算法意外行为的简短样本(请参阅粗体值)。实际上,这是一个类,它还包含每个值的日期。

C#计算偏差? 排序打破累积链的行的算法?

建议有帮助,

[INSERT]

澄清一下,这是关于三件事 在这个主题上,性能非常重要。

首先:如果值遵循累积模式,则快速扫描。
第二:检查所有值是否合理偏差。
第三:指出并执行错误处理。

这个问题是关于第一个和第二个问题。

6 个答案:

答案 0 :(得分:61)

使用LINQ:

double average = someDoubles.Average();
double sumOfSquaresOfDifferences = someDoubles.Select(val => (val - average) * (val - average)).Sum();
double sd = Math.Sqrt(sumOfSquaresOfDifferences / someDoubles.Length); 

sd变量将具有标准偏差。

如果您有List<double>,请在代码的最后一行使用someDoubles.Count代替someDoubles.Length

答案 1 :(得分:14)

要计算标准偏差,您可以使用此代码。直接取自Victor Chen在C#中计算双变量的标准偏差。

private double getStandardDeviation(List<double> doubleList)  
{  
   double average = doubleList.Average();  
   double sumOfDerivation = 0;  
   foreach (double value in doubleList)  
   {  
      sumOfDerivation += (value) * (value);  
   }  
   double sumOfDerivationAverage = sumOfDerivation / (doubleList.Count - 1);  
   return Math.Sqrt(sumOfDerivationAverage - (average*average));  
}  

link to Victor's site不再有效,但仍然包含在内以帮助维护归因。

答案 2 :(得分:3)

鉴于异常值,您可能会发现interquartile range比标准偏差更有用。这很容易计算:只需对数字进行排序,找出第75百分位数和第25百分位数值的差异。

答案 3 :(得分:3)

您已经有一些关于计算标准差的好答案,但我想添加Knuth's algorithm来计算列表的方差。 Knuth的算法一次性通过数据执行计算。如上所述,标准偏差就是方差的平方根。 Knuth的算法还允许您随时计算方差的中间值,如果证明有用的话。

Re:“快速扫描,如果值遵循累积模式,”如果您的数据预计会线性增长,我建议计算连续元素之间差异的均值和方差( 10.5,10.4和23.0将是您数据中的前三个差值)。然后找出这些差值的异常值而不是数据点。这将使您的示例中的异常数据值(如1400.32)更加明显,尤其是当数据最终变得足够大以至于1400接近均值时。

答案 4 :(得分:2)

如果您使用的是.NET 4.0,则下一个链接可以提供帮助 Standard Deviation in LINQ
http://msdn.microsoft.com/en-us/library/dd456873.aspx

答案 5 :(得分:0)

在VB.Net中,标准偏差,Z-Score和NormSDist的代码。我已经剪切并粘贴了工作代码,并将其修改为更通用。我可能已经介绍了问题。另外,我不是一个数学家,所以要小心。

Public Property SumOfSquaresOfDifferences As Double ' calculated elsewhere

Public ReadOnly Property StdOfTotalMatches As Double
    Get
        If NumberOfTickets = 0 Then Return 0
        Return Math.Sqrt(SumOfSquaresOfDifferences / NumberOfTickets)
    End Get
End Property

Public ReadOnly Property zScoreOfTotalMatches As Double
    Get
        If StdOfTotalMatches = 0 Then Return 0
        Return (TotalMatches / NumberOfTickets - AverageMatches) / StdOfTotalMatches
    End Get
End Property

Public ReadOnly Property NormSDistOfTotalMatches As Double
    Get
        Return NormSDist(zScoreOfTotalMatches)
    End Get
End Property

Public ReadOnly Property AverageMatches As Double
    Get
        Return If(NumberOfTickets, TotalMatches / NumberOfTickets, 0)
    End Get
End Property

Shared Function NormSDist(ByVal zScore As Double) As Double
    Dim ErfResult As Double = Erf(zScore / Math.Sqrt(2.0))
    Dim res As Double = ErfResult + (1 - ErfResult) / 2
    Return If(zScore < 0, 1 - res, res)
End Function

Shared Function Erf(ByVal n As Double) As Double

    Dim t As Double = 1.0 / (1.0 + 0.5 * Math.Abs(n))

    ' use Horner's method - thanks to http://bytes.com/topic/c-sharp/answers/240995-normal-distribution
    Dim d As Double = 1 - t * Math.Exp(-n * n - 1.26551223 + _
    t * (1.00002368 + _
    t * (0.37409196 + _
    t * (0.09678418 + _
    t * (-0.18628806 + _
    t * (0.27886807 + _
    t * (-1.13520398 + _
    t * (1.48851587 + _
    t * (-0.82215223 + _
    t * (0.17087277))))))))))

    'Return If(d >= 0, d, 1 - d)
    Return d

End Function