Skip to main content
 首页 » 编程设计

python之如何为任意函数定义 chi2 值函数

2025年05月04日9sky-heaven

我正在使用 pyminuit Python 绑定(bind)为 minuit 最小化代码 (http://code.google.com/p/pyminuit/) 进行一些数据拟合。最小化器接受一个函数并使用内省(introspection)来提取要最小化的参数。通常,我想在给定特定函数来描述数据集的情况下最小化数据集的卡方值。

我的问题:有没有办法定义一个卡方函数,给定一个具有不同数量参数的任意函数,返回一个函数,该函数给出该函数的卡方值和仅包含函数参数规范中要最小化的参数?

例子:

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} 

提前感谢您的帮助!

请您参考如下方法:

既然 PyMinuit 使用内省(introspection),你也必须使用内省(introspection)。 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']