Schätzen von Parabel-Parametern anhand von Messwerten |
09.07.2020, 10:54 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Schätzen von Parabel-Parametern anhand von Messwerten ich möchte gerne Messwerte, die einer auf dem Kopf stehenden Parabel ähneln, fitten. Ich nutze dafür die C-Bibliothek lmfit. Hierfür muss man allerdings Startwerte für die Parabel-Parameter übergeben und wenn die Startwerte schlecht sind, dann kann es sein, dass Blödsinn herauskommt. Nun würde ich gerne herausfinden, wie ich an gute Startwerte herankomme. Wenn die Parabelfunktion folgendermaßen aussieht: Dann kann ich sagen, dass wenn die Parabel auf dem Kopf steht und alle Funktionswerte positiv sind, dass dann negativ und wahrscheinlich positiv ist. Über bin ich mir im unklaren. Das ist schon mal kein schlechter Anfang, aber das reicht nicht immer aus. Kann man das noch besser eingrenzen, auch was die Größenordnung angeht? Danke im Voraus. MatheKind |
||||||||
09.07.2020, 11:20 | Huggy | Auf diesen Beitrag antworten » | ||||||
RE: Schätzen von Parabel-Parametern anhand von Messwerten Schätze die Parameter der Parabel mit der Methode der kleinsten Quadrate. Da brauchst du keine Anfangswerte. |
||||||||
09.07.2020, 11:32 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Diese MKQ kann man in den Kontext "Multiple Lineare Regression" einbetten, so wie hier für Polynomgrad 6 beschrieben. Du hier benötigst nur Grad 2, was die Matrixdimension schon mal auf 3x3 reduziert. |
||||||||
09.07.2020, 12:41 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Das werde ich mal ausprobieren, vielen Dank!!! Liebe Grüße, MatheKind |
||||||||
09.07.2020, 12:46 | Huggy | Auf diesen Beitrag antworten » | ||||||
Auch wenn ich kein C-Programmierer bin, vermute ich stark, dass man dafür in C-Bibliotheken ein fertiges Programm findet. |
||||||||
09.07.2020, 14:08 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Gut möglich. Aber auch mit nur einer gewöhnlichen LinAlg-Bibliothek ist der Programmieraufwand für noch sehr überschaubar. |
||||||||
Anzeige | ||||||||
|
||||||||
09.07.2020, 14:23 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Super, das hat geklappt, vielen Dank!!! Zum Lösen von habe ich OpenCV benutzt, da ich diese Bibliothek sowieso benutze. Von daher brauche ich kein lmfit mehr, da das Overkill ist. lmfit fittet nämlich jede beliebige Funktion die man übergibt. |
||||||||
09.07.2020, 18:32 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Ich mache gerade die Erfahrung von numerischen Instabilitäten. Bei kleinen x-Werten (und großen y-Werten?), bekomme ich vollkommenen Unsinn heraus. Gibt es einen Trick, wie ich das Problem umgehen kann? |
||||||||
09.07.2020, 21:38 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Ich habe bei einer numpy-Bibliothek gelesen, dass man für eine bessere numerische Stabilität den X-Vektor zentrieren sollte, in dem man den Mittelwert abzieht: Die Frage ist nun, wie ich die gefitteten Parameter anpassen muss, damit ich dieselben Parameter zurückbekomme als wenn ich nicht vorher zentriert hätte. Jemand eine Idee? |
||||||||
10.07.2020, 08:51 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||
Das sollte doch zu schaffen sein: Viele Grüße Steffen |
||||||||
10.07.2020, 10:43 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Das ist generell zu empfehlen, wenn die Spreizung der x-Daten (etwa charakterisiert durch deren Standardabweichung) um Größenordnungen kleiner ist als die absolute Lage (etwa charakterisiert durch deren Mittelwert). Das Problem wird auch umso größer, wenn man mit ungenauerer Arithmetik (etwa nur 32Bit-Single-Floating Point) arbeitet. Da ist dann die genannte Zentrierung dann dringend anratsam. |
||||||||
10.07.2020, 10:57 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Alternativ könnte ich aber auch die X-Werte mit einem größeren Faktor skalieren. Das vergrößert ja ebenfalls die Spreizung. Oder irre ich mich da? @Steffen Bühler: Danke, das werde ich mir mal anschauen. |
||||||||
10.07.2020, 10:59 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Und im gleichen Maße den Mittelwert... Nein, bloßes Multiplizieren löst das Problem nicht. |
||||||||
10.07.2020, 11:40 | MatheKind | Auf diesen Beitrag antworten » | ||||||
@HAL 9000 Da hast du recht.
Mir ist nicht klar, wie sich das verallgemeinern ließe, so dass ich für jedes Polynom die korrigierten Parameter-Werte zurückgeben kann. |
||||||||
10.07.2020, 13:07 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||
Also gilt bei für die zu korrigierenden Parameter : |
||||||||
10.07.2020, 13:42 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Eigentlich ist es so, dass man auch die Rechnungen mit der fertigen Parabel besser im verschobenen Koordinatensystem durchführen sollte, denn das Numerikproblem durch Auslöschung besteht ja dort auch: Man hat also wenig gewonnen, wenn man zwar die Regression numerisch stabil bis hin zu den Koeffizienten geführt hat, es aber anschließend durch die Rechnung statt numerisch wieder "versaut". |
||||||||
10.07.2020, 14:20 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Also ich kann rein praktisch sagen, dass Skalieren massiv(!) hilft! Viel besser als zentrieren! Ich halte das auch für einleuchtend, denn ich hatte gelernt, dass wenn durch kleine Zahlen geteilt wird, der Fehler schnell wächst. Teilt man durch große Zahlen, dann sinkt der Fehler (oder er wächst nicht so schnell. Eins von beiden). Da ja man die Inverse von X berechnet, ist das ja wie ein Teilen. Oder habe ich da etwas falsch verstanden? Man muss dann beim Zurückrechnen der Parameter wieder skalieren mit , wobei der Skalierungsfaktor ist und die Potenz des Parameters. |
||||||||
10.07.2020, 14:22 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Danke, das schaue ich mir Zuhause mal genauer an. Der Einwand von HAL 9000 gibt mir aber zu bedenken. EDIT: Eigentlich meinte ich eine Verallgemeinerung eines Poynoms k-ten Grades. Ich will den Algorithmus nämlich allgemein implementieren. |
||||||||
10.07.2020, 14:31 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Bei Verwendung von Floating-Point-Zahlen muss ich diese Aussage als reinsten Humbug klassifizieren. Falls du natürlich mit Festkomma- oder Integerzahlen rechnest, dann kann was dran sein - aber das hatte ich nicht angenommen. |
||||||||
10.07.2020, 14:35 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Ich verwende double-Werte und ich kann das rein praktisch nachvollziehen. Was ist mit meiner Begründung, die ich geliefert habe? Teilen durch kleine Zahlen vs. Teilen durch große Zahlen. |
||||||||
10.07.2020, 14:37 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Reines Skalieren bringt hier numerisch gar nichts. Den einzigen Sinn von Skalieren würde ich darin sehen, wenn man sich mit den Werten gefährlich nahe den Bereichsgrenzen des jeweiligen Datenformats nähert (das ist bei 32Bit-Single ca. ), und das muss man auch für die Zwischenwerte wie die beachten. Bei 64Bit-Double muss man schon mit sehr exotischen Werten hantieren, dass man sich der Grenze gefährlich nähert. Wenn du aber in deinen Code irgendwelchen Unfug wie solche absoluten Vergleiche eingebaut hast, dann können natürlich die seltsamsten Dinge passieren. Aber sowas macht man ja vernünftigerweise auch nicht. |
||||||||
10.07.2020, 14:52 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Möglicherweise hast du recht, aber ich kann das Ergebnis andererseits nicht ignorieren. Ich habe keine Ahnung, was cv::solve() von OpenCV alles macht, damit sich das so verhält. Schreibe ich die Formel übrigens explizit hin, verhält sich das noch instabiler. Letztendlich bin ich Informatiker und kein Mathematiker... Was hast du studiert, wenn ich fragen darf? PS: habe ich nun umgesetzt, aber das ändert nichts am Verhalten. |
||||||||
10.07.2020, 14:55 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Mathematik, arbeite aber seit 15 Jahren im wesentlichen als Software-Ingenieur. Ich weiß also, wovon ich spreche. |
||||||||
10.07.2020, 16:14 | Ulrich Ruhnau | Auf diesen Beitrag antworten » | ||||||
Wenn das Dein Problem ist, mußt Du etwas falsch gemacht haben. Wichtig ist hier, daß Du die Parabel danach auswertest, wo ihr Extrempunkt liegt. . Wenn Du die Werte zentrierst, also von allen an der Parabel beteiligten -Werten den Wert abziehst, dann liegt der Extrempunkt um den Wert nach links verschoben. Man muß sich außerdem überlegen, wieviele Punkte man zum Fitten einsetzt. Nimmt man zu viele, wird man dadurch ungenau. Um das Ergebnis zu prüfen, schaue ich mir Daten nebst Fitparabel und Extemwert an. Das ist wichtig, weil ein Fehler alles nur schlimmer macht. Du kannst ja ein paar Probedaten hier einstellen. |
||||||||
10.07.2020, 20:42 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Das ist mir bekannt: Wenn der Mittelwert abgezogen wurde, dann:
Den Optimalfall will ich erst mal nicht testen, sondern erst mal nur, wie stabil das Verfahren ist. Die Dinge sind folgende: - Das Fitting funktioniert ja für viele Beispiele ziemlich gut, aber es gibt ein Beispiel, wo das nicht funktioniert. Hier liegen die X-Werte irgendwo im Bereich von , wenn ich das richtig in Erinnerung habe. Die y-Werte liegen im Bereich von . Und es kommt vollkommener Quatsch heraus, was aussieht wie eine Gerade. - Verwende ich beim besagten Beispiel statt OpenCV die GNU Scientific Library (aufgrund der GPL-Lizenz darf ich die aber nicht verwenden), erhalte ich die korrekten Werte. Im Falle von OpenCV wird beim besagten Beispiel nur dann richtig gerechnet, wenn ich den X-Vektor um den Faktor 10.000 skaliere und die gefitteten Parameter um diesen Faktor wieder skaliere (wie oben beschrieben. Der Anwender meiner Funktion soll nämlich davon nichts wissen). Das besagte Signal kann ich evtl. am Montag hochladen, wenn mir das mein Vorgesetzter erlaubt. |
||||||||
10.07.2020, 23:16 | Ulrich Ruhnau | Auf diesen Beitrag antworten » | ||||||
Wir brauchen x- und y-Werte in Textform z.B. als Textdatei. |
||||||||
11.07.2020, 11:29 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||
Dir ist schon klar, dass das hier dann also eine gewerbliche Nutzung des Matheboards ist? Aus unseren Nutzungsbedingungen:
Oder hast Du das mit den Betreibern abgestimmt? |
||||||||
11.07.2020, 13:54 | MatheKind | Auf diesen Beitrag antworten » | ||||||
In dem Fall würde ich evtl. ein Ticket beim OpenCV-Projekt eröffnen. Aber letztendlich ist das ja eine freiwillige Arbeit der Community. |
||||||||
11.07.2020, 14:21 | Steffen Bühler | Auf diesen Beitrag antworten » | ||||||
Nein, es geht um dieses Board, das Du, spitzfindig ausgedrückt, verwendest, damit Dein Arbeitgeber Geld verdient. Der Parabelfit optimiert vielleicht irgendeinen Prozess, das spart Zeit und ist damit ein unversteuerter geldwerter Vorteil. Wir sehen das, soviel ich weiß, normalerweise nicht so eng, aber es sollte Dir bewusst sein. Wie gesagt, kläre das eventuell mit den Admins ab. |
||||||||
13.07.2020, 08:32 | Ulrich Ruhnau | Auf diesen Beitrag antworten » | ||||||
Steffen, was soll das? Hier fragt Mathekind etwas ohne dafür Geld zu bezahlen. Damit steht die private Nutzung außer Zweifel. Ob Mathekind seine Erkenntnisse nach Befragung von Matheboard für seinen Beruf nutzt, ist doch nicht wichtig. Auch die Schüler, welche Matheboard nutzen, werden später ihre hier erworbenen Kenntnisse kommerziell einsetzen. Die von Dir zitierten Regeln sollen nur sicherstellen, daß sich niemand hier seine Dienstleistungen bezahlen läßt. |
||||||||
13.07.2020, 08:32 | Thomas | Auf diesen Beitrag antworten » | ||||||
Geht aus meiner Sicht in Ordnung. |
||||||||
13.07.2020, 10:33 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Anbei findet ihr das Signal. Achtung: Die erste Spalte ist das Signal und die zweite die Position. Die Position muss noch beim Einlesen durch 1'000'000'000 geteilt werden. Die korrekten Parameter sollten ungefähr in diesem Bereich liegen: a: -1,753501E+25 b: 5,052680E+17 c: -3,639784E+09 Den C++ Code findet ihr hier: https://github.com/opencv/opencv/issues/17824 EDIT: Ich habe die Parameter kurz editiert. Also was herauskommen sollte. Im ursprünglichen Post, waren das noch die mit der falschen Skalierung. |
||||||||
13.07.2020, 11:46 | Ulrich Ruhnau | Auf diesen Beitrag antworten » | ||||||
Nein! In diesem Bereich liegen Deine Punkte bestimmt nicht. Ich habe Deine Werte mal analysiert. Man hat ungeordnete x-Werte von 14.38 bis 14.44 und ganzzahlige vierstellige y-Werte. Um die Daten zu lesen, muß man die Kommata durch Punkte ersetzen. In jeder Zeile stehen ein y-Wert, dann ein Semikolon und dann ein x-Wert. Zu schauen, was man da machen kann erfordert etwas Zeit. Man könnte ein kompliziertes Programm schreiben, daß das ganze als Gaußkurve plus Gerade interpretiert. Oder man schreibt eine einfacheres Programm, das maximale y-Werte sucht und dort ein Polynom fittet. Damit werde ich mich beschäftigen, wenn ich dafür Zeit habe (heute, morgen, übermorgen). [attach]51703[/attach] |
||||||||
13.07.2020, 12:11 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Sorry, ich hatte zuerst falsche Parameter reinkopiert. Die kommen zustande, wenn ich nicht skaliere. Ich habe das nun korrigiert. Das ist auch nur ein Test, den ich so in der Praxis nicht anwenden würde. Es geht mir viel mehr um einen Stresstest. |
||||||||
13.07.2020, 12:26 | Nils Hoppenstedt | Auf diesen Beitrag antworten » | ||||||
Sieht eher nach einer Lorentzkurve aus. https://de.wikipedia.org/wiki/Lorentzkurve |
||||||||
13.07.2020, 13:54 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Hallo, ich wollte nochmal anmerken, dass es mir hier nur um einen Stresstest meiner Polyfit-Funktion geht. Skaliere ich die X-Werte nicht, bekomme ich als gefittetes Signal etwas, das wie eine Gerade aussieht: a: -1,753501E+41 b: 5,052680E+33 c: -3,639784E+09 Skaliere ich die X-Werte mit 10.000 und korrigiere das dann wieder, erhalte ich folgende Parameter und das obige geplottete Fitting-Signal: a: -1,753501E+25 b: 5,052680E+17 c: -3,639784E+09 Etwas kann also hier nicht stimmen und darum geht es mir letztendlich. |
||||||||
13.07.2020, 18:54 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Die Mantissen scheinen zu stimmen, aber die 10er-Potenz-Exponenten sind bei komplett durchgeknallt. Richtig ist mit deinen obigen Originaldaten Wie du auf die Exponenten 41/33 bzw. dann 25/17 kommst, ist mir unerklärlich. P.S.: Quadratische Funktion als Anpassung scheint hier wohl wirklich ziemlich ungeeignet zu sein. |
||||||||
13.07.2020, 21:24 | MatheKind | Auf diesen Beitrag antworten » | ||||||
Möglicherweise hast du die Positionsdaten nicht durch 1'000'000'000 geteilt. PS: In der Praxis wird auch nur der Hut der Funktion gefittet. Also nicht die ganze Funktion. |
||||||||
13.07.2020, 22:26 | HAL 9000 | Auf diesen Beitrag antworten » | ||||||
Wenn man dich nicht beim Wort nehmen kann
ist jede weitere Betrachtung sinnlos. Außerdem erklärt auch diese jetzt von dir aus dem Hut gezauberte Skalierung nicht diese bescheuerten Exponenten. |
||||||||
13.07.2020, 23:51 | Ulrich Ruhnau | Auf diesen Beitrag antworten » | ||||||
Auch ohne Skalierung kann ich deinen zweiten Satz an Parametern ermitteln. Aber ich will hier auf etwas anderes hinaus. Wenn man die ganze Funktion mit 3100 Wertepaaren gut fitten möchte, dann ist ein Rationaler Polynomfit am besten. Mit einem Quotienten aus zwei Polynomen (gelb) von gelingt zwar ein besserer Fit als mit einem Polynom, jedoch hätte man da immer noch das Problem, den Extrempunkt nicht einfach ermitteln zu können. Praktikabler wäre es also, die Punkte in der Nähe des Maximums zu nehmen und dort eine Parabel zu fitten. Das habe ich gemacht und dabei das Polynom (rot) erhalten. Dazu mußte ich erst einmal die Punkte nach ihren x-Werten sortieren, dann das Wertepaar mit maximalem y bestimmen, dann 200 Punkte davor und dahinter nehmen und den Rest abschneiden. Der Fit durch 401 Punkte liefert mir die rote Parabel: Das ergibt ein Maximum an der Stelle (vertikale Linie) [attach]51716[/attach] Fazit: Man kann die Daten so aufbereiten, daß ein Maximalwert ermittelt wird. Dazu muß man die Daten nach x-Werten sortieren, das y-Maximum suchen, und den Parabelfit auf eine Umgebung des y-Maximums beschränken. |
|
Verwandte Themen
Die Beliebtesten » |
|
Die Größten » |
|
Die Neuesten » |