Calcul du nouvel écart-type à l'aide de l'ancien écart-type après modification de l'ensemble de données

16

J'ai un tableau de n valeurs réelles, qui a la moyenne μold et l'écart type σold . Si un élément du tableau xi est remplacé par un autre élément xj , alors la nouvelle moyenne sera

μnew=μold+xjxin

L'avantage de cette approche est qu'elle nécessite un calcul constant quelle que soit la valeur de n . Existe-t-il une approche pour calculer σnew utilisant σold comme le calcul de μnew utilisant μold ?

utilisateur
la source
Est-ce des devoirs? Une tâche très similaire a été demandée dans notre cours de statistique mathématique ...
krlmlr
2
@ user946850: Non, ce ne sont pas des devoirs. Je mène ma thèse sur l' algorithme évolutionnaire . Je veux utiliser l'écart-type comme mesure de la diversité de la population. Je cherche juste une solution plus efficace.
utilisateur
1
La SD est la racine carrée de la variance, qui est juste la valeur quadratique moyenne (ajustée par un multiple de la moyenne quadratique, que vous savez déjà comment mettre à jour). Par conséquent, les mêmes méthodes utilisées pour calculer une moyenne mobile peuvent être appliquées sans aucun changement fondamental pour calculer une variance courante. En fait, des statistiques beaucoup plus sophistiquées peuvent être calculées en ligne en utilisant les mêmes idées: voir les discussions sur stats.stackexchange.com/questions/6920 et stats.stackexchange.com/questions/23481 , par exemple.
whuber
1
@whuber: Ceci est mentionné dans l'article Wikipedia pour Variance , mais aussi avec une note sur l'annulation catastrophique (ou la perte de signification) qui peut survenir. Est-ce surestimé ou un vrai problème pour la variance en cours?
krlmlr
Voilà une excellente question. Si vous accumulez les écarts naïvement, sans les centrer au préalable, vous pouvez en effet avoir des ennuis. Le problème se produit lorsque les nombres sont énormes mais que leur variance est faible. Par exemple, considérons une série de mesures précises de la vitesse de la lumière en m / s, comme dans 299792458.145, 299792457.883, 299792457.998, ...: leur variance, qui est d'environ 0,01, est si petite par rapport à leurs carrés, qui est d'environ , qu'un calcul imprudent (même en double précision) entraînerait une variance nulle: tous les chiffres significatifs disparaîtraient. 1017
whuber

Réponses:

7

Une section de l'article de Wikipédia sur "Algorithmes de calcul de la variance" montre comment calculer la variance si des éléments sont ajoutés à vos observations. (Rappelez-vous que l'écart-type est la racine carrée de la variance.) Supposons que vous ajoutez à votre tableau, puisxn+1

σnew2=σold2+(xn+1μnew)(xn+1μold).

EDIT : La formule ci-dessus semble être erronée, voir le commentaire.

Maintenant, remplacer un élément signifie ajouter une observation et en supprimer une autre; les deux peuvent être calculés avec la formule ci-dessus. Cependant, gardez à l'esprit que des problèmes de stabilité numérique peuvent survenir; l'article cité propose également des variantes numériquement stables.

Pour dériver la formule par vous-même, calculez utilisant la définition de la variance de l'échantillon et remplacez μ n e w par la formule que vous avez donnée le cas échéant. Cela vous donne σ 2 n e w - σ 2 o l d à la fin, et donc une formule pour σ n e w étant donné σ o l d et(n1)(σnew2σold2)μnewσnew2σold2σnewσold . Dans ma notation, je suppose que vous remplacez l'élément xμold par x n :xnxn

σ2=(n1)1k(xkμ)2(n1)(σnew2σold2)=k=1n1((xkμnew)2(xkμold)2)+ ((xnμnew)2(xnμold)2)=k=1n1((xkμoldn1(xnxn))2(xkμold)2)+ ((xnμoldn1(xnxn))2(xnμold)2)

The xk in the sum transform into something dependent of μold, but you'll have to work the equation a little bit more to derive a neat result. This should give you the general idea.

krlmlr
la source
the first formula you gave does not seem correct, well it means that if the xn+1 is smaller/larger then from both new and old mean, the variance always increases, which does not make any sense. It may increase or decrease depending on the distribution.
Emmet B
@EmmetB: Yes, you're right -- this should probably be σnew2=n1nσold2+1n(xn+1μnew)(xn+1μold). Unfortunately, this renders void my whole discussion from there, but I'm leaving it for historic purposes. Feel free to edit, though.
krlmlr
4

Based on what i think i'm reading on the linked Wikipedia article you can maintain a "running" standard deviation:

real sum = 0;
int count = 0;
real S = 0;
real variance = 0;

real GetRunningStandardDeviation(ref sum, ref count, ref S, x)
{
   real oldMean;

   if (count >= 1)
   {
       real oldMean = sum / count;
       sum = sum + x;
       count = count + 1;
       real newMean = sum / count;

       S = S + (x-oldMean)*(x-newMean)
   }
   else
   {
       sum = x;
       count = 1;
       S = 0;         
   }

   //estimated Variance = (S / (k-1) )
   //estimated Standard Deviation = sqrt(variance)
   if (count > 1)
      return sqrt(S / (count-1) );
   else
      return 0;
}

Although in the article they don't maintain a separate running sum and count, but instead have the single mean. Since in thing i'm doing today i keep a count (for statistical purposes), it is more useful to calculate the means each time.

Ian Boyd
la source
0

Given original x¯, s, and n, as well as the change of a given element xn to xn, I believe your new standard deviation s will be the square root of

s2+1n1(2nΔx¯(xnx¯)+n(n1)(Δx¯)2),
where Δx¯=x¯x¯, with x¯ denoting the new mean.

Maybe there is a snazzier way of writing it?

I checked this against a small test case and it seemed to work.

Whistling in the Dark
la source
1
@john / whistling in the Dark: I liked your answer, it seems work properly in my small dataset. Is there any mathematical foundation/reference on it? Could you kindly help?
Alok Chowdhury
The question was all @Whistling in the Dark, I just cleaned it up for the site. You should pose a new question referencing the question and answer here. And also you should upvote this answer if you feel that way.
John