Metadata-Version: 2.4
Name: deep-inference
Version: 0.1.0
Summary: Production-grade econometrics with neural networks
Author: Pranjal Rawat
License-Expression: MIT
Project-URL: Homepage, https://github.com/rawatpranjal/deep-inference
Project-URL: Repository, https://github.com/rawatpranjal/deep-inference
Project-URL: Documentation, https://rawatpranjal.github.io/deep-inference
Keywords: econometrics,causal-inference,deep-learning,neural-networks,statistics,machine-learning
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: torch>=2.0
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=2.0
Requires-Dist: scipy>=1.10
Requires-Dist: scikit-learn>=1.3
Requires-Dist: formulaic>=1.0
Requires-Dist: tabulate>=0.9
Requires-Dist: tqdm>=4.65
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: pre-commit>=3.7; extra == "dev"
Provides-Extra: parity
Requires-Dist: rpy2>=3.5; extra == "parity"
Provides-Extra: docs
Requires-Dist: sphinx>=7.0; extra == "docs"
Requires-Dist: pydata-sphinx-theme>=0.16; extra == "docs"
Requires-Dist: myst-parser>=2.0; extra == "docs"
Requires-Dist: sphinx-autodoc-typehints>=1.25; extra == "docs"
Requires-Dist: sphinx-copybutton>=0.5; extra == "docs"
Provides-Extra: plotting
Requires-Dist: matplotlib>=3.8; extra == "plotting"
Requires-Dist: seaborn>=0.13; extra == "plotting"
Provides-Extra: all
Requires-Dist: deep-inference[dev,docs,parity,plotting]; extra == "all"
Dynamic: license-file

# `deep-inference`

**Deep Learning for Individual Heterogeneity**

`deep-inference` is a Python package for **enriching structural economic models** with deep learning. It implements the framework developed by Farrell, Liang, and Misra (2021, 2025) to recover rich, non-linear parameter heterogeneity ($\theta(X)$) while maintaining the interpretability and validity of structural economics.

Standard deep learning minimizes prediction error, which leads to biased parameter estimates ("The Inference Trap"). This package implements **Influence Function-based Debiasing** (a form of Double Machine Learning) to provide valid confidence intervals and p-values for economic targets.
1
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Why `deep-inference`?

Economic structure and Machine Learning are **complements**, not substitutes.
*   **Deep Learning** provides the capacity to learn complex, high-dimensional heterogeneity.
*   **Structural Models** provide the constraints necessary for causal interpretation and counterfactuals.

`deep-inference` enforces the structural loss (e.g., Tobit likelihood) on the output of a neural network, ensuring that the estimated parameters $\alpha(X), \beta(X)$ respect the economic theory.

## Installation

```bash
pip install deep-inference
```

## Quickstart

Estimate a linear demand model where Price Elasticity $\beta$ varies non-linearly with customer characteristics $X$.

```python
import torch
from deep_inference import get_dgp, get_family, influence

# 1. Generate synthetic data (Linear Demand with Heterogeneity)
dgp = get_dgp("linear", seed=42)
data = dgp.generate(n=2000)

# 2. Define the Structural Family
# (Defines the Loss, Score, and Hessian automatically)
family = get_family("linear")

# 3. Run Inference
# The package trains the structural network, computes the influence function,
# and aggregates results via 10-fold cross-fitting.
result = influence(
    X=data.X, T=data.T, Y=data.Y,
    family=family,
    config={
        "hidden_dims": [128, 64, 32],
        "epochs": 50,
        "lr": 0.01
    }
)

print(f"Avg Elasticity (Truth): {data.mu_true:.4f}")
print(f"Avg Elasticity (Est):   {result.mu_hat:.4f}")
print(f"Standard Error:         {result.se:.4f}")
print(f"95% CI:                 [{result.ci_lower:.4f}, {result.ci_upper:.4f}]")
```

## Supported Structural Families

The package abstracts the math of influence functions. You simply select the family that matches your outcome variable.

