Jason R'ın cevabında, Knuth'un "Bilgisayar Programlama Sanatı" adlı kitabında tartışılan bir kusur var. 2. Sorun, ortalamanın küçük bir kısmı olan standart bir sapmanız varsa ortaya çıkar: E (x ^ 2) - (E (x) ^ 2) 'nin hesaplanması, hassas hassasiyetten kayan nokta yuvarlama hatalarına maruz kalır.
Bunu bir Python betiğinde de deneyebilirsiniz:
ofs = 1e9
A = [ofs+x for x in [1,-1,2,3,0,4.02,5]]
A2 = [x*x for x in A]
(sum(A2)/len(A))-(sum(A)/len(A))**2
Matematik, sonucun negatif olamayacağını öngördüğü için, açıkça hesaplamalı olarak geçerli olmayan bir cevap olarak -128.0 elde ediyorum.
Knuth, koşu ortalamasını ve bunun gibi bir şeye giden standart sapmayı hesaplamak için (mucidin adını hatırlamıyorum) bir yaklaşıma işaret ediyor:
initialize:
m = 0;
S = 0;
n = 0;
for each incoming sample x:
prev_mean = m;
n = n + 1;
m = m + (x-m)/n;
S = S + (x-m)*(x-prev_mean);
ve sonra her adımdan sonra, değeri m
ortalamadır ve standart sapma , en sevdiğiniz standart sapma tanımına bağlı olarak sqrt(S/n)
veya bu şekilde hesaplanabilir sqrt(S/n-1)
.
Yukarıda yazdığım denklem Knuth'dakiden biraz farklı, ancak hesaplamalı olarak eşdeğer.
Birkaç dakikam olduğunda, yukarıdaki formülü Python'da kodlayacağım ve negatif olmayan bir cevap alacağınızı göstereceğim (umarım doğru değere yakındır).
güncelleme: işte burada.
test1.py:
import math
def stats(x):
n = 0
S = 0.0
m = 0.0
for x_i in x:
n = n + 1
m_prev = m
m = m + (x_i - m) / n
S = S + (x_i - m) * (x_i - m_prev)
return {'mean': m, 'variance': S/n}
def naive_stats(x):
S1 = sum(x)
n = len(x)
S2 = sum([x_i**2 for x_i in x])
return {'mean': S1/n, 'variance': (S2/n - (S1/n)**2) }
x1 = [1,-1,2,3,0,4.02,5]
x2 = [x+1e9 for x in x1]
print "naive_stats:"
print naive_stats(x1)
print naive_stats(x2)
print "stats:"
print stats(x1)
print stats(x2)
sonuç:
naive_stats:
{'variance': 4.0114775510204073, 'mean': 2.0028571428571427}
{'variance': -128.0, 'mean': 1000000002.0028572}
stats:
{'variance': 4.0114775510204073, 'mean': 2.0028571428571431}
{'variance': 4.0114775868357446, 'mean': 1000000002.0028571}
Hala bir yuvarlama hatası olduğunu not edersiniz, ancak fena değil, oysa naive_stats
sadece kusar.
düzenleme: Sadece Belisarius'un Knuth algoritmasından bahseden Vikipedi'ye atıfta bulunan yorumunu fark ettim .