All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.cmu.tetrad.search.GFci Maven / Gradle / Ivy

///////////////////////////////////////////////////////////////////////////////
// For information as to what this class does, see the Javadoc, below.       //
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,       //
// 2007, 2008, 2009, 2010, 2014, 2015, 2022 by Peter Spirtes, Richard        //
// Scheines, Joseph Ramsey, and Clark Glymour.                               //
//                                                                           //
// This program is free software; you can redistribute it and/or modify      //
// it under the terms of the GNU General Public License as published by      //
// the Free Software Foundation; either version 2 of the License, or         //
// (at your option) any later version.                                       //
//                                                                           //
// This program is distributed in the hope that it will be useful,           //
// but WITHOUT ANY WARRANTY; without even the implied warranty of            //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             //
// GNU General Public License for more details.                              //
//                                                                           //
// You should have received a copy of the GNU General Public License         //
// along with this program; if not, write to the Free Software               //
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA //
///////////////////////////////////////////////////////////////////////////////
package edu.cmu.tetrad.search;

import edu.cmu.tetrad.data.Knowledge;
import edu.cmu.tetrad.graph.EdgeListGraph;
import edu.cmu.tetrad.graph.Graph;
import edu.cmu.tetrad.graph.GraphUtils;
import edu.cmu.tetrad.graph.Node;
import edu.cmu.tetrad.search.score.Score;
import edu.cmu.tetrad.search.utils.FciOrient;
import edu.cmu.tetrad.search.utils.SepsetProducer;
import edu.cmu.tetrad.search.utils.SepsetsGreedy;
import edu.cmu.tetrad.util.TetradLogger;

import java.io.PrintStream;
import java.util.List;

import static edu.cmu.tetrad.graph.GraphUtils.gfciExtraEdgeRemovalStep;