| Family | Model Structure | Use Case |
|--------|-----------------|----------|
| **Linear** | $Y = \alpha(X) + \beta(X)T + \varepsilon$ | Wages, Test Scores, consumption |
| **Logit** | $P(Y=1) = \sigma(\alpha(X) + \beta(X)T)$ | Binary Choice, Market Entry |
| **Tobit** | $Y = \max(0, \alpha(X) + \beta(X)T + \varepsilon)$ | Labor Supply, Censored Demand |
| **Poisson** | $Y \sim \text{Pois}(\exp(\alpha(X) + \beta(X)T))$ | Patent Counts, Doctor Visits |
| **Gamma** | $Y \sim \text{Gamma}(k(X), \theta(X))$ | Healthcare Costs, Insurance Claims |
| **Weibull** | $Y \sim \text{Weibull}(\dots)$ | Duration Analysis, Unemployment Spells |

*Note: For complex models like Tobit, `deep-inference` automatically handles the joint estimation of structural variance $\sigma(X)$ required for consistent inference.*

## Methodological Details

### 1. The Enriched Model
We replace fixed parameters $\theta$ with neural networks $\theta(X)$:

```math
\hat{\theta}(\cdot) = \arg \min_{\theta \in \mathcal{F}_{DNN}} \sum \ell(y_i, t_i, \theta(x_i))
```

### 2. The Influence Function Correction
Naive averaging of $\hat{\theta}(X)$ yields biased inference. We construct a Neyman-Orthogonal score $\psi$ using the **Influence Function**:

```math
\psi(z) = H(\hat{\theta}) + \nabla_\theta H \cdot \Lambda(x)^{-1} \cdot \nabla_\theta \ell(z, \hat{\theta})
```

Where $\Lambda(x) = \mathbb{E}[\nabla^2 \ell \mid X=x]$ is the conditional Hessian.
*   **Automatic Differentiation:** `deep-inference` uses PyTorch Autograd to compute exact Jacobians and Hessians for any model family.
*   **Stability:** Includes Tikhonov regularization for inverting Hessians in non-linear models (e.g., Logit/Tobit).

## Validation (Monte Carlo Results)

M=30 simulations, N=10,000 observations. Target: 95% coverage, SE ratio ≈ 1.0.

### Linear Model

![Linear Results](logs/kde_money_slide.png)

| Config | K | Network | Coverage | SE Ratio | RMSE | Bias²/MSE |
|--------|---|---------|----------|----------|------|-----------|
| **Best** | 50 | [64,32] | **93.3%** | 1.03 | **0.032** | 22% |
| Deep | 20 | [128,64,32] | 93.3% | 1.02 | 0.033 | 21% |
| E=100 | 20 | [64,32] | 90.0% | 0.90 | 0.036 | 18% |
| Separate | 20 | [128,64,32]×2 | 80.0% | 0.82 | 0.036 | 14% |
| Naive | — | — | 10% | 0.09 | 0.083 | 1% |

**Finding:** K=50 folds achieves best coverage and lowest RMSE. Separate networks don't help.

### Logit Model

![Logit Results](logs/logit_stress_test/logit_results.png)

Target: E[β(X)] = average log-odds ratio

| Method | Coverage | SE Ratio | RMSE | Hessian min λ |
|--------|----------|----------|------|---------------|
| **Influence** | **90.0%** | 0.93 | **0.054** | 0.051 |
| Naive | 3.3% | 0.03 | 0.108 | — |

### Summary

| Model | Target | Naive Cov | IF Cov | RMSE Improvement |
|-------|--------|-----------|--------|------------------|
| Linear | E[β(X)] | 10% | **93%** | 2.6× |
| Logit | E[β(X)] | 3% | **90%** | 2.0× |
| Poisson | E[β(X)] | TBD | TBD | — |
| Gamma | E[β(X)] | TBD | TBD | — |

## Citation

```bibtex
@article{farrell2021deep,
  title={Deep Neural Networks for Estimation and Inference},
  author={Farrell, Max H. and Liang, Tengyuan and Misra, Sanjog},
  journal={Econometrica},
  volume={89},
  number={1},
  pages={181--213},
  year={2021}
}

@article{farrell2025heterogeneity,
  title={Deep Learning for Individual Heterogeneity},
  author={Farrell, Max H. and Liang, Tengyuan and Misra, Sanjog},
  journal={Working Paper},
  year={2025}
}
```

## License

MIT
