科学曲线拟合负值 [英] scipy curve fitting negative value

查看:172
本文介绍了科学曲线拟合负值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用curve_fit拟合曲线并防止其变为负数.不幸的是,下面的代码不起作用.有什么提示吗?非常感谢!

I would like to fit a curve with curve_fit and prevent it from becoming negative. Unfortunately, the code below does not work. Any hints? Thanks a lot!

# 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!!

推荐答案

您的模型实际上工作正常,如下图所示.我使用了您的代码,并绘制了原始数据和使用合适的参数获得的数据:

Your model actually works fine as the following plot shows. I used your code and plotted the original data and the data you obtain with the fitted parameters:

如您所见,可以很好地重现数据,但是您确实为d获得了一个负值(根据模型的上下文,这一定不是一件坏事).如果要避免这种情况,建议您使用lmfit来将参数限制在特定范围内.下图显示了结果.

As you can see, the data can nicely be reproduced but you indeed obtain a negative value for d (which must not be a bad thing depending on the context of the model). If you want to avoid it, I recommend to use lmfit where you can constrain your parameters to certain ranges. The next plot shows the outcome.

如您所见,它还可以很好地重现数据,并且您可以根据需要为d获得一个正值.

As you can see, it also reproduces the data well and you obtain a positive value for d as desired.

即:

m:  -0.35199747 
c:   8.48813181 
d:   0.05775745

下面是复制数字的完整代码:

Here is the entire code that reproduces the figures:

# 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

这篇关于科学曲线拟合负值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