2016-10-24 2 views
0

Ich versuche, eine Kurve durch einige Daten anzupassen. Die Funktion, die ich bin versucht zu passen wie folgt:Scipy curve_fit schlägt fehl für Daten mit Sinusfunktion

def f(x,a,b,c): 
    return a +b*x**c 

Wenn scipy.optimize.curve_fit mit erhalte ich keine Ergebnisse: Es gibt den (Standard) Ausgangsparameter:

(array([ 1., 1., 1.]), 
array([[ inf, inf, inf], 
     [ inf, inf, inf], 
     [ inf, inf, inf]])) 

I habe versucht, die Daten wiedergegeben werden, und festgestellt, dass eine Sinusfunktion das Problem verursacht wurde (enthalten die Daten täglich Variation):

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit 

xdata=np.random.rand(1000) + 0.002 *np.sin(np.arange(1000)/(1.5*np.pi)) 
ydata=0.1 + 23.4*xdata**0.56 + np.random.normal(0,2,1000) 

def f(x,a,b,c): 
    return a +b*x**c 

fit=curve_fit(f,xdata,ydata) 

fig,ax=plt.subplots(1,1) 
ax.plot(xdata,ydata,'k.',markersize=3) 
ax.plot(np.arange(0,1,.01), f(np.arange(0,1,.01),*fit[0])) 
fig.show() 

ich natürlich curve_fit etwas in der Nähe zurückzukehren erwarten würde [0,1, 23,4, 0,56 ].

Beachten Sie, dass die Sinusfunktion nicht wirklich die Daten ('xdata') im Wert beeinflusst, da der erste Term von xdata zwischen 0 und 1 liegt und ich etwas zwischen -0.002 und +0.002 addiere Es führt jedoch dazu, dass der Anpassvorgang fehlschlägt. Ich fand den Wert 0.002 nahe bei dem 'kritischen' Wert für den Fehler; Wenn es kleiner ist, ist es weniger wahrscheinlich, dass das Verfahren fehlschlägt, und umgekehrt. Bei 0,002 versagt die Prozedur ungefähr so ​​oft wie nicht.

Ich habe versucht, dieses Problem zu lösen, indem ich die "xdata" und "ydata" gleichzeitig, ohne Wirkung mischte. Ich dachte (ohne besonderen Grund), dass das Problem eventuell durch das Entfernen der Autokorrelation der Daten behoben werden könnte.

Also meine Frage ist: Wie kann ich dieses Problem beheben/umgehen? Ich kann den Sinus-Beitrag in den synthetischen Daten im obigen Ausschnitt ändern, aber für meine realen Daten kann ich das natürlich nicht.

+2

Nachdem Ihren Code-Snippet lief, finde ich, dass es sinnvoll, fit Werte jedes Mal, wenn nicht alle Elemente des 'xdata' sind negativ zurückzukehren scheint (in diesem Fall einig' YDATA 'sind' nan', weil Sie eine negative Zahl auf eine Bruchzahl erhöhen. –

+0

Ich stimme mit @AngusWilliams überein. Nachdem ich einen kleinen Offset zu xdata (+0,003 statt +0,002) hinzugefügt habe, gibt es vernünftige Werte zurück. –

Antwort

0

können Sie die NaNs durch negative x-Werte innerhalb der Modellfunktion erzeugt beseitigen:

def f(x,a,b,c): 
    y = a +b*x**c 
    y[np.isnan(y)] = 0.0 
    return y 

alle NaNs von 0 Ersetzen vielleicht nicht die beste Wahl sein. Sie könnten Nachbarwerte ausprobieren oder eine Art Extrapolation durchführen.

Wenn Sie generierte Testdaten einspeisen, müssen Sie sicherstellen, dass dort auch keine NaNs vorhanden sind. Also direkt nach den Daten Generation setzte so etwas wie:

if xdata.min() < 0: 
    print 'expecting NaNs' 
    ydata[np.isnan(ydata)] = 0.0 
Verwandte Themen