causal-learn

repository·main·Indexed 23 days ago

https://github.com/py-why/causal-learn

An open-source Python platform for causal discovery designed to recover causal structures from observational data. It provides implementations of constraint-based, score-based, permutation-based, and Granger causality methods, as well as constrained functional causal models (including LiNGAM, PNL, and ANM) and hidden causal representation learning. The library serves as a translation and extension of the Tetrad Java code and includes utilities for independence tests, score functions, and graph operations.

Tokens
16.3K
Snippets
46
Records
82
Agent score
82%

What's inside causal-learn

  1. Overview of causal-learn

    main

    causal-learn is a Python library that provides a translation and extension of the Tetrad Java code. It is designed to offer implementations of modern causal discovery methods through simple and intuitive APIs.

    Note: This project is under active development.

  2. Overview of Score-based causal discovery methods

    main

    The causal-learn library provides several score-based causal discovery methods for identifying causal structures. These methods use scoring functions to evaluate the quality of different graph structures.

    Available methods include:

    • GES (Greedy Equivalence Search): Implemented with the BIC score and a generalized score. GES is a standard approach for finding the best-scoring causal structure.
    • DGES: An extension of GES designed to handle data containing deterministic (functional) relationships among variables.
    • Exact Search: Methods that aim to find the globally optimal Bayesian network structure, specifically implementing DP (Dynamic Programming) and A* algorithms.
  3. Overview of causal-learn capabilities

    main

    Causal-learn is an open-source platform for causal discovery that aims to recover causal structures from observational data. It provides implementations for several categories of causal discovery methods:

    • Constraint-based causal discovery methods.
    • Score-based causal discovery methods.
    • Constrained functional causal models based methods.
    • Hidden causal representation learning.
    • Permutation-based causal discovery methods.
    • Granger causality.

    Additionally, the package provides utilities for building custom methods, including independence tests, score functions, graph operations, and evaluations.

  4. Constraint-based causal discovery methods overview

    main

    Constraint-based causal discovery methods in causal-learn identify causal structures by testing for conditional independence constraints in the data. This library provides implementations for several key algorithms:

    • PC: A standard algorithm for discovering causal structures in the presence of observed variables.
    • FCI (Fast Causal Inference): An algorithm designed to handle causal discovery in the presence of latent (unobserved) variables and selection bias.
    • CD-NOD (Causal Discovery from Non-stationary Data): An algorithm specifically designed for causal discovery from heterogeneous or non-stationary data.
  5. Available score functions in causal-learn

    main

    The causal-learn library provides several score functions used for causal discovery and model selection. Currently supported score functions include:

    • BIC score: Bayesian Information Criterion.
    • BDeu score: Bayesian Dirichlet equivalent uniform score.
    • Generalized score functions: Includes scores based on cross-validation or marginal likelihood.
  6. Explore causal discovery methods based on constrained functional causal models

    main

    The causal-learn library provides several causal discovery methods categorized under constrained functional causal models. These methods are used to identify causal structures by leveraging specific assumptions about the functional forms and noise distributions of the causal mechanisms.

    Available method categories include:

    • LiNGAM-based methods: Methods utilizing Linear Non-Gaussian Acyclic Models. Specific implementations include:
      • ICA-based LiNGAM
      • DirectLiNGAM
      • VAR-LiNGAM
      • RCD (Repetitive causal discovery with latent confounders)
      • CAM-UV (Causal Additive Models with Unobserved Variables)
    • Post-nonlinear (PNL) causal models: Methods designed for post-nonlinear causal structures.
    • Additive noise models (ANM): Methods for nonlinear causal discovery using additive noise assumptions.
  7. Understand the CausalGraph output format

    main

    The pc function returns a CausalGraph object (cg). The underlying graph structure is accessible via cg.G. The adjacency matrix values indicate the type of relationship between nodes i and j:

    • cg.G.graph[j,i]=1 and cg.G.graph[i,j]=-1 $\implies$ i --> j (Directed edge)
    • cg.G.graph[i,j] = cg.G.graph[j,i] = -1 $\implies$ i --- j (Undirected edge)
    • cg.G.graph[i,j] = cg.G.graph[j,i] = 1 $\implies$ i <-> j (Bi-directed edge)
  8. Inspect latent variables in RLCD results

    main

    The CausalGraph returned by RLCD includes both observed and detected latent variables. Observed variables appear first in the variable list, followed by latent variables named L1, L2, etc.

    To identify latent nodes, iterate through the graph nodes and check if their type is NodeType.LATENT. RLCD also attaches several useful attributes to the returned object:

    • cg.stage1_cg: The stage-1 graph over observed variables.
    • cg.adjacency: The full adjacency matrix including observed and latent variables.
    • cg.all_vars: A list of all variable names (observed followed by latent).
    from causallearn.graph.NodeType import NodeType
    
    # Find latent nodes
    latent_nodes = [
        node for node in cg.G.get_nodes()
        if node.get_node_type() == NodeType.LATENT
    ]
    
    print([node.get_name() for node in latent_nodes])
    print(cg.all_vars)
  9. Understand the CD-NOD CausalGraph output format

    main

    The cdnod function returns a CausalGraph object. The underlying graph structure cg.G.graph uses the following integer encoding to represent edges between nodes i and j:

    • i --> j: cg.G.graph[j,i]=1 and cg.G.graph[i,j]=-1
    • i --- j (undirected): cg.G.graph[i,j] = cg.G.graph[j,i] = -1
    • i <-> j (bi-directed): cg.G.graph[i,j] = cg.G.graph[j,i] = 1
  10. Assign colors to nodes by category

    main

    You can group features into categories to automatically assign a unique color to each group. This is useful for distinguishing between different types of variables (e.g., 'treatment' vs 'outcome').

    When using category_to_features, if you do not provide a labels list, the node labels are automatically derived by flattening the category dictionary in order.

    Example:

    category_to_features = {
        'demographics': ['Age', 'Education'],
        'financial': ['Income', 'Spending'],
    }
    GraphUtils.plot_graph(Record['G'], category_to_features=category_to_features)
    category_to_features = {
        'demographics': ['Age', 'Education'],
        'financial': ['Income', 'Spending'],
    }
    GraphUtils.plot_graph(Record['G'],
                          category_to_features=category_to_features,
                          title='Causal Graph by Category',
                          save_path='graph_by_category.png')
  11. Cache p-values to speed up PC algorithm runs

    main

    If your dataset is large or you are using computationally expensive independence tests (like kci), you can use the cache_path parameter to save p-value results to a .json file.

    This allows you to resume discovery or fine-tune other parameters (like uc_rule) without re-calculating the independence tests. The algorithm will check the data and parameter hashes to ensure consistency. The cache is saved to the local file every 30 seconds during runtime.

    from causallearn.search.ConstraintBased.PC import pc
    from causallearn.utils.cit import kci
    
    # Define a path for the JSON cache file
    citest_cache_file = "/my/path/to/citest_cache_dataname_kci.json"
    
    # First run: performs full calculation and creates the cache
    cg1 = pc(data, 0.05, kci, cache_path=citest_cache_file)
    
    # Subsequent run: reuses p-values from the cache to quickly test a different uc_rule
    cg2 = pc(data, 0.05, kci, cache_path=citest_cache_file, uc_rule=1)