Esta solução implementa uma sugestão feita por @Innuo em um comentário à pergunta:
Você pode manter um subconjunto aleatório de tamanho 100 ou 1000 de amostra uniforme de todos os dados vistos até o momento. Este conjunto e as "cercas" associadas podem ser atualizadas em .O ( 1 )
Depois que soubermos manter esse subconjunto, poderemos selecionar qualquer método que gostemos de estimar a média de uma população dessa amostra. Este é um método universal, sem nenhuma suposição, que funcionará com qualquer fluxo de entrada com uma precisão que pode ser prevista usando fórmulas de amostragem estatística padrão. (A precisão é inversamente proporcional à raiz quadrada do tamanho da amostra.)
Este algoritmo aceita como entrada um fluxo de dados t = 1 , 2 , … , um tamanho de amostra m e gera um fluxo de amostras s ( t ), cada um dos quais representa a população X ( t ) = ( x ( 1 ) , x ( 2 ) , … , x ( t ) ) . Especificamente, para 1 ≤ i ≤x ( t ) , t = 1 , 2 , … ,ms ( t )X(t)=(x(1),x(2),…,x(t)) , s ( i ) é uma amostra aleatória simples de tamanho m de X ( t ) (sem substituição).1≤i≤ts(i)mX(t)
Para que isso aconteça, basta que cada subconjunto de elementos de { 1 , 2 , … , t } tenha chances iguais de serem os índices de x em s ( t ) . Isso implica a chance de que x ( i ) , 1 ≤ i < t , seja em s ( t ) igual a m / t, desde que t ≥ m .m{1,2,…,t}xs(t)x(i), 1≤i<t,s(t)m/tt≥m
No começo, apenas coletamos o fluxo até que elementos sejam armazenados. Nesse ponto, existe apenas uma amostra possível; portanto, a condição de probabilidade é trivialmente satisfeita.m
O algoritmo assume quando . Suponha indutivamente que s (t=m+1 é uma amostra aleatória simples de X ( t ) para t > m . Defina provisoriamente s ( t + 1 ) = s ( t ) . Seja U ( t + 1 ) uma variável aleatória uniforme (independente de qualquer variável anterior usada para construir s ( t ) ). E ses(t)X(t)t>ms(t+1)=s(t)U(t+1)s(t) substitui um elemento escolhido aleatoriamente de s por x ( t + 1 ) . U(t+1)≤m/(t+1)sx(t+1) Esse é todo o procedimento!
Claramente tem probabilidade m / ( t + 1 ) de estar em s ( t + 1 ) . Além disso, pela hipótese de indução, x ( i ) tinha probabilidade m / t de estar em s ( t ) quando i ≤ t . Com probabilidade m / ( t + 1 ) × 1 / mx(t+1)m/(t+1)s ( t + 1 )x ( i )m / ts ( t )i ≤ tm / ( t + 1 ) × 1 / m= será removido de s ( t + 1 ) , de onde sua probabilidade de permanecer igual1 / ( t + 1 )s ( t + 1 )
mt( 1 - 1t + 1) = mt + 1,
exatamente conforme necessário. Por indução, então, todas as probabilidades de inclusão do no s ( t ) estão corretas e é claro que não há correlação especial entre essas inclusões. Isso prova que o algoritmo está correto.x ( i )s ( t )
A eficiência do algoritmo é porque em cada estágio são computados no máximo dois números aleatórios e no máximo um elemento de uma matriz de m valores é substituído. O requisito de armazenamento é O ( m ) .O ( 1 )mO ( m )
A estrutura de dados para esse algoritmo consiste na amostra juntamente com o índice t da população X ( t ) que ele coleta. Inicialmente, pegamos s = X ( m ) e prosseguimos com o algoritmo para t = m + 1 , m + 2 , … . Aqui está uma implementação para atualizar ( s , t ) com um valor x para produzir ( s , t +stX( T )s = X( M )t = m + 1 , m + 2 , ... .R
( s , t )x . (O argumentodesempenha o papel de T eé m . O índice de t será mantida pelo chamador.)( 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)
}
Para ilustrar e testar isso, usarei o estimador usual (não robusto) da média e compararei a média estimada em com a média real de X ( t ) (o conjunto cumulativo de dados visto em cada etapa) ) Eu escolhi um fluxo de entrada um tanto difícil que muda bastante suavemente, mas periodicamente sofre saltos dramáticos. O tamanho da amostra de m = 50 é bastante pequeno, permitindo ver flutuações da amostra nessas parcelas.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]))
Nesse ponto, online
está a sequência de estimativas médias produzida pela manutenção dessa amostra em execução de valores, enquanto é a sequência de estimativas médias produzida a partir de todos os dados disponíveis em cada momento. O gráfico mostra os dados (em cinza), (em preto) e duas aplicações independentes desse procedimento de amostragem (em cores). O contrato está dentro do erro de amostragem esperado:50.actual
actual
plot(x, pch=".", col="Gray")
lines(1:dim(actual)[2], actual["Mean", ])
lines(1:dim(online)[2], online["Mean", ], col="Red")
Para estimadores robustos da média, pesquise em nosso site termos estranhos e relacionados. Entre as possibilidades que vale a pena considerar estão as médias Winsorized e M-estimadores.