Package for SPICE-Net, a neural network based estimation framework to estimate causal effects using proxy variables.
Project description
spiceaisle: A Python Package for SPICE-Net to estimate causal effects under unobserved confounding using proxies
This is a PyTorch implementation of SPICE-Net based on the paper https://arxiv.org/abs/2604.09135, to estimate the causal effect of a treatment X on an outcome Y under unobserved confounding U by the use of proxy variables W.
SPICE-Net is a two-step procedure. First, spicenet learns the conditional density of U given X and Y up to a linear transformation.
Second, we can use samples from this conditional density to estimate the causal effect of X on Y, with any standard
causal effect estimator for observed confounding, for example with the implemented regression_adjustment.
If you use SPICE-Net in your research, please consider citing:
@article{vollmer2026identifying,
title={Identifying Causal Effects Using a Single Proxy Variable},
author={Vollmer, Silvan and Pfister, Niklas and Weichwald, Sebastian},
journal={arXiv preprint arXiv:2604.09135},
year={2026}
}
Installation and Usage
pip install spiceaisle
# Example for causal effect estimation using SPICE-Net
import torch
from spiceaisle import spicenet, regression_adjustment
import numpy as np
from sklearn.neural_network import MLPRegressor
# Example training data
n = 2000
u_data = torch.randn(n, 1) # unobserved confounder
w_data = u_data + torch.randn(n, 1) # proxy variable
x_data = u_data + torch.randn(n, 1) # treatment
y_data = u_data + x_data + torch.randn(n, 1) # outcome
# Example test data
n_test = 500
u_data_test = torch.randn(n_test, 1) # unobserved confounder
w_data_test = u_data_test + torch.randn(n_test, 1) # proxy variable
x_data_test = u_data_test + torch.randn(n_test, 1) # treatment
y_data_test = u_data_test + x_data_test + torch.randn(n_test, 1) # outcome
# 1. First step of SPICE-Net: Learn the conditional density (using Engression https://github.com/xwshen51/engression/tree/main)
model = spicenet(
layer_dims=[5, 10, 20, 10, 5], # (list): List of integers specifying the dimensions of each layer.
x_data=x_data, # (torch.Tensor): Input tensor for treatment (X).
y_data=y_data, # (torch.Tensor): Input tensor for outcome (Y).
w_data=w_data, # (torch.Tensor): Input tensor for proxy (W).
noise_nodes_dim=5,
# (int, optional): Dimension of the Gaussian noise nodes to be added at each layer. Defaults to 5.
noise_nodes_std=1, # (float, optional): Standard deviation of the Gaussian noise nodes. Defaults to 1.
distribution_e="Normal", # (str): Type of distribution for the error term.
params_e={
# (dict): Parameters for the error term distribution (set to "learn" if you want to use SPICE-Net-Approx).
"loc": [0],
"scale": [1]
},
params_e_initialize={
# (dict): Parameters for the initialization of the error term distribution (only used for SPICE-Net-Approx).
"loc": [0],
"scale": [1]
},
lr=None,
# (float, optional): (Initial) learning rate for the optimizer. Defaults to Default of https://docs.pytorch.org/docs/stable/generated/torch.optim.Adam.html
adaptive_lr=True, # (bool, optional): Whether to use adaptive learning rate. Defaults to True.
patience_lr=500, # (int, optional): Patience for adaptive learning rate scheduler. Defaults to 1000.
beta=1, # (float, optional): Power parameter in the energy score loss. Defaults to 1.
num_epochs=4000, # (int, optional): Number of epochs for training. Defaults to 2000.
verbose=True, # (bool, optional): Whether to print training progress. Defaults to False.
confounder_dim=None,
# (int): Dimension of the unobserved confounder variable. Defaults to None, which sets it equal to dimension of W.
batch_size=200 # (int, optional): Batch size for training. Defaults to 200.
)
# train the model
model.train()
# predict for test data
u_samples_spice = model.predict_new_data(x_data, y_data)
u_samples_spice_np = u_samples_spice.detach().cpu().numpy()
# 2. Second step of SPICE-Net: Estimate the causal function
spice_preds = regression_adjustment(
x_data=x_data,
y_data=y_data,
adj_samples=u_samples_spice_np,
x_data_test=x_data_test,
)
# Adjustment using the true unobserved confounder
adj_u_preds = regression_adjustment(
x_data=x_data,
y_data=y_data,
adj_samples=u_data,
x_data_test=x_data_test,
)
# Adjustment using the proxy variable
adj_w_preds = regression_adjustment(
x_data=x_data,
y_data=y_data,
adj_samples=w_data,
x_data_test=x_data_test,
)
# 3. Results (MSE)
x_test_np = np.ravel(x_data_test).reshape(-1, 1)
mse_spice = np.mean((spice_preds - x_test_np) ** 2)
mse_adj_u = np.mean((adj_u_preds - x_test_np) ** 2)
mse_adj_w = np.mean((adj_w_preds - x_test_np) ** 2)
print("SPICE-Net adjustment MSE:", mse_spice)
print("True-confounder adjustment MSE:", mse_adj_u)
print("Proxy adjustment MSE:", mse_adj_w)
Requirements
- Python >= 3.14
- PyTorch >= 2.11.0
- NumPy >= 2.4.4
- scikit-learn >= 1.8.0
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 spiceaisle-0.1.0.tar.gz.
File metadata
- Download URL: spiceaisle-0.1.0.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e07c2ad374419fd8b4ca5aedff681b6587be81c65684073564feaaee09ce319
|
|
| MD5 |
e370933cb1d617a310d2d1f73eeb90ed
|
|
| BLAKE2b-256 |
f59286bdda7a770ddb1b7a6cc8b86bcd4a10ff0e47d054651c87d4bf1fdcabda
|
File details
Details for the file spiceaisle-0.1.0-py3-none-any.whl.
File metadata
- Download URL: spiceaisle-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02fe8d6ee302e7068908faeff7870eab38fa1fa3c586b126f419a963840b1f78
|
|
| MD5 |
ec5b572d5c0fa7e47737f7bd9680a714
|
|
| BLAKE2b-256 |
dbe5c9674694e6350e0342e186fd9840b4fab168860ff65d07077bbc130e090f
|