Eu tenho um pequeno problema que está me deixando em pânico. Eu tenho que escrever o procedimento para um processo de aquisição on-line de uma série temporal multivariada. A cada intervalo de tempo (por exemplo, 1 segundo), recebo uma nova amostra, que é basicamente um vetor de ponto flutuante do tamanho N. A operação que preciso fazer é um pouco complicada:
Para cada nova amostra, calculo os percentuais dessa amostra (normalizando o vetor para que os elementos sejam somados a 1).
Calculo o vetor percentual médio da mesma maneira, mas usando os valores passados.
Para cada valor passado, calculo o desvio absoluto do vetor percentual relacionado a essa amostra com o vetor percentual médio global calculado na etapa 2. Dessa forma, o desvio absoluto é sempre um número entre 0 (quando o vetor é igual à média vector) e 2 (quando é totalmente diferente).
Usando a média dos desvios para todas as amostras anteriores, calculo o desvio absoluto médio, que é novamente um número entre 0 e 2.
Utilizo o desvio médio absoluto para detectar se uma nova amostra é compatível com as outras amostras (comparando seu desvio absoluto com o desvio absoluto médio de todo o conjunto calculado na etapa 4).
Como toda vez que uma nova amostra é coletada, a média global é alterada (e o desvio absoluto médio também é alterado), existe uma maneira de calcular esse valor sem verificar o conjunto de dados inteiro várias vezes? (uma vez para calcular os percentuais médios globais e uma vez para coletar os desvios absolutos). Ok, eu sei que é absolutamente fácil calcular as médias globais sem varrer todo o conjunto, já que eu só tenho que usar um vetor temporário para armazenar a soma de cada dimensão, mas e o desvio absoluto médio? Seu cálculo inclui o abs()
operador, então eu preciso acessar todos os dados passados!
Obrigado pela ajuda.
fonte
Eu usei a seguinte abordagem no passado para calcular o desvio de absolvição moderadamente eficiente (observe que essa é uma abordagem de programadores, não um estatístico, então, indubitavelmente, pode haver truques inteligentes como o shabbychef que podem ser mais eficientes).
AVISO: Este não é um algoritmo online. Isso requer
O(n)
memória. Além disso, possui o pior desempenho possívelO(n)
, para conjuntos de dados como[1, -2, 4, -8, 16, -32, ...]
(ou seja, o mesmo que o recálculo completo). [1]No entanto, como ainda funciona bem em muitos casos de uso, pode valer a pena postar aqui. Por exemplo, para calcular o desvio absoluto de 10000 números aleatórios entre -100 e 100 à medida que cada item chega, meu algoritmo leva menos de um segundo, enquanto o recálculo completo leva mais de 17 segundos (na minha máquina, variará por máquina e de acordo com os dados de entrada). No entanto, é necessário manter o vetor inteiro na memória, o que pode ser uma restrição para alguns usos. O esboço do algoritmo é o seguinte:
O(n)
operações de movimentação, para muitos casos de uso, não é o caso.Alguns exemplos de código, em python, estão abaixo. Observe que apenas permite que itens sejam adicionados à lista, não removidos. Isso poderia ser facilmente adicionado, mas no momento em que escrevi isso não era necessário. Em vez de implementar as filas de prioridade, usei a lista classificada do excelente pacote de blist de Daniel Stutzbach , que usa internamente as árvores B + Tree .
Considere este código licenciado sob a licença MIT . Não foi significativamente otimizado ou polido, mas funcionou para mim no passado. Novas versões estarão disponíveis aqui . Deixe-me saber se você tiver alguma dúvida ou encontrar algum erro.
[1] Se os sintomas persistirem, consulte seu médico.
fonte
O(n)
memória e, na pior das hipóteses, leva O (n) tempo para cada item adicionado. Em dados normalmente distribuídos (e provavelmente em outras distribuições), ele funciona com bastante eficiência.fonte
MAD (x) é apenas dois cálculos medianos simultâneos, cada um dos quais pode ser disponibilizado online através do algoritmo binmediano .
Você pode encontrar o documento associado, bem como os códigos C e FORTRAN on-line aqui .
(este é apenas o uso de um truque inteligente em cima do truque inteligente de Shabbychef, para economizar memória).
Termo aditivo:
Existem vários métodos antigos de múltiplas passagens para calcular quantis. Uma abordagem popular é manter / atualizar um reservatório de tamanho determinístico de observações selecionadas aleatoriamente a partir do fluxo e calcular quantis recursivamente (veja esta revisão) neste reservatório. Essa abordagem (e relacionada) é substituída pela proposta acima.
fonte
A seguir, é apresentada uma aproximação imprecisa, embora a imprecisão dependa da distribuição dos dados de entrada. É um algoritmo online, mas apenas aproxima o desvio absoluto. Ele é baseado em um algoritmo bem conhecido para o cálculo da variação on-line, descrito por Welford na década de 1960. Seu algoritmo, traduzido para R, se parece com:
Ele executa de maneira muito semelhante à função de variação interna de R:
Modificar o algoritmo para calcular o desvio absoluto simplesmente envolve uma
sqrt
chamada adicional . No entanto,sqrt
apresenta imprecisões que são refletidas no resultado:Os erros, calculados como acima, são muito maiores do que no cálculo da variação:
No entanto, dependendo do seu caso de uso, essa magnitude do erro pode ser aceitável.
fonte
n
torna grande, o seerror/n
torna muito pequeno, surpreendentemente rápido.sqrt
imprecisão. É porque ele usa a estimativa média corrente. Para ver quando isso ocorrerá, tentexs <- sort(rnorm(n.testitems))
Quando eu tento isso com seu código (após corrigi-lo para retornara.dev / n
), recebo erros relativos da ordem de 9% a 16%. Portanto, este método não é invariante permutação, o que poderia causar estragos ...