python lmfit, немодифицируемый массив как параметр для класса Model? - PullRequest
0 голосов
/ 06 июля 2018

Я просто пытаюсь подобрать функцию, которая извлекает коэффициент корреляции Пирсона между двумя массивами. Эти два массива передаются в функцию в качестве входных параметров, но они не меняются. Для функции они должны интерпретироваться как константы. Я нашел опцию для параметров, где можно зафиксировать один параметр, то есть он не может изменяться, но работает только для скалярных значений.

Когда я вызываю Model.make_params (), Модельный класс пытается проверить, меньше ли эти массивы или меньше, чем минимум / максимум. Эта оценка не нужна, поскольку они являются постоянными.

Моя функция:

def __lin_iteration2__(xref, yref_scaled, xobs, yobs, slope, offset, verbose=False, niter=None):

    Acal = 1 + (offset + slope*xref)/xref
    xr_new = xref * Acal
    obs_interp1d = interp1d(xobs, yobs, kind='cubic')
    yobs_new = scale_vector(obs_interp1d(xr_new))
    rho = Pearson(yref_scaled, yobs_new)

    return rho

Где xref, yref_scaled, xobs и yobs - это массивы, которые не меняются, то есть константы. «interp1d» - это оператор интерполяции, полученный из scipy.interpolate, «scale_vector» масштабирует вектор от -1 до 1, а «Pearson» вычисляет коэффициент корреляции Пирсона.

Кого я настраиваю, Модель класса:

m = Model(corr.__lin_iteration3__)
par = m.make_params(yref_scaled = corr.yref_scaled, \
                    obs_interp1d=corr.obs_interp1d, offset=0, scale=0)
par['yref_scaled'].vary = False
par['obs_interp1d'].vary = False
r = m.fit

Ошибка, которую я получил (только во второй строке, когда я вызываю функцию 'make_params' класса модели):

Traceback (most recent call last):

  File "<ipython-input-3-c8f6550e831e>", line 1, in <module>
    runfile('/home/andrey/Noveltis/tests/new_correl_sp/new_correl.py', wdir='/home/andrey/Noveltis/tests/new_correl_sp')

  File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 705, in runfile
    execfile(filename, namespace)

  File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "/home/andrey/Noveltis/tests/new_correl_sp/new_correl.py", line 264, in <module>
    obs_interp1d=corr.obs_interp1d, offset=0, scale=0)

  File "/usr/lib/python3/dist-packages/lmfit/model.py", line 401, in make_params
    params.add(par)

  File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 338, in add
    self.__setitem__(name.name, name)

  File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 145, in __setitem__
    self._asteval.symtable[key] = par.value

  File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 801, in value
    return self._getval()

  File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 786, in _getval
    if self._val > self.max:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

1 Ответ

0 голосов
/ 06 июля 2018

В lmfit ожидается, что аргументами функции модели будут скалярные значения параметров с плавающей запятой, за исключением «независимых переменных», которые могут быть любыми объектами python. По умолчанию первый аргумент функции считается независимой переменной, как и любой аргумент ключевого слова с нечисловым значением по умолчанию. Но вы можете указать, какие аргументы являются независимыми переменными (и их может быть несколько) при создании модели.

Я думаю, что вы хотите:

m = Model(corr.__lin_iteration3__, independent_vars=['xref', 'yref_scaled', 'xobs', 'yobs'])

Но также : Вы также можете передать любой объект Python, чтобы вы могли упаковать ваши ref и obs данные в другие структуры и сделать что-то вроде

def lin_iteration(Data, slope, offset, verbose=False, niter=None):

    Acal = 1 + (offset + slope*Data['xref'])/Data['xref']
    xr_new = Data['xref'] * Acal
    # or maybe that would be clearer as just
    #   xr_new = offset + (1+slope)* Data['xref'] 
    obs_interp1d = interp1d(Data['xobs'], Data['yobs'], kind='cubic')
    yobs_new = scale_vector(obs_interp1d(xr_new))
    rho = Pearson(Data['yref_scaled'], yobs_new)

    return rho

и

m = Model(lin_iteration)
par = m.make_params(offset=0, scale=0)
Data = {'xref': xref, 'yref_scaled': yref_scaled, 'xobs': xobs, 'yobs': yobs}
result = m.fit(Data, params)

Конечно, это все не проверено, но это может сделать вашу жизнь проще ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...