causal inference and machine learning

# Causal Inference and Machine Learning

## Introduction & Motivation

Causal inference distinguishes correlation from causation, critical for decision-making in materials processing, pharmaceutical development, and complex systems. ML combined with causal frameworks enables discovery of true relationships and optimal interventions.

Motivation: Infer causal effects from observational and experimental data.

Applications: Treatment effect estimation, policy evaluation, intervention optimization, mechanism discovery.

---

## Core Concepts & Theory

### Causal DAGs

Directed acyclic graphs.

### Confounding

Spurious associations.

### Identification

Estimability conditions.

### Treatment Effects

Average and heterogeneous effects.

---

## Mathematical Formulation

Potential Outcomes:
$$Y_i(1), Y_i(0) \quad ext{for treatment and control}$$

Average Treatment Effect:
$$ ext{ATE} = \mathbb{E}[Y_i(1) - Y_i(0)]$$

Backdoor Adjustment:
$$P(y|do(x)) = \sum_z P(y|x,z)P(z)$$

---

## Advanced Theory & Extensions

### Double Machine Learning

Debiased estimation.

### Causal Forests

Heterogeneous treatment effects.

### Instrumental Variables

Handling unmeasured confounding.

---

## Computational Considerations

Matching: O(N·D) distance.

Regression: O(N·D²) estimation.

Forest: O(N·log N·T).

---

## Practical Implementation Strategies

### Confounder Control

Regression, matching, weighting.

### Sensitivity Analysis

Robustness to hidden confounding.

### Effect Heterogeneity

Subgroup analysis.

---

## Benchmark Datasets & Evaluation

LaLonde Dataset: Classic treatment study.

IHDP: Causal inference benchmark.

Twins Dataset: Natural experiments.

---

## Key Challenges & Limitations

### Identifiability

Unverifiable assumptions.

### Hidden Confounding

Unmeasured variables.

### Extrapolation

Policy relevance.

---

## Hyperparameter Tuning

Caliper: Matching distance.

Regularization: Effect estimation.

Forest depth: Treatment heterogeneity.

---

## Real-World Applications & Case Studies

Clinical Trials: Treatment efficacy.

Policy Evaluation: Program impact.

Materials: Process optimization.

---

## Integration with Other Methods

Causal inference + ML; + experimental design; + optimization.

---

## Summary & Key Takeaways

Causal inference enables decision-making from data.

Principles:
1. DAGs: Model causality.
2. Confounding: Control spurious.
3. Identification: Assumptions matter.
4. Estimation: Multiple methods.
5. Sensitivity: Test robustness.

---

## Appendix: Practical Labs

### Lab 1: Propensity Score Matching

import numpy as np

def propensity_score_matching(X, T):
 """Estimate propensity score"""
 # Logistic regression (simplified)
 prob_t = 1 / (1 + np.exp(-X @ np.random.randn(X.shape[1])))
 return prob_t

def match_on_propensity(X, T, y, caliper=0.1):
 """Match on propensity score"""
 ps = propensity_score_matching(X, T)
 
 matched_diff = []
 
 for i in np.where(T == 1)[0]:
 control_matches = np.where((T == 0) & (np.abs(ps - ps[i]) < caliper))[0]
 
 if len(control_matches) > 0:
 j = control_matches[0]
 matched_diff.append(y[i] - y[j])
 
 ate = np.mean(matched_diff) if matched_diff else 0
 return ate

X = np.random.randn(100, 5)
T = (X[:, 0] > 0).astype(int)
y = T * 2 + X[:, 0] + np.random.randn(100) * 0.5

ate = match_on_propensity(X, T, y)
print(f"✓ ATE via matching: {ate:.3f}")

### Lab 2: Backdoor Adjustment

import numpy as np

def backdoor_adjustment(X, T, y, Z):
 """Estimate effect controlling for confounders"""
 # Simple regression adjustment
 from sklearn.linear_model import LinearRegression
 
 model = LinearRegression()
 features = np.column_stack([T, Z])
 model.fit(features, y)
 
 # Effect estimate
 effect = model.coef_[0]
 return effect

X = np.random.randn(50, 1)
Z = np.random.randn(50, 2) # Confounders
T = (Z[:, 0] > 0).astype(int)
y = T * 3 + Z[:, 0] + np.random.randn(50) * 0.5

effect = backdoor_adjustment(X, T, y, Z)
print(f"✓ ATE via backdoor: {effect:.3f}")

### Lab 3: Instrumental Variables

import numpy as np

def instrumental_variable_estimation(Z, T, y):
 """IV estimation"""
 # Two-stage least squares
 
 # First stage: predict T from Z
 beta_1 = np.linalg.lstsq(Z.reshape(-1, 1), T, rcond=None)[0]
 T_pred = Z * beta_1
 
 # Second stage: predict y from predicted T
 beta_2 = np.linalg.lstsq(T_pred.reshape(-1, 1), y, rcond=None)[0]
 
 return beta_2[0]

Z = np.random.randn(100) # Instrument
T = 0.5 * Z + np.random.randn(100) * 0.5
y = 2 * T + np.random.randn(100) * 0.5

effect = instrumental_variable_estimation(Z, T, y)
print(f"✓ IV estimate: {effect:.3f}")

### Lab 4: Causal Forest

import numpy as np

class CausalForest:
 def __init__(self, n_trees=100):
 self.n_trees = n_trees
 self.trees = []
 
 def fit(self, X, T, y):
 """Fit causal forest"""
 for _ in range(self.n_trees):
 # Bootstrap sample
 indices = np.random.choice(len(X), len(X), replace=True)
 X_boot = X[indices]
 T_boot = T[indices]
 y_boot = y[indices]
 
 # Fit tree
 tree_effect = np.mean(y_boot[T_boot == 1]) - np.mean(y_boot[T_boot == 0])
 self.trees.append(tree_effect)
 
 def predict(self, X_test):
 """Predict treatment effect"""
 effects = np.array(self.trees)
 return np.mean(effects) * np.ones(len(X_test))

X = np.random.randn(100, 5)
T = np.random.binomial(1, 0.5, 100)
y = T * 2 + X[:, 0] + np.random.randn(100) * 0.5

cf = CausalForest(n_trees=100)
cf.fit(X, T, y)
effects = cf.predict(X[:10])

print(f"✓ Causal forest predictions: {effects[:3]}")

---

Go deeper with CFSGPT

Get AI-powered deep-dives, save terms, and run advanced simulations — free account.

Create Free Account