c# - sacar - Cómo calcular una desviación estándar
media y desviacion estandar (6)
Dados los valores atípicos, es posible que el rango intercuartil sea más útil que la desviación estándar. Esto es simple de calcular: simplemente ordene los números y encuentre la diferencia de los valores en el percentil 75 y en el percentil 25.
Esta pregunta ya tiene una respuesta aquí:
- Desviación estándar en LINQ 5 respuestas
double[] someDoubles = { 34.6, 45.1, 55.5, 78.5, 84.66, **1400.32**, 99.04, 103.99 };
Este código anterior es una muestra breve de un comportamiento inesperado de un algoritmo acumulativo (ver el valor en negrita). En realidad, esta es una clase que también tiene una fecha con cada valor.
C # Calcular una desviación? ¿Algoritmo que ordena las filas que rompen la cadena acumulativa?
Los consejos son de ayuda,
[INSERTAR]
Para aclarar, esto es sobre tres cosas.
El rendimiento es realmente importante en este tema.
Primero: Exploración rápida si los valores siguen un patrón acumulativo.
Segundo: verifique si todos los valores entran en una desviación razonable.
Tercero: señalar y hacer el manejo de errores.
Esta pregunta es sobre el primero y el segundo.
En VB.Net, código para la desviación estándar, Z-Score y NormSDist. He cortado y pegado desde el código de trabajo y lo he modificado para que sea más genérico. Puede que haya introducido problemas. Además, no soy un chico de matemáticas, así que ten cuidado.
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
Para calcular la desviación estándar puede utilizar este código. Tomado directamente de Calcular desviación estándar de variables dobles en C # por Victor Chen.
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));
}
Este enlace al sitio de Victor ya no funciona, pero aún se incluye para ayudar a mantener la atribución.
Si estás en .NET 4.0, los siguientes enlaces pueden ser útiles
Desviación estándar en LINQ
http://msdn.microsoft.com/en-us/library/dd456873.aspx
Usando lambdas
double average = someDoubles.Average();
double sumOfSquaresOfDifferences = someDoubles.Select(val => (val - average) * (val - average)).Sum();
double sd = Math.Sqrt(sumOfSquaresOfDifferences / someDoubles.Length);
La variable sd tendrá la desviación estándar.
Si tiene una List<double>
, use someDoubles.Count
en la última línea para el código en lugar de someDoubles.Length
.
Ya tiene algunas buenas respuestas para calcular la desviación estándar, pero me gustaría agregar el algoritmo de Knuth para calcular la varianza a la lista. El algo de Knuth realiza el cálculo en una sola pasada sobre los datos. La desviación estándar es solo la raíz cuadrada de la varianza, como se señaló anteriormente. El algoritmo de Knuth también le permite calcular valores intermedios de la variación a medida que avanza, si eso resulta útil.
Re: "Escaneo rápido si los valores siguen un patrón acumulativo", si se espera que sus datos crezcan linealmente, sugeriría calcular una media y una varianza para la diferencia entre elementos sucesivos (10.5, 10.4 y 23.0 serían los tres primeros valores de diferencia de sus datos). Luego encuentre valores atípicos de estos valores de diferencia en lugar de los puntos de datos. Esto hará que los valores de datos anómalos como 1400.32 en su ejemplo sean mucho más evidentes, especialmente cuando los datos finalmente crezcan lo suficiente como para que 1400 se acerque a la media.