Propensity Score Matching (PSM), Full Matching, Genetic Matching, Cardinality Matching, CEM, and Causal Inference in Python. A port of R's MatchIt.
Project description
pymatchit-causal: Propensity Score Matching in Python
Scalable Causal Inference, Propensity Score Matching (PSM), and Coarsened Exact Matching (CEM).
pymatchit-causal is a Python port of the standard R package MatchIt. It allows data scientists to preprocess data for causal inference by balancing covariates between treated and control groups using state-of-the-art matching methods. With the 0.5.0 release, it emphasizes a cohesive, publication-ready visual diagnostic suite.
Why use pymatchit?
If you are looking for Propensity Score Matching in Python, this library provides a robust, "R-style" workflow including:
- Propensity Score Estimation: Logistic Regression (GLM), Random Forest, GBM, Neural Networks.
- Matching Algorithms: Nearest Neighbor (Greedy), Optimal Matching, Exact, Subclassification, and Coarsened Exact Matching (CEM).
- Diagnostics: Publication-ready visual alignment—featuring Love Plots (Covariate Balance), Propensity Density Plots, ECDF plots, and the newly added Jitter Plots for intuitive match verification.
Features
- Matching Methods: Nearest Neighbor, Optimal Matching, Exact, Coarsened Exact Matching (CEM), Subclassification.
- Distance Metrics: Logistic Regression (GLM), Mahalanobis, Random Forest, GBM, Neural Networks, etc.
- Diagnostics: Cohesive diagnostic plots including visually aligned Love Plots, Jitter Plots, and Summary Tables (SMD, Variance Ratios).
- Parity: Designed to mirror the R
MatchItAPI (matchit(formula, data, method=...)).
Installation
pip install pymatchit-causal
Dependencies: numpy, pandas, scipy, statsmodels, matplotlib, scikit-learn, seaborn, patsy.
Example Workflow
Scenario: You have a dataset healthcare_data.xlsx with a binary treatment variable took_drug, an outcome recovery_time, and confounders like age, severity, and income.
1. Load Data
import pandas as pd
from pymatchit import MatchIt
# Load your dataset
df = pd.read_excel("healthcare_data.xlsx")
2. Initialize and Match
We will use Nearest Neighbor matching using a Random Forest to estimate the propensity score, applying a caliper to ensure good matches.
# Initialize the matching model
m = MatchIt(
data=df,
method='nearest', # 1:1 Nearest Neighbor matching
distance='randomforest', # Use Random Forest for Propensity Scores
distance_options={'n_estimators': 500},
caliper={'distance': 0.1, 'age': 2},
replace=False,
random_state=42
)
# Fit the model using an R-style formula
m.fit("took_drug ~ age + severity + income + gender")
3. Assess Balance (Diagnostics)
Verify that the treatment and control groups are balanced with cohesive visualization tools.
# 1. Statistical Summary
summary = m.summary()
# 2. Visual Inspection: Love Plot
m.plot(type='balance', threshold=0.1)
# 3. Visual Inspection: Propensity Jitter Plot (New in 0.5.0!)
m.plot(type='jitter')
# 4. Visual Inspection: Propensity Density Overlap
m.plot(type='propensity')
# 5. Visual Inspection: ECDF Plot
m.plot(type='ecdf', variable='age')
4. Extract Matched Data
If balance is satisfactory, extract the data for analysis.
# Get the final dataset containing only matched units
matched_df = m.matches(format='long')
# Get data with weights and subclass
final_analysis_set = m.matched_data
5. Downstream Inference
Calculate cluster-robust standard errors in your final effect estimation:
import statsmodels.formula.api as smf
model = smf.wls("recovery_time ~ took_drug", data=final_analysis_set, weights=final_analysis_set['weights'])
results = model.fit(cov_type='cluster', cov_kwds={'groups': final_analysis_set['subclass']})
print(results.summary())
Citation
If you use pymatchit-causal in your research, please cite it:
Tünnermann, J. (2026). pymatchit: Propensity Score Matching and Causal Inference in Python (Version 0.5.0). Zenodo. https://doi.org/10.5281/zenodo.17839522
BibTeX:
@software{pymatchit_causal,
author = {Jonas Tünnermann},
title = {pymatchit: Propensity Score Matching and Causal Inference in Python},
year = 2026,
publisher = {Zenodo},
version = {0.5.0},
doi = {10.5281/zenodo.17839522},
url = {https://doi.org/10.5281/zenodo.17839522}
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pymatchit_causal-0.5.0.tar.gz.
File metadata
- Download URL: pymatchit_causal-0.5.0.tar.gz
- Upload date:
- Size: 40.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
133c39fa26bbe1de493916b1783be523276e794865bff243e190245a88e8e05c
|
|
| MD5 |
88624fe9a81e9ea04bd86c8cf87ae98b
|
|
| BLAKE2b-256 |
bed44d079a6f1b2080a9ac27230d3a3eb813cb7bd9936c10e909050b15aeed66
|
File details
Details for the file pymatchit_causal-0.5.0-py3-none-any.whl.
File metadata
- Download URL: pymatchit_causal-0.5.0-py3-none-any.whl
- Upload date:
- Size: 37.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c27f4b9e63d33600dc706e0189f910620ef22480c88f55a5ae196146c96c1f03
|
|
| MD5 |
505b23cf01c2392e78e6d8659cc255e8
|
|
| BLAKE2b-256 |
3a9cf82e8a0b54a3647860e3e6435112f89f7885f2c8a7bf64a2697e0b8e6d48
|