Profile Likelihood Methods
LikelihoodProfiler provides a range of methods to profile likelihood functions and explore practical identifiability. The method should be provided as the second argument to the solve function.
Optimization-based profiles
The method computes profiles for each parameter by iteratively changing the value of the parameter and re-optimizing the likelihood function with respect to all other parameters.
LikelihoodProfiler.OptimizationProfiler — Type
OptimizationProfiler{S, opType, optsType}A profiler method that uses stepwise re-optimization to profile the likelihood function.
Fields
stepper::S: The algorithm used to compute the next profile point. Supported steppers include:FixedStep: Proposes steps from the configured step rule in the profiling direction (Default).AdaptiveStep: Adapts the step size based on trial objective increases.
optimizer::opType: The optimizer used for the optimization process.optimizer_opts::optsType: Options for the optimizer. Defaults toNamedTuple().
Stepping Options
The stepper argument controls how the next profile point is chosen. For example:
stepper = FixedStep(initial_step=0.1): Use a constant step size of 0.1.stepper = AdaptiveStep(predictor=LinearPredictor()): Use adaptive stepping with a secant-like linear predictor.
See the documentation for each stepper type (e.g., ?FixedStep, ?AdaptiveStep) for more details and customization options.
Example
using OptimizationLBFGSB
profiler = OptimizationProfiler(; optimizer = LBFGSB(), optimizer_opts = (reltol=1e-4,))Optimization steppers
OptimizationProfiler uses a stepper to choose the next value along the profiled parameter axis before re-optimizing all remaining parameters.
Use FixedStep when you want a predictable step rule that does not inspect the objective function at trial points:
method = OptimizationProfiler(
optimizer = LBFGSB(),
stepper = FixedStep(; initial_step = 0.1),
)Use AdaptiveStep when you want the profiler to adjust the step length based on the objective increase observed at trial points:
method = OptimizationProfiler(
optimizer = LBFGSB(),
stepper = AdaptiveStep(; initial_step = AdaptiveInitialStep()),
)The default AdaptiveInitialStep scales the first step with the current profiled value and clamps it to configured minimum and maximum bounds. This is useful when parameters have different numerical scales.
With its default settings, AdaptiveInitialStep() proposes max(0.01 * abs(x), 1e-3) and clamps the result to [1e-4, Inf]. These defaults are conservative for parameters on their original scale. For parameters on a log or otherwise standardized scale, a fixed initial step such as 0.01 can also be a convenient choice.
How adaptive stepping works
After the first profile point, AdaptiveStep separates the proposal into a direction and a length:
- The predictor estimates how all parameters should move when the profiled parameter changes.
- The controller evaluates the objective at trial points along that direction, without re-optimizing the nuisance parameters.
- The trial step is increased or decreased until its objective change is close to the upper target, or a profile bound or configured step limit is reached.
- The nuisance parameters are re-optimized only after the proposal has been selected.
The trial objective therefore measures the quality of the optimization starting point, not the final profile objective. The final objective will usually be lower after re-optimization, and it is allowed to cross the profile threshold. A threshold crossing terminates that profile branch in the usual way.
The default LinearPredictor extrapolates the complete parameter vector from the two previous optimized profile points. It is usually the most efficient choice for smooth profiles because it follows the estimated profile path through the nuisance-parameter space. SingleAxisPredictor changes only the profiled parameter and leaves all nuisance parameters at their current optimum. It is more conservative and can be useful for profiles with abrupt turns, local optima, or unreliable extrapolation.
# Default: first-order extrapolation of the complete profile path
adaptive = AdaptiveStep(; predictor = LinearPredictor())
# Conservative alternative: move only the profiled parameter
conservative = AdaptiveStep(; predictor = SingleAxisPredictor())If adaptive search with LinearPredictor fails or reaches its minimum step, the profiler automatically retries with SingleAxisPredictor. If optimization at an accepted adaptive proposal fails, it is retried once with half the proposed step.
Objective step control
ObjectiveStepControl defines the desired objective change and the allowed profile-axis step sizes. For a finite profile threshold, its upper target is
\[\Delta f_{\mathrm{target}} = \operatorname{clamp}(\mathtt{threshold\_fraction}\,\tau, \mathtt{min\_obj\_step}, \mathtt{max\_obj\_step}),\]
where tau is the objective threshold relative to the optimum. The default threshold_fraction=0.1 aims for approximately ten profile steps over that objective range when the local profile shape is regular.
When threshold=Inf, no confidence threshold is available as an objective scale. The target is instead based on target_factor times the absolute objective change between the two previous optimized profile points, clamped by min_obj_step and max_obj_step.
The most useful tuning options are:
| Option | Effect of increasing it |
|---|---|
threshold_fraction | Fewer, larger steps for finite thresholds |
min_obj_step | Larger steps when the objective is flat or threshold=Inf |
step_factor | Faster but coarser trial-step growth and reduction |
max_x_step_growth | Faster growth across flat profile regions |
min_x_step | Prevents excessively dense sampling |
max_x_step | Limits jumps along the profiled parameter axis |
For a profile that remains too dense in flat regions, first increase the initial step or min_obj_step. If growth is still too slow, increase max_x_step_growth. For unstable optimization or a sharply curved profile, reduce threshold_fraction or max_x_step, or select SingleAxisPredictor().
controller = ObjectiveStepControl(
threshold_fraction = 0.1,
min_obj_step = 0.01,
min_x_step = 1e-4,
max_x_step = 0.5,
)
method = OptimizationProfiler(
optimizer = LBFGSB(),
stepper = AdaptiveStep(; controller),
)LikelihoodProfiler.AdaptiveInitialStep — Type
AdaptiveInitialStep(; rel_step=0.01, abs_step=1e-3, min_step=1e-4, max_step=Inf)Initial profile step rule that adapts to the current profiled parameter value.
The proposed step is max(rel_step * abs(x), abs_step), where x is the current profiled parameter value. The result is finally clamped to [min_step, max_step].
This is useful when parameters have different numerical scales and a single fixed absolute step would be inefficient.
LikelihoodProfiler.FixedStep — Type
FixedStep{S}Profiler stepper that proposes each profile point from the configured initial_step rule without adapting to trial objective values.
Constructors
FixedStep(;initial_step=AdaptiveInitialStep())Keyword arguments
initial_step=AdaptiveInitialStep(): The step rule to use for each profile step. This can be a number (for a constant absolute step size), anAdaptiveInitialStep, or a callablectx -> stepfor custom logic depending on the current profiler cache. If a number is provided, it is automatically wrapped as a function.
LikelihoodProfiler.AdaptiveStep — Type
AdaptiveStep(; initial_step=AdaptiveInitialStep(),
predictor=LinearPredictor(),
controller=ObjectiveStepControl())Profiler stepper that adapts the profile step length based on the observed objective increase from trial points.
The first profile step uses initial_step. Later steps use predictor to choose the direction in parameter space and controller to keep the next objective increase in a useful range.
LikelihoodProfiler.ObjectiveStepControl — Type
ObjectiveStepControl(; threshold_fraction=0.1,
target_factor=1.5,
lower_factor=0.25,
min_obj_step=1e-2,
max_obj_step=Inf,
min_x_step=1e-4,
max_x_step=Inf,
step_factor=1.5,
max_x_step_growth=5.0,
maxiters=15)Controls adaptive profile stepping by defining acceptable objective and profile-axis step ranges.
For finite likelihood thresholds, the target objective increase is based on threshold_fraction * threshold. For infinite thresholds, the target increase is based on target_factor * abs(obj_cur - obj_prev).
The previous optimized profile objective change is used to nudge the first trial step up or down. Trial points below the upper objective target are then treated as safe to grow until the upper target, profile bound, or iteration limit is reached. The next profile-axis step is additionally capped by max_x_step_growth * previous_step to avoid abrupt jumps in flat profile regions.
LikelihoodProfiler.LinearPredictor — Type
LinearPredictor()Extrapolates all parameters using linear extrapolation based on the last two successful profile points.
LikelihoodProfiler.SingleAxisPredictor — Type
SingleAxisPredictor()Extrapolates only the profiled parameter using linear extrapolation based on the last two successful profile points.
Integration-based profiles
The method computes profiles for each parameter (or function of parameters) by integrating the differential equations system.
LikelihoodProfiler.IntegrationProfiler — Type
IntegrationProfiler{opType, optsType, DEAlg, DEOpts}A profiler method that uses integration of differential equations system to profile the likelihood function.
Fields
reoptimize::Bool: Indicates whether to re-optimization after each step of theintegrator. Defaults tofalse.optimizer::opType: The optimizer used for the optimization process. Defaults tonothing.optimizer_opts::optsType: Options for the optimizer. Defaults toNamedTuple().integrator::DEAlg: The differential equation algorithm used for integration.integrator_opts::DEOpts: Options for the differential equation solver. Defaults toNamedTuple().matrix_type::Symbol: The type of matrix to be used for the Hessian approximation. Possible options are::hessian,:identity. Defaults to:hessian.gamma::Float64: Correction factor used in integration if full hessian is not computed (e.g.matrix_type = :identity). Defaults to1.0.
Example
using OrdinaryDiffEqTsit5
profiler = IntegrationProfiler(integrator = Tsit5(), integrator_opts = (dtmax=0.3,), matrix_type = :hessian)References:
- Chen, J.-S. & Jennrich, R. I. Simple Accurate Approximation of Likelihood Profiles. Journal of Computational and Graphical Statistics 11, 714–732 (2002).
- Chen, J.-S. & Jennrich, R. I. The Signed Root Deviance Profile and Confidence Intervals in Maximum Likelihood Analysis. Journal of the American Statistical Association 91, 993–998 (1996).
Confidence Intervals by Constrained Optimization (CICO)
The method computes intersections (endpoints of the confidence interval (CI)) of the profile with the predefined confidence level (threshold) without restoring the exact trajectory of the profile. Requires using CICOBase package.
LikelihoodProfiler.CICOProfiler — Type
CICOProfilerConfidence Intervals by Constrained Optimization (CICO) method to find the intersections of the likelihood function with the threshold. See CICOBase docs for more details. Requires using CICOBase.
Fields
optimizer::Symbol: The optimizer used for the optimization process. Defaults to NLopt:LN_NELDERMEAD.scan_tol::Float64: The tolerance for the endpoints scan. Defaults to1e-3.
Example
profiler = CICOProfiler(optimizer = :LN_NELDERMEAD, scan_tol = 1e-3)References:
- Borisov, I. & Metelkin, E. Confidence intervals by constrained optimization—An algorithm and software package for practical identifiability analysis in systems biology. PLoS Comput Biol 16, e1008495 (2020).
- Venzon, D. J. & Moolgavkar, S. H. A Method for Computing Profile-Likelihood-Based Confidence Intervals. Applied Statistics 37, 87 (1988).
Quadratic approximation (FIM curvature at optimum)
LikelihoodProfiler.QuadraticApproxProfiler — Type
QuadraticApproxProfilerQuadratic-approximation confidence intervals (Wald approximation) based on local curvature at the optimum. The curvature is approximated by the Fisher Information Matrix/Hessian, so the resulting confidence intervals reflect the local quadratic approximation of the likelihood around optpars. By default this method reuses Hessian logic from OptimizationProblem (user-supplied Hessian or AD backend). The confidence interval is computed as θ̂ ± z * sqrt(Σ[idx, idx]), where - θ̂ is the optpars[idx], - z is the quantile of the chi-squared distribution corresponding to the conf_level and df parameters of the ProfileLikelihoodProblem, - Σ is the covariance matrix obtained by inverting the FIM.
cov_factor controls Hessian/objective scaling conventions. Common choices are:
1.0when Hessian is for-logL.2.0when Hessian is for-2logLand you want covariance on the-logLscale.
Any strictly positive value is allowed (not only 1 or 2), which can be useful for calibrated or robust variance scaling.
Fields
inversion::Symbol: Matrix inversion strategy (:cholesky,:pinv).clamp_to_bounds::Bool: Clip estimated interval endpoints to profile bounds.cov_factor::Real: Multiplicative factor applied toinv(H)to obtain covariance (Σ = cov_factor * inv(H)).resolution::Int: Number of points per branch (left/right) used to sample the quadratic approximation.