/**
 * 

Implements a modification of FCI that started by running the FGES algorithm and * then fixes that result to be correct for latent variables models. First, colliders from the FGES results are copied * into the final circle-circle graph, and some independence reasoning is used to add the remaining colliders into the * graph. Then, the FCI final orientation rules are applied. The reference is here:

* *

Ogarrio, J. M., Spirtes, P., & Ramsey, J. (2016, August). A hybrid causal * search algorithm for latent variable models. In Conference on probabilistic graphical models (pp. 368-379). * PMLR.

* *

Because the method both runs FGES (a score-based algorithm) and does * additional checking of conditional independencies, both as part of its collider orientation step and also as part of * the the definite discriminating path step in the final FCI orientation rules, both a score and a test need to be used * to construct a GFCI algorithm.

* *

Note that various score-based algorithms could be used in place of FGES * for the initial step; in this repository we give three other options, GRaSP-FCI, BFCI (BOSS FCI), and SP-FCI * (see).

* *

For more information on the algorithm, see the reference above.

* *

This class is configured to respect knowledge of forbidden and required * edges, including knowledge of temporal tiers.

* * @author Juan Miguel Ogarrio * @author peterspirtes * @author josephramsey * @see Fci * @see FciOrient * @see GraspFci * @see BFci * @see SpFci * @see Fges * @see Knowledge */ public final class GFci implements IGraphSearch { private final IndependenceTest independenceTest; private final TetradLogger logger = TetradLogger.getInstance(); private final Score score; private Knowledge knowledge = new Knowledge(); private boolean completeRuleSetUsed = true; private int maxPathLength = -1; private int maxDegree = -1; private boolean verbose; private PrintStream out = System.out; private boolean faithfulnessAssumed = true; private boolean doDiscriminatingPathRule = true; private boolean possibleMsepSearchDone = true; private int depth = -1; /** * Constructs a new GFci algorithm with the given independence test and score. * * @param test The independence test to use. * @param score The score to use. */ public GFci(IndependenceTest test, Score score) { if (score == null) { throw new NullPointerException(); } this.score = score; this.independenceTest = test; } /** * Runs the graph and returns the search PAG. * * @return This PAG. */ public Graph search() { this.independenceTest.setVerbose(verbose); List nodes = getIndependenceTest().getVariables(); this.logger.log("info", "Starting FCI algorithm."); this.logger.log("info", "Independence test = " + getIndependenceTest() + "."); Graph graph; Fges fges = new Fges(this.score); fges.setKnowledge(getKnowledge()); fges.setVerbose(this.verbose); fges.setFaithfulnessAssumed(this.faithfulnessAssumed); fges.setMaxDegree(this.maxDegree); fges.setOut(this.out); graph = fges.search(); Knowledge knowledge2 = new Knowledge(knowledge); Graph referenceDag = new EdgeListGraph(graph); // GFCI extra edge removal step... SepsetProducer sepsets = new SepsetsGreedy(graph, this.independenceTest, null, this.depth, knowledge); gfciExtraEdgeRemovalStep(graph, referenceDag, nodes, sepsets); GraphUtils.gfciR0(graph, referenceDag, sepsets, knowledge); FciOrient fciOrient = new FciOrient(sepsets); fciOrient.setCompleteRuleSetUsed(this.completeRuleSetUsed); fciOrient.setMaxPathLength(this.maxPathLength); fciOrient.setDoDiscriminatingPathColliderRule(this.doDiscriminatingPathRule); fciOrient.setDoDiscriminatingPathTailRule(this.doDiscriminatingPathRule); fciOrient.setVerbose(verbose); fciOrient.setKnowledge(knowledge2); fciOrient.doFinalOrientation(graph); return graph; } /** * Sets the maximum indegree of the output graph. * * @param maxDegree This maximum. */ public void setMaxDegree(int maxDegree) { if (maxDegree < -1) { throw new IllegalArgumentException( "Depth must be -1 (unlimited) or >= 0: " + maxDegree); } this.maxDegree = maxDegree; } /** * Returns the knowledge used in search. * * @return This knowledge */ public Knowledge getKnowledge() { return this.knowledge; } /** * Sets the knowledge to use in search. * * @param knowledge This knowledge. */ public void setKnowledge(Knowledge knowledge) { if (knowledge == null) { throw new NullPointerException(); } this.knowledge = knowledge; } /** * Sets whether Zhang's complete rules are used. * * @param completeRuleSetUsed set to true if Zhang's complete rule set should be used, false if only R1-R4 (the rule * set of the original FCI) should be used. True by default. */ public void setCompleteRuleSetUsed(boolean completeRuleSetUsed) { this.completeRuleSetUsed = completeRuleSetUsed; } /** * Sets the maximum path length for the discriminating path rule. * * @param maxPathLength the maximum length of any discriminating path, or -1 if unlimited. */ public void setMaxPathLength(int maxPathLength) { if (maxPathLength < -1) { throw new IllegalArgumentException("Max path length must be -1 (unlimited) or >= 0: " + maxPathLength); } this.maxPathLength = maxPathLength; } /** * Sets whether verbose output should be printed. * * @param verbose True, if so. */ public void setVerbose(boolean verbose) { this.verbose = verbose; } /** * Returns the independence test used in search. * * @return This test. */ public IndependenceTest getIndependenceTest() { return this.independenceTest; } /** * Sets the print stream used for output, default System.out. * * @param out This print stream. */ public void setOut(PrintStream out) { this.out = out; } /** * Sets whether one-edge faithfulness is assumed. For FGES * * @param faithfulnessAssumed True, if so. * @see Fges#setFaithfulnessAssumed(boolean) */ public void setFaithfulnessAssumed(boolean faithfulnessAssumed) { this.faithfulnessAssumed = faithfulnessAssumed; } /** * Sets whether the discriminating path rule should be used. * * @param doDiscriminatingPathRule True, if so. */ public void setDoDiscriminatingPathRule(boolean doDiscriminatingPathRule) { this.doDiscriminatingPathRule = doDiscriminatingPathRule; } /** * Sets whether the possible m-sep search should be done. * * @param possibleMsepSearchDone True, if so. */ public void setPossibleMsepSearchDone(boolean possibleMsepSearchDone) { this.possibleMsepSearchDone = possibleMsepSearchDone; } /** * Sets the depth of the search for the possible m-sep search. * * @param depth This depth. */ public void setDepth(int depth) { this.depth = depth; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy