nimare.ml.coefficient_image
- coefficient_image(estimator, bunch, coef=None, kind='weights', atlas='voxel', X=None)[source]
Return a fitted model’s voxel weights, or its activation pattern, as an image.
With
kind="weights", walks the fitted steps backwards, undoing each reduction, until the weights are one per voxel again, and unmasks them. Every step between the model and the voxels has to be read back for a weight to name a place in the brain, and a step that cannot be stops the walk and says so.With
kind="pattern", returns the activation pattern of Haufe et al.[1] instead: how each voxel covaries with the model’s scores. Weights say what a model uses, including voxels that only cancel noise elsewhere; a pattern says where the data differ along what the model reads, and is what a weight map is usually mistaken for.- Parameters:
estimator (
Pipelineor estimator) – A fitted pipeline ending in a model withcoef_, or the model itself when the features are already voxels.bunch (
sklearn.utils.Bunch) – The bunch the model was fitted on, for itsmaskerand the span of its voxel columns.coef (array_like, optional) – Weights to project instead of the model’s own, by default None. One per feature the final step was given, which is what a permutation importance returns. With
kind="pattern"they are read as a linear readout,scores = features @ coef.T.kind ({"weights", "pattern"}, default="weights") – What to return.
"weights"gives one weight per voxel such that the model’s scores are the voxel maps times the weights, plus a constant."pattern"givescov(voxels, scores) @ pinv(cov(scores)), computed fromX; it needs no step to be undone, so it works through any pipeline whose final model is linear in its features.atlas ({"voxel", "region"}, default="voxel") – How weights are read back through a
MaskerTransformerthat reduced voxels to regions."voxel"gives each voxel its own weight, the transpose of the reduction: a region’s weight divided by its size for an averaging labels atlas, and corrected for the overlap of the maps for a probabilistic atlas."region"paints each region’s weight over its voxels, which shows the regions but is not a per-voxel weight. Ignored withkind="pattern".X (array_like or sparse matrix, optional) – The rows to compute a pattern from, as the pipeline takes them, by default None, which uses
bunch.data. Pass the voxel block, for instance, when that is what the pipeline was fitted on. Only used withkind="pattern".
- Returns:
One weight per voxel, in the bunch masker’s space. A model with one set of weights gives a 3D image, several give a 4D one.
- Return type:
- Raises:
ValueError – If
kindoratlasis not recognised, if no weights can be found, if a step cannot be undone, or if the weights or the voxel data do not end up one per voxel.
Notes
A model that scores
w @ (A x + c)scores(A.T @ w) @ xplus a constant, so a weight moves back through a linear step by the transpose of its linear part, and the step’s offset belongs to the intercept. That is not whatinverse_transformcomputes: it maps a point back,A^-1 (z - c), which agrees with the transpose only for an orthogonal step with no offset. Through aStandardScalerit would givew * scale + meanwhere the weight isw / scale. The steps read back are therefore the ones whose linear part is known: the scikit-learn scalers (StandardScaler,MaxAbsScaler,MinMaxScalerunless it clips,RobustScaler),PCA,TruncatedSVD, feature selectors, and aMaskerTransformer, which is undone through the atlas it applied. Any other step is refused.Through an atlas the same rule applies. A labels atlas that averages has
A[r, v] = 1 / n_rover then_rvoxels of regionr, so each voxel carriesw_r / n_r; one that sums carriesw_r. A probabilistic atlas fits each map by least squares,A = (M M.T)^-1 M, so the voxel weights areM.T (M M.T)^-1 w. ANiftiMaskerthat only smooths is its own transpose. Strategies and signal cleaning that are not linear in the voxels are refused.A pattern is a covariance in voxel space, so it moves through a step the way data do, not the way weights do. Rather than walk the steps for it, the pattern is computed where the voxels are: the output of the
MAKernel, orXitself when there is none. The scores are the final features times the weights, without the intercept, which a covariance does not see.References
See also
nimare.ml.MaskerTransformerUndone through the atlas it applied.
Examples
>>> image = coefficient_image(pipeline, bunch) >>> plotting.plot_stat_map(image)