2017-01-13 7 views
5

ich eine optimize Warnung bin immer:Mit Scipy curve_fit mit weise definierte Funktion

OptimizeWarning: Covariance of the parameters could not be estimated 
       category=OptimizeWarning) 

, wenn ich meine weise definierte Funktion, um meine Daten zu passen scipy.optimize.curve_fit verwenden. Das bedeutet, dass keine Anpassung stattfindet. Ich kann problemlos eine Parabel an meine Daten anpassen, und ich liefere curve_fit mit, was ich für gute Anfangsparameter halte. Das vollständige Codebeispiel unten. Weiß jemand, warum curve_fit nicht mit np.piecewise auskommen kann? Oder mache ich einen anderen Fehler?

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


def piecewise_linear(x, x0, y0, k1, k2): 
    y = np.piecewise(x, [x < x0, x >= x0], 
        [lambda x:k1*x + y0-k1*x0, lambda x:k2*x + y0-k2*x0]) 
    return y 

def parabola(x, a, b): 
    y = a * x**2 + b 
    return y 

x = np.array([-3, -2, -1, 0, 1, 2, 3]) 
y = np.array([9.15, 5.68, 2.32, 0.00, 2.05, 5.29, 8.62]) 


popt_piecewise, pcov = curve_fit(piecewise_linear, x, y, p0=[0.1, 0.1, -5, 5]) 
popt_parabola, pcov = curve_fit(parabola, x, y, p0=[1, 1]) 

new_x = np.linspace(x.min(), x.max(), 61) 


fig, ax = plt.subplots() 

ax.plot(x, y, 'o', ls='') 
ax.plot(new_x, piecewise_linear(new_x, *popt_piecewise)) 
ax.plot(new_x, parabola(new_x, *popt_parabola)) 

ax.set_xlim(-4, 4) 
ax.set_ylim(-2, 16) 

enter image description here

Antwort

5

Es ist ein Problem mit Typen, müssen Sie die folgende Zeile ändern, so dass die x als Schwimmer gegeben:

x = np.array([-3, -2, -1, 0, 1, 2, 3]).astype(np.float) 

sonst die piecewise_linear wird vielleicht am Ende Casting der Typen.

einfach auf der sicheren Seite zu sein, auch die ersten Punkte schweben hier machen könnte:

popt_piecewise, pcov = curve_fit(piecewise_linear, x, y, p0=[0.1, 0.1, -5., 5.]) 
+0

Wie auch immer Sie schließen, dass hat? –

+0

Ich habe versucht, die 'stückweise_linearen' mit den gegebenen Datenpunkten zu bewerten, und es hat nicht funktioniert, so dass ich das Problem schlussfolgern muss irgendwo da sein. Ich denke, es hat mit einem seltsamen Verhalten von 'np.piecewise' zu ​​tun. –

+0

Ich habe etwas ähnliches versucht und das komplett vermisst. Sehr gut! –

2

Für Vollständigkeit, ich nicht verlangen np.piecewise hinweisen werde nicht eine stückweise lineare Funktion passend: Eine solche Funktion kann aus absoluten Werten konstruiert werden, wobei für jede Biegung ein Vielfaches von np.abs(x-x0) verwendet wird. Die folgende erzeugt eine gute Anpassung an die Daten:

def pl(x, x0, a, b, c): 
    y = a*np.abs(x-x0) + b*x + c 
    return y 

popt_pl, pcov = curve_fit(pl, x, y, p0=[0, 0, 0, 0]) 

print(pl(x, *popt_pl)) 

Ausgabe auf original y-Werte in der Nähe ist:

[ 8.90899998 5.828  2.74700002 -0.33399996 2.03499998 5.32 
    8.60500002] 
Verwandte Themen