Je comprends le principe de base d'un filtre à particules et j'ai essayé de l'implémenter. Cependant, je me suis accroché à la partie de rééchantillonnage.
Théoriquement parlant, c'est assez simple: à partir de l'ancien ensemble de particules (et pondéré), dessinez un nouvel ensemble de particules avec remplacement. Ce faisant, privilégiez les particules de poids élevé. Les particules de poids élevé sont attirées plus souvent et les particules de faible poids moins souvent. Peut-être une seule fois ou pas du tout. Après le rééchantillonnage, tous les poids reçoivent le même poids.
Ma première idée sur la façon de mettre en œuvre cela était essentiellement la suivante:
- Normaliser les poids
- Multipliez chaque poids par le nombre total de particules
- Arrondissez ces pondérations à l'entier le plus proche (par exemple avec
int()
en Python)
Maintenant, je devrais savoir à quelle fréquence dessiner chaque particule, mais en raison des erreurs d'arrondi, je finis par avoir moins de particules qu'avant l'étape de rééchantillonnage.
La question: comment «remplir» les particules manquantes afin d'obtenir le même nombre de particules qu'avant l'étape de rééchantillonnage? Ou, au cas où je ne serais pas complètement sur la bonne voie ici, comment puis-je rééchantillonner correctement?
la source
Comme je suppose que vous l'avez découvert vous-même, la méthode de rééchantillonnage que vous proposez est légèrement défectueuse, car elle ne devrait pas modifier le nombre de particules (sauf si vous le souhaitez). Le principe est que le poids représente la probabilité relative par rapport aux autres particules. Dans l'étape de rééchantillonnage, vous dessinez à partir de l'ensemble de particules de telle sorte que pour chaque particule, le poids normalisé multiplié par le nombre de particules représente le nombre de fois où cette particule est dessinée en moyenne. En ce que votre idée est correcte. Ce n'est qu'en utilisant l'arrondi au lieu de l'échantillonnage que vous éliminerez toujours les particules dont la valeur attendue est inférieure à la moitié.
Il existe plusieurs façons d'effectuer correctement le rééchantillonnage. Il y a un bon article intitulé On resampling algorithms for particules filters , compare the different methods. Juste pour donner un bref aperçu:
Rééchantillonnage multinomial: imaginez une bande de papier où chaque particule a une section, où la longueur est proportionnelle à son poids. Choisissez au hasard un emplacement sur la bande N fois et choisissez la particule associée à la section.
Rééchantillonnage résiduel: cette approche tente de réduire la variance de l'échantillonnage, en allouant d'abord à chaque particule leur plancher entier de la valeur attendue, et en laissant le reste au rééchantillonnage multinomial. Par exemple, une particule avec une valeur attendue de 2,5 aura 2 copies dans l'ensemble rééchantillonné et une autre avec une valeur attendue de 0,5.
Rééchantillonnage systématique: prenez une règle avec des marques régulièrement espacées, de sorte que N marques soient de la même longueur que votre bande de papier. Placez au hasard la règle à côté de votre bande. Prenez les particules aux marques.
Rééchantillonnage stratifié: identique au rééchantillonnage systématique, sauf que les repères sur la règle ne sont pas placés uniformément, mais ajoutés en tant que N processus aléatoires d'échantillonnage à partir de l'intervalle 0..1 / N.
Donc pour répondre à votre question: ce que vous avez mis en place pourrait être étendu à une forme d'échantillonnage résiduel. Vous remplissez les emplacements manquants par échantillonnage basé sur une distribution multinoniale des rappels.
la source
Pour un exemple de code python qui implémente correctement le rééchantillonnage, vous pourriez trouver ce projet github utile: https://github.com/mjl/particle_filter_demo
De plus, il est livré avec sa propre représentation visuelle du processus de rééchantillonnage, qui devrait vous aider à déboguer votre propre implémentation.
Dans cette visualisation, la tortue verte montre la position réelle, le gros point gris montre la position estimée et devient vert quand il converge. Le poids passe de probable (rouge) à peu probable (bleu).
la source
une façon simple de le faire est numpy.random.choice (N, N, p = w, replace = True) où N est le non. de particules et w = poids normalisés.
la source
p
votre fonction? Plus votre réponse sera détaillée, plus elle sera utile aux futurs visiteurs ayant le même problème.J'utilise l'approche de @ narayan pour implémenter mon filtre à particules:
a est le vecteur de vos particules à échantillonner, la taille est le nombre de particules et p est le vecteur de leurs poids normalisés. replace = True gère l'échantillonnage bootstrap avec remplacement. La valeur de retour est un vecteur de nouveaux objets particules.
la source