Estou criando um componente que visa calcular a média e a variação de uma métrica associada a eventos que ocorrem durante o tempo, mas com uma memória interna limitada.
Imagine que os eventos são visitantes que entram em uma loja e a métrica é a idade deles.
Durante o tempo, meu componente recebe eventos com a idade de cada visitante. Não quero que meu componente memorize a história de cada idade. Idealmente, eu gostaria de armazenar apenas um componente leve: a média A
, a variação V e o número de eventos N
.
Após cada evento com a idade E
, desejo atualizar esses três valores:
N<=N+1
A<=(A*N+E)/(N+1)
V<=???
Para que V
? Estou pensando em algo como:
V<=(V*N+(E-A)^2)/(N+1)
Eu sei que não é exato, pois o meu anterior V
está usando o antigo, A
que não é mais a média.
Q1 - Existe uma fórmula exata?
Q2 - Se não, minha proposta é uma boa estimativa? É tendencioso? Irá convergir corretamente quando N
aumentar?
Q3 - Existe uma fórmula melhor?
Respostas:
Um algoritmo agradável e simples para a variância computacional da maneira online foi descrito por Welford (1962). Abaixo, você pode ver a implementação em C ++ / Rcpp que funciona offline, mas pode ser facilmente adaptada ao cenário online:
Como você pode ver, ele precisa armazenar apenas quatro variáveis:
n
,delta
,msq
emean
e calcula média e variância, simultaneamente, como você queria.Welford, BP (1962). Observe um método para calcular somas corrigidas de quadrados e produtos . Technometrics 4 (3): 419-420.
fonte
A variância pode ser expressa como proporcional à diferença ao quadrado entre cada valor e o valor médio, ou (como muitos threads aqui em stats.SE documentados, como esta resposta que escrevi para outra pergunta) ela pode ser expressa como proporcional ao quadrado diferença de pares entre cada amostra.
Então sabemos:
Digamos que você adicione outra amostra, indexada como o último índice, . Sua variação anterior seria:k
Sua nova variação é
Mas
assim
Como o @ MarkL.Stone disse nos comentários, isso ainda não é eficiente, porque devemos manter todos os . Então, vamos expandir a fórmula para chegar a algo mais tratável.Xi
O formulário final é então
Você pode usar esta fórmula para atualizar a variação efetivamente em memória. Você também pode complementá-lo para usar lotes em vez de atualizações de ponto único.
Basicamente, você precisa armazenar a média, a média das amostras ao quadrado e a variação a cada iteração e usá-la para atualizar a fórmula de variação.
Mais longe
O que reduz o número de quantidades que precisam ser armazenadas para 2.
fonte
OK, Andy W deu a resposta. Conservando a média da mesma maneira que a média E, você pode usar .E2 V=exp(E2)−exp(E)2
fonte