Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spiceaisle-0.1.0.tar.gz (10.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spiceaisle-0.1.0-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

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

Hashes for spiceaisle-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6e07c2ad374419fd8b4ca5aedff681b6587be81c65684073564feaaee09ce319
MD5 e370933cb1d617a310d2d1f73eeb90ed
BLAKE2b-256 f59286bdda7a770ddb1b7a6cc8b86bcd4a10ff0e47d054651c87d4bf1fdcabda

See more details on using hashes here.

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

Hashes for spiceaisle-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 02fe8d6ee302e7068908faeff7870eab38fa1fa3c586b126f419a963840b1f78
MD5 ec5b572d5c0fa7e47737f7bd9680a714
BLAKE2b-256 dbe5c9674694e6350e0342e186fd9840b4fab168860ff65d07077bbc130e090f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page