Note
Go to the end to download the full example code.
Using Inter-Site Matched Interpolation (ISMI) with matching covariates#
This notebook demonstrates the use of InterSiteMatchedInterpolation for harmonizing multi-site data using matching covariates.
2026-06-10 10:54:19 [debug ] Total Samples to generate 3000
2026-06-10 10:54:19 [debug ] Total Samples to generate per site [1000 1000 1000]
2026-06-10 10:54:19 [info ] Using balanced classes: [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5]]
2026-06-10 10:54:19 [info ] `balance_per_site` is: [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5]]
2026-06-10 10:54:19 [info ] Overall class balance across sites: [0.5 0.5]
2026-06-10 10:54:19 [debug ] locs: [50, 50, 50] and probs: None
2026-06-10 10:54:19 [debug ] locs: None and probs: [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5]]
2026-06-10 10:54:19 [debug ] Covariates requested: ['age', 'sex']
2026-06-10 10:54:19 [info ] For site 0
2026-06-10 10:54:19 [info ] Generating 1000 samples
2026-06-10 10:54:19 [debug ] Balance [0.5, 0.5] for site 0
2026-06-10 10:54:19 [debug ] Site 0 â covariate 'age': mean=50.893
2026-06-10 10:54:19 [debug ] Site 0 â covariate 'sex': mean=0.524
2026-06-10 10:54:19 [debug ] Site 0, site effect strength [3.0, 3.0, 3.0]
2026-06-10 10:54:19 [info ] For site 1
2026-06-10 10:54:19 [info ] Generating 1000 samples
2026-06-10 10:54:19 [debug ] Balance [0.5, 0.5] for site 1
2026-06-10 10:54:19 [debug ] Site 1 â covariate 'age': mean=49.223
2026-06-10 10:54:19 [debug ] Site 1 â covariate 'sex': mean=0.508
2026-06-10 10:54:19 [debug ] Site 1, site effect strength [3.0, 3.0, 3.0]
2026-06-10 10:54:19 [info ] For site 2
2026-06-10 10:54:19 [info ] Generating 1000 samples
2026-06-10 10:54:19 [debug ] Balance [0.5, 0.5] for site 2
2026-06-10 10:54:19 [debug ] Site 2 â covariate 'age': mean=49.728
2026-06-10 10:54:19 [debug ] Site 2 â covariate 'sex': mean=0.519
2026-06-10 10:54:19 [debug ] Site 2, site effect strength [3.0, 3.0, 3.0]
2026-06-10 10:54:19 [info ] Generated 3000 samples across 3 sites
2026-06-10 10:54:19 [info ] Class distribution: [1500 1500]
2026-06-10 10:54:19 [info ] Site distribution: [1000 1000 1000]
2026-06-10 10:54:19 [debug ] Using 1 categorical covariates
2026-06-10 10:54:19 [debug ] Using 1 continuous covariates with tolerance: [5.]
2026-06-10 10:54:19 [info ] [ISMI] Mode: pairwise
2026-06-10 10:54:19 [info ] [ISMI] Sites: [0 1 2] (3 sites, 3 pairs)
2026-06-10 10:54:19 [info ] [ISMI] Alpha: uniform[0.2, 0.4]
2026-06-10 10:54:19 [info ] [ISMI] Behavior: k=2 matches per sample
2026-06-10 10:54:19 [info ] [ISMI] Target tolerance: None
2026-06-10 10:54:19 [info ] [ISMI] Categorical covariates: 1
2026-06-10 10:54:19 [info ] [ISMI] Continuous covariates: 1 (tol: [5.])
2026-06-10 10:54:19 [info ] [ISMI] Processing 3 pairs
2026-06-10 10:54:19 [info ] [ISMI] Pair: 0 (1000) â 1 (1000)
/home/runner/work/UniHarmony/UniHarmony/src/uniharmony/interpolation/_inter_site_matched.py:469: UserWarning: Sample has 1 matches but k=2 requested, using all
X_synth_1, y_synth_1, n_un_1 = self._interpolate(X1, y1, X2, y2, matches_1to2, self.alpha_min_, self.alpha_max_)
/home/runner/work/UniHarmony/UniHarmony/src/uniharmony/interpolation/_inter_site_matched.py:475: UserWarning: Sample has 1 matches but k=2 requested, using all
X_synth_2, y_synth_2, n_un_2 = self._interpolate(X2, y2, X1, y1, matches_2to1, rev_min, rev_max)
2026-06-10 10:54:20 [info ] [ISMI] Generated 3970 samples (8 unmatched)
2026-06-10 10:54:20 [info ] [ISMI] Pair: 0 (1000) â 2 (1000)
2026-06-10 10:54:20 [info ] [ISMI] Generated 3978 samples (4 unmatched)
2026-06-10 10:54:20 [info ] [ISMI] Pair: 1 (1000) â 2 (1000)
2026-06-10 10:54:20 [info ] [ISMI] Generated 3970 samples (8 unmatched)
2026-06-10 10:54:20 [info ] [ISMI] Complete: 3000 original + 11918 synthetic = 14918 total (397.3% increase), 20 unmatched
{(np.int64(0), np.int64(1)): 6, (np.int64(1), np.int64(0)): 2, (np.int64(0), np.int64(2)): 2, (np.int64(2), np.int64(0)): 2, (np.int64(1), np.int64(2)): 4, (np.int64(2), np.int64(1)): 4}
import numpy as np
from uniharmony.interpolation import InterSiteMatchedInterpolation
from uniharmony.datasets import make_multisite_classification
# Generate sample data with 3 sites
X, y, sites, covars = make_multisite_classification(n_samples=3000, n_sites=3, covariates=["age", "sex"])
# Define covariates for matching
categorical_covariate = covars["sex"].reshape(-1,1)
continuous_covariate = covars["age"].reshape(-1,1)
covariate_tolerance = np.array([5.0]) # Âą5 years tolerance
# Create interpolator with pairwise mode and k=2 matches
ismi = InterSiteMatchedInterpolation(alpha=(0.2, 0.4),
covariate_tolerance=covariate_tolerance,
k=2,
mode="pairwise",
random_state=42)
# Generate harmonized dataset
X_res, y_res = ismi.fit_resample(X, y, sites,
categorical_covariate=categorical_covariate,
continuous_covariate=continuous_covariate)
# Check unmatched samples
print(ismi.unmatched_samples_)
Total running time of the script: (0 minutes 2.091 seconds)