mantispy.pp.feature_select_chatterjee#

mantispy.pp.feature_select_chatterjee(adata, by='Metadata_Perturbation', threshold=0.1, m=1, seed=0, min_finite=40, key_added='selected_chatterjee', copy=False)[source]#

Keep features whose values depend on the group, monotonically or otherwise.

Parameters:
adata AnnData

Object to select features on.

by str (default: 'Metadata_Perturbation')

obs column the features are tested against.

threshold float (default: 0.1)

Keep features scoring above this. xi is near zero under independence and approaches one when the feature is a deterministic function of the group, so the threshold is comparable across datasets in a way a correlation cutoff is not.

m int (default: 1)

Right nearest neighbors [Lin and Han, 2022]. m=1 is the coefficient of Chatterjee [2020] up to a term of order 1/n; larger values lower the noise floor without changing what the statistic converges to.

seed int (default: 0)

Seed for breaking ties between rows of the same group.

min_finite int (default: 40)

Fewest finite values a feature may be scored on. A feature measured fewer times than this scores NaN, which is above no threshold and so is never selected.

key_added str (default: 'selected_chatterjee')

Name of the boolean var column written.

copy bool (default: False)

Return a modified copy instead of mutating in place.

Return type:

AnnData | None

Returns:

None, or the modified copy. Writes var[key_added] and the statistic itself to var["chatterjee_xi"], which is NaN for a feature that is constant or too sparsely measured to score.

Raises:

ValueError – If by has a single group, so that no feature can depend on it.

Notes

Run it after feature_select(), which drops redundant or unmeasurable features; this keeps the features that carry information about the perturbation. Subset with mt.pp.subset_features(adata, key="selected_chatterjee").

A feature is scored on the rows where it was measured, so one that is missing in a whole group is scored against the groups that do have it rather than against the pattern of what is missing.

xi reaches one only for a noiseless function of the group, so real values are much lower and the default threshold of 0.1 is permissive. Check the distribution in var["chatterjee_xi"] before relying on a fixed cutoff.

With shuffled group labels xi collapses toward zero while the real values barely change, so the score reflects dependence on the group rather than noise. m=1 is the default because the threshold was calibrated there. scmorph uses m=5, and on input free of ties the two implementations agree to 1e-9. scmorph breaks ties in y at random, so on tied input the two differ.