J'ai besoin de savoir si un nombre par rapport à un ensemble de nombres est en dehors de 1 stddev de la moyenne, etc.
Réponses
Trop de publicités?Tandis que la somme des carrés de l'algorithme fonctionne bien la plupart du temps, il peut causer de graves ennuis si vous êtes aux prises avec de très grands nombres. En gros, vous pourriez finir avec un écart négatif...
De Plus, ne jamais, jamais, jamais, calculer a^2 comme pow(a,2), a * a est presque certainement plus rapide.
De loin la meilleure façon de calculer un écart-type est de Welford de la méthode. Mes C est très rouillé, mais il pourrait ressembler à quelque chose comme:
public static double StandardDeviation(List<double> valueList)
{
double M = 0.0;
double S = 0.0;
int k = 1;
foreach (double value in valueList)
{
double tmpM = M;
M += (value - tmpM) / k;
S += (value - tmpM) * (value - M);
k++;
}
return Math.Sqrt(S / (k-2));
}
Si vous avez l' ensemble de la population (par opposition à un échantillon de la population), puis utilisez return Math.Sqrt(S / (k-1));
.
EDIT: j'ai mis à jour le code en fonction de Jason remarques...
EDIT: j'ai aussi mis à jour le code en fonction de Alex remarques...
La réponse acceptée par Jaime est excellente, sauf que vous devez diviser par k-2 à la dernière ligne (vous devez diviser par "number_of_elements-1"). Mieux encore, commencez k à 0:
public static double StandardDeviation(List<double> valueList)
{
double M = 0.0;
double S = 0.0;
int k = 0;
foreach (double value in valueList)
{
k++;
double tmpM = M;
M += (value - tmpM) / k;
S += (value - tmpM) * (value - M);
}
return Math.Sqrt(S / (k-1));
}
Vous pouvez éviter de faire deux passes sur les données en accumulant la moyenne et la moyenne des carrés
cnt = 0
mean = 0
meansqr = 0
loop over array
cnt++
mean += value
meansqr += value*value
mean /= cnt
meansqr /= cnt
et formant
sigma = sqrt(meansqr - mean^2)
Un facteur d' cnt/(cnt-1)
est souvent approprié ainsi.
BTW-- Le premier passage sur les données de Demi et McWafflestix les réponses sont cachées dans les appels d' Average
. Ce genre de chose est certainement trivial sur une petite liste, mais si la liste dépasse la taille de la mémoire cache, ou même l'ensemble de travail, cela devient une offre promo.
Extrait de code:
public static double StandardDeviation(List<double> valueList)
{
if (valueList.Count < 2) return 0.0;
double sumOfSquares = 0.0;
double average = valueList.Average(); //.NET 3.0
foreach (double value in valueList)
{
sumOfSquares += Math.Pow((value - average), 2);
}
return Math.Sqrt(sumOfSquares / (valueList.Count - 1));
}
Voici le code pour calculer un écart-type pour un ensemble de nombres. Une fois que vous avez cela, cela vous donne une limite supérieure et inférieure pour comparer le nombre.