python - 使用指数减法评估 symfit 模型时的 AttributeError

标签 python sympy attributeerror symfit

我已经建立了一个模型来拟合一些指数减法的数据。它适合拟合,但当我显式评估模型时,我得到奇怪的结果和 AttributeError:“Mul”对象没有属性“exp”。

问题似乎源于 lambdify 的工作方式,并在评估包含重要函数(例如增强或求幂)的模型时发生。

import symfit as sf

a = sf.Parameter('a',1,0,2) #name, initial value, minimum, maximum
b = sf.Parameter('b',1,0,2)
c=sf.Parameter('c',1,0,2)
x, y = sf.variables('x, y')

model=sf.Model({y: a * (c - sf.exp((x) / b))})
model(1,a,b,c)
Out: Ans(y=a*(c + 1))

model=sf.Model({y: a * (1 - sf.exp((x-c) / b))})
model(1,a,b,c)
Traceback (most recent call last):

  File "<ipython-input-9-faba3b52b923>", line 1, in <module>
    model(1,a,b,c)

  File "C:\PortablePrograms\Python\WPy-3670\python-3.6.7.amd64\lib\site-packages\symfit\core\fit.py", line 334, in __call__
    return Ans(*self.eval_components(**bound_arguments.arguments))

  File "C:\PortablePrograms\Python\WPy-3670\python-3.6.7.amd64\lib\site-packages\symfit\core\fit.py", line 296, in eval_components
    return [expr(*args, **kwargs) for expr in self.numerical_components]

  File "C:\PortablePrograms\Python\WPy-3670\python-3.6.7.amd64\lib\site-packages\symfit\core\fit.py", line 296, in <listcomp>
    return [expr(*args, **kwargs) for expr in self.numerical_components]

  File "C:\PortablePrograms\Python\WPy-3670\python-3.6.7.amd64\lib\site-packages\sympy\utilities\lambdify.py", line 444, in wrapper
    return funcarg(*newargs, **kwargsx)

  File "<string>", line 1, in <lambda>

AttributeError: 'Mul' object has no attribute 'exp'

我希望要么使用参数的初始值,要么得到一个象征性的答案,但两者都得不到。

因此,对于第一个模型,结果既错误又不一致,我预计

Ans(y=a*(c-exp(1/b)) 

Ans(y=a*(c-1)) 

或者只是简单地

Ans(y=0)

对于第二个模型,lambdify 似乎无法解析表达式。

使用 sf.sqrt() 或 sympy.exp() 时也是如此。 我在 python 3.6.7 和 IPython 7.1.1 中工作,使用 Symfit 0.4.6 和 Sympy 1.1.1(因为 Symfit 不适用于根据 pip 的更高版本)。

我可以使用任一模型来拟合数据并使用最佳拟合参数评估模型,如此处示例 (https://pypi.org/project/symfit/) 所示。线路

yfit = model(x=xdata, **fit_result.params)[y] 

也不起作用(在 python 2.7、3.5 和 3.6 上试过),除非更改为

yfit = [model(x=x, **fit_result.params) for x in xdata]

最佳答案

symfit 中调用 Model 意味着符号表达式被转换为 lambda 函数,即不再是符号的普通 python 函数。

在你的例子中,调用

sf.Model({y: a * (c - sf.exp((x) / b))})

相当于写

lambda x, a, b, c: a * (c - np.exp((x) / b))

请注意,符号指数现在已更改为 numpy 指数。从这个例子中可以看出,模型不是用符号表达式调用的,而是用数字或数组调用的。

所以你的电话应该改成

model(x=1, a=1, b=1, c=1)

如果您需要在符号级别上工作,请继续直接使用 Model 中的表达式,该调用纯粹用于数值用途。

最后,文档中的示例假设 xdata 是一个数组,但在示例中它是一个列表。那应该(由我)更新。

作为最后的话,学会喜欢 python 中的关键字参数;)。以下是等价的:

a = sf.Parameter('a',1,0,2) #name, initial value, minimum, maximum
a = sf.Parameter('a', value=1, min=0, max=2)

但只有一个是 self 记录的:)。

关于python - 使用指数减法评估 symfit 模型时的 AttributeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54134273/

相关文章:

python - 为什么我的 3D numpy 数组中的值在我将其写入文件时会发生变化?

python - 是否可以使用 Matplotlib 绘制隐式方程?

python - 用任意参数替换 sympy 函数

python - model.summary() - 属性错误 : 'Tensor' object has no attribute 'summary'

python - Python代码返回: Syntaxerror non-keyword after keyword arg

python - 在堆栈中获取上一层函数的 __file__

python sympy 不能很好地分解 bool 多项式

pygame - “事件”对象在 pygame 中没有属性 'get'

python - “模块”对象没有属性 'choice' - 尝试使用 random.choice

python - 神经网络中权重的更新