To rozwiązanie implementuje sugestię @Innuo w komentarzu do pytania:
Możesz zachować jednolicie próbkowany losowy podzbiór o wielkości 100 lub 1000 na podstawie wszystkich danych do tej pory obserwowanych. Ten zestaw i związane z nim „ogrodzenia” można zaktualizować w czasie .O(1)
Kiedy już wiemy, jak zachować ten podzbiór, możemy wybrać dowolną metodę, którą chcemy oszacować średnią populacji z takiej próby. Jest to metoda uniwersalna, nie zakładająca żadnych założeń, która będzie działać z dowolnym strumieniem wejściowym z dokładnością, którą można przewidzieć za pomocą standardowych wzorów statystycznego próbkowania. (Dokładność jest odwrotnie proporcjonalna do pierwiastka kwadratowego z wielkości próby).
Ten algorytm przyjmuje jako dane wejściowe strumień danych wielkość próbki , i wysyła strumień próbek z których każda reprezentuje populację . W szczególności dla , jest prostą losową próbką o rozmiarze z (bez zamiany).x(t), t=1,2,…,ms(t)X(t)=(x(1),x(2),…,x(t))1≤i≤ts(i)mX(t)
W tym stanie, wystarczy, że każdy -elementowe podzbiór mają równe prawdopodobieństwo być indeksów w . Oznacza to szansę, że jest w równa się pod warunkiem, że .m{1,2,…,t}xs(t)x(i), 1≤i<t,s(t)m/tt≥m
Na początku zbieramy strumień, dopóki nie zostanie zapisanych elementów. W tym momencie istnieje tylko jedna możliwa próbka, więc warunek prawdopodobieństwa jest trywialnie spełniony.m
Algorytm przejmuje, gdy . Indukcyjnie załóżmy, że jest prostą losową próbką dla . Wstępnie ustawione . Niech będzie jednolitą zmienną losową (niezależną od poprzednich zmiennych używanych do konstruowania ). Jeśli to zamień losowo wybrany element na . To cała procedura!t=m+1s(t)X(t)t>ms(t+1)=s(t)U(t+1)s(t)U(t+1)≤m/(t+1)sx(t+1)
Wyraźnie ma prawdopodobieństwo przebywania w . Ponadto, zgodnie z hipotezą indukcyjną, miało prawdopodobieństwo bycia gdy . Z prawdopodobieństwem = zostanie on usunięty ze , stąd prawdopodobieństwo pozostania równex(t+1)m/(t+1)s(t+1)x(i)m/ts(t)i≤tm/(t+1)×1/m1/(t+1)s(t+1)
mt(1−1t+1)=mt+1,
dokładnie w razie potrzeby. Dzięki indukcji wszystkie prawdopodobieństwa włączenia w są prawidłowe i jasne jest, że nie ma specjalnej korelacji między tymi wtrąceniami. To dowodzi, że algorytm jest poprawny.x(i)s(t)
Efektywność algorytmu wynosi ponieważ na każdym etapie obliczane są co najwyżej dwie liczby losowe i co najwyżej jeden element tablicy wartości jest zastępowany. Wymagane miejsce to .O(1)mO(m)
Struktura danych dla tego algorytmu składa się z próbki wraz z indeksem populacji , którą próbkuje. Początkowo bierzemy i postępujemy zgodnie z algorytmem dla Oto implementacja do aktualizacji o wartości do wyprodukowania . (Argument odgrywa rolę i jest . Indeks będzie utrzymywana przez dzwoniącego).stX(t)s=X(m)t=m+1,m+2,….R
(s,t)x(s,t+1)n
tsample.size
mt
update <- function(s, x, n, sample.size) {
if (length(s) < sample.size) {
s <- c(s, x)
} else if (runif(1) <= sample.size / n) {
i <- sample.int(length(s), 1)
s[i] <- x
}
return (s)
}
Aby to zilustrować i przetestować, użyję zwykłego (nieelastycznego) estymatora średniej i porównuję średnią oszacowaną na podstawie z rzeczywistą średnią (skumulowany zestaw danych widoczny na każdym etapie ). Wybrałem nieco trudny strumień wejściowy, który zmienia się dość płynnie, ale okresowo przechodzi dramatyczne skoki. Wielkość próby jest dość mała, co pozwala nam zobaczyć fluktuacje próbkowania na tych wykresach.s(t)X(t)m=50
n <- 10^3
x <- sapply(1:(7*n), function(t) cos(pi*t/n) + 2*floor((1+t)/n))
n.sample <- 50
s <- x[1:(n.sample-1)]
online <- sapply(n.sample:length(x), function(i) {
s <<- update(s, x[i], i, n.sample)
summary(s)})
actual <- sapply(n.sample:length(x), function(i) summary(x[1:i]))
W tym momencie online
jest sekwencja średnich oszacowań uzyskanych przez utrzymanie tej bieżącej próbki wartości, podczas gdy jest sekwencją średnich oszacowań uzyskanych ze wszystkich danych dostępnych w każdym momencie. Wykres pokazuje dane (w kolorze szarym), (w kolorze czarnym) i dwa niezależne zastosowania tej procedury próbkowania (w kolorach). Umowa mieści się w oczekiwanym błędzie próbkowania:50actual
actual
plot(x, pch=".", col="Gray")
lines(1:dim(actual)[2], actual["Mean", ])
lines(1:dim(online)[2], online["Mean", ], col="Red")
Aby uzyskać wiarygodne estymatory średniej, wyszukaj naszą stronę w poszukiwaniu odstającei powiązane warunki. Wśród możliwości wartych rozważenia są środki Winsorized i estymatory M.