Perhitungan deviasi standar baru menggunakan deviasi standar lama setelah perubahan dalam dataset

16

Saya memiliki array nilai riil, yang memiliki rata-rata μ o l d dan standar deviasi σ o l d . Jika elemen array x i digantikan oleh elemen lain x j , maka rata-rata baru akan menjadinμoldσoldxixj

μnew=μold+xjxin

Keuntungan dari pendekatan ini adalah ia membutuhkan perhitungan yang konstan terlepas dari nilai . Apakah ada pendekatan untuk menghitung σ n e w menggunakan σ o l d seperti perhitungan μ n e w menggunakan μ o l d ?nσnewσoldμnewμold

pengguna
sumber
Apakah ini pekerjaan rumah? Tugas yang sangat mirip ditanyakan dalam kursus statistik matematika kami ...
krlmlr
2
@ user946850: Tidak, ini bukan pekerjaan rumah. Saya sedang melakukan tesis saya tentang Algoritma Evolusi . Saya ingin menggunakan standar deviasi sebagai ukuran keragaman populasi. Hanya mencari solusi yang lebih efisien.
pengguna
1
SD adalah akar kuadrat dari varians, yang hanya nilai kuadrat rata-rata (disesuaikan dengan kelipatan dari kuadrat rata-rata, yang sudah Anda ketahui cara memperbarui). Oleh karena itu, metode yang sama digunakan untuk menghitung rata-rata berjalan dapat diterapkan tanpa perubahan mendasar untuk menghitung varian berjalan. Faktanya, statistik yang jauh lebih canggih dapat dihitung secara online dengan menggunakan ide yang sama: lihat utas di stats.stackexchange.com/questions/6920 dan stats.stackexchange.com/questions/23481 , misalnya.
whuber
1
@whuber: Ini disebutkan dalam artikel Wikipedia untuk Variance , tetapi juga dengan catatan tentang pembatalan bencana (atau kehilangan arti penting) yang mungkin terjadi. Apakah ini berlebihan, atau masalah nyata untuk varian yang berjalan?
krlmlr
Itu pertanyaan yang bagus. Jika Anda mengakumulasikan varian secara naif, tanpa memusatkannya terlebih dahulu, Anda memang bisa mendapat masalah. Masalahnya terjadi ketika jumlahnya besar tetapi variansinya kecil. Misalnya, perhatikan serangkaian pengukuran akurat kecepatan cahaya dalam m / s, seperti pada 299792458.145, 299792457.883, 299792457.998, ...: varians mereka, yaitu sekitar 0,01, sangat kecil dibandingkan dengan kuadratnya, yaitu sekitar , perhitungan yang ceroboh (bahkan dalam presisi ganda) akan menghasilkan nol varians: semua digit signifikan akan hilang. 1017
whuber

Jawaban:

7

Sebuah bagian dalam artikel Wikipedia pada "Algoritma untuk menghitung varians" menunjukkan bagaimana untuk menghitung varians jika elemen ditambahkan ke pengamatan Anda. (Ingat bahwa standar deviasi adalah akar kuadrat dari varians.) Asumsikan bahwa Anda menambahkan ke array Anda, makaxn+1

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

EDIT : Formula di atas sepertinya salah, lihat komentar.

Sekarang, mengganti elemen berarti menambahkan observasi dan menghapus yang lain; keduanya dapat dihitung dengan rumus di atas. Namun, perlu diingat bahwa masalah stabilitas numerik dapat terjadi; artikel yang dikutip juga mengusulkan varian yang stabil secara numerik.

Untuk mendapatkan formula sendiri, hitung menggunakan definisi varians sampel dan gantikan μ n e w dengan formula yang Anda berikan saat yang tepat. Ini memberi Anda σ 2 n e w - σ 2 o l d pada akhirnya, dan dengan demikian formula untuk σ n e w diberikan σ o l d dan(n1)(σnew2σold2)μnewσnew2σold2σnewσoldμold . Dalam notasi saya, saya menganggap Anda mengganti elemen xn dengan :xn

σ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
sumber
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
sumber
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
sumber
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