Targets Module#
The targets module defines what quantity you want to estimate. A target is a functional H(θ) that maps the structural parameters to a scalar.
Overview#
Target |
Formula |
Use Case |
|---|---|---|
|
E[θ_j] |
Average treatment effect |
|
E[p(1-p)·β] |
Marginal effect on probability |
|
E[G(θ, t̃)] |
Average predicted outcome at treatment level |
|
E[t̃ · G(θ, t̃)] |
Expected revenue at price level |
|
E[P(Y > c | θ, t̃)] |
Exceedance/risk probability |
|
E[Var(Y | θ, t̃)] |
Model-implied outcome variance |
|
E[G(θ, t) - G(θ, t₀)] |
Combinatorial treatment effect |
|
P(Y=j | W, X) |
Multinomial choice probability |
|
∂P(Y=j)/∂x_{jk} |
Multinomial marginal effect |
|
User-defined h(x,θ,t̃) |
Any custom functional |
Built-in Targets#
AverageParameter#
The default target: average of a specific parameter across the population.
from deep_inference.targets import AverageParameter
# Target: E[β(X)] where β is the second parameter (index=1)
target = AverageParameter(param_index=1, theta_dim=2)
Formula:
H(θ) = (1/n) Σ θ_j(x_i)
Jacobian (closed-form):
∂H/∂θ = [0, ..., 1/n, ..., 0] (1 at position j)
AME (Average Marginal Effect)#
For logit models, the marginal effect on probability (not log-odds).
from deep_inference.targets import AME
# Target: E[p(1-p)·β] evaluated at t_tilde
target = AME(param_index=1, model_type='logit')
Formula (logit):
H(θ, t̃) = (1/n) Σ σ'(α_i + β_i·t̃) · β_i
= (1/n) Σ p_i(1-p_i) · β_i
Where p_i = σ(α_i + β_i·t̃).
Jacobian (closed-form for logit):
∂H/∂α = p(1-p)(1-2p)·β / n
∂H/∂β = p(1-p)[1 + (1-2p)·β·t̃] / n
DoseResponse#
Average predicted outcome at a given treatment level — the fundamental counterfactual target.
from deep_inference.targets import DoseResponse
# Target: E[σ(α + β·t̃)] at treatment level t̃=1.0
target = DoseResponse(model_type='logit')
Formula (logit):
H(θ, t̃) = σ(α + β·t̃)
Jacobian (closed-form):
∂H/∂α = p(1-p)
∂H/∂β = p(1-p)·t̃
Where p = σ(α + β·t̃). Supports logit, linear, and poisson model types.
Usage:
from deep_inference import inference
result = inference(Y, T, X, model='logit', target='dose_response', t_tilde=1.0)
Reference: Colangelo & Lee (2026, JBES)
Profit#
Expected revenue per consumer at a given price level: price × purchase probability.
from deep_inference.targets import Profit
target = Profit(model_type='logit')
Formula (logit):
H(θ, t̃) = t̃ · σ(α + β·t̃)
Jacobian (closed-form):
∂H/∂α = t̃·p(1-p)
∂H/∂β = t̃·p(1-p)·t̃
Usage:
result = inference(Y, T, X, model='logit', target='profit', t_tilde=2.0)
Reference: Dubé & Misra (2023, JPE)
TailProbability#
Probability that the outcome exceeds a threshold: P(Y > c | θ, t̃).
from deep_inference.targets import TailProbability
# P(Y > 5 | Poisson rate) at exposure level t̃=1.0
target = TailProbability(threshold=5, model_type='poisson')
Formula (Poisson):
H(θ, t̃) = 1 - Σ_{k=0}^{c} e^{-λ}·λ^k/k! where λ = exp(α + β·t̃)
Formula (logit, c=0):
H(θ, t̃) = σ(α + β·t̃) (identical to DoseResponse)
Formula (linear/Gaussian):
H(θ, t̃) = 1 - Φ((c - μ)/σ) where μ = α + β·t̃
Closed-form Jacobian for logit and linear; autodiff for Poisson.
Reference: Melnychuk & Feuerriegel (2026, ICLR)
ConditionalVariance#
Model-implied variance of outcomes — captures heterogeneity in risk across covariates.
from deep_inference.targets import ConditionalVariance
target = ConditionalVariance(model_type='logit')
Formula (logit):
H(θ, t̃) = p(1-p) where p = σ(α + β·t̃)
Jacobian (closed-form):
∂H/∂α = p(1-p)(1-2p)
∂H/∂β = p(1-p)(1-2p)·t̃
Usage:
result = inference(Y, T, X, model='logit', target='conditional_variance', t_tilde=0.0)
Reference: Melnychuk & Feuerriegel (2026, ICLR)
MultiTreatmentATE#
Average treatment effect for combinatorial experiments with multiple binary treatments.
from deep_inference.targets import MultiTreatmentATE
from deep_inference.models.combinatorial import CombinatorialModel
model = CombinatorialModel(n_treatments=3, link='gen_sigmoid_ii')
target = MultiTreatmentATE(
model=model,
treatment=[1, 0, 1], # Apply treatments 1 and 3
control=[0, 0, 0], # vs no treatment
)
Formula:
H(θ) = G(θ, t) - G(θ, t₀)
Where G is the structural link function from CombinatorialModel. Jacobian computed via autodiff.
Reference: Ye et al. (2025, Management Science)
ChoiceProbabilityTarget#
For multinomial logit models: probability of choosing a specific alternative.
from deep_inference.targets.choice_probability import ChoiceProbabilityTarget
# P(Y=j | W, X) for alternative j=1
target = ChoiceProbabilityTarget(
alternative=1, # Which alternative (0-indexed)
n_alternatives=3, # Total alternatives J
n_attributes=2 # Attributes per alternative K
)
Formula:
H = P(Y=j|W,X) = softmax(V)[j]
V_j = alpha_j + x'_j * beta
Jacobian (closed-form):
∂P_j/∂alpha_m = P_{m+1}(delta_{j,m+1} - P_j)
∂P_j/∂beta_k = P_j(x̃_{jk} - x̄_pk)
Where \(\bar{x}_{pk} = \sum_j P_j x_{jk}\) is the probability-weighted mean attribute.
MultinomialAME#
Average Marginal Effect for multinomial logit: how a unit change in attribute \(k\) affects the probability of choosing alternative \(j\).
from deep_inference.targets.choice_probability import MultinomialAME
# dP(Y=1)/dx_{1,0}: effect of attribute 0 on probability of alternative 1
target = MultinomialAME(
alternative=1, # Which alternative
attribute=0, # Which attribute
n_alternatives=3, # Total alternatives J
n_attributes=2 # Attributes per alternative K
)
Formula:
∂P_j/∂x_{jk} = beta_k * P_j * (1 - P_j)
This generalizes the familiar binary logit AME to the multinomial context.
Custom Targets#
Define any target function and the Jacobian is computed via autodiff.
CustomTarget#
from deep_inference.targets import CustomTarget
import torch
def my_target(x, theta, t_tilde):
"""
Custom target function.
Args:
x: Covariates (unused for average targets)
theta: (theta_dim,) parameter vector
t_tilde: Evaluation point for treatment
Returns:
Scalar value
"""
alpha, beta = theta[0], theta[1]
return torch.sigmoid(alpha + beta * t_tilde)
target = CustomTarget(h_fn=my_target)
Example: Average Prediction#
import torch
from deep_inference import inference
def avg_prediction(x, theta, t_tilde):
"""E[P(Y=1|T=t̃)] = E[σ(α + β·t̃)]"""
return torch.sigmoid(theta[0] + theta[1] * t_tilde)
result = inference(
Y, T, X,
model='logit',
target_fn=avg_prediction,
t_tilde=0.0 # Prediction at T=0
)
Example: Counterfactual Comparison#
def treatment_effect(x, theta, t_tilde):
"""E[P(Y=1|T=1) - P(Y=1|T=0)]"""
alpha, beta = theta[0], theta[1]
p1 = torch.sigmoid(alpha + beta * 1.0)
p0 = torch.sigmoid(alpha + beta * 0.0)
return p1 - p0
result = inference(
Y, T, X,
model='logit',
target_fn=treatment_effect
)
Target Protocol#
All targets implement this interface:
class Target(Protocol):
def h(self, x: Tensor, theta: Tensor, t_tilde: Tensor) -> Tensor:
"""Compute target value for a single observation."""
...
def jacobian(self, x: Tensor, theta: Tensor, t_tilde: Tensor) -> Tensor:
"""Compute ∂h/∂θ. Falls back to autodiff if not implemented."""
...
Implementing Custom Targets#
from deep_inference.targets import BaseTarget
import torch
class MyTarget(BaseTarget):
def h(self, x, theta, t_tilde):
# Your target computation
return theta[0] ** 2 + theta[1] * t_tilde
def jacobian(self, x, theta, t_tilde):
# Optional: closed-form Jacobian (faster than autodiff)
return torch.tensor([2 * theta[0], t_tilde])
Using Targets with inference()#
Built-in Target Strings#
# Average beta (log-odds for logit)
result = inference(Y, T, X, model='logit', target='beta')
# Average marginal effect
result = inference(Y, T, X, model='logit', target='ame', t_tilde=0.0)
Custom Target Functions#
def my_target(x, theta, t_tilde):
return theta[0] + theta[1] * t_tilde
result = inference(Y, T, X, model='logit', target_fn=my_target, t_tilde=1.0)
Autodiff Jacobian#
When you provide a custom target function, the package automatically computes the Jacobian via PyTorch autodiff:
# Internally, this happens:
theta.requires_grad_(True)
h_value = target_fn(x, theta, t_tilde)
jacobian = torch.autograd.grad(h_value, theta)[0]
This enables arbitrary differentiable targets without manual derivatives.