Class FaskPool
FaskVote does.
The procedure has two stages:
- Obtain a common adjacency graph: by combining external graphs supplied by the
caller, one per dataset, or from a
PooledAdjacencySearch(IMaGES, pooled FAS, or one of the moral-graph-based methods designed to remain correct when the true graph is cyclic; seePooledAdjacencySearch.Method). Where that stage compels a direction, it is retained as orientation evidence; see below. - For each adjacency X—Y, compute the signed FASK left-right statistic
lr_k separately within each dataset k (on standardized columns, with FASK's
skew-sign correction applied within each dataset, as
Fask.leftRightDiff(double[], double[], int)does internally), and combine them as a weighted average, lr = Σ w_k lr_k / Σ w_k. The edge is oriented X→Y when lr > 0 and Y→X when lr < 0.
This is the meta-analytic fixed-effect analog of FASK-Vote: where a vote discards the magnitude of each dataset's evidence, the pooled statistic retains it, so a dataset in which the left-right statistic is decisive counts for more than one in which it is a near coin flip. It is to FASK-Vote what the IMaGES averaged BIC score is to voting over per-dataset graphs.
Two weighting schemes are provided:
FaskPool.Weighting.N(default): w_k = n_k, the sample size of dataset k. This is exact when the datasets are homogeneous in everything but sample size and requires no variance estimation.FaskPool.Weighting.INVERSE_VARIANCE: w_k = 1 / Var(lr_k), where Var(lr_k) is estimated by a within-dataset pairwise bootstrap. This is the standard fixed-effect meta-analysis estimator and downweights noisy datasets even when they are large.
Optionally, when the orientation alpha is set above zero, a bootstrap standard
error of the pooled statistic is computed and the edge is left undirected (an
abstention) unless the pooled statistic differs significantly from zero at that
level. With the default alpha of zero, every adjacency is oriented by the sign of
the pooled statistic, matching single-dataset FASK's behavior. A Cochran Q
heterogeneity statistic is recorded per edge whenever bootstrap variances are
available, so edges on which the datasets genuinely disagree in direction can be
inspected via getEdgeStats().
Important: the datasets are never concatenated. Between-dataset differences in location, scale, or skew would make the concatenated sample a mixture, and mixtures can manufacture exactly the kind of asymmetric conditional-correlation structure the left-right rules read as causal signal. Only the finished, within-dataset, sign-corrected statistics are combined.
Orientation evidence. The graph-based stage does not only deliver adjacencies: where it compels a direction, that direction is evidence, and the pooled left-right statistic must beat it rather than simply replace it. Evidence comes from one of two sources, never both:
- The adjacency stage. With
PooledAdjacencySearch.Method.IMAGESandsetUseAdjacencyOrientations(boolean)left at its default of true, the compelled edges of the IMaGES CPDAG—BOSS over the score averaged across the datasets—are kept as default orientations. Because IMaGES pools the score over all the datasets, its CPDAG is already a combination of them, and it counts as one unanimous evidence graph. The other adjacency methods return undirected graphs and so contribute no orientation evidence. - External graphs.
setExternalGraphs(List)takes one graph per dataset—each dataset's own search result—and combines them, which is the point: a single external graph fitted to one dataset, or to the datasets pooled, would impose one skeleton and one set of orientations on all of them and defeat the cross-dataset construction. The composite skeleton keeps a pair when it is adjacent in more thansetExternalAdjacencyFraction(double)of the graphs (default: a strict majority), and the compelled orientations are tallied per pair: the majority direction, if there is one, becomes the default, and a tie leaves the pair to the pooled statistic. When the adjacency stage is thereby skipped,setUseExternalOrientations(boolean)set to false makes the graphs contribute adjacencies only.
Only compelled orientations act: a graph that is a legal DAG (e.g., BOSS run with CPDAG output off, or a graph drawn by hand) is converted to its CPDAG first, so that reversible edges do not masquerade as compelled, and reversible edges are oriented from the pooled statistic exactly as if no evidence graph had been supplied.
What it takes to overturn a default scales with the strength of the evidence for
it. In every case the pooled statistic must oppose the default and, when the
orientation alpha is above zero, be significant at that level; beyond that, if the
evidence is unanimous (no evidence graph compels the opposite direction), every
dataset's statistic must individually oppose the default as well (strict
cross-dataset sign consensus), whereas evidence that is itself divided yields to the
pooled statistic alone. This is a lexicographic override, not additive pooling: the
score-based orientation is the default, and the higher-moment statistic overrules it
only on a counter-signal at least as strong as the evidence it is displacing. Note
that with a single dataset the sign consensus is vacuous, so a positive orientation
alpha should be set to give the override a meaningful gate. The provenance of each
orientation, and the evidence counts behind it, are recorded in
getEdgeStats().
Background knowledge is respected: a required or forbidden edge orients the pair regardless of the pooled statistic. Two-cycle detection is off by default, following FASK-Vote. When the two-cycle alpha is set above zero, the single-dataset FASK two-cycle test is run separately within each dataset, and the pair is output as a two-cycle only when EVERY dataset passes the test (unanimity). Caution: in a resimulation-null calibration on real data, the two-cycle channel of the closely-related single-dataset override procedure reproduced its detections under an acyclic null, so detections from this channel should not be trusted without a calibration of that kind on the data at hand.
Mixed data. With discrete variables in the datasets, the adjacency stage must be IMaGES with a score for mixed data (or external graphs). The pooled left-right statistic and the two-cycle test are computed for continuous pairs only, and only continuous variables are conditioned on in the two-cycle test. An adjacency with a discrete endpoint is oriented by knowledge or by the majority compelled orientation of the evidence graphs, if either applies, and is otherwise kept as an undirected edge, which means only that the method does not orient the pair.
- Author:
- josephramsey
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordPooled statistics for one edge.static enumThe provenance of an orientation decision, recorded per edge ingetEdgeStats().static enumThe weighting scheme for pooling per-dataset left-right statistics. -
Constructor Summary
ConstructorsConstructorDescriptionFaskPool(List<DataSet> dataSets, ScoreWrapper score) Constructs a pooled-FASK search from the supplied datasets and score wrapper. -
Method Summary
Modifier and TypeMethodDescriptionReturns the per-edge pooled statistics recorded during the last search, keyed by the edge added to the result graph.search(Parameters parameters) Runs the search and returns the composite graph.voidSets how the common adjacency structure is obtained when no external graph is set.voidsetExternalAdjacencyFraction(double externalAdjacencyFraction) Sets the fraction of the external graphs in which a pair must be adjacent for it to be an adjacency of the composite skeleton: the pair is kept when its count exceeds this fraction of the number of graphs.voidsetExternalGraph(Graph externalGraph) Sets a single external graph, applied to every dataset.voidsetExternalGraphs(List<Graph> externalGraphs) Sets the external graphs, one per dataset, in the order of the datasets.voidsetFasAlpha(double fasAlpha) Sets the alpha level for the FAS-style adjacency tests.voidsetFasDepth(int fasDepth) Sets the depth of the FAS-style adjacency searches (-1 for unlimited; capped at 4 in MG_FAS).voidsetFastIcaA(double fastIcaA) Sets the FastICA tanh nonlinearity parameter for the LiNG adjacency stage.voidsetFastIcaMaxIter(int fastIcaMaxIter) Sets the FastICA maximum iterations for the LiNG adjacency stage.voidsetFastIcaTolerance(double fastIcaTolerance) Sets the FastICA convergence tolerance for the LiNG adjacency stage.voidsetKnowledge(Knowledge knowledge) Sets background knowledge for the search.voidsetLeftRight(Fask.LeftRight leftRight) Sets the left-right rule used within each dataset.voidsetLingThreshold(double lingThreshold) Sets the threshold on the pooled absolute LiNG B-hat entries above which a moral pair is kept as an adjacency.voidsetNumBootstraps(int numBootstraps) Sets the number of bootstrap resamples per dataset used to estimate Var(lr_k).voidsetOrientationAlpha(double orientationAlpha) Sets the significance level for the orientation decision.voidsetTwoCycleAlpha(double twoCycleAlpha) Sets the alpha for the per-dataset two-cycle test.voidsetUseAdjacencyOrientations(boolean useAdjacencyOrientations) Sets whether the adjacency stage's compelled orientations act as default orientations in the same way.voidsetUseExternalOrientations(boolean useExternalOrientations) Sets whether the external graphs' compelled orientations act as default orientations that the pooled statistic can overturn only on strong opposing evidence (see the class Javadoc).voidsetWeighting(FaskPool.Weighting weighting) Sets the weighting scheme for pooling.
-
Constructor Details
-
FaskPool
Constructs a pooled-FASK search from the supplied datasets and score wrapper.- Parameters:
dataSets- the datasets to search overscore- the score wrapper for the IMaGES adjacency stage- Throws:
NullPointerException- if any argument is nullIllegalArgumentException- if the dataset list is empty
-
-
Method Details
-
search
Runs the search and returns the composite graph.- Parameters:
parameters- the search parameters (passed to the IMaGES stage)- Returns:
- the composite graph
- Throws:
InterruptedException- if the underlying IMaGES search is interrupted
-
setKnowledge
Sets background knowledge for the search. A defensive copy is stored.- Parameters:
knowledge- knowledge containing forbidden and required edges- Throws:
NullPointerException- if the supplied knowledge is null
-
setExternalGraph
Sets a single external graph, applied to every dataset. Equivalent tosetExternalGraphs(List)with a one-element list; since one graph cannot disagree with itself, its compelled orientations count as unanimous evidence, so a positive orientation alpha should be set to give the override a meaningful gate. Prefer supplying one graph per dataset.- Parameters:
externalGraph- the external graph, or null to use the adjacency search
-
setExternalGraphs
Sets the external graphs, one per dataset, in the order of the datasets. When nonempty, the adjacency stage is skipped and these graphs are combined: a pair is an adjacency of the composite skeleton when it is adjacent in more thansetExternalAdjacencyFraction(double)of them, and their compelled orientations are tallied into orientation evidence, with the majority direction (if any) becoming the default orientation of that pair.The list need not have one entry per dataset—any number of graphs over the same variables is combined the same way—but supplying each dataset's own graph is the point: it is what makes the evidence cross-dataset, so that unanimity among the graphs means something.
- Parameters:
externalGraphs- the external graphs, or null or empty to use the adjacency search
-
setUseExternalOrientations
public void setUseExternalOrientations(boolean useExternalOrientations) Sets whether the external graphs' compelled orientations act as default orientations that the pooled statistic can overturn only on strong opposing evidence (see the class Javadoc). When false, the external graphs contribute adjacencies only. Only consulted when external graphs have been set. Default: true.- Parameters:
useExternalOrientations- true to use the external orientations as defaults
-
setUseAdjacencyOrientations
public void setUseAdjacencyOrientations(boolean useAdjacencyOrientations) Sets whether the adjacency stage's compelled orientations act as default orientations in the same way. OnlyPooledAdjacencySearch.Method.IMAGESproduces any: the CPDAG of a BOSS search over the score averaged across the datasets, whose compelled orientations are score-based, cross-dataset evidence about direction. When false, only the adjacencies of that CPDAG are used and every edge is oriented from the pooled statistic. Only consulted when no external graphs have been set. Default: true.- Parameters:
useAdjacencyOrientations- true to use the adjacency stage's orientations as defaults
-
setExternalAdjacencyFraction
public void setExternalAdjacencyFraction(double externalAdjacencyFraction) Sets the fraction of the external graphs in which a pair must be adjacent for it to be an adjacency of the composite skeleton: the pair is kept when its count exceeds this fraction of the number of graphs. Zero takes the union of the skeletons, 0.5 (the default) a strict majority, and 1.0 the intersection. Ignored unless more than one external graph is supplied.- Parameters:
externalAdjacencyFraction- the fraction, in [0, 1]
-
setTwoCycleAlpha
public void setTwoCycleAlpha(double twoCycleAlpha) Sets the alpha for the per-dataset two-cycle test. Zero (the default) disables two-cycle detection; above zero, a pair is output as a two-cycle only when every dataset passes the single-dataset FASK two-cycle test at this level. See the class Javadoc for a caution about this channel.- Parameters:
twoCycleAlpha- the significance level, in [0, 1]
-
setLeftRight
Sets the left-right rule used within each dataset. Default: FASK2.- Parameters:
leftRight- the left-right rule
-
setWeighting
Sets the weighting scheme for pooling. Default: N (sample-size weights).- Parameters:
weighting- the weighting scheme
-
setAdjacencyMethod
Sets how the common adjacency structure is obtained when no external graph is set. Default: IMAGES. Ignored when an external graph has been set.- Parameters:
method- the adjacency method
-
setFasAlpha
public void setFasAlpha(double fasAlpha) Sets the alpha level for the FAS-style adjacency tests. Default: 0.05.- Parameters:
fasAlpha- the alpha level, in (0, 1)
-
setFasDepth
public void setFasDepth(int fasDepth) Sets the depth of the FAS-style adjacency searches (-1 for unlimited; capped at 4 in MG_FAS). Default: -1.- Parameters:
fasDepth- the depth
-
setLingThreshold
public void setLingThreshold(double lingThreshold) Sets the threshold on the pooled absolute LiNG B-hat entries above which a moral pair is kept as an adjacency. Default: 0.1.- Parameters:
lingThreshold- the threshold, nonnegative
-
setFastIcaMaxIter
public void setFastIcaMaxIter(int fastIcaMaxIter) Sets the FastICA maximum iterations for the LiNG adjacency stage. Default: 2000.- Parameters:
fastIcaMaxIter- maximum iterations, positive
-
setFastIcaTolerance
public void setFastIcaTolerance(double fastIcaTolerance) Sets the FastICA convergence tolerance for the LiNG adjacency stage. Default: 1e-6.- Parameters:
fastIcaTolerance- the tolerance, positive
-
setFastIcaA
public void setFastIcaA(double fastIcaA) Sets the FastICA tanh nonlinearity parameter for the LiNG adjacency stage. Default: 1.1.- Parameters:
fastIcaA- the parameter
-
setOrientationAlpha
public void setOrientationAlpha(double orientationAlpha) Sets the significance level for the orientation decision. Zero (the default) orients every adjacency by the sign of the pooled statistic; above zero, an edge is left undirected unless the pooled statistic differs significantly from zero at this level (two-sided, bootstrap standard error).- Parameters:
orientationAlpha- the significance level, in [0, 1]
-
setNumBootstraps
public void setNumBootstraps(int numBootstraps) Sets the number of bootstrap resamples per dataset used to estimate Var(lr_k). Default: 200.- Parameters:
numBootstraps- the number of resamples, at least 2
-
getEdgeStats
Returns the per-edge pooled statistics recorded during the last search, keyed by the edge added to the result graph. The z and Q entries are NaN when bootstrap variances were not computed (n-weighting with orientation alpha zero).- Returns:
- an unmodifiable view of the per-edge statistics
-