2D-GAUSS-Fit für die Intensitäten an bestimmten Koordinaten in Python
Habe ich eine Reihe von Koordinaten (x, y, z(x, y)), die beschreiben, Intensität (z) mit den Koordinaten x, y. Für eine festgelegte Anzahl von diese Intensitäten an verschiedenen Koordinaten, die ich brauche, um fit 2D-GAUSS-das minimiert den mean squared error.
Die Daten werden in numpy-Matrizen und bei jeder Anprobe habe ich entweder 4, 9, 16 oder 25 Koordinaten. Letztlich brauche ich nur, um die zentrale position der Gauß-Kurve (x_0, y_0), die kleinsten MSE.
Alle Beispiele, die ich gefunden habe, verwenden scipy.optimieren.curve_fit, aber die Eingabe von Daten ist über das gesamte Netz eher als ein paar Koordinaten.
Jede Hilfe würde geschätzt werden.
- Was ist Ihr Ausgangspunkt. Können Sie einige code, um zu diskutieren? Das ist, was DAMIT gemeint ist, für!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einführung
Gibt es mehrere Möglichkeiten, dies zu nähern. Sie können nicht-lineare Methoden (z.B.
scipy.optimize.curve_fit
), aber Sie werden langsamer und sind nicht garantiert, um zu konvergieren. Sie können linearisieren das problem (schnelle, eindeutige Lösung), aber jedes Geräusch in der "Schwänze" der Verteilung Probleme bereiten. Es gibt tatsächlich ein paar tricks, die Sie anwenden können, um diesem besonderen Fall zu vermeiden das zweite Problem. Ich werde ein paar Beispiele zeigen, aber ich habe nicht Zeit zu zeigen, alle "tricks" jetzt.Nur als Randnotiz, eine Allgemeine 2D-guassian hat 6 Parameter, so werden Sie nicht in der Lage, vollständig passen die Dinge mit 4 Punkten. Aber es klingt wie Sie sein könnte, unter der Annahme, dass es keine Kovarianz zwischen x und y und der Varianzen in jeder Richtung (d.h. eine vollkommen "Runde" bell-Kurve). Wenn das der Fall ist, dann brauchen Sie nur vier Parameter. Wenn Sie wissen, die amplitude der guassian, müssen Sie nur drei. Aber ich werde beginnen mit der Allgemeinen Lösung und vereinfachen Sie es später, wenn Sie wollen.
Für den moment konzentrieren wir uns auf die Lösung dieses problem mit nicht-linearen Methoden (z.B.
scipy.optimize.curve_fit
).Die Allgemeine Gleichung für eine 2D-guassian ist (direkt aus der wikipedia):
wo:
ist im wesentlichen 0.5 über die Kovarianz-matrix A ist die amplitude,
und (X₀, Y₀) ist das Zentrum
Generieren vereinfachte Beispieldaten
Schreiben wir die obige Gleichung aus:
Und dann lassen Sie uns generieren Sie einige Beispiel-Daten. So starten Sie mit, wir erstellen einige Daten, die leicht zu passen:
Beachten Sie, dass wir noch nicht Hinzugefügt, jedes Geräusch, und das Zentrum der Verteilung liegt innerhalb der Bandbreite, die wir haben die Daten (also center bei 0,3, 0,7 und eine Streuung in den x -, y-Beobachtungen zwischen 0 und 1). Für den moment bleiben wir bei dieser, und dann werden wir sehen, was passiert, wenn wir den Rauschen-hinzufügen-und-shift-Zentrum.
Nicht-linearen Montage
So starten Sie mit, lassen Sie uns
scpy.optimize.curve_fit
Vorform einer nicht-linearen least-squares-fit der Gauß-Funktion. (On a side note, Sie können spielen, um mit der exakten Minimierung Algorithmus durch einige der anderen Funktionen inscipy.optimize
.)Den
scipy.optimize
Funktionen erwarten eine etwas andere Funktion Unterschrift als die, die wir ursprünglich oben schrieb. Wir könnten schreiben eine wrapper-zu "übersetzen", aber lasst uns einfach neu schreiben Sie diegauss2d
- Funktion statt:Alles, was wir Taten, war die Funktion haben, erwarten, dass die unabhängigen Variablen (x & y) als Einzel-2xN-array.
Nun müssen wir eine erste Vermutung an, was die guassian Kurve die Parameter tatsächlich sind. Dies ist optional (der Standard ist alle lieben, wenn ich mich Recht erinnere), aber du bist wahrscheinlich Probleme konvergiert, wenn 1 1 ist nicht besonders nah an die "wahre" Zentrum der Gauß-Kurve. Aus diesem Grund verwenden wir die x-und y-Werte, die unsere größte beobachtete z-Wert, die als Ausgangspunkt für das Zentrum. Ich lasse den rest der Parameter als 1, aber wenn Sie wissen, dass Sie wahrscheinlich durchweg signifikant Verschieden sein, ändern Sie Sie, um etwas mehr zumutbar ist.
Hier die komplette stand-alone-Beispiel:
In diesem Fall genau(ish) die Wiedergewinnung der ursprünglichen, "wahren" Parameter.
Wie wir gleich sehen werden, ist dieses nicht immer der Fall sein wird...
Hinzufügen Von Rauschen
Fügen wir einige Geräusche unserer Beobachtungen. Alles was ich getan habe, ist hier ändern Sie die
generate_example_data
Funktion:Aber das Ergebnis sieht ganz anders aus:
Soweit es die Parameter:
Den vorhergesagten center hat sich nicht viel verändert, aber die
b
undc
Parameter haben sich ziemlich geändert.Wenn wir die änderung der Mitte der Funktion irgendwo etwas außerhalb unserer Streuung der Punkte:
Bekommen wir mit kompletter Unsinn als Ergebnis in der Gegenwart von Rauschen! (Es funktioniert immer noch einwandfrei, ohne Geräusche.)
Dies ist ein häufiges problem beim Einbau einer Funktion, die zerfällt zu null. Jeglicher Lärm in den "tails" führen kann, in einem sehr schlechten Ergebnis. Es gibt eine Reihe von Strategien für den Umgang mit diesem. Eine der einfachsten ist es, das Gewicht der inversion durch die beobachteten z-Werte. Hier ist ein Beispiel für den 1D-Fall: (mit dem Fokus auf der linearisierten problem) Wie kann ich eine least-squares fitting über mehrere Daten-sets schnell? Wenn ich Zeit habe, später werde ich ein Beispiel für den 2D-Fall.