Merkwürdiges Ergebnis mit Pythons (scipy) Kurvenanpassung

Dies ist mein Code (es ist ein Beispiel für ein größeres Stück Code):

from scipy.optimize import curve_fit def func(x, a, b): return a + b*x xlist = [10, 30, 50, 70, 90, 110, 130, 150, 170, 190, 210, 230] ylist = [0.0074999999999999997, 0.011875, 0.0057812499999999999, 0.0036458333333333334, 0.0020312500000000001, 0.0013125000000000001, 0.00098958333333333342, 0.00089285714285714283, 0.00074218750000000001, 0.00093749999999999997, 0.00071874999999999999, 0.00088068181818181821] popt, pcov = curve_fit(func, xlist, ylist) print(popt[0], popt[1]) 

Wie Sie sehen können, versuche ich eine ganz einfache Passform mit einer ganz einfachen a + b*x Funktion. Das Problem ist, dass dies die Werte zurückgibt:

  • Wie stelle ich eine Einschränkung auf die SciPy-Kurve ein?
  • So passen Sie parametrische Gleichungen zu Datenpunkten in Python an
  • Passen Sie mehrere parametrische Kurven mit scipy
  • Scipy.optimize.curvefit () - Array darf keine infs oder NaNs enthalten
  • Kurvenanpassung mit einer bekannten Funktion numpy
  • Ich weiß, dass scipy curve_fit besser machen kann
  •  (-119.99689110581872, 1.0) 

    Für a=popt[0] und b=popt[1] aber die gleiche passen mit zunzun.com gibt viel mehr vernünftige Werte:

     a = 7.8372289537296004E-03 b = -3.9402329475524466E-05 

    Für genau die gleiche Funktion.

    Was mache ich hier falsch?


    Bearbeiten

    Warren unten erklärte, dass dies ein Fehler sein könnte. Soll ich es als solches melden oder ist das das erwartete Verhalten?

  • Python File Creation Date & Umbenennen - Request for Critique
  • Wie kann ich das Datum in einem normalen Format in Python drucken?
  • Wie kann ich einen Tag von einem Python-Datum subtrahieren?
  • Python: Wie bekomme ich einen Wert von datetime.today () das ist "timezone bewusst"?
  • Holen Sie sich den Namen des Monats ab
  • Konvertieren Sie JSON-Datumsstring in Python datetime
  • 2 Solutions collect form web for “Merkwürdiges Ergebnis mit Pythons (scipy) Kurvenanpassung”

    Es funktioniert, wenn Sie die Werte in xlist in ein numpy Array ändern:

     In [38]: popt, pcov = curve_fit(func, array(xlist, dtype=float), ylist) In [39]: popt Out[39]: array([ 7.83722896e-03, -3.94023294e-05]) 

    Zuerst sieht das wie ein Bug aus, aber was passiert ist, dass der zugrunde liegende Code das Argument xdata und es unverändert an deine Funktion übergibt. In deinem Beispiel bedeutet dies im Ausdruck a + b*x , x ist eine Python-Liste. Das bedeutet, dass b*x nicht die Berechnung, die Sie wollen.

    Also, um deine Definition von func Arbeit zu machen, muss das Argument xdata ein numpy Array sein. Oder du kannst so definieren:

     def func(x, a, b): return a + b*np.asarray(x) 

    Die Standard-Anfangsparameter für die Kurvenanpassungsroutine von scipy sind alle 1,0, wenn ich mich richtig erinnere. Während dies funktioniert gut für einfache Fälle wie gerade Linien – da Fehler Platz ist einfacher für geradlinige Kurve passt – wenn Sie versuchen, passen, wo Fehler Platz ist "holprig und uneben" werden Sie wahrscheinlich wieder sehen Unterschiede zwischen Ihren Ergebnissen und denen von zunzun .com

    Wenn Sie eine Vorstellung von den richtigen Werten (oder Wertebereich) haben, wo die optimale Lösung vorhanden ist, beginnt das Starten der Scipy-Routine mit solchen Werten in fast allen Fällen bessere Ergebnisse als mit allen zu beginnen.

    Während zunzun.com erlaubt die Eingabe von Anfangsparameter "Schätzungen" – oder Vermutungen – diese sind nicht von der Website erforderlich, da ein genetischer Algorithmus verwendet wird, um erste Parameter Schätzungen zu bestimmen. Der BSD-lizenzierte Python-Anpassungsquellcode für die Webseite der zunzun.com ist

    http://code.google.com/p/pyeq2/

    Und es kommt mit einer breiten Palette von Beispielen. Schauen Sie sich die Unterseite der zunzun.com Webseiten für Links zum Code an. Lassen Sie mich wissen, wenn Sie irgendwelche Fragen haben und ich werde gerne helfen.

    James Phillips zunzun@zunzun.com

    Python ist die beste Programmiersprache der Welt.