Как определить функцию значения chi2 для произвольной функции?

Я делаю некоторые данные, используя привязки Pythinuit Python для кода минимизации minuit (http://code.google.com/p/pyminuit/). Минимизер принимает функцию и использует интроспекцию для извлечения параметров, которые должны быть сведены к минимуму. В общем, я хочу свести к минимуму квадратичное значение chi для набора данных, учитывая определенную функцию для описания набора данных.

Мой вопрос: существует ли способ определить квадратную функцию chi, которая при заданной произвольной функции с различным числом параметров возвращает функцию, которая дает квадратное значение chi для этой функции и содержит только параметры для быть сведено к минимуму в спецификации аргумента функции?

Пример:

from scipy import *
import minuit
# Generate some data to fit
data_x = arange(50)
noise = 0.3
data_y = data_x**3 + normal(0.0, noise)
# Fit function, e.g. a cubic
fit_func = lambda x, a1, a2, a3, a4: a1 + a2*x + a3*x**2 + a4*x**3

# Minimisation function e.g. chi squared
# Note this has only the parameters to be minimised in the definition (eg not data_x)
min_func = lambda a1, a2, a3, a4: sum( (fit_func(data_x, a1, a2, a3, a4) - data_y)**2/noise**2 )

Вот где я хотел бы написать что-то вроде min_func = make_chi2 (fit_func) . Я не знаю, что делать, поскольку data_x и data_y определяются только вне функции. Остальная часть процедуры минимизации, для полноты, выглядит так:

# Initialise minimiser object with initial values
m = minuit.Minuit(min_func, {'a1': 1.0, 'a2': 1.0, 'a3': 1.0, 'a4': 1.0})
# Run minimiser
m.migrad()
# Print minimised values - example output
print m.values
>>> {'a1': 0.000, 'a2': 0.000, 'a3': 0.000, 'a4': 1.000}

Заранее спасибо за помощь!

2
Я бы назвал тот факт, что pyminuit извлекает параметры только путем интроспекции и не позволяет явно называть их по крайней мере сомнительным дизайном со стороны pyminuit. Разрешат ли они давать параметры явно, ваша проблема будет тривиальной для решения.
добавлено автор Sven Marnach, источник

1 ответы

Поскольку PyMinuit использует интроспекцию, вы также должны использовать интроспекцию. make_chi_squared() может быть реализован следующим образом:

import inspect

chi_squared_template = """
def chi_squared(%(params)s):
    return (((f(data_x, %(params)s) - data_y)/errors) ** 2).sum()
"""

def make_chi_squared(f, data_x, data_y, errors):
    params = ", ".join(inspect.getargspec(f).args[1:])
    exec chi_squared_template % {"params": params}
    return chi_squared

Пример использования:

import numpy

def f(x, a1, a2, a3, a4):
    return a1 + a2*x + a3*x**2 + a4*x**3

data_x = numpy.arange(50)
errors = numpy.random.randn(50) * 0.3
data_y = data_x**3 + errors

chi_squared = make_chi_squared(f, data_x, data_y, errors)
print inspect.getargspec(chi_squared).args

печать

['a1', 'a2', 'a3', 'a4']
1
добавлено
У меня было что-то подобное написано, но это гораздо более краткий и аккуратный. Благодаря!
добавлено автор almailer, источник
Python
Python
7 654 участник(ов)

Уютный чат для профессионалов, занимающихся поиском питоньих мудростей. Как не получить бан: https://t.me/ru_python/577926

Python beginners
Python beginners
4 449 участник(ов)

Вопросы про Python для чайников. Cпам и троллинг неприемлем. Не злоупотребляйте стикерами. Частозадаваемые вопросы: https://github.com/ru-python-beginners/faq/blob/master/README.md Статистика тут: https://grstats.me/chat/x4qym2k5uvfkr3al6at7

pro.python
pro.python
1 090 участник(ов)

Сообщество разработчиков под Python Создатель: @rodgelius

Rude Python
Rude Python
971 участник(ов)

Python без „девочек”, здесь матерятся и унижают Django. Not gay friendly. Правила: t.me/rudepython/114107 @rudepython | t.me/rudepython

rupython
rupython
509 участник(ов)

Группа создана с целью оперативного получения ответов на возникающие вопросы по разработке на яп python, смежные темы, а также человеческого общения. Приветствую!

Python-programming
Python-programming
266 участник(ов)

Чат группы вконтакте https://vk.com/python_community