double[] someDoubles = { 34.6, 45.1, 55.5, 78.5, 84.66, **1400.32**, 99.04, 103.99 };
Ce code ci-dessus est un exemple abrégé d'un comportement inattendu d'un algorithme cumulatif (voir la valeur en gras). En réalité, il s'agit d'une classe qui contient également une date avec chaque valeur.
C # Calculer un écart? Un algorithme qui trie les lignes qui rompt la chaîne cumulative?
Les conseils sont utiles,
[INSÉRER]
Pour clarifier, il s'agit de trois choses
Les performances sont vraiment importantes sur ce sujet.
First: Fast-Scan si les valeurs suivent un modèle cumulatif.
Second: Vérifiez si toutes les valeurs sont dans un écart raisonnable.
Troisième: Soulignez et faites la gestion des erreurs.
Cette question concerne la première et la seconde.
Utilisation de LINQ:
double average = someDoubles.Average();
double sumOfSquaresOfDifferences = someDoubles.Select(val => (val - average) * (val - average)).Sum();
double sd = Math.Sqrt(sumOfSquaresOfDifferences / someDoubles.Length);
La variable sd
aura l'écart type.
Si tu as un List<double>
, puis utilisez someDoubles.Count
dans la dernière ligne pour le code au lieu de someDoubles.Length
.
Pour calculer l'écart type, vous pouvez utiliser ce code. Tiré directement de Calculer l'écart type des variables doubles en C # par 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));
}
Ce lien vers le site de Victor ne fonctionne plus, mais est toujours inclus pour aider à maintenir l'attribution.
Étant donné les valeurs aberrantes, vous pourriez trouver la plage interquartile plus utile que l'écart-type. C'est simple à calculer: il suffit de trier les nombres et de trouver la différence des valeurs au 75e centile et au 25e centile.
Vous avez déjà de bonnes réponses sur le calcul de l'écart-type, mais j'aimerais ajouter algorithme de Knuth pour calculer la variance à la liste. L'algo de Knuth effectue le calcul en un seul passage sur les données. L'écart type n'est alors que la racine carrée de la variance, comme indiqué ci-dessus. L'algorithme de Knuth vous permet également de calculer des valeurs intermédiaires de la variance au fur et à mesure, si cela s'avère utile.
Re: "Fast-Scan si les valeurs suivent un modèle cumulatif", si vos données devraient croître linéairement, je suggère de calculer une moyenne et une variance pour la différence entre les éléments successifs (10,5, 10,4 et 23,0 seraient les trois premières valeurs de différence de vos données). Recherchez ensuite les valeurs aberrantes de ces valeurs de différence au lieu des points de données. Cela rendra les valeurs de données anormales comme 1400.32 dans votre exemple beaucoup plus évidentes, en particulier lorsque les données deviennent finalement suffisamment grandes pour que 1400 soit proche de la moyenne.
Si vous êtes sur .NET 4.0, les liens suivants peuvent être utiles
Écart type dans LINQ
http://msdn.Microsoft.com/en-us/library/dd456873.aspx
Dans VB.Net, codez pour l'écart-type, le score Z et NormSDist. J'ai coupé et collé du code de travail et l'ai modifié pour qu'il soit plus générique. J'ai peut-être introduit des problèmes. De plus, je ne suis pas un mathématicien alors méfiez-vous.
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