Fitten von Daten - Gewichtung

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
zweihorn
User
Beiträge: 27
Registriert: Donnerstag 11. Mai 2017, 17:09

Montag 16. April 2018, 21:19

Hallo!

Ich habe mal eine allgemeine Frage zum fitten von Daten bei denen eine ungleiche Gewichtung berücksichtigt werden soll. Als Beispiel: Man nehme fünf x-y-Paare bei denen das erste z.B. fünffach und das dritte 0,2-fach gewichtet werden soll.

Wie wird denn normalerweise eine solche Gewichtung umgesetzt? Nach meinen Recherchen gibt es diverse Möglichkeiten diese zu definieren (1/y oder 1/Sigma oder 1/(Sigma^2), etc.)

Normalerweise fitte ich meine Daten mit scipy.curve_fit und dort kann ich nur ein Sigma angeben (relativ oder absolut).

Gibt es da allgemeine „Kochrezepte“ oder Literatur ohne, dass ich gleich tief in die Statistik einsteigen muss?


Danke!
Benutzeravatar
kbr
User
Beiträge: 871
Registriert: Mittwoch 15. Oktober 2008, 09:27

Montag 16. April 2018, 21:32

@zweihorn: Dies nennt man Kurvenanpassung anhand er kleinsten Fehlerquadrate. Du musst Deine (Mess-)Punkte mit Fehlertoleranzen versehen. Je kleiner der Fehler, desto stärker die Gewichtung. Dazu gibt es Literatur, aber ohne Statistik bzw. Mathematik geht das nicht.
Benutzeravatar
MagBen
User
Beiträge: 768
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Dienstag 17. April 2018, 07:25

Das steuerst du über die Parameter absolute_sigma und sigma:
https://docs.scipy.org/doc/scipy-0.18.1 ... e_fit.html
"absolute_sigma : bool, optional
If False, sigma denotes relative weights of the data points."
a fool with a tool is still a fool, www.magben.de, YouTube
zweihorn
User
Beiträge: 27
Registriert: Donnerstag 11. Mai 2017, 17:09

Dienstag 17. April 2018, 07:29

Danke für deine Antwort, allerdings ist mir das schon bewusst. Ich habe den Post gestern vom Handy aus verfasst und mich wohl etwas zu kurz gefasst.

Mir geht es darum, wie ich möglichst einfach eine Gewichtung mit curve_fit realisieren kann. Wenn ich die Doku richtig verstanden habe, dann minimiert curve_fit das chi^2 sobald ich ein sigma angebe. Außerdem sollten die Gewichte die ich angeben muss 1/sigma sein, wenn ich das richtig sehe. Reicht es dann, wenn man das kleine Beispiel im Eingangspost nimmt, wenn ich curve_fit folgendes sigma gebe:
sigma=np.array([1/5,1,1/0.2,1,1]). Da das ja nun keine echten Unsicherheiten sind, tue ich mir da bei der Umsetzung etwas schwer. Außerdem gibt es noch einen Unterschied ob man ein relatives oder absolutes sigma angibt. Was macht das denn für einen Unterschied und welches der beiden sollte ich in meinem Fall den nutzen?

Das Problem ist halt, dass in Statistik-Lehrbüchern sehr viel mehr (und meist auch noch in anderen Worten) steht. Da fällt es mir schwer das notwendige vom überflüssigen zu trennen.

Danke!

Edit: @MagBe dein Post hat sich überschnitten, könntest du das evtl. etwas detaillierter ausführen?
Benutzeravatar
MagBen
User
Beiträge: 768
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Dienstag 17. April 2018, 07:54

zweihorn hat geschrieben:Man nehme fünf x-y-Paare bei denen das erste z.B. fünffach und das dritte 0,2-fach gewichtet werden soll.
curve_fit(..., sigma=[5, 1, 0.2, 1, 1], absolute_sigma=True, ...)
Mit "absolute_sigma=True" übergibst du mit dem Parameter sigma nicht das mathematische Sigma, sondern die Gewichte.
zweihorn hat geschrieben:Mir geht es darum, wie ich möglichst einfach eine Gewichtung mit curve_fit realisieren kann.
Ich finde das ist einfach.
zweihorn hat geschrieben:Außerdem sollten die Gewichte die ich angeben muss 1/sigma sein, wenn ich das richtig sehe.
Wer sagt das? Steht das so in der Aufgabe drin oder meinst du das aus der Doku gelesen zu haben?
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
MagBen
User
Beiträge: 768
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Dienstag 17. April 2018, 10:20

