Model Fitting

While fixed models (i.e. models that predict a fixed RDM) are important, many models have free parameters that can be fit to the data. All models come equipped with a default fitting function, which is called using the fit function of the model. This function takes a data RDMs object as input and returns a parameter value.

Individual vs. group fits

In the RSA toolbox, the models will always be fit to all RDMs that are passed to the fitting routine. That is, if the different RDMs are calculated on different subjects, the fit will be a group fit, with one set of parameters for the whole group. If you require individual fits, you need to loop over participants pass each RDM seperately to the fitting function.

Continuous vs. rank-based evaluation metrics

Most model fitting techniques require the evaluation metric to be differentiable with regard to the model parameters and this is true for most RDM comparison metrics provided by the toolbox. However, rank based evaluations (i.e. Spearman $rho$ and Kendall’s $tau$) are not differentiable and thus often lead to problems for optimization. Thus, we generally do not recommend fitting models using these criteria.

Two model types with their special fitting methods are exempt from this recommendation: Selection models and Interpolation models, which use a simple selection strategy and a derivative free bisection method for finding the best models respectively and can thus deal with discontinuous objective functions.

Fitting algorithms

Different fitting methods can be found in rsatoolbox.model.fitter module. To use them you can either apply them manually you can set them as the default of a model by settings its default_fitter property.

Unconstrained optimization

The function rsatoolbox.fitter.fit_optimize uses a general purpose optimization method. It simply maximizes the criterion using either positive or negative theta weights.

Non-negative optimization

The function rsatoolbox.fitter.fit_optimize_positive maximizes the fit, but constraints the parameter values to be non-negative. This is the most appropriate fitting method for weighting RDMs, because weighting features in an underlying representation can only add to the distances between points not subtract from them.

Regression-based methods

For correlation and cosine distances and weighted models, rsatoolbox.fitter.fit_regress provides more reliable and faster solutions based on linear algebra. Being specialized this method works only for the ‘cosine’, ‘corr’, ‘cosine_cov’ and ‘corr_cov’ comparison methods.

Analogously, rsatoolbox.fitter.fit_regress_nn provides a method for non-negative fits of such models.

Calling the fitting function directly

All fitting methods take the following inputs: A model object, data, a data RDMs object to fit to, method, a string that defines which similarity measure is optimized, and a pattern_idx, pattern_descriptor combination that defines which subset of the RDM the provided data RDMs correspond to. Additionally, they might take a ridge_weight, which adds a penalty on the squared norm of the weights vector to the objective and sigma_k, which is required for adjusting the whitened correlation and cosine similarity measures to dependent measurements.

For simple fitting of a single model simply apply the fit function to the model and data as shown in the following example:

import rsatoolbox
# generate 2 random model RDMs of 10 conditions
model_features = [rsatoolbox.data.Dataset(np.random.rand(10, 7)) for i in range(2)]
model_rdms = rsatoolbox.rdm.calc_rdm(model_features)
model = rsatoolbox.model.ModelWeighted('test', model_rdms)

# generate 5 random data RDMs of 10 conditions
data = [rsatoolbox.data.Dataset(np.random.rand(10, 7)) for i in range(5)]
data_rdms = rsatoolbox.rdm.calc_rdm(data)

# fit model to group data to maximize cosine similarity using its default fitter
theta = model.fit(data_rdms, method='cosine')

# explicitly use the fit_optimize function to do the fit
theta2 = rsatoolbox.model.fitter.fit_optimize(model, data_rdms, method='cosine')

Using the Fitter object

To provide an object, which fixes some parameters of the fitting function, rsatoolbox provides the fitter object. This type of object is defined as rsatoolbox.model.fitter.Fitter and takes a fitting function and additional keyword arguments as inputs. It then behaves as the original fitting function, with defaults changed to given keyword arguments.

To create a fitting function which sets the ridge_weight to 1 by default you could use the following code for example:

# fix some parameter of the function by using a fitter object:
fitter = rsatoolbox.model.fitter.Fitter(rsatoolbox.model.fit_optimize, ridge_weight=1)
theta3 = fitter(model, data_rdms, method='cosine')

Observe that this does indeed slightly change the fitted parameters compared to theta and theta2

Both the fitting functions themselves and the fitter objects can be used as inputs to the crossvalidation and bootstrap-crossvalidation methods to change how models are fit to data.