Fitting

hddid.fit_hddid(*, y0, y1, treat, x, z, z0, basis_family='polynomial', basis_degree=1, alpha=0.1, n_folds=2, random_state=0, trim_lower=0.01, trim_upper=0.99, nuisance_payload=None, oracle_lane=None, nuisance_estimator=None, penalty_lambda=0.0, max_iter=10000, tol=1e-10, n_jobs=1, solver='sklearn')[source]

Fit the High-Dimensional Difference-in-Differences model.

Executes the full HD-DID pipeline: input validation, cross-fit sample splitting, nuisance parameter estimation (propensity score, conditional means), doubly-robust score construction, and the partially-linear sieve regression of Eq. (3.1).

Parameters:
  • y0 (array-like of shape (n,)) – Pre-treatment outcome vector.

  • y1 (array-like of shape (n,)) – Post-treatment outcome vector.

  • treat (array-like of shape (n,)) – Binary treatment indicator (1 = treated, 0 = control).

  • x (array-like of shape (n, p)) – High-dimensional covariate matrix.

  • z (array-like of shape (n,)) – Scalar nonparametric variable entering the sieve component.

  • z0 (float or array-like) – Evaluation grid point(s) at which the nonparametric function f(z0) is estimated.

  • basis_family (str, default "polynomial") – Sieve basis family. One of “polynomial”, “trigonometric”, or “bspline”.

  • basis_degree (int, default 1) – Degree (order) of the sieve basis expansion.

  • alpha (float, default 0.1) – Significance level for confidence intervals.

  • n_folds (int, default 2) – Number of cross-fitting folds.

  • random_state (int or None, default 0) – Seed for the random number generator controlling fold assignment. Use None for non-deterministic splits.

  • trim_lower (float, default 0.01) – Lower propensity score trimming threshold.

  • trim_upper (float, default 0.99) – Upper propensity score trimming threshold.

  • nuisance_payload (NuisancePayload or None, default None) – Pre-computed nuisance estimates. When provided, cross-fitting is skipped and this payload is used directly.

  • oracle_lane (str or None, default None) – Oracle nuisance lane identifier for simulation studies. Only valid when nuisance_payload is None.

  • nuisance_estimator (estimator, dict, or None, default None) – User-supplied sklearn-compatible first-stage estimator(s). If a single estimator is passed, it is used for both the propensity score and the conditional outcome means. If a dict is passed, it must contain the keys "propensity" and "outcome". The propensity estimator must implement .fit(X, y) and .predict_proba(X); the outcome estimator must implement .fit(X, y) and .predict(X). When None, the built-in IRLS logistic regression and OLS linear regression are used, exactly as before.

  • penalty_lambda (float or "auto", default 0.0) – L1 penalty on the parametric coefficients in Eq. (3.1). Set to “auto” for the rate-optimal choice 2.2 * sqrt(log(p) / n_valid).

  • max_iter (int, default 10000) – Maximum coordinate-descent iterations for the Lasso solver.

  • tol (float, default 1e-10) – Convergence tolerance for coordinate descent.

  • n_jobs (int, default 1) – Number of parallel jobs for cross-fit fold processing.

  • solver (str, default "sklearn") – Solver backend for the beta block. One of “sklearn” (scikit-learn Lasso), “builtin” (pure-NumPy coordinate descent), or “native” (alias for “builtin”).

Returns:

Frozen dataclass containing all intermediate payloads and the final HDDIDResult with point estimates for beta_hat, gamma_hat, and f_hat_at_z0.

Return type:

HDDIDFit

Raises:
  • ValueError – If inputs fail validation (non-numeric, mismatched shapes, invalid basis_family, trim bounds, etc.).

  • Eq31SolverConvergenceError – If the coordinate-descent Lasso fails to converge within max_iter iterations.

  • Eq31ProjectionRankError – If the sieve basis matrix is rank-deficient.

Notes

Implements the two-stage estimation procedure from Section 3 of Ning, Peng, and Tao (2020). The first stage constructs the doubly-robust score S_hat (Eq. 2.5/2.7); the second stage solves the partially-linear model S_hat = X’beta + f(Z) + error via sieve projection and penalized regression (Eq. 3.1).

Reference: Ning, Peng, and Tao (2020), arXiv preprint arXiv:2009.03151.

Examples

>>> import numpy as np
>>> from hddid import fit_hddid
>>> rng = np.random.default_rng(42)
>>> n, p = 200, 5
>>> x = rng.standard_normal((n, p))
>>> z = rng.uniform(0, 1, n)
>>> treat = (rng.uniform(size=n) > 0.5).astype(float)
>>> y0 = x @ rng.standard_normal(p) + rng.standard_normal(n)
>>> y1 = y0 + 1.0 + rng.standard_normal(n)
>>> result = fit_hddid(
...     y0=y0, y1=y1, treat=treat, x=x, z=z,
...     z0=np.array([0.25, 0.5, 0.75]),
... )
class hddid.HDDIDFit(data, crossfit_plan, nuisance_payload, score_payload, estimation_payload, result)[source]

Container for a complete HDDID estimation run.

Parameters:
data

Validated inputs and basis configuration.

Type:

ValidatedHDDIDData

crossfit_plan

Cross-fitting fold assignments (None if nuisance provided externally).

Type:

CrossfitPlan or None

nuisance_payload

Cross-fitted propensity scores and outcome predictions.

Type:

NuisancePayload

score_payload

Doubly-robust score vector and basis matrices.

Type:

ScorePayload

estimation_payload

Eq. (3.1) regression outputs (beta_hat, gamma_hat, residuals).

Type:

EstimationPayload

result

User-facing estimates, standard errors, intervals, and diagnostics.

Type:

HDDIDResult

classmethod from_dataframe(df, *, y0_col, y1_col, treat_col, x_cols, z_col, z0, **kwargs)[source]

Construct an HDDIDFit from a pandas DataFrame.

Parameters:
  • df (pandas.DataFrame) – Input data containing all required columns.

  • y0_col (str) – Column name for pre-treatment outcome.

  • y1_col (str) – Column name for post-treatment outcome.

  • treat_col (str) – Column name for binary treatment indicator.

  • x_cols (list[str]) – Column names for high-dimensional covariates.

  • z_col (str) – Column name for the scalar nonparametric variable.

  • z0 (float or array-like) – Evaluation grid points for the nonparametric function.

  • **kwargs – Additional arguments passed to fit_hddid (basis_family, basis_degree, alpha, n_folds, random_state, trim_lower, trim_upper, etc.)

Returns:

Fitted HDDID model.

Return type:

HDDIDFit

Raises:
  • ImportError – If pandas is not installed.

  • KeyError – If a specified column name does not exist in the DataFrame.

  • ValueError – If data validation fails (e.g., non-numeric columns, NaN values).

summary(format='text')[source]

Generate a formatted summary of the estimation results.

Parameters:

format (str, default "text") – Output format. One of: - “text”: Human-readable plain text summary - “markdown”: Markdown-formatted table (delegates to to_markdown) - “dict”: Structured dictionary (delegates to to_summary)

Returns:

Formatted estimation summary including parameter estimates, confidence intervals, standard errors, and diagnostics.

Return type:

str or dict