MagBen hat geschrieben:curve_fit(..., sigma=[5, 1, 0.2, 1, 1], absolute_sigma=True, ...)
Mit "absolute_sigma=True" übergibst du mit dem Parameter sigma nicht das mathematische Sigma, sondern die Gewichte.
Korrektur:
curve_fit(..., sigma=[5, 1, 0.2, 1, 1], absolute_sigma=False, ...)
Mit "absolute_sigma=False" übergibst du mit dem Parameter sigma nicht das mathematische Sigma, sondern die Gewichte.
a fool with a tool is still a fool, www.magben.de, YouTube
zweihorn
User
Beiträge: 27
Registriert: Donnerstag 11. Mai 2017, 17:09

Dienstag 17. April 2018, 12:18

Ja, das ist einfach, so habe ich das auch gemacht (bis auf die Sache mit den reziproken Gewichten). Ich war mir nur nicht sicher, ob das so korrekt ist.

Das ich die Gewichte reziprok nehmen muss, habe ich in einer etwas älteren GitHub Diskussion gefunden aber ich weiß nicht ob das veraltet ist oder ich etwas missverstanden habe.


Zusatzfrage: Ich habe eine Reihe von Messwerten sowie eine Modellfunktion und die bereits gefitteten Parameter. Nun habe ich versucht mit curve_fit den originalen Fit nachzubilden (als Übung). Dazu habe ich die Modell-Funktion in Python abgebildet und anschließend curve_fit darauf losgelassen. Als Startwerte für die einzelnen Parameter habe ich curve_fit die Parameter aus dem Beispiel gegeben. Erwartet hätte ich nun, dass curve_fit (im Rahmen der numerischen Genauigkeit) die selben Parameter liefert und die beiden Regressions-Kurven identisch aussehen.

Leider oszilliert meine Kurve zwischen den Stützstellen, was die Originalkurve nicht macht. Kann sich da jemand einen Reim drauf machen, da die Modell-Funktion ja identisch ist. Gibt es eine Möglichkeit das irgendwie "steifer" zu machen?

Danke!
Benutzeravatar
MagBen
User
Beiträge: 768
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Dienstag 17. April 2018, 15:02

zweihorn hat geschrieben:Leider oszilliert meine Kurve zwischen den Stützstellen, was die Originalkurve nicht macht. Kann sich da jemand einen Reim drauf machen, da die Modell-Funktion ja identisch ist. Gibt es eine Möglichkeit das irgendwie "steifer" zu machen?
Wenn die gefittete Kurve zwischen den Stützstellen oszilliert, dann ist die Ordnung der Kurve im Vergleich zur Anzahl der Stützstellen zu hoch.
a fool with a tool is still a fool, www.magben.de, YouTube
zweihorn
User
Beiträge: 27
Registriert: Donnerstag 11. Mai 2017, 17:09

Dienstag 17. April 2018, 15:28

ja, klar. Aber weshalb oszilliert der originale Fit nicht, der die identische Modell-Funktion (von der gleichen Ordnung) nutzt?
zweihorn
User
Beiträge: 27
Registriert: Donnerstag 11. Mai 2017, 17:09

Donnerstag 19. April 2018, 07:49

also wenn ich das anhand eines simplen Beispiels teste, dann muss ich die Gewichte doch reziprok angeben:

Man beachte, dass der Ausreißer übergewichtet werden soll!

Ob absolute_sigma nun ture oder false ist, scheint nichts zu ändern.

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as sc

x = np.array([1,2,3,4,5,6,7])
y = np.array([1,2,3,7,5,6,7])

sigma1 = np.array([1,1,1,10,1,1,1])
sigma2 = np.array([1,1,1,0.1,1,1,1])

plt.plot(x,y,'ro')

A = sc.curve_fit(lambda t,a: a*t, x, y, sigma=sigma1, absolute_sigma=False)
B = sc.curve_fit(lambda t,a: a*t, x, y, sigma=sigma2, absolute_sigma=False)

y1=A[0][0]*x
y2=B[0][0]*x

plt.plot(x,y1,label='normal')
plt.plot(x,y2,label='reziprok')
plt.legend()
plt.show()
zweihorn
User
Beiträge: 27
Registriert: Donnerstag 11. Mai 2017, 17:09

Dienstag 24. April 2018, 17:30

Hm, vllt. Implizierte mein Beispiel, dass ich die Lösung selbst gefunden habe. Allerdings hatte ich mir eine Auflösung des Widerspruchs zwischen meinem Test und macben‘s Antwort erhofft. Ich habe so den Verdacht, dass ich immer noch was falsch verstehe.
zweihorn
User
Beiträge: 27
Registriert: Donnerstag 11. Mai 2017, 17:09

Freitag 27. April 2018, 08:54

niemand mehr? :(
Antworten