<div align="center">
  
# SpinSVAR: Estimating Structural Vector Autoregression Assuming Sparse Input  
**Panagiotis Misiakos & Markus Püschel**  
<sub>To appear in: *Uncertainty in Artificial Intelligence (UAI), 2025*</sub>

</div>

---

## Overview

**SpinSVAR** is a novel method for estimating a structural vector autoregression (SVAR) model from time-series data under a **sparse input** assumption. The method formulates a **maximum likelihood estimator** (MLE) based on least absolute error regression by modeling the input as i.i.d. Laplacian variables.

For a quick demo, check out [`SpinSVAR_demo.ipynb`](SpinSVAR_demo.ipynb).

If you find this repository useful please cite:

```
@inproceedings{misiakos2025spinsvar,
      title={SpinSVAR: Estimating Structural Vector Autoregression Assuming Sparse Input}, 
      author={Panagiotis Misiakos and Markus Püschel},
      publisher = {To appear in: Uncertainty in Artificial Intelligence},
      year={2025},
}
```
---
## Key Results

### 1. Dependencies Between S&P 500 Stocks

SpinSVAR uncovers economically meaningful structures in stock returns. When applied to S&P 500 data, it clusters stocks by sector and reveals significant **structural shocks** linked to market behavior.

<p align="center">
  <img src="experiments/plots_UAI/S&P500/window_graph.png" alt="Dependencies graph" width="650"/>
</p>

> **Interpretation**:  
> The learned $\widehat{\mathbf{B}}_0$ matrix roughly clusters stocks according to their economic sectors. Some outliers (e.g., large IT firms) span sectors:
> - **MSFT** influences **GOOG** and **AMZN**  
> - **META**, **AAPL**, and **MSFT** influence **AMZN**  
> - **AMZN** influences **GOOG** and **MSFT**  
>  
> Notably, the weights of $\widehat{\mathbf{B}}_0$ are positive, indicating that these stocks tend to move together: when one rises or falls, the others follow.

---

### 2. Structural Shocks in the S&P 500

By estimating the SVAR input from S&P 500 time series, SpinSVAR captures **unexpected economic events** as structural shocks.

<p align="center">
  <img src="experiments/plots_UAI/S&P500/root_causes.png" alt="Structural shocks" width="650"/>
</p>

> **Examples**:  
> - **Feb 1, 2024**: META shows a positive shock of **+0.18** — the same day it announced its first-ever dividend.  
> - **May 24, 2023**: NVDA shows a shock of **+0.20** — coinciding with an upward forecast due to rising AI demand.

---

## Installation

The code runs successfully on **Windows 11** and **macOS Sequoia 15.4.1** with **Python 3.9.7**.

### 1. Create and activate a conda environment:

```bash
conda create -n spinsvar python=3.9.7
conda activate spinsvar
```

### 2. Install required libraries:

```bash
# install all requirements with pip
pip install -r requirements.txt
```

And you are all set!


## Full experiment reproducibility 
Current version of the code was run successfully in Windows 11 with python 3.9.7.


Setup the python environment:
```bash
# create a new conda environment
conda create -n spinsvar python=3.9.7
conda activate spinsvar

# install all requirements with pip
pip install -r requirements.txt
# javabridge:
conda install -c conda-forge python-javabridge
```

We suggest installation of the following packages using conda.
```bash
# install pydot with conda
conda install pydot
conda install numpy=1.23.4
conda install cvxopt
```

### Other repos
Then manually import the following repositories. 
```bash
# install py-causal repo
pip install git+https://github.com/bd2kccd/py-causal

# clone the following repositories
cd neurips_experiments/methods/
git clone https://github.com/xunzheng/notears
git clone https://github.com/cdt15/lingam
git clone https://github.com/M-Nauta/TCDF
git clone https://github.com/xiangyu-sun-789/NTS-NOTEARS
git clone https://github.com/jakobrunge/tigramite
git clone https://github.com/i6092467/GVAR (not used as method in the paper)
git clone https://github.com/causalml-lab/pcmci-omega (not used as method in the paper)
```

Make sure to have R installed and that the path to the R directory in file **time_series_experiment.py** [`experiments/methods/utils.py`](experiments/methods/utils.py) is correct. Also note the required packages on R for the [causal discovery toolbox](https://fentechsolutions.github.io/CausalDiscoveryToolbox/html/index.html).


## Execution   
To execute the full experiments you may run
```bash
# run all experiments
bash run.sh
# for the plots
bash report.sh
```

In the above shell scripts you may find all the commands to run our experiments.
