Entiendo el principio básico de un filtro de partículas e intenté implementar uno. Sin embargo, me colgué en la parte de remuestreo.
Teóricamente hablando, es bastante simple: del conjunto de partículas antiguo (y ponderado), dibuje un nuevo conjunto de partículas con reemplazo. Al hacerlo, favorezca las partículas que tienen pesos altos. Las partículas con pesos altos se extraen con mayor frecuencia y las partículas con pesos bajos con menos frecuencia. Quizás solo una vez o nada en absoluto. Después de volver a muestrear, a todos los pesos se les asigna el mismo peso.
Mi primera idea sobre cómo implementar esto fue esencialmente esto:
- Normaliza los pesos
- Multiplique cada peso por el número total de partículas.
- Redondee esos pesos escalados al número entero más cercano (por ejemplo, con
int()
Python)
Ahora debería saber con qué frecuencia dibujar cada partícula, pero debido a los errores de redondeo, termino teniendo menos partículas que antes del paso de remuestreo.
La pregunta: ¿Cómo puedo "llenar" las partículas que faltan para llegar al mismo número de partículas que antes del paso de remuestreo? O, en caso de que esté completamente fuera de lugar aquí, ¿cómo puedo volver a muestrear correctamente?
fuente
Como supongo que lo descubrió usted mismo, el método de remuestreo que está proponiendo es ligeramente defectuoso, ya que no debería alterar el número de partículas (a menos que lo desee). El principio es que el peso representa la probabilidad relativa con respecto a las otras partículas. En el paso de remuestreo, extrae del conjunto de partículas de manera que, para cada partícula, el peso normalizado multiplicado por el número de partículas representa el número de veces que esa partícula se extrae en promedio. En eso tu idea es correcta. Solo utilizando el redondeo en lugar del muestreo, siempre eliminará las partículas cuyo valor esperado sea inferior a la mitad.
Hay varias formas de realizar el remuestreo correctamente. Hay un buen artículo llamado Sobre algoritmos de remuestreo para filtros de partículas , que compara los diferentes métodos. Solo para dar una visión general rápida:
Muestreo multinomial: imagine una tira de papel donde cada partícula tiene una sección, donde la longitud es proporcional a su peso. Elija aleatoriamente una ubicación en la tira N veces, y elija la partícula asociada con la sección.
Muestreo residual: este enfoque intenta reducir la varianza del muestreo, asignando primero a cada partícula su piso entero del valor esperado, y deja el resto a un muestreo multinomial. Por ejemplo, una partícula con un valor esperado de 2.5 tendrá 2 copias en el conjunto muestreado y otra con un valor esperado de 0.5.
Muestreo sistemático: tome una regla con marcas espaciadas regulares, de modo que las marcas N tengan la misma longitud que su tira de papel. Coloca al azar la regla al lado de tu tira. Toma las partículas en las marcas.
Muestreo estratificado: igual que el muestreo sistemático, excepto que las marcas en la regla no se colocan de manera uniforme, sino que se agregan como N procesos aleatorios de muestreo del intervalo 0..1 / N.
Entonces, para responder a su pregunta: lo que ha implementado podría extenderse a una forma de muestreo residual. Rellena los espacios faltantes mediante un muestreo basado en una distribución multinonmial de los recordatorios.
fuente
Para ver un ejemplo de código de Python que implementa correctamente el remuestreo, puede encontrar útil este proyecto github: https://github.com/mjl/particle_filter_demo
Además, viene con su propia representación visual del proceso de remuestreo, que debería ayudarlo a depurar su propia implementación.
En esta visualización, la tortuga verde muestra la posición real, el gran punto gris muestra la posición estimada y se vuelve verde cuando converge. El peso va de probable (rojo) a improbable (azul).
fuente
Una forma simple de hacer esto es numpy.random.choice (N, N, p = w, replace = True) donde N es el no. de partículas yw = pesos normalizados.
fuente
p
en tu función? Cuanto más detallado sea su respuesta, más útil será para los futuros visitantes que tengan el mismo problema.Utilizo el enfoque de @ narayan para implementar mi filtro de partículas:
a es el vector de sus partículas para muestrear, el tamaño es el recuento de partículas y p es el vector de sus pesos normalizados. replace = True maneja el muestreo bootstrap con reemplazo. El valor de retorno es un vector de nuevos objetos de partículas.
fuente