【问题标题】:How to fit the following function using curve_fit如何使用curve_fit拟合以下函数
【发布时间】:2016-08-03 21:57:44
【问题描述】:

我有以下功能需要解决:

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 的最佳值。

【问题讨论】:

  • 刚刚编辑了方程。
  • 在担心实施之前,您应该澄清您真正想要解决的问题。正在尝试为哪个变量求解方程 exp((1-Y)/Y) = exp(c) -b*x?
  • np.exp(c) 在这种情况下只是另一个常量,因此您可以将其替换为 C。你能添加一些数据吗?!
  • 你的第一个陈述是一个方程,而不是一个函数。如果你把这个方程放到 wolfram.alpha 中,你会得到一个解析解,比如Y。然后,您可以使用 numpy/matplotlib 绘制结果(小心,它很复杂,并且有多种解决方案)。
  • @Cleb 刚刚添加了一些数据点。

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


【解决方案1】:

有两个问题困扰着我:

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

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

【讨论】:

  • 您似乎没有正确理解赋值语句,这是一个非常基本的问题。你根本不能有任何形式的f(Y)=f(x,c,b) 类型的赋值。在作业的左侧,您只能有一个名称,没有参数:g=f(x,c,b) 所以 g 现在包含对 f(x, c, b) 的评估结果。
【解决方案2】:

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

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

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]

如您所见,拟合值与原始值接近,并且拟合很好地描述了数据。

您的数据如下所示:

[-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()

【讨论】:

  • 在使用函数中:def f_log(x, b, c_ln): return b * x - c_ln y_data是否应该转换为ln(y_data)?
  • @CodeMAK:是的,您需要再次转换数据。您是否已经提供了对数数据?
  • 不,给定的 y 数据未转换为对数值
  • 好的,那么您必须先执行此操作,然后再将它们转换回来。您也可以查看stackoverflow.com/questions/35903506/… 以获取类似示例。
  • 谢谢哥们的帮助!!
【解决方案3】:

您的问题在于定义函数():

def function(x, b, c):

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

您正在尝试分配

ln(c) - b*x

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

【讨论】:

  • 能否以上述函数为例说明如何做到这一点
猜你喜欢
  • 2020-05-05
  • 2012-06-07
  • 2020-05-18
  • 1970-01-01
  • 2016-09-16
  • 2017-04-11
  • 2019-02-12
  • 2017-03-17
  • 1970-01-01
相关资源
最近更新 更多