如何使用curve_fit拟合以下函数

时间:2016-04-13 02:47:12

标签: python numpy scipy curve-fitting scientific-computing

我有以下需要解决的功能:

np.exp((1-Y)/Y) = np.exp(c) -b*x

我将函数定义为:

def function(x, b, c):

    np.exp((1-Y)/Y) = np.exp(c) -b*x
    return y

def function_solve(y, b, c):

    x = (np.exp(c)-np.exp((1-Y)/Y))/b
    return x

然后我用了:

x_data = [4, 6, 8, 10]

y_data = [0.86, 0.73, 0.53, 0.3] 

popt, pcov = curve_fit(function, x_data, y_data,(28.14,-0.25))
answer = function_solve(0.5, popt[0], popt[1])

我尝试运行代码,错误是:

  

无法分配到函数调用

我试图解决的函数是线性形式的y = 1/ c*exp(-b*x)。我有很多y_datax_data,我希望获得cb的最佳值。

3 个答案:

答案 0 :(得分:1)

有两个问题突然袭来我:

  1. ln((1-Y)/Y) = ln(c) -b*x这不是有效的Python代码。在左侧,你必须有一个名字,而在这里你有一个函数调用ln(..),因此错误。

  2. ln()不是标准库中的Python函数。有一个math.log()函数。除非您在其他地方定义了ln(),否则它将无效。

答案 1 :(得分:0)

你的问题在于定义function():

def function(x, b, c):

    ln((1-Y)/Y) = ln(c) -b*x
    return y

您正在尝试分配

ln(c) - b*x

调用另一个函数ln(),而不是变量。相反,求解变量(函数)的函数,以便它可以存储在python变量中。

答案 2 :(得分:0)

已经指出了代码的一些问题。这是一个解决方案:

首先,您需要获得原始函数的正确对数表达式:

y = 1 / (c * exp(-b * x))
y = exp(b * x) / c
ln(y) = b * x + ln(1/c)
ln(y) = b * x - ln(c)

如果要在curve_fit中使用它,则需要按如下方式定义函数:

def f_log(x, b, c_ln):
    return b * x - c_ln

我现在向您展示一些随机生成的数据(使用b = 0.08c = 100.5)使用原始函数的结果,然后显示您提供的数据的输出结果:

[  8.17260899e-02   1.17566291e+02]

enter image description here

正如您所看到的那样,拟合值接近原始值并且拟合非常好地描述了数据。

对于您的数据,它看起来如下:

[-0.094 -1.263]

enter image description here

以下是代码:

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


def f(x, b, c):
    return 1. / (c * np.exp(-b * x))


def f_log(x, b, c_ln):
    return b * x - c_ln

# some random data
b_org = 0.08
c_org = 100.5
x_data = np.linspace(0.01, 100., 50)
y_data = f(x_data, b_org, c_org) + np.random.normal(0, 0.5, len(x_data))

# fit the data
popt, pcov = curve_fit(f, x_data, y_data, p0=(0.1, 50))
print popt

# plot the data
xnew = np.linspace(0.01, 100., 5000)
plt.plot(x_data, y_data, 'bo')
plt.plot(xnew, f(xnew, *popt), 'r')
plt.show()

# your data
x_data = np.array([4, 6, 8, 10])
y_data = np.array([0.86, 0.73, 0.53, 0.3])

# fit the data
popt_log, pcov_log = curve_fit(f_log, x_data, y_data)
print popt_log

# plot the data
xnew = np.linspace(4, 10., 500)
plt.plot(x_data, y_data, 'bo')
plt.plot(xnew, f_log(xnew, *popt_log), 'r')
plt.show()