【问题标题】:How to use scipy.optimize.curve_fit to use lists of variable如何使用 scipy.optimize.curve_fit 使用变量列表
【发布时间】:2020-06-05 16:46:20
【问题描述】:

我有想要拟合函数的时变数据跟踪。函数的输入是列表,我希望 curve_fit 优化列表中的所有值以拟合曲线。我已经到了这么远-

from scipy.optimize import curve_fit
from matplotlib.pylab import plt
from numpy import exp

def ffunc2(x, a, b):
    counter = 0
    return_value = 0
    while counter < len(a):
        return_value += a[counter] * exp(b[counter] * x)
        counter += 1
    return return_value

# INITIAL DATA
x = [1, 2, 3, 5]
y = [1, 8, 81, 125]


number_variable = 2

# INTIAL GUESS
p0 = []
counter = 0
while counter < number_variable:
    p0.append(0.0)
    counter += 1

p, _ = curve_fit(ffunc2, x, y, p0=[0.0, 0.0])

我想创建一个循环,它通过最小化错误来让我最适合最大数量的变量。

我也发现了这个讨论 - Using scipy curve_fit for a variable number of parameters

from numpy import exp
from scipy.optimize import curve_fit

def wrapper_fit_func(x, N, *args):
    a, b, c = list(args[0][:N]), list(args[0][N:2*N]), list(args[0][2*N:3*N])
    return fit_func(x, a, b)

def fit_func(x, a, b):
    counter = 0
    return_value = 0
    while counter < len(a):
        return_value += a[counter] * exp(b[counter] * x)
        counter += 1
    return return_value


x = [1, 2, 3, 5]
y = [1, 8, 81, 125]
params_0 = [0,1.0,2.0,3.0,4.0,5.0]

popt, pcov = curve_fit(lambda x, *params_0: wrapper_fit_func(x, 3, params_0), x, y, p0=params_0)

但是得到一个错误 -´´´ 文件“C:\python\lib\site-packages\scipy\optimize\minpack.py”,第 387 行,至少 sq raise TypeError('输入错误:N=%s 不得超过 M=%s' % (n, m)) TypeError:输入不当:N=6 不得超过 M=4 '''

【问题讨论】:

    标签: scipy python-3.7


    【解决方案1】:

    简短的回答是“不”。 curve_fit 需要一个变量参数列表/ndarray,这些变量参数按顺序与您提供的模型函数的参数相对应。也就是说,您必须明确命名函数中的所有参数,并使变量列表严格为一维。

    再一次,curve_fit 只不过是scipy.optimize.least_squares 的包装。要使用这种方法,您传入一个(仍然严格是一维的)列表/ndarray,并使用这些值从该单个变量数组构建要最小化的数组(通常是data-model)。在一些具有许多组件或数据集的复杂情况下,这可能会变得更容易使用。也就是说,curve_fit 方法不能很好地扩展到 50 个位置变量。

    根据问题的性质,您可能还会发现lmfithttps://lmfit.github.io/lmfit-py/ -- 免责声明:我是原作者)很有用。这按名称组织参数,而不是在列表中的位置,并提供更多内置方法来约束参数和探索不确定性。对于您的情况可能特别重要的是,用于曲线拟合的 lmfit.Model 类包括将模型轻松添加到复合中的能力(例如,2 高斯 + n 指数背景,如 https://lmfit.github.io/lmfit-py/examples/documentation/builtinmodels_nistgauss2.html 所示)。这可能会帮助你表达你想要做的事情。

    【讨论】:

      【解决方案2】:

      我能够直接使用 sci_py.optimize.least_squares 来解决这个问题,因为它直接将元组作为输入而不是变量。但我必须定义错误函数。我认为它有助于解决我现在的问题。

      from scipy.optimize import least_squares
      from matplotlib.pylab import plt
      from numpy import exp
      import numpy as np
      
      
      # define function to fit
      def ffunc2(a, x):
          counter = 0
          return_value = 0
          while counter < len(a):
              return_value += a[counter] * exp(x * a[counter + 1])
              counter += 2
      
          return return_value
      
      
      def error_func(tpl, x, y):
          return ffunc2(tpl,x) - y
      
      
      # INPUT DATA
      x = np.array([1, 2, 3, 5])
      y = np.array([0.22103418, 0.24428055, 0.26997176, 0.32974425,])
      
      # INITIAL GUESS
      p0 = (1, 1)*10
      output = least_squares(error_func, x0=p0, jac='2-point', bounds=(0, np.inf), method='trf', ftol=1e-08,
                             xtol=1e-08, gtol=1e-08, x_scale=1.0, loss='linear', f_scale=1.0, diff_step=None,
                             tr_solver=None,
                             tr_options={}, jac_sparsity=None, max_nfev=None, verbose=0, args=(x, y))
      
      tpl_final = output.x
      print (tpl_final)
      
      final_curve = ffunc2(tpl_final,x)
      
      plt.plot(x, y, 'r-', x, final_curve, 'g-')
      plt.show()
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-29
        • 2021-02-21
        • 1970-01-01
        • 1970-01-01
        • 2019-05-01
        • 2018-01-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多