### Install dodiscover using pip Source: https://github.com/py-why/dodiscover/blob/main/README.md Use this command to install the dodiscover package. This is the standard method for most users. Ensure you have pip installed and updated. ```bash pip install -U dodiscover ``` -------------------------------- ### Install dodiscover with development extras Source: https://github.com/py-why/dodiscover/blob/main/README.md Install the package along with optional extras for documentation, building, style checking, and unit testing. This is recommended for contributors and developers. ```bash pip install .[doc, build, style, test] ``` -------------------------------- ### Install dodiscover from source Source: https://github.com/py-why/dodiscover/blob/main/doc/installation.md Clone the dodiscover repository and install it from source using pip. This is useful for development or if you need the latest unreleased changes. ```bash git clone https://github.com/pywhy/dodiscover.git cd dodiscover pip install -e . ``` -------------------------------- ### Install dodiscover using pip Source: https://github.com/py-why/dodiscover/blob/main/doc/installation.md Install the dodiscover package from PyPI using pip. Ensure you have Python 3.10 or higher. ```bash pip install dodiscover ``` -------------------------------- ### Install dodiscover from source using pip Source: https://github.com/py-why/dodiscover/blob/main/README.md For developers, clone the repository and install the package in editable mode. This allows for direct code modifications and testing. ```bash pip install -e . ``` -------------------------------- ### Initialize PC Algorithm with Data Source: https://context7.com/py-why/dodiscover/llms.txt Set up the PC algorithm for causal discovery using generated data. This snippet demonstrates the initial setup before defining context or constraints. ```python import numpy as np import pandas as pd from dodiscover import PC, make_context from dodiscover.ci import FisherZCITest # Generate data np.random.seed(42) n = 300 treatment = np.random.randn(n) mediator = 0.6 * treatment + np.random.randn(n) * 0.3 outcome = 0.4 * treatment + 0.5 * mediator + np.random.randn(n) * 0.3 confounder = np.random.randn(n) data = pd.DataFrame({ 'treatment': treatment, 'mediator': mediator, 'outcome': outcome, 'confounder': confounder }) # Define domain knowledge # This part is incomplete in the source, but shows initialization of PC algorithm pc_alg = PC(data=data, ci_test=FisherZCITest()) context = make_context(data.columns) # Further steps would involve learning the graph with constraints ``` -------------------------------- ### Create and activate Python virtual environment Source: https://github.com/py-why/dodiscover/blob/main/CONTRIBUTING.md Create a Python 3 virtual environment using Conda and activate it. Then, install the project in editable mode. ```bash conda create -n dodiscover python=3.10 conda activate dodiscover pip install -e . ``` -------------------------------- ### Load and rename example dataset Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Loads the 'asia' dataset from bnlearn and renames its columns for clarity in causal discovery analysis. ```python # Load example dataset data = bn.import_example(data='asia') data.rename(columns = { 'tub': 'T', 'lung': 'L', 'bronc': 'B', 'asia': 'A', 'smoke': 'S', 'either': 'E', 'xray': 'X', 'dysp': 'D'}, inplace=True ) data.head() ``` -------------------------------- ### Learn Causal Graph with Constraints using PC Source: https://context7.com/py-why/dodiscover/llms.txt This example demonstrates how to use the PC algorithm with explicit constraints on included and excluded edges. Ensure the FisherZCITest is appropriate for your data. ```python import networkx as nx from dodiscover.ci_test import FisherZCITest from dodiscover.pc import PC from dodiscover.context import make_context # Assume 'data' is a pandas DataFrame and 'make_context' is available # Example data and context setup: included = nx.DiGraph([('treatment', 'outcome')]) excluded = nx.DiGraph([ ('outcome', 'treatment'), ('outcome', 'mediator'), ('confounder', 'treatment') # known: confounder doesn't affect treatment ]) context = make_context() \ .variables(data=data) \ .included_edges(included) \ .excluded_edges(excluded) \ .build() # Run PC with constraints ci_test = FisherZCITest() pc = PC(ci_estimator=ci_test, alpha=0.05) pc.learn_graph(data, context) # The learned graph respects the constraints learned_graph = pc.graph_ print(f"Learned edges: {list(learned_graph.edges())}") # Verify constraints are satisfied assert learned_graph.has_edge('treatment', 'outcome'), "Included edge missing" for u, v in excluded.edges(): assert not learned_graph.has_edge(u, v), f"Excluded edge {u}->{v} present" ``` -------------------------------- ### Define Context with Data Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Create a `context.Context` object to house data and prior assumptions for causal discovery algorithms. This example shows how to include data. ```python context = make_context().variables(data=data).build() ``` -------------------------------- ### Specify Treatments and Outcomes Source: https://github.com/py-why/dodiscover/wiki/Knowledge-elicitation-through-"Context" Define treatments and outcomes for causal effect inference queries within the Context. This guides the discovery towards relevant causal pathways. ```Python context = Context( treatments={'A', 'B'}, outcomes={'C'} ) ``` -------------------------------- ### Generate Confusion Matrix for Network Adjacency Source: https://context7.com/py-why/dodiscover/llms.txt Obtain a confusion matrix comparing the adjacency structure of two networks, ignoring edge direction. The `normalize` parameter can be used to get a normalized matrix. ```python from dodiscover.metrics import confusion_matrix_networks # True and predicted DAGs true_dag = nx.DiGraph([('x', 'y'), ('z', 'y'), ('z', 'w')]) pred_dag = nx.DiGraph([('x', 'y'), ('y', 'z'), ('z', 'w')]) # wrong z-y direction # Confusion matrix for adjacency structure (ignores direction) cm = confusion_matrix_networks(true_dag, pred_dag) print(f"Confusion matrix: {cm}") # [[TN, FP], [FN, TP]] # Normalized confusion matrix cm_norm = confusion_matrix_networks(true_dag, pred_dag, normalize='true') print(f"Normalized confusion matrix: {cm_norm}") ``` -------------------------------- ### Initialize and Run PC Algorithm with Oracle Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Initialize the PC algorithm with an oracle CI estimator for ideal conditions. Then, learn the graph from the provided data and context. ```python pc = PC(ci_estimator=oracle) pc.learn_graph(data, context) ``` -------------------------------- ### Initialize Alternative Causal Discovery Algorithms Source: https://context7.com/py-why/dodiscover/llms.txt Instantiate and learn graphs using alternative algorithms like CAM, DAS, and NoGAM. These algorithms may have different assumptions or performance characteristics. ```python cam = CAM(alpha=0.05, prune=True, pns=False) cam.learn_graph(data, context) ``` ```python das = DAS(alpha=0.05, prune=True) das.learn_graph(data, context) ``` ```python nogam = NoGAM(alpha=0.05, prune=True) nogam.learn_graph(data, context) ``` -------------------------------- ### Instantiate Oracle for CI Tests Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Use the `Oracle` class when evaluating discovery algorithms in a simulation setting. It requires the ground truth causal graph. ```python oracle = Oracle(ground_truth) ``` -------------------------------- ### Initialize Context and Learn Graph Source: https://github.com/py-why/dodiscover/wiki/Knowledge-elicitation-through-"Context" Initialize a Context object and pass it along with data to the learn_graph function for causal discovery. ```Python context = Context(...) model = learn_graph(context, data, discovery_algo) ``` -------------------------------- ### Initialize PC Algorithm with GSquareCITest Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Initialize the PC algorithm using the GSquareCITest for binary data. Set the significance level alpha to 0.05. ```python ci_estimator = GSquareCITest(data_type="binary") pc = PC(ci_estimator=ci_estimator, alpha=0.05) ``` -------------------------------- ### Create and Configure Context with make_context Source: https://context7.com/py-why/dodiscover/llms.txt Use `make_context()` and `ContextBuilder` to specify observed/latent variables and edge constraints. This sets up domain knowledge before running causal discovery algorithms. ```python import pandas as pd import networkx as nx from dodiscover import make_context # Create sample data data = pd.DataFrame({ 'x': [0, 1, 1, 0, 1], 'y': [1, 2, 1, 2, 0], 'z': [0, 1, 0, 1, 1], 'w': [1, 1, 0, 1, 0] }) # Basic context from data - infers variables from columns context = make_context().variables(data=data).build() # Context with explicit variable specification context = make_context().variables( observed={'x', 'y', 'z', 'w'}, latents=set() ).build() # Context with edge constraints - force certain edges to be included/excluded included_edges = nx.DiGraph([('x', 'y')]) # x must cause y excluded_edges = nx.DiGraph([('z', 'x')]) # z cannot directly cause x context = make_context() \ .variables(data=data) \ .edges(include=included_edges, exclude=excluded_edges) \ .build() # Access context attributes print(f"Observed variables: {context.observed_variables}") print(f"Latent variables: {context.latent_variables}") print(f"Included edges: {list(context.included_edges.edges())}") print(f"Excluded edges: {list(context.excluded_edges.edges())}") ``` -------------------------------- ### Advanced Algorithm Usage with PC and BIC Source: https://github.com/py-why/dodiscover/wiki/v0-API-[WIP] Use algorithms directly with a scikit-learn-like API. Requires importing the specific algorithm and fitting it with a context object. ```python discoverer1= PC(test="chi-squared", alpha=.05) discoverer1.fit(context) cpdag = discoverer1.graph_ separating_sets = discoverer1.sep_sets_ discoverer2 = BIC() discoverer2.fit(context) ``` -------------------------------- ### Run PC Algorithm with Real CI Test Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Learn the graph using the PC algorithm with a real Conditional Independence (CI) test estimator. This reflects a more realistic scenario with finite data and potential noise. ```python pc.learn_graph(data, context) ``` -------------------------------- ### Clone the repository Source: https://github.com/py-why/dodiscover/blob/main/CONTRIBUTING.md Clone your fork of the repository locally. Use the HTTPS or SSH URL provided by GitHub. ```bash git clone https://github.com/USERNAME/dodiscover.git ``` ```bash git clone git@github.com:USERNAME/dodiscover.git ``` -------------------------------- ### Create a new feature branch Source: https://github.com/py-why/dodiscover/blob/main/CONTRIBUTING.md Create a new branch for your contribution and push it to your origin. This keeps your work isolated and organized. ```bash # replace BRANCH with whatever name you want to give it git checkout -b BRANCH git push -u origin BRANCH ``` -------------------------------- ### Import necessary libraries for causal discovery Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Imports required libraries including bnlearn, networkx, numpy, pywhy_graphs, and dodiscover components for causal discovery and visualization. ```python import bnlearn as bn import networkx as nx import numpy as np from pywhy_graphs import CPDAG from pywhy_graphs.viz import draw from dodiscover import PC, make_context from dodiscover.ci import GSquareCITest, Oracle ``` -------------------------------- ### Utilities API (Kernel Utils) Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst Utility functions for kernel-based calculations. ```APIDOC ## Utilities API (Kernel Utils) ### Description Provides utility functions for kernel-based calculations used in conditional testing. ### Functions - `compute_kernel` - `corrent_matrix` - `von_neumann_divergence` - `f_divergence_score` - `kl_divergence_score` ``` -------------------------------- ### Visualize the ground truth graph Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Visualizes the ground truth directed graph using networkx and matplotlib. Requires 'seed' for reproducible layout. ```python pos = nx.spring_layout(ground_truth, seed=1234) nx.draw(ground_truth, with_labels=True, pos=pos) ``` -------------------------------- ### Visualize Graph Learned with Real CI Test Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Draw the graph learned using a real CI test. This visualization helps in assessing the discovered causal structure under practical conditions. ```python graph = pc.graph_ draw(graph, direction='TB') ``` -------------------------------- ### dodiscover Module Documentation Source: https://github.com/py-why/dodiscover/blob/main/doc/_templates/autosummary/class.rst Detailed documentation for the dodiscover module, including special members and general members. ```APIDOC ## dodiscover Module Documentation ### Description This section details the `dodiscover` module, outlining its special members and general members. It also includes examples from the module. ### Module dodiscover ### Class autoclass:: {{ objname }} :special-members: __contains__,__getitem__,__iter__,__len__,__add__,__sub__,__mul__,__div__,__neg__,__hash__ :members: ### Examples .. include:: {{module}}.{{objname}}.examples ``` -------------------------------- ### Psi-FCI Algorithm for Interventional Discovery Source: https://context7.com/py-why/dodiscover/llms.txt Implement Psi-FCI for causal discovery with multiple observational and interventional datasets. Requires combining data and creating an InterventionalContextBuilder. ```python import numpy as np import pandas as pd from dodiscover import PsiFCI, make_context from dodiscover.ci import FisherZCITest from dodiscover.cd import KernelCDTest from dodiscover.context_builder import InterventionalContextBuilder np.random.seed(42) n_samples = 200 # Observational distribution x_obs = np.random.randn(n_samples) y_obs = 0.7 * x_obs + np.random.randn(n_samples) * 0.3 z_obs = 0.5 * y_obs + np.random.randn(n_samples) * 0.4 data_obs = pd.DataFrame({'x': x_obs, 'y': y_obs, 'z': z_obs}) data_obs['distribution'] = 0 # Interventional distribution (intervention on x) x_int = np.random.randn(n_samples) * 0.5 # different distribution for x y_int = 0.7 * x_int + np.random.randn(n_samples) * 0.3 z_int = 0.5 * y_int + np.random.randn(n_samples) * 0.4 data_int = pd.DataFrame({'x': x_int, 'y': y_int, 'z': z_int}) data_int['distribution'] = 1 # Combine datasets data = pd.concat([data_obs, data_int], ignore_index=True) # Create interventional context with known targets context = make_context(create_using=InterventionalContextBuilder) \ .variables(observed={'x', 'y', 'z'}) \ .num_distributions(2) \ .intervention_targets([('x',)]) \ .build() # CI test for conditional independence ci_test = FisherZCITest() # CD test for conditional discrepancy between distributions cd_test = KernelCDTest() # Run Psi-FCI (unknown targets) or I-FCI (known targets) psi_fci = PsiFCI( ci_estimator=ci_test, cd_estimator=cd_test, alpha=0.05, known_intervention_targets=True # set False for Psi-FCI ) # Note: learn_graph expects list of DataFrames for interventional data # psi_fci.learn_graph([data_obs.drop('distribution', axis=1), # data_int.drop('distribution', axis=1)], context) ``` -------------------------------- ### Visualize Ground Truth Graph Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Draw the ground truth graph for comparison. This helps in evaluating the accuracy of the learned graph. ```python draw(ground_truth_cpdag, direction='TB') ``` -------------------------------- ### Utilities API (Monte Carlo) Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst Utility functions for Monte-Carlo testing of conditional independence. ```APIDOC ## Utilities API (Monte Carlo) ### Description Provides utility functions for Monte-Carlo testing of conditional independence. ### Functions - `generate_knn_in_subspace` - `restricted_nbr_permutation` ``` -------------------------------- ### Compare Learned Graph with Ground Truth Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Compare the learned CPDAG with the ground truth CPDAG for both directed and undirected edges using graph isomorphism. Prints the comparison results. ```python match_directed = nx.is_isomorphic(ground_truth_cpdag.sub_directed_graph(), graph.sub_directed_graph()) match_undirected = nx.is_isomorphic(ground_truth_cpdag.sub_undirected_graph(), graph.sub_undirected_graph()) print(f'The oracle learned CPDAG via the PC algorithm matches the ground truth in directed edges: {match_directed} ' f'and matches the undirected edges: {match_undirected}') ``` -------------------------------- ### Visualize Learned Graph Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Draw the learned graph. This is useful for visualizing the structure discovered by the PC algorithm. ```python graph = pc.graph_ draw(graph, direction='TB') ``` -------------------------------- ### Builder Pattern for Context Creation Source: https://github.com/py-why/dodiscover/wiki/Knowledge-elicitation-through-"Context" Utilize the builder pattern prototype to construct a Context object with specified nodes, forced edges, and prevented edges. ```Python context = make_context() .nodes(...) .forced_edges(include_df) .prevented_edges(exclude_df) .build() ``` -------------------------------- ### FCI Algorithm with KernelCITest Source: https://context7.com/py-why/dodiscover/llms.txt An alternative FCI implementation using KernelCITest for non-linear dependencies. Note the different alpha value. ```python from dodiscover.ci import KernelCITest kernel_ci_test = KernelCITest( kernel_x='rbf', kernel_y='rbf', kernel_z='rbf', approx_with_gamma=True ) fci_kernel = FCI(ci_estimator=kernel_ci_test, alpha=0.01) fci_kernel.learn_graph(data, context) ``` -------------------------------- ### Ensemble Discovery with Bootstrapping Source: https://github.com/py-why/dodiscover/wiki/v0-API-[WIP] Perform causal discovery using a bootstrapping procedure. This involves creating multiple contexts from bootstrapped data and learning graphs for each. ```python get_context = partial(BayesianContext, prior={ "pseudocounts": 10, "edgewise": prior_df } ) contexts = [get_context(boot_df) for boot_df in bootstrap_dfs] def get_pdags(context): return learn_graph( context, method=score_discoverer, ) pdags = map(contexts, get_pdags) ``` -------------------------------- ### Order-based structure learning API Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst API for order-based structure learning algorithms. ```APIDOC ## Order-based structure learning API ### Description Provides classes for order-based structure learning algorithms. ### Classes - `CAM` - `SCORE` - `DAS` - `NoGAM` ``` -------------------------------- ### Add upstream remote Source: https://github.com/py-why/dodiscover/blob/main/CONTRIBUTING.md Add a remote named 'upstream' that points to the main dodiscover repository. This allows you to fetch updates from the original project. ```bash git remote add upstream https://github.com/py-why/dodiscover.git ``` -------------------------------- ### End-to-End Causal Effect Estimation Workflow Source: https://github.com/py-why/dodiscover/wiki/v0-API-[WIP] An end-to-end workflow for causal effect estimation within a consensus setting. It involves learning a graph, identifying an estimand, and estimating the effect. ```python def get_effect(context): pdag = learn_graph( context, method=score_discoverer ) dag = cextend(pdag) estimand = dowhy.identify_effect(dag, action_node="A", outcome_node="B", observed_nodes=...) estimator = dowhy.LinearRegressionEstimator(estimand) estimator.fit(context.data) estimate = estimator.estimate_effect(action_value=..., control_value=...) return estimate estimates = map(contexts, get_effect) mean(estimates) ``` -------------------------------- ### Constraint-based structure learning API Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst API for constraint-based structure learning algorithms. ```APIDOC ## Constraint-based structure learning API ### Description Provides classes for constraint-based structure learning, including skeleton learning and algorithm implementations like PC and FCI. ### Classes - `LearnSkeleton` - `LearnSemiMarkovianSkeleton` - `LearnInterventionSkeleton` - `ConditioningSetSelection` - `PC` - `FCI` - `PsiFCI` ``` -------------------------------- ### Comparing causal discovery algorithms API Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst API for comparing causal discovery algorithms using various metrics. ```APIDOC ## Comparing causal discovery algorithms API ### Description Provides functions to compare causal discovery algorithms using metrics like confusion matrices and distance measures. ### Functions - `confusion_matrix_networks` - `structure_hamming_dist` - `toporder_divergence` ``` -------------------------------- ### Update local fork Source: https://github.com/py-why/dodiscover/blob/main/CONTRIBUTING.md Ensure your local main branch is up-to-date with the upstream repository by rebasing. Then, push the changes to your fork. ```bash git checkout main git pull --rebase upstream main git push ``` -------------------------------- ### Conditional k-sample testing API Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst API for conditional discrepancy (k-sample) testing. ```APIDOC ## Conditional k-sample testing API ### Description Provides an interface for conditional discrepancy testing, also known as k-sample conditional independence testing. ### Classes - `BaseConditionalDiscrepancyTest` - `KernelCDTest` - `BregmanCDTest` ``` -------------------------------- ### FCI Algorithm with FisherZCITest Source: https://context7.com/py-why/dodiscover/llms.txt Use the FCI algorithm for causal discovery with continuous Gaussian data. Requires setting up a context and choosing a CI estimator like FisherZCITest. ```python import numpy as np import pandas as pd from dodiscover import FCI, make_context from dodiscover.ci import FisherZCITest np.random.seed(42) n_samples = 300 latent_u = np.random.randn(n_samples) # unobserved confounder x = latent_u + np.random.randn(n_samples) * 0.5 y = 0.8 * x + latent_u + np.random.randn(n_samples) * 0.3 z = 0.5 * y + np.random.randn(n_samples) * 0.4 data = pd.DataFrame({'x': x, 'y': y, 'z': z}) context = make_context().variables(data=data).build() ci_test = FisherZCITest() fci = FCI( ci_estimator=ci_test, alpha=0.05, selection_bias=False, # assume no selection bias max_path_length=None, # no limit on discriminating paths max_iter=1000 # max iterations for orientation rules ) fci.learn_graph(data, context) print(f"PAG nodes: {list(pag.nodes)}") print(f"PAG edges: {list(pag.edges())}") ``` -------------------------------- ### Consensus Graph from Multiple PDAGs Source: https://github.com/py-why/dodiscover/wiki/v0-API-[WIP] Generate a consensus graph by averaging multiple PDAGs (Partially Directed Acyclic Graphs). ```python pdag = consensus_graph(pdags) ``` -------------------------------- ### Context for causal discovery API Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst Experimental API for constructing and using context objects in causal discovery. ```APIDOC ## Context for causal discovery API ### Description This is an experimental API for providing additional context (e.g., prior knowledge, different environments) to structure learning algorithms. Use the `make_context` builder for construction. ### Functions and Classes - `make_context` (Builder function) - `ContextBuilder` - `InterventionalContextBuilder` - `context.Context` ``` -------------------------------- ### Run PC Algorithm for Causal Discovery Source: https://context7.com/py-why/dodiscover/llms.txt The PC algorithm assumes causal sufficiency and learns a CPDAG using conditional independence tests. Configure the `ci_estimator` (e.g., `GSquareCITest` for discrete data) and algorithm parameters. ```python import numpy as np import pandas as pd from dodiscover import PC, make_context from dodiscover.ci import GSquareCITest, FisherZCITest, Oracle # Generate sample data np.random.seed(42) n_samples = 500 x = np.random.binomial(1, 0.5, n_samples) z = np.random.binomial(1, 0.9, n_samples) y = x + z + np.random.binomial(1, 0.3, n_samples) # y depends on x and z w = z + np.random.binomial(1, 0.5, n_samples) # w depends on z data = pd.DataFrame({'x': x, 'y': y, 'z': z, 'w': w}) # Create context from data context = make_context().variables(data=data).build() # For discrete data, use G-Square test ci_test = GSquareCITest(data_type='discrete') # Initialize and run PC algorithm pc = PC( ci_estimator=ci_test, alpha=0.05, # significance level for CI tests max_cond_set_size=None, # no limit on conditioning set size apply_orientations=True, # apply Meek's orientation rules keep_sorted=False # don't sort by test statistic ) pc.learn_graph(data, context) # Access the learned CPDAG cpdag = pc.graph_ print(f"Nodes: {list(cpdag.nodes)}") print(f"Edges: {list(cpdag.edges())}") print(f"Number of CI tests run: {pc.n_ci_tests}") print(f"Separating sets: {pc.separating_sets_}") # For ideal evaluation, use an Oracle with the true graph true_graph = nx.DiGraph([('x', 'y'), ('z', 'y'), ('z', 'w')]) oracle = Oracle(true_graph) pc_oracle = PC(ci_estimator=oracle) pc_oracle.learn_graph(data, context) oracle_cpdag = pc_oracle.graph_ ``` -------------------------------- ### Initialize FCI Algorithm for Discovery with Latents Source: https://context7.com/py-why/dodiscover/llms.txt The FCI algorithm handles latent confounders and selection bias, outputting a Partial Ancestral Graph (PAG). It requires specifying a conditional independence test, such as `FisherZCITest` or `KernelCITest`. ```python import numpy as np import pandas as pd from dodiscover import FCI, make_context from dodiscover.ci import FisherZCITest, KernelCITest ``` -------------------------------- ### Specify Base Nodes for Discovery Source: https://github.com/py-why/dodiscover/wiki/Knowledge-elicitation-through-"Context" Define the target nodes for causal discovery using the 'base_nodes' argument in the Context constructor. This helps focus the discovery on relevant variables. ```Python context = Context( base_nodes=("X", "Y", "Z") ) model = learn_graph(context, data, discovery_algo) ``` ```Python context = Context( base_nodes=data.columns ) ``` -------------------------------- ### Typing API Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst Defines custom types for use with mypy and third-party packages. ```APIDOC ## Typing API ### Description Defines custom types to enhance compatibility with static type checkers like mypy. ### Types - `Column` - `SeparatingSet` - `NetworkxGraph` ``` -------------------------------- ### Convert CPDAG to DAG Source: https://github.com/py-why/dodiscover/wiki/v0-API-[WIP] Convert a CPDAG (Cyclic Pattern Directed Acyclic Graph) to a DAG (Directed Acyclic Graph) for further analysis. ```python dag = cextend(cpdag) ``` -------------------------------- ### Learning Graph with Score Discoverer Source: https://github.com/py-why/dodiscover/wiki/v0-API-[WIP] Learn a causal graph using the score-based discoverer method. This function returns an equivalence class graph representation (CPDAG) by default. ```python cpdag = learn_graph( context, method=score_discoverer ) ``` -------------------------------- ### Builder Pattern for Treatments and Outcomes Source: https://github.com/py-why/dodiscover/wiki/Knowledge-elicitation-through-"Context" Use the builder pattern to create a Context object specifying treatments, outcomes, forced edges, and prevented edges for causal discovery. ```Python context = make_context() .treatments(...) .outcomes(...) .forced_edges(include_df) .prevented_edges(exclude_df) .build() ``` -------------------------------- ### SCORE Algorithm for Order-Based Discovery Source: https://context7.com/py-why/dodiscover/llms.txt Utilize the SCORE algorithm for causal discovery, which learns a topological ordering and then prunes a DAG. Requires data from an additive noise model (ANM). ```python import numpy as np import pandas as pd from dodiscover import make_context from dodiscover.toporder import SCORE, CAM, DAS, NoGAM np.random.seed(42) n_samples = 500 # True structure: x -> y, z -> y, z -> w x = np.random.randn(n_samples) z = np.random.randn(n_samples) y = 0.8 * x + 0.6 * z + np.random.randn(n_samples) * 0.3 w = 0.5 * z + np.random.randn(n_samples) * 0.4 data = pd.DataFrame({'x': x, 'y': y, 'z': z, 'w': w}) # Create context context = make_context().variables(data=data).build() # SCORE algorithm - uses Stein Hessian for ordering score = SCORE( eta_G=0.001, # regularization for gradient estimator eta_H=0.001, # regularization for Hessian estimator alpha=0.05, # significance for pruning prune=True, # apply CAM pruning n_splines=10, # splines for GAM fitting estimate_variance=False ) score.learn_graph(data, context) # Access results dag = score.graph_ order = score.order_ order_graph = score.order_graph_ # fully connected DAG from ordering print(f"Learned topological order: {order}") print(f"DAG edges (after pruning): {list(dag.edges())}") print(f"Order graph edges: {list(order_graph.edges())}") ``` -------------------------------- ### Conditional Independence Testing API Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst API for conditional independence testing. ```APIDOC ## Conditional Independence Testing API ### Description Provides an interface for conditional independence testing, a core component of constraint-based structure learning. ### Classes - `BaseConditionalIndependenceTest` - `Oracle` - `KernelCITest` - `GSquareCITest` - `FisherZCITest` - `ClassifierCITest` - `CMITest` - `ClassifierCMITest` - `CategoricalCITest` ``` -------------------------------- ### Use Oracle for Simulation Studies Source: https://context7.com/py-why/dodiscover/llms.txt The Oracle CI test is designed for simulation studies, leveraging d-separation on a known true graph to determine conditional independence. It returns a binary result (0 or 1). ```python import networkx as nx from dodiscover.ci import Oracle # Oracle for simulation studies - uses d-separation on true graph true_graph = nx.DiGraph([('x', 'y'), ('z', 'y')]) oracle = Oracle(true_graph) stat, pvalue = oracle.test(df, {'x'}, {'z'}, {'y'}) print(f"Oracle (x _||_ z | y): p-value={pvalue}") # returns 0 or 1 ``` -------------------------------- ### Graph protocols API Source: https://github.com/py-why/dodiscover/blob/main/doc/api.rst Defines graph protocols for representing causal structures. ```APIDOC ## Graph protocols API ### Description Defines protocols for graph representations used within the library. ### Protocols - `Graph` - `EquivalenceClass` ``` -------------------------------- ### Calculate Structural Hamming Distance (SHD) Source: https://context7.com/py-why/dodiscover/llms.txt Compute the Structural Hamming Distance between two Directed Acyclic Graphs (DAGs) to quantify differences in their structure. The `double_for_anticausal` parameter affects how edge reversals are counted. ```python import networkx as nx from dodiscover.metrics import structure_hamming_dist # True and predicted DAGs true_dag = nx.DiGraph([('x', 'y'), ('z', 'y'), ('z', 'w')]) pred_dag = nx.DiGraph([('x', 'y'), ('y', 'z'), ('z', 'w')]) # wrong z-y direction # Structural Hamming Distance (SHD) # Counts edge additions, deletions, and reversals shd = structure_hamming_dist(true_dag, pred_dag, double_for_anticausal=True) print(f"SHD (double for anticausal): {shd}") shd_single = structure_hamming_dist(true_dag, pred_dag, double_for_anticausal=False) print(f"SHD (single count for wrong direction): {shd_single}") ``` -------------------------------- ### Specify Included and Excluded Edges Source: https://github.com/py-why/dodiscover/wiki/Knowledge-elicitation-through-"Context" Use 'forced_edges' and 'excluded_edges' DataFrames to provide expert knowledge, including or excluding specific causal relationships to constrain the search space. ```Python context = Context( nodes=... forced_edges=include_df, excluded_edges=exclude_df ) ``` -------------------------------- ### Define ground truth graph edges Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Defines the edges for the ground truth causal graph using a list of tuples. ```python ground_truth_edges = [ ("A", "T"), ("T", "E"), ("L", "E"), ("S", "L"), ("S", "B"), ("B", "D"), ("E", "D"), ("E", "X") ] ground_truth = nx.DiGraph(ground_truth_edges) ``` -------------------------------- ### Define ground truth CPDAG components Source: https://github.com/py-why/dodiscover/blob/main/doc/tutorials/markovian/example-pc-algo.ipynb Constructs a CPDAG object representing the ground truth causal structure, separating directed and undirected edges. ```python cpdag_directed = [ ("T", "E"), ("L", "E"), ("B", "D"), ("E", "D"), ("E", "X") ] cpdag_undirected = [ ("A", "T"), ("S", "L"), ("S", "B"), ] ground_truth_cpdag = CPDAG(cpdag_directed, cpdag_undirected) ``` -------------------------------- ### Perform Kernel Conditional Independence Test Source: https://context7.com/py-why/dodiscover/llms.txt Employ the Kernel CI test for detecting non-linear relationships, suitable when data does not follow a Gaussian distribution. It supports various kernels and uses a Gamma approximation for speed. ```python from dodiscover.ci import KernelCITest # Kernel CI test for non-linear relationships kernel_test = KernelCITest( kernel_x='rbf', kernel_y='rbf', kernel_z='rbf', null_size=1000, approx_with_gamma=True, # faster Gamma approximation threshold=1e-5 ) stat, pvalue = kernel_test.test(df, {'x'}, {'y'}, {'z'}) print(f"Kernel CI: stat={stat:.4f}, p-value={pvalue:.4f}") ``` -------------------------------- ### Calculate Topological Order Divergence Source: https://context7.com/py-why/dodiscover/llms.txt Measure the divergence between a graph's topological ordering and a proposed ordering. This metric indicates how many edges are incompatible with the proposed order. Nodes must be relabeled to integers for comparison. ```python import networkx as nx from dodiscover.metrics import toporder_divergence # Topological order divergence # Measures how many edges are incompatible with a proposed ordering true_order = [0, 2, 1, 3] # corresponds to ['x', 'z', 'y', 'w'] wrong_order = [1, 0, 2, 3] # y before x and z - incompatible # Relabel nodes to integers for order comparison true_dag_int = nx.DiGraph([(0, 1), (2, 1), (2, 3)]) divergence = toporder_divergence(true_dag_int, true_order) print(f"Order divergence (compatible order): {divergence}") divergence_wrong = toporder_divergence(true_dag_int, wrong_order) print(f"Order divergence (incompatible order): {divergence_wrong}") ```