Entendo o princípio básico de um filtro de partículas e tentei implementá-lo. No entanto, fiquei pendurado na parte de reamostragem.
Teoricamente falando, é bastante simples: a partir do conjunto de partículas antigo (e ponderado), desenhe um novo conjunto de partículas com substituição. Enquanto isso, favorece as partículas que têm pesos altos. Partículas com pesos altos são atraídas com mais frequência e partículas com pesos baixos com menos frequência. Talvez apenas uma vez ou não. Após a reamostragem, todos os pesos recebem o mesmo peso.
Minha primeira idéia de como implementar isso foi essencialmente esta:
- Normalizar os pesos
- Multiplique cada peso pelo número total de partículas
- Arredonde esses pesos dimensionados para o número inteiro mais próximo (por exemplo, com
int()
em Python)
Agora eu deveria saber com que frequência desenhar cada partícula, mas devido aos erros de arredondamento, acabo tendo menos partículas do que antes da etapa de reamostragem.
A pergunta: como "preenche" as partículas ausentes para obter o mesmo número de partículas que antes da etapa de reamostragem? Ou, caso eu esteja completamente fora de controle aqui, como reamostrar corretamente?
fonte
Como eu acho que você se descobriu, o método de reamostragem que você está propondo é levemente defeituoso, pois não deve alterar o número de partículas (a menos que você queira). O princípio é que o peso representa a probabilidade relativa em relação às outras partículas. Na etapa de reamostragem, você extrai do conjunto de partículas de modo que, para cada partícula, o peso normalizado vezes o número de partículas represente o número de vezes que a partícula é desenhada em média. Nesse sentido, sua ideia está correta. Somente usando o arredondamento em vez da amostragem, você sempre eliminará partículas para as quais o valor esperado é menor que a metade.
Existem várias maneiras de executar a reamostragem corretamente. Existe um bom artigo chamado Algoritmos de reamostragem para filtros de partículas , comparando os diferentes métodos. Apenas para dar uma rápida visão geral:
Reamostragem multinomial: imagine uma tira de papel em que cada partícula tenha uma seção, em que o comprimento seja proporcional ao seu peso. Escolha aleatoriamente um local na faixa N vezes e escolha a partícula associada à seção.
Reamostragem residual: essa abordagem tenta reduzir a variação da amostragem, alocando primeiro cada partícula seu piso inteiro do valor esperado e deixando o restante para reamostragem multinomial. Por exemplo, uma partícula com um valor esperado de 2,5 terá 2 cópias no conjunto reamostrado e outra com um valor esperado de 0,5.
Reamostragem sistemática: faça uma régua com marcas espaçadas regulares, de modo que as marcas N tenham o mesmo comprimento da sua tira de papel. Coloque aleatoriamente a régua ao lado da sua faixa. Pegue as partículas nas marcas.
Reamostragem estratificada: igual à reamostragem sistemática, exceto que as marcas na régua não são colocadas uniformemente, mas adicionadas como N processos aleatórios de amostragem a partir do intervalo 0..1 / N.
Então, para responder à sua pergunta: o que você implementou pode ser estendido a uma forma de amostragem residual. Você preenche os slots ausentes por amostragem com base em uma distribuição multinonial dos lembretes.
fonte
Para um exemplo de código python que implementa adequadamente a reamostragem, você pode achar útil esse projeto no github: https://github.com/mjl/particle_filter_demo
Além disso, ele vem com sua própria representação visual do processo de reamostragem, que deve ajudá-lo a depurar sua própria implementação.
Nesta visualização, a tartaruga verde mostra a posição real, o grande ponto cinza mostra a posição estimada e fica verde quando converge. O peso passa de provável (vermelho) para improvável (azul).
fonte
Uma maneira simples de fazer isso é numpy.random.choice (N, N, p = w, replace = True) em que N é o não. de partículas ew = pesos normalizados.
fonte
p
em sua função? Quanto mais detalhada você puder responder, mais útil será para futuros visitantes que tiverem o mesmo problema.Eu uso a abordagem do @ narayan para implementar meu filtro de partículas:
a é o vetor de suas partículas a serem amostradas, tamanho é a contagem de partículas ep é o vetor de seus pesos normalizados. replace = True lida com a amostragem de autoinicialização com substituição. O valor de retorno é um vetor de novos objetos de partículas.
fonte