繁体   English   中英

使用scipy.optimize.curve_fit来拟合分段函数

[英]Using scipy.optimize.curve_fit to fit a piecewise function

我试图编写一个程序,将一个.csv文件中的两个数据集读取到数组中,然后将其拟合为分段函数。 对我来说最重要的是,因为这些拟合具有相同的参数,所以它们是同时完成的。 这个分段功能是我这样做的尝试,尽管如果您知道同时安装它们的更好方法,我也将非常感谢对此的建议。

为了避免上载csv文件,我将数据直接添加到了数组中。

import numpy
import csv
import matplotlib
from scipy import optimize

xdata = [2.0, 10.0, 30.0, 50.0, 70.0, 90.0, 110.0, 130.0, 150.0, 250.0, 400.0, 1002.0, 1010.0, 1030.0, 1050.0, 1070.0, 1090.0, 1110.0, 1130.0, 1150.0, 1250.0, 1400.0]
ydata = [0.013833958803215633, 0.024273268442992078, 0.08792766000711709, 0.23477725658012044, 0.31997367288103884, 0.3822895295625711, 0.46037063893452784, 0.5531831477605121, 0.559757863748663, 0.6443036770720387, 0.7344601382896991, 2.6773979205076136e-09, 9.297289736857164e-10, 0.10915332214935693, 0.1345307163724643, 0.1230161681870127, 0.11286094974672768, 0.09186485171688986, 0.06609131137369342, 0.052616358869021135, 0.034629686697483314, 0.03993853791147095]

我想适合标有'SSdecay'的功能的前11点,我想适合标有'SUdecay'的功能的后11点。 我同时尝试执行此操作的目的是使分段功能标记为“ fitfunciton”。

#defines functions to be used in fitting

#to fit the first half of data
def SSdecay(x, lam1, lam2, norm, xoff):
    return norm*(1 + lam2/(lam1 - lam2)*numpy.exp(-lam1*(x - xoff)) -
        lam1/(lam1 - lam2)*numpy.exp(-lam2*(x - xoff)))

#to fit the second half of data
def SUdecay(x, lam1, lam2, norm, xoff):
    return norm*(lam1/(lam1 - lam2))*(-numpy.exp(-lam1*(x - xoff)) +
        numpy.exp(-lam2*(x - xoff)))

#piecewise function combining SS and SU functions to fit the whole data set
def fitfunction(x, lam1, lam2, norm, xoff):
    y = numpy.piecewise(x,[x < 1000, x >= 1000],[SSdecay(x, lam1, lam2, norm, xoff),SUdecay(x, lam1, lam2, norm, xoff)])
    return y

#fits the piecewise function with initial guesses for parameters
p0=[0.01,0.02,1,0]
popt, pcov = optimize.curve_fit(fitfunction, xdata, ydata, p0)

print(popt)
print(pcov)

运行此后,我得到错误:

ValueError: NumPy boolean array indexing assignment cannot assign 22 input values to the 11 output values where the mask is true

似乎curve_fit不喜欢我正在使用分段函数,但是我不确定为什么或是否是可解决的问题。

这是我使用归一化数据分别拟合两个函数的结果。 这些看起来不可能像单个分段方程那样工作,请参见下面的绘图图像和源代码。 对于两个方程,我也有非常不同的拟合参数:

SS参数:[0.0110936、0.09560932、0.72929264、6.82520026]

SU参数:[3.46853883e-02,9.54208972e-03,1.99877873e-01,1.00465563e + 03]

情节

import numpy
import matplotlib
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

xdata = [2.0, 10.0, 30.0, 50.0, 70.0, 90.0, 110.0, 130.0, 150.0, 250.0, 400.0, 1002.0, 1010.0, 1030.0, 1050.0, 1070.0, 1090.0, 1110.0, 1130.0, 1150.0, 1250.0, 1400.0]
ydata = [0.013833958803215633, 0.024273268442992078, 0.08792766000711709, 0.23477725658012044, 0.31997367288103884, 0.3822895295625711, 0.46037063893452784, 0.5531831477605121, 0.559757863748663, 0.6443036770720387, 0.7344601382896991, 2.6773979205076136e-09, 9.297289736857164e-10, 0.10915332214935693, 0.1345307163724643, 0.1230161681870127, 0.11286094974672768, 0.09186485171688986, 0.06609131137369342, 0.052616358869021135, 0.034629686697483314, 0.03993853791147095]

#to fit the first half of data
def SSdecay(x, lam1, lam2, norm, xoff):
    return norm*(1 + lam2/(lam1 - lam2)*numpy.exp(-lam1*(x - xoff)) -
        lam1/(lam1 - lam2)*numpy.exp(-lam2*(x - xoff)))

#to fit the second half of data
def SUdecay(x, lam1, lam2, norm, xoff):
    return norm*(lam1/(lam1 - lam2))*(-numpy.exp(-lam1*(x - xoff)) +
        numpy.exp(-lam2*(x - xoff)))

# some initial parameter values
initialParameters_ss = numpy.array([0.01, 0.02, 1.0, 0.0])
initialParameters_su = initialParameters_ss # same values for this example

# curve fit the equations individually to their respective data
ssParameters, pcov = curve_fit(SSdecay, xdata[:11], ydata[:11], initialParameters_ss)
suParameters, pcov = curve_fit(SUdecay, xdata[11:], ydata[11:], initialParameters_su)

# values for display of fitted function
lam1_ss, lam2_ss, norm_ss, xoff_ss = ssParameters
lam1_su, lam2_su, norm_su, xoff_su = suParameters

# for plotting the fitting results
y_fit_ss = SSdecay(xdata[:11], lam1_ss, lam2_ss, norm_ss, xoff_ss) # first data set, first equation
y_fit_su = SUdecay(xdata[11:], lam1_su, lam2_su, norm_su, xoff_su) # second data set, second equation

plt.plot(xdata, ydata, 'D') # plot the raw data as a scatterplot
plt.plot(xdata[:11], y_fit_ss) # plot the SS equation using the fitted parameters
plt.plot(xdata[11:], y_fit_su) # plot the SU equation using the fitted parameters
plt.show()

print('SS parameters:', ssParameters)
print('SU parameters:', suParameters)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM