Как рассчитать стандартное отклонение [массив]
double[] someDoubles = { 34.6, 45.1, 55.5, 78.5, 84.66, **1400.32**, 99.04, 103.99 };
Этот код, приведенный выше, представляет собой короткую интерпретацию непредвиденного поведения кумулятивного алгоритма (см. жирное значение). В реальности это класс, который также содержит дату с каждым значением.
С# Вычислить отклонение?
Алгоритм, который сортирует строки, которые разбивают кумулятивную цепочку?
Советы помогают,
[ВСТАВИТЬ]
Чтобы прояснить, речь идет о трех вещах
Производительность действительно важна в этой теме.
Сначала: Быстрое сканирование, если значения соответствуют кумулятивному шаблону.
Второе: Проверьте, все ли значения соответствуют разумному отклонению.
Третий: Укажите и выполните обработку ошибок.
Этот вопрос касается первого и второго.
Ответы
Ответ 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 будет близким к среднему.
Ответ 5
Если вы используете .NET 4.0, следующие ссылки могут быть полезны
Стандартное отклонение в LINQ
http://msdn.microsoft.com/en-us/library/dd456873.aspx
Ответ 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