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!
Fitten von Daten - Gewichtung
@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.
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."
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."
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?
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?
curve_fit(..., sigma=[5, 1, 0.2, 1, 1], absolute_sigma=True, ...)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.
Mit "absolute_sigma=True" übergibst du mit dem Parameter sigma nicht das mathematische Sigma, sondern die Gewichte.
Ich finde das ist einfach.zweihorn hat geschrieben:Mir geht es darum, wie ich möglichst einfach eine Gewichtung mit curve_fit realisieren kann.
Wer sagt das? Steht das so in der Aufgabe drin oder meinst du das aus der Doku gelesen zu haben?zweihorn hat geschrieben:Außerdem sollten die Gewichte die ich angeben muss 1/sigma sein, wenn ich das richtig sehe.
Korrektur: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.
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.
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!
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!
Wenn die gefittete Kurve zwischen den Stützstellen oszilliert, dann ist die Ordnung der Kurve im Vergleich zur Anzahl der Stützstellen zu hoch.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?
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.
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()
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.