Calcolo della nuova deviazione standard utilizzando la vecchia deviazione standard dopo la modifica del set di dati


16

Ho una matrice di valori reali, che ha media e deviazione standard . Se un elemento dell'array viene sostituito da un altro elemento , allora sarà la nuova medianμoldσoldxixj

μnew=μold+xjxin

Il vantaggio di questo approccio è che richiede un calcolo costante indipendentemente dal valore di . Esiste un approccio per calcolare usando come il calcolo di usando ?nσnewσoldμnewμold


Sono compiti a casa? Un compito molto simile è stato chiesto nel nostro corso di statistiche matematiche ...
krlmlr

2
@ user946850: No, non sono i compiti. Sto conducendo la mia tesi sull'algoritmo evolutivo . Voglio usare la deviazione standard come misura della diversità della popolazione. Sto solo cercando una soluzione più efficiente.
utente

1
La SD è la radice quadrata della varianza, che è solo il valore medio quadrato (regolato da un multiplo della media quadrata, che già sai come aggiornare). Pertanto, gli stessi metodi utilizzati per calcolare una media corrente possono essere applicati senza alcuna modifica fondamentale per calcolare una varianza corrente. In effetti, statistiche molto più sofisticate possono essere calcolate su base online usando le stesse idee: vedere i thread su stats.stackexchange.com/questions/6920 e stats.stackexchange.com/questions/23481 , ad esempio.
whuber

1
@whuber: questo è menzionato nell'articolo di Wikipedia per la varianza , ma anche con una nota sulla cancellazione catastrofica (o perdita di significato) che può verificarsi. È sopravvalutato o è un vero problema per la varianza corrente?
krlmlr,

Questa è un'ottima domanda. Se accumuli le varianze ingenuamente, senza centrarle in anticipo, puoi davvero metterti nei guai. Il problema si verifica quando i numeri sono enormi ma la loro varianza è piccola. Ad esempio, considera una serie di misurazioni accurate della velocità della luce in m / s, come in 299792458.145, 299792457.883, 299792457.998, ...: la loro varianza, che è di circa 0,01, è così piccola rispetto ai loro quadrati, che è di circa , quel calcolo imprudente (anche in doppia precisione) comporterebbe una varianza zero: tutte le cifre significative svanirebbero. 1017
whuber

Risposte:


7

Una sezione dell'articolo di Wikipedia su "Algoritmi per il calcolo della varianza" mostra come calcolare la varianza se gli elementi vengono aggiunti alle tue osservazioni. (Ricorda che la deviazione standard è la radice quadrata della varianza.) Supponi di aggiungere al tuo array, quindixn+1

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

EDIT : sopra la formula sembra essere sbagliato, vedi commento.

Ora, sostituire un elemento significa aggiungere un'osservazione e rimuoverne un'altra; entrambi possono essere calcolati con la formula sopra. Tuttavia, tenere presente che possono derivarne problemi di stabilità numerica; l'articolo citato propone anche varianti numericamente stabili.

Per derivare la formula da solo, calcola usando la definizione della varianza del campione e sostituisci μ n e w con la formula che hai dato quando appropriato. Questo ti dà σ 2 n e w - σ 2 o l d alla fine, e quindi una formula per σ n e w dato σ o l d e(n1)(σnew2σold2)μnewσnew2σold2σnewσoldμold . Nella mia notazione, suppongo che sostituisca l'elemento con 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.


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.


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.


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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.