【问题标题】:Error using lmfit v0_9_3使用 lmfit v0_9_3 时出错
【发布时间】:2016-04-21 15:18:47
【问题描述】:

我对使用 python 进行数据分析以及使用 lmfit 进行非线性方程拟合有些陌生。我正在尝试模拟一个复杂的半解析函数,该函数描述污染物羽流在 1D 通道中随时间的运动。我正在使用 lmfit v0.9.3。我已经成功完成了 lmfit 教程中的几个示例,但似乎无法让我自己的模型正常工作。下面的脚本在 tsm_mod.fit() 调用之前有效,但随后返回错误:

文件“C:\Anaconda\lib\site-packages\lmfit\model.py”,第 501 行,在 合身 对于 p in params.values()])

TypeError: 'numpy.ndarray' 对象不可调用

代码如下:

import numpy as np
import scipy as sp
import pandas as pd
from lmfit import Model

desmedt = pd.read_table('Directory\desmedt_test.txt',sep='\t')

x = desmedt['Times']
y = desmedt['Conc']

def tsm_intfunc(t,x,tau,u,k,alpha,beta,mass,ac):
    return((mass/(2*ac*(t*np.pi*k)**(1/2)))*np.exp(-((x-u*t)**2)/(4*k*t))*np.exp(-alpha*tau-alpha*(t-tau)/beta)
        *np.sqrt(beta*tau/(t-tau))*sp.special.iv(2*np.sqrt((alpha**2)*tau*(t-tau)/beta),1))

def tsm_desmedt(t,x,u,k,alpha,beta,mass,ac,nsteps):   
    dtau = t/nsteps
    cxt = (mass/(2*ac*np.sqrt(t*np.pi*k)))*np.exp(-((x-u*t)**2)/(4*k*t))*np.exp(-alpha*t)
    cxv = tsm_intfunc(t,x,0.00000001,u,k,alpha,beta,mass,ac)/2
    i = 1

    while (i<nsteps):
        cxv = cxv+tsm_intfunc(t,x,dtau*i,u,k,alpha,beta,mass,ac)/2
        i = i+1

    return cxt+(alpha/beta)*cxv*dtau

tsm_mod = Model(tsm_desmedt)
tsm_mod.set_param_hint('ac',value=18.2,vary=False)
tsm_mod.set_param_hint('alpha',value=1e-4)
tsm_mod.set_param_hint('beta',value=1e-1)
tsm_mod.set_param_hint('k',value=3)
tsm_mod.set_param_hint('mass',value=157100,vary=False)
tsm_mod.set_param_hint('nsteps',value=100,vary=False)
tsm_mod.set_param_hint('u',value=0.4)
tsm_mod.set_param_hint('x',value=4604,vary=False)

tsm_pars = tsm_mod.make_params()
tsm_fit = tsm_mod.fit(y,x,tsm_pars)

这可能是 lmfit 中的错误吗?或者,您认为我使用 lmfit 设置问题的方式有误吗?

编辑: 拟合中用到的数据如下:

7787.628 8330.04 8640 8756.244 8988.696 9143.676 9337.392 9492.372 9724.86 9918.576 10034.784 10228.536 10383.516 10577.232 10770.948 11003.4 11119.644 11313.36 11468.34 11700.792 11855.772 12010.752 12204.468 12359.448 12630.672 12824.388 13173.084 13483.044 13793.004 14412.924 14955.336 15575.256 16195.14 17357.472

浓度

0.00944669 0.0850202 0.236167 0.576248 1.00135 2.01215 2.84345 3.51417 4.53441 5.21457 5.59244 5.74359 5.88529 6.0081 5.75304 5.61134 5.20513 4.95007 4.41161 3.74089 3.46694 3.07962 2.80567 2.41835 2.1444 1.74764 1.47368 1.20918 0.935223 0.661269 0.406208 0.132254 0.11336 0.151147

【问题讨论】:

  • 您能否提供您正在使用的数据或至少其中的一部分?
  • 根据docs onlineModel.fit期望被传递的args数据,params,weights,...;你给了它 y, x, tsm_pars,这对我来说显然不正确。特别是,它将把你的x 当作它的params,它期望它是一个Parameters 对象。
  • 按照我在网上看到的——我自己从来没有使用过 py-lmfit——我想你可能想要tsm_fit = tsm_mod.fit(y, tsm_pars, x=x) 这样的东西。
  • 我已编辑问题以包含拟合中使用的数据。这是从 desmedt 文本文件中导入的数据。另外,我相信我让它工作了:我没有意识到 Gareth 建议的格式需要一个指向函数参数列表中自变量的指针,因为它写在参数中: tsm_fit=tsm_mod.fit(y, tsm_pars , t=x) 谢谢大家的及时回复。

标签: python numpy lmfit


【解决方案1】:

您的示例有点令人困惑,因为您的模型函数同时包含一个自变量t 和一个变量x,并且在您的主程序中您调用了时间x。反正你要的电话是

tsm_fit = tsm_mod.fit(y, tsm_pars, t=x)

合身似乎效果不佳,但这似乎是一个单独的问题。

【讨论】:

  • 是的,感谢您的意见。我已经意识到我的代码中的错误并且能够成功实现它(见上面的评论)。但是,该模型存在参数可识别性问题,因此如果初始参数猜测远离其最佳值,则拟合不佳。有趣的是,我还在 R 中实现了这个算法,并且能够更好地拟合(使用 LMFit 包),参数值更接近它们应该比 Python 更短的时间。最有趣的是 Excel Solver 给出了参数值的最佳估计,但不能报告标准误差。
猜你喜欢
  • 1970-01-01
  • 2020-02-03
  • 2021-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多