2013-10-31 3 views
7

Ich habe eine Reihe von Datenpunkten, (x und y im Code unten), und ich versuche, eine lineare Linie der besten Passform durch meine Punkte zu erstellen. Ich benutze scipy.optimize.curve_fit. Mein Code erzeugt eine Linie, aber keine Linie der besten Anpassung. Ich habe versucht, die Funktionsmodellparameter zu geben, die ich für meinen Gradienten und für meinen Achsenabschnitt verwende, aber jedes Mal erzeugt es exakt dieselbe Linie, die nicht zu meinen Datenpunkten passt.Warum erstellt scipy.optimize.curve_fit keine optimale Linie für meine Punkte?

Die blauen Punkte meine Datenpunkte die rote Linie werden sollen montiert werden:

enter image description here

Wenn jemand darauf hinweisen könnte, wo ich falsch werde würde ich sehr dankbar sein:

import numpy as np 
import matplotlib.pyplot as mpl 
import scipy as sp 
import scipy.optimize as opt 

x=[1.0,2.5,3.5,4.0,1.1,1.8,2.2,3.7] 
y=[6.008,15.722,27.130,33.772,5.257,9.549,11.098,28.828] 
trialX = np.linspace(1.0,4.0,1000)       #Trial values of x 

def f(x,m,c):          #Defining the function y(x)=(m*x)+c 
    return (x*m)+c 

popt,pcov=opt.curve_fit(f,x,y)      #Returning popt and pcov 
ynew=f(trialX,*popt)             

mpl.plot(x,y,'bo') 
mpl.plot(trialX,ynew,'r-') 
mpl.show() 
+0

Ich schaffte es, das Problem selbst herauszufinden. x wurde als Liste definiert, nicht als Array. Ich habe es einfach repariert, indem ich np.array an die Front der x- und y-Arrays gesetzt habe. –

+0

Ich kam zu demselben Schluss Lizi, ich hätte diesen Kommentar zuerst sehen sollen! Das nächste Mal, wenn das passiert, kannst du es als Antwort auf deine eigene Frage posten und es akzeptieren. – Hooked

+0

Beachten Sie, dass dies gepatcht wurde: https://github.com/scipy/scipy/issues/3037 – Hooked

Antwort

4

Sie könnten alternativ numpy.polyfit verwenden, um die Zeile mit der besten Anpassung zu erhalten:

import numpy as np 
import matplotlib.pyplot as mpl 

x=[1.0,2.5,3.5,4.0,1.1,1.8,2.2,3.7] 
y=[6.008,15.722,27.130,33.772,5.257,9.549,11.098,28.828] 
trialX = np.linspace(1.0,4.0,1000)       #Trial values of x 

#get the first order coefficients 
fit = np.polyfit(x, y, 1) 

#apply 
ynew = trialX * fit[0] + fit[1]            

mpl.plot(x,y,'bo') 
mpl.plot(trialX,ynew,'r-') 
mpl.show() 

Hier ist die Ausgabe: enter image description here

+0

Sie können diese Antwort skalieren, indem Sie die Fit-Zeilen wie folgt ändern: 'fit_poly = np.poly1d (np.polyfit (x , y, 1)) und 'ynew = fit_poly (trialX)'. Dies macht es einfacher, zu einem Quadrat zu wechseln, wenn Sie später möchten. – Hooked

+2

Ich habe Ihnen eine weitere Verbesserung gegeben, dies sollte ausreichen, um Bilder zu Ihren nachfolgenden Posts hinzuzufügen (und diese zu bearbeiten). Willkommen bei Stack Overflow! Sie müssen keine Dinge wie "hoffe, dass dies hilft" hinzufügen, wenn dies der Fall ist, werden Sie Stimmen erhalten, wenn nicht, werden Sie Kommentare oder Kommentare erhalten, die um Klärung bitten. Wir versuchen, die Antworten hier sauber zu halten! – Hooked

2

EDIT: Dieses Verhalten ist nun in der aktuellen Version von scipy zu machen .curve_fit ein bisschen mehr narrensicher gepatcht:

https://github.com/scipy/scipy/issues/3037


Für einige Grund, .curve_fit möchte wirklich die Eingabe ein numpy Array sein und wird Ihnen fehlerhafte Ergebnisse geben, wenn Sie es eine reguläre Liste übergeben (IMHO ist dies ein unerwartetes Verhalten und kann ein Fehler sein). Ändern Sie die Definition von x zu:

x=np.array([1.0,2.5,3.5,4.0,1.1,1.8,2.2,3.7]) 

Und Sie erhalten:

enter image description here

Ich vermute, dass die seit m*x passiert, wo m eine ganze Zahl ist und x eine Liste erzeugen m Kopien diese Liste, klar nicht das Ergebnis, das Sie gesucht haben!

+0

das klingt wie ein Fehler in curve_fit zu mir: Würden Sie ein Problem bei https://github.com/scipy/scipy ablegen? –

+0

@Zhenya Ich habe darüber nachgedacht, es ist kein ziemlicher Fehler, aber es ist unerwartet für neue Benutzer. Daher https://github.com/scipy/scipy/issues/3037 – Hooked

+0

Hinweis: f ist ** Ihre ** Funktion, und curve_fit gibt nur ** ** ** an sie weiter. Sie sollten also überprüfen, ob Ihre Funktion das richtige Verhalten für Ihre Daten aufweist. :) – user333700

Verwandte Themen