Specification & options
The high-level entry point. Describe the model declaratively with an LCLSpec, then estimate it with lcl.fit. Behaviour is tuned through four grouped options objects rather than a long keyword list: FitOptions (the EM loop), OptimizationOptions (the M-step optimizer), InferenceOptions (covariance and standard errors), and DiagnosticsOptions (the post-fit health checks).
Fitting
lcl.fit(data, spec, *, fit_options=None, optimization_options=None, inference=None, diagnostics=None)
Fit a latent-class conditional-logit model from an :class:LCLSpec.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
object
|
Long-format choice data. |
required |
spec
|
LCLSpec
|
Declarative model specification. |
required |
fit_options
|
FitOptions | None
|
EM algorithm options. |
None
|
optimization_options
|
OptimizationOptions | None
|
M-step optimizer options. |
None
|
inference
|
InferenceOptions | None
|
Covariance and standard-error options. |
None
|
diagnostics
|
DiagnosticsOptions | None
|
Diagnostic thresholds and switches. |
None
|
Returns:
| Type | Description |
|---|---|
LCLResults
|
Fitted latent-class results. |
Source code in src/lcl/__init__.py
Model specification
lcl.spec.LCLSpec(ids, utility=None, membership=None, classes=2, constraints=None, formula=None, utility_formula=None, membership_formula=None)
dataclass
Declarative latent-class conditional-logit specification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ids
|
ChoiceIds
|
Identifier and choice columns for the long-format dataset. |
required |
utility
|
Sequence[str] | None
|
Alternative-specific variables in the utility specification. Omit when
|
None
|
membership
|
Sequence[str] | None
|
Panel-level variables for class-membership probabilities. Omit when
|
None
|
classes
|
int
|
Number of latent classes. |
2
|
constraints
|
mapping or sequence
|
Coefficient constraints. The current estimation engine supports one negative coefficient, typically a price, cost, or travel-time numeraire. |
None
|
formula
|
str | None
|
Backward-compatible combined Formulaic string such as
|
None
|
utility_formula
|
str | None
|
Formulaic string for the alternative-specific utility specification, such
as |
None
|
membership_formula
|
str | None
|
Right-hand-side Formulaic string for the class-membership demographic
regression, such as |
None
|
negative_constraint
property
Return the single negative constraint, if present.
negative_constraints
property
Return normalized negative-coefficient constraints.
numeraire
property
Return the constrained variable used as the numeraire.
numeraire_min_abs
property
Return the numeraire floor implied by the specification.
__post_init__()
Validate internal consistency.
Source code in src/lcl/spec.py
constraint_rows()
summary_lines()
Return a compact, human-readable specification summary.
Source code in src/lcl/spec.py
lcl.spec.ChoiceIds(alt, case, panel, choice)
dataclass
Column names identifying a long-format choice dataset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
alt
|
str
|
Alternative identifier column. |
required |
case
|
str
|
Choice-situation identifier column. |
required |
panel
|
str
|
Decision-maker or panel identifier column. |
required |
choice
|
str
|
Boolean or binary chosen-alternative indicator column. |
required |
lcl.constraints.NegativeCoefficient(variable=None, min_abs=DEFAULT_NEGATIVE_MIN_ABS, units=None, warn_below=None)
dataclass
Constrain a coefficient to be strictly negative.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variable
|
str | None
|
Name of the variable being constrained. It may be omitted when the object is supplied in a mapping keyed by variable name. |
None
|
min_abs
|
float
|
Minimum absolute magnitude of the structural coefficient. The forward
transform is |
1e-5
|
units
|
str | None
|
Optional human-readable units for summaries and audit reports. |
None
|
warn_below
|
float | None
|
Optional threshold used by diagnostics to flag weakly identified numeraires. |
None
|
__post_init__()
Validate constraint settings.
Source code in src/lcl/constraints.py
bind(variable)
Return a copy tied to variable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variable
|
str
|
Variable name from a specification mapping. |
required |
Returns:
| Type | Description |
|---|---|
NegativeCoefficient
|
A constraint with a concrete variable name. |
Source code in src/lcl/constraints.py
forward(raw)
hessian_diag(raw)
Options
lcl._struct.FitOptions(seed=0, max_em_iter=2000, em_tol=1e-06, num_devices=device_count(), check_interval=10, starts=1, start_method='panel_partition', refit_best_start=True)
dataclass
User-facing EM fit options.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed
|
int
|
Random seed used for panel-partition starts. |
0
|
max_em_iter
|
int
|
Maximum number of EM recursions. |
2000
|
em_tol
|
float
|
Relative log-likelihood tolerance checked over the EM history. |
1e-6
|
num_devices
|
int
|
Number of local JAX devices used for class-wise beta updates. |
device_count()
|
check_interval
|
int
|
Frequency of convergence checks. |
10
|
starts
|
int
|
Reserved for future multi-start orchestration. |
1
|
start_method
|
str
|
Initialization method label. |
"panel_partition"
|
refit_best_start
|
bool
|
Reserved for future multi-start orchestration. |
True
|
to_em_config()
Convert to the internal EM configuration dataclass.
Source code in src/lcl/_struct.py
lcl._struct.OptimizationOptions(maxiter=75, ftol=1e-05, method='newton', gradient_tol=None, hessian_damping=1e-06, max_step_norm=25.0, line_search='armijo', fallback='gradient')
dataclass
Bases: MleConfig
User-facing optimizer settings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
maxiter
|
int
|
Maximum Newton/BFGS iterations used inside each M-step. |
75
|
ftol
|
float
|
Gradient tolerance. Kept for backward compatibility with
:class: |
1e-5
|
method
|
str
|
Optimizer family requested by the user. The latent-class M-step currently uses exact Newton updates. |
"newton"
|
gradient_tol
|
float | None
|
More descriptive alias for |
None
|
hessian_damping
|
float
|
Reserved for explicit optimizer configuration in future releases. |
1e-6
|
max_step_norm
|
float
|
Reserved for explicit optimizer configuration in future releases. |
25.0
|
line_search
|
str
|
Name of the line-search strategy. |
"armijo"
|
fallback
|
str
|
Fallback direction when the Newton direction is not a descent direction. |
"gradient"
|
lcl._struct.InferenceOptions(robust=True, skip_std_errs=False, covariance='clustered', cluster='panel', finite_sample_correction=True, skip=False)
dataclass
Bases: ErrorConfig
User-facing inference and covariance settings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
robust
|
bool
|
Legacy flag controlling robust covariance calculation. |
True
|
skip_std_errs
|
bool
|
Legacy flag to skip standard-error calculations. |
False
|
covariance
|
str
|
Covariance estimator label. |
"clustered"
|
cluster
|
str | None
|
Cluster level label for reports. The current latent-class estimator clusters at panel level. |
"panel"
|
finite_sample_correction
|
bool
|
Whether reports should describe the finite-sample correction. |
True
|
skip
|
bool
|
Descriptive alias for |
False
|
__post_init__()
Normalize user-facing covariance labels.
Source code in src/lcl/_struct.py
lcl._struct.DiagnosticsOptions(check_separation=True, check_collinearity=True, warn_near_zero_numeraire=True, warn_large_coefficients=True, near_zero_numeraire_threshold=0.001, large_coefficient_threshold=25.0)
dataclass
Options controlling public diagnostic summaries.