Глобальная примерка с Symfit: типовая структура набора данных - PullRequest
1 голос
/ 11 октября 2019

Я хочу выполнить глобальную подборку наборов данных с общими переменными, используя symfit . У меня есть массив NumPy xdata, который является общим для всех наборов данных ydata_i, которые также являются массивами NUMPY.

Следуя примеру в документации a, можно настроить переменные, параметры и модель, но мне не удается настроить подгонку: fit = Fit(model, x_1=xdata_1, x_2=xdata_2, ..., y_1=ydata_1, y_2=ydata_2, ...)

Для небольшого числаиз наборов данных я могу написать код вручную или скопировать / вставить его, но у меня есть сто наборов данных, и я надеюсь, что я могу избежать ввода кода вручную. Я пытался использовать списки [xdata, ydata_1, ydata2, ...] или [xdata, ydata_1, xdata, ydata2, ...] или массивы, но это, кажется, не правильный путь.

Кто-нибудь знает, как должна выглядеть структура / тип order_data ,Спасибо

Ответы [ 2 ]

2 голосов
/ 12 октября 2019

Для большого количества наборов данных вы можете использовать словарь:

data = {'x_1': xdata_1, 'x_2': xdata_2, ..., 'y_1': ydata_1, 'y_2': ydata_2, ...}
fit = Fit(model, **data)

Таким образом, вместо этого он будет заканчиваться на named_data, что является предпочтительным. Удачи!

ps. Вы также можете рассмотреть возможность использования JacobianModel или CallableModel вместо модели по умолчанию, если вы работаете с такими большими моделями, потому что вычисление якобиана и гессиана для такой моделиможет быть дорогим и ненужным.

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

Извините, мне нужна еще раз ваша помощь. Я заканчиваю с ошибкой wrapped_func() keywords must be strings или 'Variable' object has no attribute 'symbol'. Я думаю, что это простая проблема, но я не понимаю, в чем суть. Не могли бы вы взглянуть на следующий пример?

import numpy as np
import symfit as sf

# creating the data
freq = 10 * np.linspace(0.1,0.3,2)
phase = np.pi * np.linspace(0,0.3,2)
offset = 1.0
amplitude = 0.1

# x - array
x_array = np.arange(0,20,0.02)
# create dataset
dataset = [offset + amplitude * np.cos(freq * x_array + phase) + np.random.normal(size=len(x_array), scale=0.01) for freq,phase in zip(freq,phase)]

# independent variables
xs = sf.variables(', '.join('x_{}'.format(i) for i in range(len(dataset))))
# dependent variables
ys = sf.variables(', '.join('y_{}'.format(i) for i in range(len(dataset))))
# coupled parameters
amp, off = sf.parameters('amp, off', value=[1.0,0.1])
# decoupled parameters
freqc = sf.parameters(', '.join('f_{}'.format(i) for i in range(len(dataset))),value=freq)
phasec = sf.parameters(', '.join('p_{}'.format(i) for i in range(len(dataset))),value=phase)

# setup model
model_dict = {y : off + amp * sf.cos(freq * x + phase) for x, y, freq, phase in zip(xs, ys, freqc, phasec) }
# create dataset_dict
xdata = [x_array for i in range(len(dataset))] # just to have equal length of xdata list and y-data list
#data_dict = {x : data for x, data in zip(xs + ys, xdata + dataset)} # error 'wrapped_func() keywords must be strings'
#data_dict = {str(x) : data for x, data in zip(xs + ys, xdata + dataset)} # error 'Variable' object has no attribute 'symbol'
data_dict = {'x_0': x_array, 'x_1': x_array, 'y_0': dataset[0], 'y_1': dataset[1]} # error 'Variable' object has no attribute 'symbol'
# # do the fit
fit = sf.Fit(model_dict, **data_dict)
fit_result = fit.execute()

Я использую Python 3.7.4 на ПК с Windows через Anconda. Версия Symfit: 0.4.6, версия Sympy: 1.4

Traceback (most recent call last):

  File "C:/Users/dummy/Documents/Scripts/Python/Scripts/SymFit_example.py", line 42, in <module>
    fit_result = fit.execute()

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\fit.py", line 1537, in execute
    minimizer_ans = self.minimizer.execute(**minimize_options)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\minimizers.py", line 359, in execute
    return super(ScipyGradientMinimize, self).execute(jacobian=self.wrapped_jacobian, **minimize_options)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\support.py", line 355, in wrapped_func
    return func(*bound_args.args, **bound_args.kwargs)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\minimizers.py", line 296, in execute
    **minimize_options

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\scipy\optimize\_minimize.py", line 594, in minimize
    return _minimize_bfgs(fun, x0, args, jac, callback, **options)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\scipy\optimize\optimize.py", line 996, in _minimize_bfgs
    gfk = myfprime(x0)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\scipy\optimize\optimize.py", line 326, in function_wrapper
    return function(*(wrapper_args + args))

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\scipy\optimize\optimize.py", line 756, in approx_fprime
    return _approx_fprime_helper(xk, f, epsilon, args=args)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\scipy\optimize\optimize.py", line 690, in _approx_fprime_helper
    f0 = f(*((xk,) + args))

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\scipy\optimize\optimize.py", line 326, in function_wrapper
    return function(*(wrapper_args + args))

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\minimizers.py", line 273, in wrapped_func
    return np.array(func(**parameters))

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\support.py", line 355, in wrapped_func
    return func(*bound_args.args, **bound_args.kwargs)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\objectives.py", line 151, in __call__
    evaluated_func = self.model(**jac_kwargs)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\fit.py", line 334, in __call__
    return Ans(*self.eval_components(**bound_arguments.arguments))

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\fit.py", line 296, in eval_components
    return [expr(*args, **kwargs) for expr in self.numerical_components]

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\support.py", line 217, in __get__
    setattr(obj, self.cache_attr, self.fget(obj))

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\fit.py", line 457, in numerical_components
    return [sympy_to_py(expr, self.independent_vars, self.params) for expr in self.values()]

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\fit.py", line 457, in <listcomp>
    return [sympy_to_py(expr, self.independent_vars, self.params) for expr in self.values()]

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\symfit\core\support.py", line 91, in sympy_to_py
    return lambdify((vars + params), func, modules='numpy', dummify=False)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\sympy\utilities\lambdify.py", line 767, in lambdify
    funcstr = funcprinter.doprint(funcname, args, expr)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\sympy\utilities\lambdify.py", line 977, in doprint
    argstrs, expr = self._preprocess(args, expr)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\sympy\utilities\lambdify.py", line 1039, in _preprocess
    s = self._argrepr(arg)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\sympy\printing\codeprinter.py", line 100, in doprint
    lines = self._print(expr).splitlines()

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\sympy\printing\printer.py", line 287, in _print
    return getattr(self, printmethod)(expr, **kwargs)

  File "C:\Users\dummy\Anaconda3\envs\spyder-beta\lib\site-packages\sympy\printing\codeprinter.py", line 344, in _print_Variable
    return self._print(expr.symbol)

AttributeError: 'Variable' object has no attribute 'symbol'
...