Wie zu verwenden Kalman-filter in Python für Standort-Daten?
[BEARBEITEN]
Die Antwort von @Claudio gibt mir einen wirklich guten Tipp, wie man herausfiltern, die Ausreißer. Ich möchte beginnen mit einem Kalman-filter auf meine Daten obwohl. Also änderte ich die Beispiel Daten unten, so dass es subtile variation Geräusche, die sind nicht so extrem (was ich sehr gut). Wenn sonst jemand könnte mir einige Richtung für die Verwendung PyKalman auf meine Daten, das wäre toll.
[/EDIT]
Für ein Robotik-Projekt, das ich bin versucht zu verfolgen, einen kite in der Luft mit einer Kamera. Ich bin Programmierung in Python und ich klebte einige laute Lage nachstehenden Ergebnisse (jeder Artikel hat auch ein datetime-Objekt enthalten, aber ich ließ Sie für Klarheit).
[ # X Y
{'loc': (399, 293)},
{'loc': (403, 299)},
{'loc': (409, 308)},
{'loc': (416, 315)},
{'loc': (418, 318)},
{'loc': (420, 323)},
{'loc': (429, 326)}, # <== Noise in X
{'loc': (423, 328)},
{'loc': (429, 334)},
{'loc': (431, 337)},
{'loc': (433, 342)},
{'loc': (434, 352)}, # <== Noise in Y
{'loc': (434, 349)},
{'loc': (433, 350)},
{'loc': (431, 350)},
{'loc': (430, 349)},
{'loc': (428, 347)},
{'loc': (427, 345)},
{'loc': (425, 341)},
{'loc': (429, 338)}, # <== Noise in X
{'loc': (431, 328)}, # <== Noise in X
{'loc': (410, 313)},
{'loc': (406, 306)},
{'loc': (402, 299)},
{'loc': (397, 291)},
{'loc': (391, 294)}, # <== Noise in Y
{'loc': (376, 270)},
{'loc': (372, 272)},
{'loc': (351, 248)},
{'loc': (336, 244)},
{'loc': (327, 236)},
{'loc': (307, 220)}
]
Ich zuerst dachte, die manuelle Berechnung Ausreißer und dann einfach entfernen Sie Sie aus den Daten in Echtzeit. Dann habe ich gelesen, Kalman-Filter und wie Sie speziell gemeint zu glätten verrauschter Daten.
So nach einigem suchen fand ich die PyKalman Bibliothek, die scheint perfekt für diese. Da war ich ein bisschen verloren in der ganzen Kalman-filter-Terminologie, die ich durch Lesen der wiki und einigen anderen Seiten, die auf Kalman-Filter. Ich bekomme die Allgemeine Vorstellung von einem Kalman-filter, aber ich bin wirklich verloren, wie sollte ich es anwenden, meinen code.
In der PyKalman docs fand ich Folgendes Beispiel:
>>> from pykalman import KalmanFilter
>>> import numpy as np
>>> kf = KalmanFilter(transition_matrices = [[1, 1], [0, 1]], observation_matrices = [[0.1, 0.5], [-0.3, 0.0]])
>>> measurements = np.asarray([[1,0], [0,0], [0,1]]) # 3 observations
>>> kf = kf.em(measurements, n_iter=5)
>>> (filtered_state_means, filtered_state_covariances) = kf.filter(measurements)
>>> (smoothed_state_means, smoothed_state_covariances) = kf.smooth(measurements)
Habe ich einfach ersetzt die Beobachtungen für meine eigenen Beobachtungen wie folgt:
from pykalman import KalmanFilter
import numpy as np
kf = KalmanFilter(transition_matrices = [[1, 1], [0, 1]], observation_matrices = [[0.1, 0.5], [-0.3, 0.0]])
measurements = np.asarray([(399,293),(403,299),(409,308),(416,315),(418,318),(420,323),(429,326),(423,328),(429,334),(431,337),(433,342),(434,352),(434,349),(433,350),(431,350),(430,349),(428,347),(427,345),(425,341),(429,338),(431,328),(410,313),(406,306),(402,299),(397,291),(391,294),(376,270),(372,272),(351,248),(336,244),(327,236),(307,220)])
kf = kf.em(measurements, n_iter=5)
(filtered_state_means, filtered_state_covariances) = kf.filter(measurements)
(smoothed_state_means, smoothed_state_covariances) = kf.smooth(measurements)
aber nicht, dass mir irgendwelche sinnvollen Daten. Zum Beispiel, die smoothed_state_means
wird die folgenden:
>>> smoothed_state_means
array([[-235.47463353, 36.95271449],
[-354.8712597 , 27.70011485],
[-402.19985301, 21.75847069],
[-423.24073418, 17.54604304],
[-433.96622233, 14.36072376],
[-443.05275258, 11.94368163],
[-446.89521434, 9.97960296],
[-456.19359012, 8.54765215],
[-465.79317394, 7.6133633 ],
[-474.84869079, 7.10419182],
[-487.66174033, 7.1211321 ],
[-504.6528746 , 7.81715451],
[-506.76051587, 8.68135952],
[-510.13247696, 9.7280697 ],
[-512.39637431, 10.9610031 ],
[-511.94189431, 12.32378146],
[-509.32990832, 13.77980587],
[-504.39389762, 15.29418648],
[-495.15439769, 16.762472 ],
[-480.31085928, 18.02633612],
[-456.80082586, 18.80355017],
[-437.35977492, 19.24869224],
[-420.7706184 , 19.52147918],
[-405.59500937, 19.70357845],
[-392.62770281, 19.8936389 ],
[-388.8656724 , 20.44525168],
[-361.95411607, 20.57651509],
[-352.32671579, 20.84174084],
[-327.46028214, 20.77224385],
[-319.75994982, 20.9443245 ],
[-306.69948771, 21.24618955],
[-287.03222693, 21.43135098]])
Könnte ein heller Seele, als Sie mir geben Sie mir einige Hinweise oder Beispiele in die richtige Richtung? Alle Tipps sind willkommen!
- Sie können auch brauchen einen filter, aber ich bin nicht sicher, benötigen Sie einen Kalman-filter. Es sei denn, Sie sind sicher, Sie benötigen ein Kalman-filter würde ich vorschlagen, Fragen über, welche Art der Filterung hier benutzen: dsp.stackexchange.com
- Nicht eine Antwort auf deine Frage; aber das entfernen Werte außerhalb der 3-sigma-wird loszuwerden, alle Ihre geposteten Werte lauten und nichts anderes.
- In meinen (schwachen) Verständnis ein Kalman-filter stellt die Diskrepanzen zwischen den Vorhersagen einer (unvollkommenen) physikalisch/mathematischen Modell und der tatsächlichen (verrauschte) Messungen. — In Ihrer Problembeschreibung kann ich nicht erkennen, ein prädiktives Modell aus der position, so Frage ich mich, wenn ein Kalman-filter konnte dir helfen.
- Von dem, was ich verstehe, ein Kalman-filter, ist, dass es dauert eine Reihe von Messungen glätten Sie es heraus, so dass es verwendet werden kann, um A) die Ergebnisse, die näher an der Realität, denn Lärm ist mehr oder weniger abgebrochen, out B) erweitern Sie die gemessenen Punkte, so dass eine Vorhersage gemacht werden kann für die Punkte vor. Oder bin ich Total falsch hier?
- Können Sie nach dem code, den Sie verwendet für die Generierung von Ergebnisse auf IHRER eigenen Daten?
- Meinst du den code, mit dem ich erzeugt, die
smoothed_state_means
ich geschrieben? - Ich habe den code, den ich verwendet, um die
smoothed_state_means
zu der ersten Frage oben. Hilft das dir? - möchten Sie vielleicht check out my open-source-book "Kalman-und Bayes-Filter in Python". Es enthält sehr ähnliche Projekte. Ich glaube nicht, verwenden PyKalman, aber meine eigene Bibliothek, FilterPy, die Sie installieren können, mit pip oder mit conda. Sorry, wenn dies scheint wie eine Werbung, aber das Buch hat so ziemlich genau die Antwort auf Ihre Frage. github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python
- Ich würde schätzen, wenn Sie konnten haben Sie einen Blick auf diese und danke: stackoverflow.com/questions/44944512/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
TL;DR, finden Sie den code und Bild auf der Unterseite.
Ich denke, dass ein Kalman-filter kann ganz gut funktionieren, in Ihrer Anwendung, aber es erfordert ein wenig mehr Gedanken über die Dynamik/Physik der kite.
Ich würde dringend empfehlen, das Lesen diese Webseite. Ich habe keine Verbindung zu oder der Kenntnis des Autors, aber ich habe über einen Tag versucht, meinen Kopf Runde Kalman-Filter, und auf dieser Seite wirklich es Klick gemacht bei mir.
Kurz; für ein system ist linear, und die bekannte Dynamik (d.h. wenn Sie wissen, den Staat und Eingänge, Sie können die Zukunft Vorhersagen-Zustand), es bietet eine optimale Kombination, was Sie wissen über ein system zu schätzen, ist es wahre Staat. Der schlaue (die kümmern sich alle matrix-algebra, die Sie sehen, auf den Seiten, es zu beschreiben) ist, wie es optimal verbindet die beiden Stücke von Informationen, die Sie haben:
Messungen (die unter "Messung von Lärm", also sensoren nicht perfekt)
Dynamik (d.h. wie Sie glauben, dass Staaten sich entwickeln unterliegen Eingaben, die unter "Prozess " Rauschen", das ist nur eine Art zu sagen, das Modell nicht mit der Realität übereinstimmen perfekt).
Können Sie angeben, wie sicher Sie sind auf jeder dieser (über die co-Varianzen Matrizen R und Q beziehungsweise), und die Kalman-Gain bestimmt, wie viel Sie glauben, Ihr Modell (z.B. Ihre aktuelle Einschätzung Ihres Staates), und wie viel Sie glauben, dass Ihre Messungen.
Kurzerhand bauen wir ein einfaches Modell von Ihrem kite. Was ich Vorschlage, unten ist ein sehr einfaches Modell möglich. Sie vielleicht wissen, mehr über die Drachen und die Dynamik so schaffen kann, eine bessere.
Behandeln wir den kite wie ein Teilchen (natürlich eine Vereinfachung, eine echte kite ist ein erweiterter Körper, so hat eine Ausrichtung in 3 Dimensionen), die vier Staaten, die für die Bequemlichkeit, können wir schreiben in einem Zustand Vektor:
x = [x, x_dot, y, y_dot],
Wobei x und y sind die Positionen, und die _dot sind die Geschwindigkeiten in den einzelnen Richtungen. Ihre Frage ich nehme an, es sind zwei (verrauschte) Messungen, die wir schreiben können in einer Messung Vektor:
z = [x, y],
Können wir schreiben-down-Messung matrix (H diskutiert hier, und
observation_matrices
impykalman
Bibliothek):z = Hx => H = [[1, 0, 0, 0], [0, 0, 1, 0]]
Dann müssen wir beschreiben die Dynamik des Systems. Hier gehe ich davon aus, dass keine äußeren Kräfte wirken, und dass es keine Dämpfung auf die Bewegung des Kites (mit mehr wissen können Sie in der Lage sein, besser zu machen, diese effektiv behandelt externe Kräfte und Dämpfung als unbekannt/unmodeled Störung).
In diesem Fall die Dynamik für jeden unserer Staaten in der aktuellen Probe "k" als Funktion von Zuständen in den vorherigen Proben "k-1" sind gegeben als:
x(k) = x(k-1) + dt*x_dot(k-1)
x_dot(k) = x_dot(k-1)
y(k) = y(k-1) + dt*y_dot(k-1)
y_dot(k) = y_dot(k-1)
Wobei "dt" ist die Zeit-Schritt. Wir nehmen an (x, y) - position aktualisiert wird, basierend auf der aktuellen position und Geschwindigkeit, und die Geschwindigkeit bleibt unverändert. Gegeben, dass keine Einheiten gegeben sind, können wir nur sagen, die velocity-Einheiten sind solche, die wir weglassen können "dt" aus den obigen Gleichungen, D. H. in Einheiten von position_units/sample_interval (ich nehme an, Ihr gemessenen Proben sind in einem Konstanten Intervall). Wir können zusammenfassen, dass diese vier Gleichungen in ein Dynamik-matrix als (F hier diskutiert, und
transition_matrices
impykalman
Bibliothek):x(k) = Fx(k-1) => F = [[1, 1, 0, 0], [0, 1, 0, 0], [0, 0, 1, 1], [0, 0, 0, 1]].
Können wir nun mal an mit dem Kalman-filter in python. Geändert von deine-code:
Produziert die folgenden zeigen, es macht einen angemessenen job, der Ablehnung der Lärm (blau ist die x-position, rot ist die y-position und x-Achse ist nur Beispiel-Zahl).
Nehme an, Sie schauen auf das Grundstück vor und denke, es sieht holprig. Wie könnte man das beheben? Wie oben erörtert, ein Kalman-filter ist die auf zwei Stücke von Informationen:
Die Dynamik im Modell erfasst, die oben sind sehr einfach. Wörtlich genommen sagen Sie, dass die Positionen aktualisiert werden, indem aktuelle Geschwindigkeiten (in einem offensichtlichen, körperlich angemessenen Art und Weise), und dass die Geschwindigkeiten konstant bleiben (dies ist eindeutig nicht physisch wahr, aber fängt unsere intuition, die Geschwindigkeiten sollte sich langsam ändern).
Wenn wir denken, dass der geschätzte Zustand sein sollte, glatter, ein Weg dies zu erreichen ist, zu sagen, wir haben weniger Vertrauen in unsere Messungen als unsere Dynamik (d.h. wir haben eine höhere
observation_covariance
, im Vergleich zu unserenstate_covariance
).Ab Ende der code oben, fixieren Sie die
observation covariance
zu 10-fache Wert von schätzungsweise zuvor, Einstellungem_vars
wie dargestellt, ist erforderlich, um zu vermeiden re-Schätzung der Beobachtung, die Kovarianz (siehe hier)Erzeugt der plot unten (Messdaten als Punkte, Staat schätzt, gepunktete Linie). Der Unterschied ist eher subtil, aber hoffentlich können Sie sehen, dass es glatter.
Schließlich, wenn Sie wollen verwenden Sie diese filter ausgestattet on-line, können Sie dies mit Hilfe der
filter_update
Methode. Beachten Sie, dass diese verwendet diefilter
- Methode, anstatt diesmooth
Methode, da diesmooth
Methode kann nur angewendet werden, um batch-Messungen. Mehr hier:Plot unten zeigt die Leistung der filter-Methode, einschließlich 3 Punkte gefunden mit der
filter_update
Methode. Punkte sind Messungen, gestrichelte Linie sind die staatlichen Schätzungen für die filter-training Periode, durchgezogene Linie sind Staaten die Schätzungen für "on-line" - Periode.Und die timing-Informationen (auf meinem laptop).
kf = kf.em(measurements, n_iter=5)
dauert zu lange für Sie in der Lage sein zu berechnen, ist es 25-mal pro Sekunde (das ist die frame rate des video-footage). Dies ist wahrscheinlich eine lange gedreht, aber würde Sie keine Möglichkeit sehen, für performance-Verbesserungen mit dieser Funktion?kf.em
online. Das ist, zu versuchen, "fit" - filter, können Sie stattdessen verwenden Sie einen pre-filter ausgebildet, mehr zu tun Schätzung. Sie möchten vielleicht gelegentlich re-passen Sie Ihre filter (im Fall der Messung der Lärm steigt, oder kite Dynamik ändern).Von dem, was ich sehen kann, mit Kalman-filtern " ist vielleicht nicht das richtige Werkzeug, in Ihrem Fall.
Was über es zu tun auf DIESE Weise? :
Hier ist die Ausgabe:
Sehen hier für einige mehr und die Quelle habe ich den obigen code aus.