首页 > 解决方案 > 将两个不同的方程拟合到一个函数 (curve_fit)

问题描述

我有一个问题:我有两个不同的方程,一个是线性方程,另一个是指数方程。然而,并非两个方程都应该同时有效,这意味着有两个不同的方案。

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 

到目前为止,我已经找到了这两个问题,但我无法弄清楚: Fit of two different functions with boarder as fit parameter 拟合由两种不同状态组成的数据的曲线

标签: pythonnumpyscipycurve-fitting

解决方案


我怀疑你在第二个等式中犯了一个错误,你在哪里做a+b*x+c*(1-np.exp(-d+x))。whereax从一条曲线变为另一条曲线的位置的值。我认为您应该使用 的值y而不是 which is 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()

在此处输入图像描述


推荐阅读