如何使用 curve_fit 拟合以下函数
How to fit the following function using curve_fit
我有以下功能需要解决:
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])
我尝试了 运行 代码,错误是:
can't assign to function call
我要求解的函数是 y = 1/ c*exp(-b*x)
的线性形式。我有一堆 y_data
和 x_data
,我想获得 c
和 b
的最佳值。
我有两个问题:
ln((1-Y)/Y) = ln(c) -b*x
这是无效的 Python 代码。在左侧你必须有一个名字,而这里你有一个函数调用 ln(..),因此错误。
ln()
不是标准库中的 Python 函数。有一个 math.log()
函数。除非您在其他地方定义了 ln()
,否则它将不起作用。
您的问题在于定义 function():
def function(x, b, c):
ln((1-Y)/Y) = ln(c) -b*x
return y
您正在尝试分配
ln(c) - b*x
调用另一个函数 ln(),而不是变量。取而代之的是,为(函数的)变量求解函数,以便它可以存储在 python 变量中。
您的代码的一些问题已经被指出。这是一个解决方案:
首先,你需要得到你原函数的正确对数表达式:
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.08
和 c = 100.5
)的结果,然后是您提供的数据的输出:
[ 8.17260899e-02 1.17566291e+02]
如您所见,拟合值与原始值接近并且拟合很好地描述了数据。
您的数据如下所示:
[-0.094 -1.263]
代码如下:
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()
我有以下功能需要解决:
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])
我尝试了 运行 代码,错误是:
can't assign to function call
我要求解的函数是 y = 1/ c*exp(-b*x)
的线性形式。我有一堆 y_data
和 x_data
,我想获得 c
和 b
的最佳值。
我有两个问题:
ln((1-Y)/Y) = ln(c) -b*x
这是无效的 Python 代码。在左侧你必须有一个名字,而这里你有一个函数调用 ln(..),因此错误。ln()
不是标准库中的 Python 函数。有一个math.log()
函数。除非您在其他地方定义了ln()
,否则它将不起作用。
您的问题在于定义 function():
def function(x, b, c):
ln((1-Y)/Y) = ln(c) -b*x
return y
您正在尝试分配
ln(c) - b*x
调用另一个函数 ln(),而不是变量。取而代之的是,为(函数的)变量求解函数,以便它可以存储在 python 变量中。
您的代码的一些问题已经被指出。这是一个解决方案:
首先,你需要得到你原函数的正确对数表达式:
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.08
和 c = 100.5
)的结果,然后是您提供的数据的输出:
[ 8.17260899e-02 1.17566291e+02]
如您所见,拟合值与原始值接近并且拟合很好地描述了数据。
您的数据如下所示:
[-0.094 -1.263]
代码如下:
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()