Negative chi-square values in `neurosynth_decode` forward inference

Summary of what happened:

While using NeurosynthDecoder to characterize an ROI, I noticed that its forward test can produce negative chi-square statistics and NaN results. It appears to use the mean selected study count across terms as the expected count for every term using one_way(n_selected_term, n_term), although their total study counts differ. This expected count can exceed a term’s total count.
With the default BH correction enabled, these NaNs propagate to the corrected forward results for all terms, including those with otherwise finite values.

The example below reproduces this using official Neurosynth v7 data. Is this a limitation of the intended method, or an issue with how the expected counts are calculated? How should these terms be handled?

Command used (and if a helper script was used, a link to the helper script or the command generated):

from nimare.extract import fetch_neurosynth
from nimare.decode.discrete import NeurosynthDecoder

dataset = fetch_neurosynth(
    version="7", source="abstract", vocab="terms",
    type="tfidf", return_type="dataset",
)[0]

ids = dataset.get_studies_by_coordinate([[-36, 18, 0]], r=12)

decoder = NeurosynthDecoder(correction=None)
decoder.fit(dataset)
result = decoder.transform(ids=ids)

print("Selected studies:", len(ids))
print("Terms:", len(result))
print(result[["pForward", "zForward"]].isna().sum())
result[["pForward", "zForward"]]

Version:

v0.21.0

Environment (Docker, Singularity / Apptainer, custom installation):

Python 3.12

Relevant log outputs (up to 20 lines):

Selected studies: 3568
Terms: 3228
pForward    343
zForward    343
dtype: int64
/usr/local/lib/python3.13/dist-packages/nimare/transforms.py:1316: RuntimeWarning: invalid value encountered in sqrt
  return np.minimum(_log_erfc(np.sqrt(chi2_values / 2.0)), 0.0)

Screenshots / relevant information:


Hi @const!

Thanks for bringing this to our attention, I replicated the NaN results. You’re right, it should be one_way(n_selected_term, n_selected), which says of all the studies that report a result within the ROI (n_selected), how many contain the term of interest within that ROI (n_selected_term). one_way(n_selected_term, n_terms) is mixing the two marginal probabilities and is honestly a bit of a nonsensical statistic. With the BH correction propogating nans, that is another separate issue.

I’m fixing the one_way test here:

and the BH error here:

I’m also adding a min_studies argument, so you can filter out low frequency terms.

Please let me know if those fix your issue!

James

1 Like

Thanks James, that makes sense! Thanks for fixing this so quickly.