corneto.methods.LinearDAGDiscovery#
- class corneto.methods.LinearDAGDiscovery(lambda_edges=0.01, coefficient_bound=5.0, fit_intercept=True, intercept_bound=10.0, max_parents=None, loss='absolute', standardize_loss=True, vertex_weights=None, sample_weights=None, enforce_signs=False, interaction_attribute='interaction', intervention_key='intervened', flow_capacity=None, flow_epsilon=1.0, min_commodity_coverage=0.0, lambda_unexplained=0.0, backend=None, coefficient_support='exact', min_abs_coefficient=0.25, *, intervention_type_key='intervention', intervention_shift_key='shift', intervention_group_key='intervention_group', intervention_shift_bound=10.0, lambda_intervention_shifts=0.0)#
Bases:
FlowMethodDiscover a sparse linear DAG inside a directed prior network.
A linear structural equation is fitted for every vertex. One nonnegative flow commodity is created for each unique intervention-to-measurement structural signature. Repeated cells and explicitly grouped intervention evidence therefore share a flow column when their source, eligible sinks, and hard-intervention edge blocks agree. Every selected biological edge must be used by at least one commodity, so the learned DAG is structurally supported by intervention-to-measurement paths without requiring every intervention to be explained.
Missing outcomes are excluded from the loss. If a candidate parent is missing in a sample, the corresponding child equation is also excluded; this conservative complete-equation rule prevents missing predictors from being silently treated as zero while preserving a linear formulation.
Feature metadata may declare
intervention="shift"for an additive soft intervention. Its structural equation remains in the loss and its measured value remains a flow source. Provideshift(orintervention_shift) for a known effect, or provideintervention_groupto estimate one bounded effect shared by its replicates. The legacyintervened=Truemetadata remains a hard intervention.- Parameters:
lambda_edges (float) – Penalty for every selected prior edge.
coefficient_bound (float) – Absolute bound on raw linear edge coefficients.
fit_intercept (bool) – Whether to fit one intercept per vertex.
intercept_bound (float) – Absolute bound on vertex intercepts.
max_parents (Optional[int | dict[Any, int]]) – Optional global or vertex-specific parent limit.
loss (str) –
"absolute"for a MILP or"squared"for a MIQP.standardize_loss (bool) – Divide residuals by the observed response standard deviation of each vertex. Coefficients remain in the original measurement units.
vertex_weights (Optional[Mapping[Any, float]]) – Optional positive loss weight per PKN vertex.
sample_weights (Optional[Mapping[Any, float]]) – Optional positive loss weight per sample.
enforce_signs (bool) – Constrain coefficients using numeric PKN interactions
+1and-1when present.intervention_type_key (str) – Feature metadata key containing
"none","hard", or"shift". A booleanintervened=Trueunderintervention_keyremains a hard intervention for compatibility.intervention_shift_key (str) – Feature metadata key containing a known additive shift. If it is absent for a shift intervention, the shift is estimated and shared by
intervention_group_key.intervention_group_key (str) – Feature metadata key identifying an explicit intervention evidence group. The target vertex is always part of the group key, so one group cannot couple different sources. For estimated shifts, the same key also shares one bounded effect parameter across its replicates.
intervention_shift_bound (float) – Absolute bound for each estimated shift.
lambda_intervention_shifts (float) – Optional L1 penalty on estimated shifts.
coefficient_support (str) –
"exact"requires every selected edge to have a fitted coefficient with magnitude at leastmin_abs_coefficient;"structural"permits selected connector edges with zero coefficients.min_abs_coefficient (float) – Minimum absolute fitted coefficient for selected edges in
"exact"mode, in normalized coefficient units. The normalized coefficient foru -> visbeta[u -> v] * scale[u] / scale[v]. The default0.25is a modeling assumption about normalized direct effects, not a solver tolerance or a guarantee of a nonzero total intervention effect.interaction_attribute (str) – Edge attribute containing PKN interaction signs.
intervention_key (str) – Feature metadata key marking legacy hard interventions.
flow_capacity (Optional[float]) – Upper bound on every commodity flow. By default, the number of PKN edges multiplied by
flow_epsilonis used.flow_epsilon (float) – Minimum positive flow on every used biological edge.
min_commodity_coverage (float) – Minimum fraction of distinct intervention evidence units that must have a selected-edge path to a measured, non-intervened response. Repeated cells in one explicit group count once, while separate groups sharing one flow signature each count once. If the unique flows represent
Kevidence units in total, a valuefrequires at leastceil(f * K)of those units to be connected. This does not measure prediction accuracy. Zero does not force any intervention to be connected.lambda_unexplained (float) – Optional objective penalty for every intervention evidence unit without such a structural path. Unlike
min_commodity_coverage, this is a soft preference rather than a minimum feasibility requirement.backend (Optional[Backend]) – Optimization backend.
- __init__(lambda_edges=0.01, coefficient_bound=5.0, fit_intercept=True, intercept_bound=10.0, max_parents=None, loss='absolute', standardize_loss=True, vertex_weights=None, sample_weights=None, enforce_signs=False, interaction_attribute='interaction', intervention_key='intervened', flow_capacity=None, flow_epsilon=1.0, min_commodity_coverage=0.0, lambda_unexplained=0.0, backend=None, coefficient_support='exact', min_abs_coefficient=0.25, *, intervention_type_key='intervention', intervention_shift_key='shift', intervention_group_key='intervention_group', intervention_shift_bound=10.0, lambda_intervention_shifts=0.0)#
- Parameters:
lambda_edges (float)
coefficient_bound (float)
fit_intercept (bool)
intercept_bound (float)
loss (str)
standardize_loss (bool)
enforce_signs (bool)
interaction_attribute (str)
intervention_key (str)
flow_capacity (float | None)
flow_epsilon (float)
min_commodity_coverage (float)
lambda_unexplained (float)
backend (Backend | None)
coefficient_support (str)
min_abs_coefficient (float)
intervention_type_key (str)
intervention_shift_key (str)
intervention_group_key (str)
intervention_shift_bound (float)
lambda_intervention_shifts (float)
Methods
__init__([lambda_edges, coefficient_bound, ...])build(pkn, data)Build a discovery problem from vertex measurements and interventions.
build_from_data(graph[, data])Build the complete optimization problem.
create_flow_based_problem(flow_problem, ...)Add commodity coverage and linear structural-equation fitting.
create_problem(graph, data)Build an efficient matrix-valued commodity-flow formulation.
Return a short method description.
evaluate(data, *[, sample_weights])Evaluate fixed forward and local losses on supplied measurements.
fit(pkn, data, *[, solve_options])Build and solve the model, returning this reusable estimator.
Return read-only metadata for the resolved structural flows.
get_edge_usage([threshold])Return the edge-by-commodity support matrix.
get_flow_bounds(graph, data)Return the precomputed per-edge, per-commodity bounds.
get_selected_edge_indices([threshold])Return selected edge indices in the original PKN.
get_solution_graph([threshold])Return the selected PKN subgraph with fitted edge metadata.
name()Return the method name.
predict(data)Predict held-out vertex values using the fixed fitted DAG.
preprocess(graph, data)Validate data and construct signature-specific flow boundaries.
references()Returns citation keys for this method.
residuals(data)Return observed-minus-local-equation residuals.
show_bibtex()Display raw BibTeX entries in a formatted block for easy copying.
show_references()Display formatted citations in a Jupyter notebook.
Reject solved exact-support models that violate coefficient support.
Attributes
backendReturn the optimization backend being used.
Return fitted coefficients in original PKN edge order.
Return fitted vertex intercepts in graph-vertex order.
Training-derived response scales used by held-out losses.
- build(pkn, data)#
Build a discovery problem from vertex measurements and interventions.
- fit(pkn, data, *, solve_options=None, **solver_options)#
Build and solve the model, returning this reusable estimator.
fitis intentionally a thin convenience wrapper. Usesolve_options(or solver keyword arguments) only for backend options; scientific inputs remain thepknanddataarguments. The constructedproblemis retained, and the backend result is available assolve_result. A time-limited incumbent is accepted when all expressions needed by prediction have finite values.
- preprocess(graph, data)#
Validate data and construct signature-specific flow boundaries.
- get_flow_bounds(graph, data)#
Return the precomputed per-edge, per-commodity bounds.
- create_problem(graph, data)#
Build an efficient matrix-valued commodity-flow formulation.
- create_flow_based_problem(flow_problem, graph, data)#
Add commodity coverage and linear structural-equation fitting.
- predict(data)#
Predict held-out vertex values using the fixed fitted DAG.
All non-hard measurements, including roots, are ignored as predictors. Roots use their fitted intercept baseline; hard interventions are clamped, soft shifts are applied to their equations, and descendants use previously predicted parents. This method never calls a solver.
- residuals(data)#
Return observed-minus-local-equation residuals.
Unlike
predict, this diagnostic intentionally uses observed parent values. It mirrors the structural-equation training objective, including its complete candidate-parent missingness mask, and is useful for local fit auditing but is not a forward intervention forecast.
- evaluate(data, *, sample_weights=None)#
Evaluate fixed forward and local losses on supplied measurements.
Forward loss excludes hard-intervention targets (which are clamped) and never uses observed descendants as predictors. Local loss uses observed values for every candidate PKN parent (with zero coefficients for unselected edges), matching the training equation objective. Both use training-derived response scales and report valid counts plus per-vertex and per-sample normalized losses. Reported losses are weighted means (configured vertex weights and optional held-out
sample_weights), not the raw summed optimization objective; training sample weights are never reused for unrelated held-out names.
- get_commodity_info()#
Return read-only metadata for the resolved structural flows.
The result is a tuple of mapping-like records, one per flow column.
group_countis the number of distinct intervention evidence units represented by that column; repeated cells in one explicit group are listed in that unit’ssample_namesbut do not increase the count. An absent group is reported asNoneand is represented by one implicit unit per structural signature.
- get_selected_edge_indices(threshold=0.5)#
Return selected edge indices in the original PKN.
- validate_solution_support()#
Reject solved exact-support models that violate coefficient support.
- Return type:
None
- get_edge_usage(threshold=0.5)#
Return the edge-by-commodity support matrix.
- get_solution_graph(threshold=0.5)#
Return the selected PKN subgraph with fitted edge metadata.
Each solution edge receives
coefficientandnormalized_coefficientattributes. The configured interaction attribute is set to the sign of the fitted coefficient and, when the original graph provided that attribute, its prior value is preserved asprior_<interaction_attribute>. Structural-support edges whose fitted coefficient is numerically zero receiveconnector=True.- Parameters:
threshold (float)