두 개의 다른 방정식을 함수에 맞추기 (curve_fit)

Nov 23 2020

문제가 있습니다. 하나는 선형 방정식이고 다른 하나는 지수 방정식입니다. 그러나 두 방정식이 동시에 유효해서는 안됩니다. 즉, 두 가지 다른 영역이 있습니다.

Equation 1 (x < a): E*x
Equation 2 (x >=a): a+b*x+c*(1-np.exp(-d*np.array(x)))

데이터의 첫 번째 부분은 선형 방정식에 적합해야하고 나머지는 앞서 언급 한 방정식 2에 적합해야 함을 의미합니다.

내가 맞추려고하는 데이터는 다음과 같습니다 (사람들이 원하는 경우 샘플 데이터도 추가했습니다).

헤비 사이드 함수로 하나의 맞춤 함수를 정의하는 것부터 이미 몇 가지 시도했습니다.

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

부분 함수 정의 :

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)))])

마지막으로 (무차별 형태의 함수 오류가 발생합니까?) :

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

오해하지 마십시오. "일부"가 맞지만 둘 중 하나 또는 다른 방정식을 사용하고 실제로 둘 다 사용하지 않는 것 같습니다. 나는 또한 여러 경계와 초기 추측을 사용해 보았지만 결코 변하지 않았습니다.

어떤 입력이라도 대단히 감사하겠습니다!

데이터:

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 

지금까지이 두 가지 질문을 찾았지만 알아낼 수 없었습니다. 적합 매개 변수로 보더를 사용하여 두 가지 다른 기능을 맞추기 두 개의 다른 체제로 구성된 데이터에 대한 곡선 맞추기

답변

2 FlavioMoraes Nov 23 2020 at 23:35

나는 당신이 두 번째 방정식에서 실수하고 있다고 생각합니다 a+b*x+c*(1-np.exp(-d+x)). 여기서는 한 곡선에서 다른 곡선으로 변경 a하는 x위치 의 값입니다 . y대신 값을 사용해야한다고 생각합니다 a*E. 또한 적합에 맞게 초기 매개 변수를 정의하는 것이 매우 중요합니다. txt 파일의 데이터로 다음 코드를 실행했으며 아래에서 볼 수 있듯이 적합성이 꽤 좋아 보입니다.

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()