Estimation

class openpkpd.estimation.base.EstimationResult(theta_final, omega_final, sigma_final, ofv, converged=False, condition_number=None, eta_shrinkage=<factory>, eps_shrinkage=<factory>, post_hoc_etas=<factory>, ofv_history=<factory>, warnings=<factory>, structured_warnings=<factory>, shrinkage_warnings=<factory>, n_function_evals=0, elapsed_time=0.0, method='', message='', diagnostics=<factory>, n_observations=0, n_subjects=0, _n_parameters=0)[source]

Bases: object

Result from a completed estimation run.

Parameters:
theta_final: ndarray
omega_final: ndarray
sigma_final: ndarray
ofv: float
converged: bool = False
condition_number: float | None = None
eta_shrinkage: ndarray
eps_shrinkage: ndarray
post_hoc_etas: dict[int, ndarray]
ofv_history: list[float]
warnings: list[str]
structured_warnings: list[EstimationWarning]
shrinkage_warnings: list[str]
n_function_evals: int = 0
elapsed_time: float = 0.0
method: str = ''
message: str = ''
diagnostics: dict[str, Any]
n_observations: int = 0
n_subjects: int = 0
property n_parameters: int

Number of free parameters in the model.

Counts free THETA elements plus unique free OMEGA and SIGMA elements (lower-triangular, excluding fixed zeros). If _n_parameters has been set explicitly (e.g. via compute_n_parameters), that value is returned directly. Otherwise the count is inferred from the matrix shapes.

property aic: float

Akaike Information Criterion.

AIC = OFV + 2 * n_parameters

where OFV = -2 * log-likelihood.

property bic: float

Bayesian Information Criterion.

BIC = OFV + ln(n_observations) * n_parameters

Returns inf when n_observations <= 0.

compute_n_parameters(theta_specs=None, omega_specs=None, sigma_specs=None)[source]

Compute and store n_parameters from specs or infer from matrix shapes.

If spec objects are provided they must expose a fixed boolean attribute. Elements with fixed=True do not contribute to the parameter count. When specs are absent, all elements are treated as free.

Parameters:
  • theta_specs (list[Any] | None) – List of ThetaSpec-like objects with a fixed attribute, one per THETA element.

  • omega_specs (list[Any] | None) – List of OmegaSpec-like objects with a fixed attribute, one per lower-triangular OMEGA element.

  • sigma_specs (list[Any] | None) – List of SigmaSpec-like objects with a fixed attribute, one per lower-triangular SIGMA element.

Return type:

None

add_structured_warning(code, message, severity=WarningSeverity.WARNING)[source]

Append a structured EstimationWarning and its string representation.

The string form is added to warnings for backward compatibility; the typed form is added to structured_warnings.

Return type:

None

Parameters:
  • code (WarningCode)

  • message (str)

  • severity (WarningSeverity)

check_omega_conditioning()[source]

Check Omega eigenvalues and condition number; add WARN_001/002/004.

Intended to be called after the M-step or covariance step. A 0×0 or empty Omega (sigma-only models) is silently skipped.

Return type:

None

summary()[source]

Return a text summary of the estimation result.

Return type:

str

to_html(path, params=None, title='OpenPKPD Estimation Report', cov_result=None, provenance=None)[source]

Write a self-contained HTML report to path.

Requires a ParameterSet for parameter labels. If params is None, a minimal report (no labels) is generated.

Parameters:
  • path (str) – Output file path (e.g. "results.html").

  • params (Any | None) – ParameterSet (optional, for THETA labels).

  • title (str) – Report heading.

  • cov_result (Any | None) – Optional CovarianceResult for SE / condition number.

  • provenance (dict[str, object] | None)

Return type:

None

to_pdf(path, params=None, title='OpenPKPD Estimation Report', cov_result=None, provenance=None)[source]

Write a PDF report to path using the optional GUI dependencies.

Return type:

None

Parameters:
compute_shrinkage(params_at_convergence=None, iwres=None)[source]

Compute ETA and EPS shrinkage with per-ETA breakdown.

ETA shrinkage for random effect k:

shrinkage_k = 1 - SD(EBE_ik, i = 1..N) / sqrt(omega_kk)

EPS shrinkage (if IWRES are available):

eps_shrinkage = 1 - SD(IWRES)

A warning is emitted and stored in shrinkage_warnings for any ETA whose shrinkage exceeds 30%, as high ETA shrinkage can inflate the apparent precision of parameter estimates and invalidates post-hoc ETA-based analyses.

Parameters:
  • params_at_convergence (Any | None) – Unused; retained for API compatibility.

  • iwres (ndarray | None) – Individual weighted residuals array for EPS shrinkage computation. If None, EPS shrinkage is not updated.

Return type:

None

compute_deshrinkage_etas()[source]

Return de-shrunken EBEs using the Combes (2013) rescaling correction.

EBEs from FOCE (and to a lesser extent SAEM) are biased toward zero because the posterior mode is shrunk relative to the true individual values. This method rescales each subject’s ETA vector so that the marginal variance matches omega_kk exactly:

eta_adj_ik = eta_ik / (1 − shrinkage_k)

which is equivalent to:

eta_adj_ik = eta_ik × sqrt(omega_kk) / SD(EBEs_k)

The relative ranking of subjects is preserved. Subjects with the same sign as the population mean shift in proportion to their original EBE magnitude.

Returns an empty dict when post-hoc ETAs or shrinkage have not been computed, or when a random effect is fully shrunk (SD(EBEs) ≈ 0).

Reference

Combes F-P, Retout S, Frey N, Mentré F (2013). Prediction of shrinkage of individual parameters using the Bayesian information matrix in nonlinear mixed-effects models with evaluation in pharmacokinetics. Pharm Res 30:2355–2367. https://doi.org/10.1007/s11095-013-1079-3

rtype:

dict[int, ndarray]

Return type:

dict[int, ndarray]

__init__(theta_final, omega_final, sigma_final, ofv, converged=False, condition_number=None, eta_shrinkage=<factory>, eps_shrinkage=<factory>, post_hoc_etas=<factory>, ofv_history=<factory>, warnings=<factory>, structured_warnings=<factory>, shrinkage_warnings=<factory>, n_function_evals=0, elapsed_time=0.0, method='', message='', diagnostics=<factory>, n_observations=0, n_subjects=0, _n_parameters=0)
Parameters:
Return type:

None

class openpkpd.estimation.base.EstimationMethod[source]

Bases: ABC

Abstract base class for estimation methods.

Each method implements estimate() which takes a PopulationModel and initial parameters and returns an EstimationResult.

method_name: str = 'BASE'
abstractmethod estimate(population_model, init_params, **kwargs)[source]

Run the estimation algorithm.

Parameters:
  • population_model (Any) – Assembled PopulationModel with dataset and PK callable.

  • init_params (Any) – Initial ParameterSet.

  • **kwargs (Any) – Method-specific options.

Return type:

EstimationResult

Returns:

EstimationResult with final parameter estimates.