python - scipy曲线拟合负值

标签 python optimization scipy curve-fitting

我想用curve_fit拟合一条曲线并防止它变成负值。不幸的是,下面的代码不起作用。有什么提示吗?非常感谢!

# Imports
from scipy.optimize import curve_fit
import numpy as np 
import matplotlib.pyplot as plt

xData = [0.0009824379203203417, 0.0011014182912933933, 0.0012433979929054324, 0.0014147106052612918, 0.0016240300315499524, 0.0018834904507916608, 0.002210485320720769, 0.002630660216394964, 0.0031830988618379067, 0.003929751681281367, 0.0049735919716217296, 0.0064961201261998095, 0.008841941282883075, 0.012732395447351627, 0.019894367886486918, 0.0353677651315323, 0.07957747154594767, 0.3183098861837907]

yData = [99.61973156923796, 91.79478510744039, 92.79302188621314, 84.32927272723863, 77.75060981602016, 75.62801782349504, 70.48026800610839, 72.21240551953743, 68.14019252499526, 55.23015406920851, 57.212682880377464, 50.777016257727176, 44.871140881319626, 40.544138806850846, 32.489105158795525, 25.65367127756607, 19.894206907130403, 13.057996247388862]

def func(x,m,c,d):
    '''
    Fitting Function
    I put d as an absolute number to prevent negative values for d?
    '''
    return x**m * c + abs(d) 

p0 = [-1, 1, 1]
coeff, _ = curve_fit(func, xData, yData, p0) # Fit curve
m, c, d = coeff[0], coeff[1], coeff[2]

print("d: " + str(d)) # Why is it negative!!

最佳答案

您的模型实际上运行良好,如下图所示。我使用您的代码并绘制了原始数据和您使用拟合参数获得的数据:

enter image description here

正如您所看到的,数据可以很好地重现,但您确实获得了 d 的负值(这一定不是一件坏事,具体取决于模型的上下文)。如果您想避免这种情况,我建议您使用 lmfit ,您可以将参数限制在特定范围内。下图显示了结果。 enter image description here

正如您所看到的,它还可以很好地再现数据,并且您可以根据需要获得 d 的正值。

即:

m:  -0.35199747 
c:   8.48813181 
d:   0.05775745

以下是重现这些数字的完整代码:

# Imports
from scipy.optimize import curve_fit
import numpy as np 
import matplotlib.pyplot as plt

#additional import
from lmfit import minimize, Parameters, Parameter, report_fit

xData = [0.0009824379203203417, 0.0011014182912933933, 0.0012433979929054324, 0.0014147106052612918, 0.0016240300315499524, 0.0018834904507916608, 0.002210485320720769, 0.002630660216394964, 0.0031830988618379067, 0.003929751681281367, 0.0049735919716217296, 0.0064961201261998095, 0.008841941282883075, 0.012732395447351627, 0.019894367886486918, 0.0353677651315323, 0.07957747154594767, 0.3183098861837907]
yData = [99.61973156923796, 91.79478510744039, 92.79302188621314, 84.32927272723863, 77.75060981602016, 75.62801782349504, 70.48026800610839, 72.21240551953743, 68.14019252499526, 55.23015406920851, 57.212682880377464, 50.777016257727176, 44.871140881319626, 40.544138806850846, 32.489105158795525, 25.65367127756607, 19.894206907130403, 13.057996247388862]

def func(x,m,c,d):
    '''
    Fitting Function
    I put d as an absolute number to prevent negative values for d?
    '''
    print m,c,d
    return np.power(x,m)*c + d

p0 = [-1, 1, 1]
coeff, _ = curve_fit(func, xData, yData, p0) # Fit curve
m, c, d = coeff[0], coeff[1], coeff[2]

print("d: " + str(d)) # Why is it negative!!
plt.scatter(xData, yData, s=30, marker = "v",label='P')
plt.scatter(xData, func(xData, *coeff), s=30, marker = "v",color="red",label='curvefit')
plt.show()

#####the new approach starts here
def func2(params, x, data):

    m = params['m'].value
    c = params['c'].value
    d = params['d'].value

    model = np.power(x,m)*c + d
    return model - data #that's what you want to minimize

# create a set of Parameters
params = Parameters()
params.add('m', value= -2) #value is the initial condition
params.add('c', value= 8.)
params.add('d', value= 10.0, min=0) #min=0 prevents that d becomes negative

# do fit, here with leastsq model
result = minimize(func2, params, args=(xData, yData))

# calculate final result
final = yData + result.residual

# write error report
report_fit(params)

try:
    import pylab
    pylab.plot(xData, yData, 'k+')
    pylab.plot(xData, final, 'r')
    pylab.show()
except:
    pass

关于python - scipy曲线拟合负值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31408782/

相关文章:

c++ - 为空间优化 tribools 数组

python - 在python中用FFT重建原始信号

python - 如何在 python flask 应用程序中安全地共享全局变量(缓存的公共(public)证书)

python - 如何将函数名作为变量传递和调用

递归函数中的 Python 命名空间

mysql - 优化自定义 Wordpress SQL 查询以获取用户元数据

python - 点之间没有线的 Seaborn 线图

Python保持排序数据的最有效方法

python - scipy 1.0.0 中的 imsave 在哪里?

python - 从 scipy 常规网格插值器返回二维数组