Anpassen von zwei unterschiedlichen Gleichungen an eine Funktion (kurve_fit)
Ich habe ein Problem: Ich habe zwei verschiedene Gleichungen, eine ist eine lineare Gleichung, die andere ist eine Exponentialgleichung. Es sollten jedoch nicht beide Gleichungen gleichzeitig gültig sein, was bedeutet, dass es zwei unterschiedliche Regime gibt.
Equation 1 (x < a): E*x
Equation 2 (x >=a): a+b*x+c*(1-np.exp(-d*np.array(x)))
Das heißt, der erste Teil der Daten sollte nur mit einer linearen Gleichung und der Rest mit der zuvor erwähnten Gleichung 2 übereinstimmen.
Die Daten, die ich anpassen möchte, sehen folgendermaßen aus (ich habe auch einige Beispieldaten hinzugefügt, wenn die Leute es versuchen möchten):

Ich habe bereits mehrere Dinge ausprobiert, indem ich nur eine Anpassungsfunktion mit einer Heaviside-Funktion definiert habe:
def fit_fun(x,a,b,c,d,E):
funktion1=E*np.array(x)
funktion2=a+b*x+c*(1-np.exp(-d*np.array(x)))
return np.heaviside(x+a,0)*funktion2+(1-np.heaviside(x+a,0))*funktion1
Definieren einer stückweisen Funktion:
def fit_fun(x,a,b,c,d,E):
return np.piecewise(x, [x <= a, x > a], [lambda x: E*np.array(x), lambda x: a+b*x+c*(1-np.exp(-d*np.array(x)))])
zum Schluss (was bringt mir unglücklicherweise einen Formfunktionsfehler?):
def plast_fun(x,a,b,c,d,E):
out = E*x
out [np.where(x >= a)] = a+b*x+c*(1-np.exp(-d+x))
return out
Versteh mich nicht falsch, ich bekomme "einige" Anfälle, aber sie scheinen entweder die eine oder die andere Gleichung zu nehmen und nicht wirklich beide zu verwenden. Ich habe auch versucht, mehrere Grenzen und anfängliche Vermutungen zu verwenden, aber es ändert sich nie.
Jede Eingabe wäre sehr dankbar!
Daten:
0.000000 -1.570670
0.000434 83.292677
0.000867 108.909402
0.001301 124.121676
0.001734 138.187659
0.002168 151.278839
0.002601 163.160478
0.003035 174.255626
0.003468 185.035092
0.003902 195.629820
0.004336 205.887161
0.004769 215.611995
0.005203 224.752083
0.005636 233.436680
0.006070 241.897851
0.006503 250.352697
0.006937 258.915168
0.007370 267.569337
0.007804 276.199005
0.008237 284.646778
0.008671 292.772349
0.009105 300.489611
0.009538 307.776858
0.009972 314.666291
0.010405 321.224211
0.010839 327.531594
0.011272 333.669261
0.011706 339.706420
0.012139 345.689265
0.012573 351.628362
0.013007 357.488150
0.013440 363.185771
0.013874 368.606298
0.014307 373.635696
0.014741 378.203192
0.015174 382.315634
0.015608 386.064126
0.016041 389.592120
0.016475 393.033854
0.016908 396.454226
0.017342 399.831519
0.017776 403.107084
0.018209 406.277016
0.018643 409.441119
0.019076 412.710982
0.019510 415.987331
0.019943 418.873140
0.020377 421.178098
0.020810 423.756827
Bisher habe ich diese beiden Fragen gefunden, aber ich konnte es nicht herausfinden: Anpassung zweier verschiedener Funktionen mit Boarder als Anpassungsparameter Passen Sie eine Kurve für Daten an, die aus zwei unterschiedlichen Regimen bestehen
Antworten
Ich vermute, Sie machen einen Fehler in der zweiten Gleichung, wo Sie es tun a+b*x+c*(1-np.exp(-d+x))
. Wo a
ist der Wert, an x
dem Sie von einer Kurve zur anderen wechseln? Ich denke, Sie sollten y
stattdessen den Wert von verwenden, der ist a*E
. Es ist auch sehr wichtig, Anfangsparameter für die Anpassung zu definieren. Ich habe den folgenden Code mit Ihren Daten in der TXT-Datei ausgeführt und die Anpassung scheint ziemlich gut zu sein, wie Sie unten sehen können:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import optimize, stats
def fit_fun(x,a,b,c,d,E):
return np.piecewise(x, [x <= a, x > a], [lambda x: E*x, lambda x: a*E+b*x+c*(1-np.exp(-d*x))])
df = pd.read_csv('teste.txt', delimiter='\s+', header=None)
df.columns = ['x','y']
xdata = df['x']
ydata = df['y']
p0 = [0.001,1,1,1,100000]
popt, pcov = optimize.curve_fit(fit_fun, xdata.values, ydata.values, p0=p0, maxfev=10000, absolute_sigma=True, method='trf')
print(popt)
plt.plot(xdata, ydata,'*')
plt.plot(xdata, fit_fun(xdata.values, *popt), 'r')
plt.show()
