How Does Fit
Work?ΒΆ
In this section we describe in more detail how Fit
gets from a (named) model and a bunch of data to a fit. We will use
NumericalLeastSquares
as example.
Consider the following example:
from symfit import parameters, variables, Fit
a, b = parameters('a, b')
x, y = variables('x, y')
model = {y: a * x + b}
fit = Fit(model, x=x_data, y=y_data, sigma_y=sigma_data)
fit_result = fit.execute()
The first thing symfit
does is build \(\chi^2\) for your model:
chi_squared = sum((y - f)**2/sigmas[y]**2 for y, f in model.items())
In this line sigmas
is a dict which contains all vars that where given a
value, or returns 1 otherwise.
This \(\chi^2\) is then transformed into a python function which can then be used to do the numerical calculations:
vars, params = seperate_symbols(chi_squared)
py_chi_squared = lambdify(vars + params, chi_squared)
We are now almost there. Just two steps left. The first is to wrap all the data
into the py_chi_squared
function using partial()
into the
function to be optimized:
from functools import partial
error = partial(py_chi_squared, **data_per_var)
where data_per_var
is a dict containing variable names: value pairs.
Now all that is left is to minimize error
as a function of the parameters.
NumericalLeastSquares
does this by calling
leastsqbound()
and have it find the best fit
parameters:
best_fit_parameters, covariance_matrix = leastsqbound(
error,
self.guesses,
self.eval_jacobian,
self.bounds,
)
That’s it! Finally there are some steps to generate a
FitResults
object, but these are not important for
our current discussion.