Подтвердить что ты не робот

Как рассчитать стандартное отклонение [массив]

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

Этот код, приведенный выше, представляет собой короткую интерпретацию непредвиденного поведения кумулятивного алгоритма (см. жирное значение). В реальности это класс, который также содержит дату с каждым значением.

С# Вычислить отклонение? Алгоритм, который сортирует строки, которые разбивают кумулятивную цепочку?

Советы помогают,

[ВСТАВИТЬ]

Чтобы прояснить, речь идет о трех вещах
Производительность действительно важна в этой теме.

Сначала: Быстрое сканирование, если значения соответствуют кумулятивному шаблону.
Второе: Проверьте, все ли значения соответствуют разумному отклонению.
Третий: Укажите и выполните обработку ошибок.

Этот вопрос касается первого и второго.

4b9b3361

Ответ 1

Используя 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.

Ответ 2

Чтобы рассчитать стандартное отклонение, вы можете использовать этот код. Взято непосредственно из "Вычислить стандартное отклонение двойных переменных в С#" Виктора Чена.

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));  
}  

Ссылка на сайт Виктора больше не работает, но по-прежнему включена, чтобы помочь сохранить атрибуцию.

Ответ 3

Учитывая выбросы, вы можете найти межквартильный диапазон более полезным, чем стандартное отклонение. Это просто вычислить: просто отсортируйте числа и найдите разницу значений в 75-м процентиле и 25-м процентиле.

Ответ 4

У вас уже есть хорошие ответы на расчет стандартного отклонения, но я хотел бы добавить алгоритм Кнута для вычисления дисперсии в списке. Knuth algo выполняет вычисления за один проход по данным. Как уже указывалось выше, стандартное отклонение является просто квадратным корнем дисперсии. Алгоритм Кнута также позволяет вам вычислять промежуточные значения дисперсии по мере продвижения, если это окажется полезным.

Re: "Быстрое сканирование, если значения соответствуют кумулятивной схеме", если ваши данные будут расти линейно, я бы предложил вычислить среднее значение и дисперсию для разницы между последовательными элементами ( 10.5, 10.4 и 23.0 будут первыми тремя значениями разностей из ваших данных). Затем найдите выбросы этих значений разности вместо точек данных. Это сделает аномальные значения данных, такие как 1400.32 в вашем примере, намного более очевидными, особенно когда данные в конечном итоге станут настолько большими, что 1400 будет близким к среднему.

Ответ 6

В 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 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