Vielen Dank nochmal für die Hinweise!
Ich habe leider erst jetzt nochmal Zeit gefunden mich damit auseinanderzusetzen und hmmm... Die Modellfunktion ist durchaus geeignet; ich hatte das nochmal nachgeschaut und man sieht es auch an der grünen Funktion (mit manuell ausprobierten Parametern). Leider liefert curve_fit dennoch nur einen sehr eckigen Verlauf, egal ob die Bestimmung ganz frei oder mit relativ engen Grenzen stattfindet (s. Grafik). Der aktuelle Stand meiner Versuche ist also:
Code: Alles auswählen
import numpy
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
xdata = numpy.array([0, 5, 7, 9.9, 10, 10.1, 13, 15, 20])
ydata = numpy.array([1, 1.5, 1.7, 4, 7, 10, 12.3, 12.5, 13])
xaxis = numpy.linspace(0, 20)
def func(x, L, a, k, x0, y0):
return (L/(a + numpy.exp(-k*(x-x0))))+y0
popt, pcov = curve_fit(func, xdata, ydata)
popt2, pcov2 = curve_fit(func, xdata, ydata, bounds=([0, 0, 0, 9, 0.], [30, 10, 10, 11, 2.]))
def func2(x):
return (10/(0.8+numpy.exp(-3*(x-10))))+1
plt.plot(xaxis, func(xaxis, *popt), 'r')
plt.plot(xaxis, func(xaxis, *popt2), 'orange')
plt.plot(xaxis, func2(xaxis), 'g')
plt.plot(xdata, ydata, "bo")
print(popt)
plt.show()
und gibt mir diesen Plot:
Auf die Idee, die Parameter einzugrenzen, kam ich vor allem wegen dieser Warnung
Code: Alles auswählen
runfile('C:/Users/TS/Desktop/untitled1.py', wdir='C:/Users/TS/Desktop')
[ 2.96832762 0.26502925 11.96250756 9.88899366 1.39999999]
C:\Users\TS\Desktop\untitled1.py:10: RuntimeWarning: overflow encountered in exp
return (L/(a + numpy.exp(-k*(x-x0))))+y0
das hat aber wie man sieht nichts gebracht, die Funktion ist dennoch schrecklich eckig (wie auch immer das sein kann...)
Ich gebe dann jetzt wohl mal auf...
Und @webbygirl21: Ich bin (wie man leider merkt) kein Numeriker, aber wenn man gar keine Ahnung hat, welche Funktion das modelliert, dann kann man immer zu einer Polynom- oder Splineinterpolation greifen, denn jede Funktion kann ja durch ein Polynom hinreichend hohen Grades angenähert werden - das braucht aber dann seeeehr viel Rechenleistung. Das habe ich übrigens auch ausprobiert:
Code: Alles auswählen
import numpy
import matplotlib.pyplot as plt
from scipy.interpolate import Rbf, InterpolatedUnivariateSpline
x = numpy.array([0, 5, 7, 9.9, 10, 10.1, 13, 15, 20])
y = numpy.array([1, 1.5, 1.7, 4, 7, 10, 12.3, 12.5, 13])
xaxis = numpy.linspace(0, 20, num=101, endpoint=True)
#k gibt quasi an, welcher Grad an Glattheit gefordert ist: für k=1
#folgt einfach ein Linienzug
f1=InterpolatedUnivariateSpline(x, y, k=1)
f2=InterpolatedUnivariateSpline(x, y, k=2)
f3=InterpolatedUnivariateSpline(x, y, k=3)
plt.plot(x,y, 'o')
plt.plot(xaxis, f1(xaxis), 'b')
plt.plot(xaxis, f2(xaxis), 'r')
plt.plot(xaxis, f3(xaxis),'y')
plt.show()
Man bekommt dann diese wunderschönen Ergebnisse:
Außerdem kann man natürlich die "üblichen Verdächtigen" durchprobieren oder jemanden mit genug Erfahrung (bzw das Internet) um Hilfe bitten; manche Menschen schauen sich die Datenpunkte an und wissen, welche Funktion sie gut beschreibt...