Scipy less_squares: "func () отсутствует n обязательный позиционный аргумент: 'n_1', 'n_2' ..." - PullRequest
1 голос
/ 14 октября 2019

Вот мой код:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import least_squares

##################################### Prepare Data #########################################

file = 'https://aegis4048.github.io/downloads/notebooks/sample_data/decline_curve.xlsx'
df = pd.read_excel(file, sheet_name='sheet_1')
df = df[df['Oil Prod. (bopd)'] > 200]           # remove bad data points
t = df['Time'][1:].values[: -40]
y = df['Oil Prod. (bopd)'][1:].values[:-40]
x = np.array([i for i in range(len(t))])

############################################################################################


def hyperbolic(x, qi, b, Di):
    return qi / (1 + b * Di * x) ** (1 / b)

res_robust = least_squares(hyperbolic, x0=[max(y), 0.1, 0.1], args=(x, y))

Я смог легко уместить его в curve_fit с этим синтаксисом:

popt, pcov = curve_fit(hyperbolic, x, y, maxfev=100000, p0=[max(y), 0.1, 0.1])

Но когда я пытаюсь уместить свои данные, используяleast_squares, я получаю это сообщение об ошибке:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-5ee2dcc8876d> in <module>()
     20     return qi / (1 + b * Di * x) ** (1 / b)
     21 
---> 22 res_robust = least_squares(hyperbolic, x0=[max(y), 0.1, 0.1], args=(x, y,))

C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_lsq\least_squares.py in least_squares(fun, x0, jac, bounds, method, ftol, xtol, gtol, x_scale, loss, f_scale, diff_step, tr_solver, tr_options, jac_sparsity, max_nfev, verbose, args, kwargs)
    797         x0 = make_strictly_feasible(x0, lb, ub)
    798 
--> 799     f0 = fun_wrapped(x0)
    800 
    801     if f0.ndim != 1:

C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_lsq\least_squares.py in fun_wrapped(x)
    792 
    793     def fun_wrapped(x):
--> 794         return np.atleast_1d(fun(x, *args, **kwargs))
    795 
    796     if method == 'trf':

TypeError: hyperbolic() missing 1 required positional argument: 'Di'

Я не понимаю разницу в работе между curve_fit и least_squares. Может кто-нибудь дать мне рабочий код, который работает с least_squares?

1 Ответ

1 голос
/ 14 октября 2019

Согласно least_squares документам, ваша fun должна иметь подпись:

fun(x, *args, **kwargs)

Другими словами, она пытается сделать:

hyperbolic(x0, x, y)     # 3 arguments

xсоответствует вашему x0 начальному значению в форме;(x,y) происходит от параметра args.

Для curve_fit ожидание равно

ydata = f(xdata, *params)

Так что назовите его

hyperbolic(x, p0[0], p0[1], p0[2])  # line up with
#hyperbolic(x, qi, b, Di)              

Ваш hyperbolic подпись соответствует вызову curve_fit, но не least_squares.

...