diff --git a/docs/source/discovery_methods/LaHiCaSI/LaHiCaSI.rst b/docs/source/discovery_methods/LaHiCaSI/LaHiCaSI.rst new file mode 100644 index 0000000..c4fd156 --- /dev/null +++ b/docs/source/discovery_methods/LaHiCaSI/LaHiCaSI.rst @@ -0,0 +1,57 @@ +LaHiCaSI (Latent Hierarchical Causal Structure Learning) +========================================================== + +Introduction +------------ + +LaHiCaSI is a causal discovery method that focuses on learning hierarchical causal structures in the presence of latent variables. It operates in two main phases: first locating latent variables by identifying causal clusters, and then inferring the causal structure among these latent variables. + +Usage +----- + +.. code-block:: python + + from cdmir.discovery.LaHiCaSl.LaHiCaSl import Latent_Hierarchical_Causal_Structure_Learning + import pandas as pd + import numpy as np + + # Load or generate your dataset + # Example: Generate random data with 10 variables and 1000 samples + data = pd.DataFrame(np.random.randn(1000, 10), columns=[f'X{i}' for i in range(10)]) + + # Set significance level + alpha = 0.05 + + # Run LaHiCaSI algorithm + Latent_Hierarchical_Causal_Structure_Learning(data, alpha) + +Parameters +---------- + +- **data**: Dataset of observed variables, typically a pandas DataFrame or numpy array. +- **alpha**: Statistical significance threshold (default: 0.05), used to determine the significance of causal relationships during the learning process. + +Returns +------- + +The function prints the resulting causal structure in the form of an adjacency matrix. It also generates intermediate results during the two-phase learning process. + +Algorithm Overview +------------------ + +LaHiCaSI consists of two main phases: + +1. **Phase I: Locate latent variables** + - **Stage I-S1**: Identify global causal clusters using `IdentifyGlobalCausalClusters` + - **Stage I-S2**: Determine latent variables by merging clusters using `Determine_Latent_Variables` + - **Stage I-S3**: Update active data and cluster information using `UpdateActiveData` + +2. **Phase II: Infer causal structure among latent variables** + - Use `LocallyInferCausalStructure` to learn the causal relationships between the identified latent variables + +The algorithm iteratively identifies clusters of variables that share common latent causes, updates the data representation to include these latent variables, and then infers the causal structure among them. + +References +---------- + +[1] Xie F, Huang B, Chen Z, et al. Generalized independent noise condition for estimating causal structure with latent variables[J]. Journal of Machine Learning Research, 2024, 25(191): 1-61. \ No newline at end of file diff --git a/docs/source/discovery_methods/LaHiCaSI/index.rst b/docs/source/discovery_methods/LaHiCaSI/index.rst new file mode 100644 index 0000000..0f8b862 --- /dev/null +++ b/docs/source/discovery_methods/LaHiCaSI/index.rst @@ -0,0 +1,7 @@ +LaHiCaSI (Latent Hierarchical Causal Structure Learning) +================= + +.. toctree:: + :maxdepth: 2 + + LaHiCaSI \ No newline at end of file diff --git a/docs/source/discovery_methods/constraint/index.rst b/docs/source/discovery_methods/constraint/index.rst index e43d7c7..975a851 100644 --- a/docs/source/discovery_methods/constraint/index.rst +++ b/docs/source/discovery_methods/constraint/index.rst @@ -9,3 +9,8 @@ Constraint-based :maxdepth: 2 PBSCM_PGF/pbscm_pgf + +.. toctree:: + :maxdepth: 2 + + pc/pc \ No newline at end of file diff --git a/docs/source/discovery_methods/constraint/pc/pc.rst b/docs/source/discovery_methods/constraint/pc/pc.rst new file mode 100644 index 0000000..779497d --- /dev/null +++ b/docs/source/discovery_methods/constraint/pc/pc.rst @@ -0,0 +1,55 @@ +PC (Peter-Clark Algorithm) +========================== + +Introduction +------------ + +PC is a constraint-based causal discovery algorithm that infers causal relationships between variables from observational data. It starts with a complete undirected graph and iteratively removes edges based on conditional independence tests, then applies a set of rules to orient edges, resulting in a Partially Directed Acyclic Graph (PDAG) that represents causal relationships. + +Usage +----- + +.. code-block:: python + + from cdmir.discovery.constraint.pc import PC + from cdmir.utils.independence import ConditionalIndependentTest + + # Initialize PC algorithm with default parameters + pc = PC(alpha=0.05, verbose=False) + + # Fit the model to data + pc.fit(data, var_names, ConditionalIndependentTest) + + # Access results + causal_graph = pc.causal_graph + skeleton = pc.skeleton + sep_set = pc.sep_set + +Parameters +---------- + +PC Class Parameters: + +- alpha: Significance level for independence tests (default: 0.05) +- adjacency_search_method: Function for adjacency search phase (default: adjacency_search) +- verbose: Whether to print algorithm progress (default: False) + +fit() Method Parameters: + +- data: Input dataset containing variable observations +- var_names: List of variable names corresponding to the columns in data +- indep_cls: Conditional independence test class implementing the ConditionalIndependentTest interface +- args: Positional arguments passed to the independence test constructor +- kwargs: Keyword arguments passed to the independence test constructor + +Returns +------- + +- causal_graph: Partially Directed Acyclic Graph (PDAG) representing inferred causal relationships +- skeleton: Undirected graph representing the skeleton of causal relationships +- sep_set: Separation sets for node pairs, stored as a dictionary where keys are node pairs and values are sets of separating nodes + +References +---------- + +[1] Spirtes, P., Glymour, C. N., Scheines, R., & Heckerman, D. (2000). Causation, prediction, and search. MIT press. \ No newline at end of file diff --git a/docs/source/discovery_methods/functional_based/OLC/olc.rst b/docs/source/discovery_methods/functional_based/OLC/olc.rst index 7fe296a..3f851ed 100644 --- a/docs/source/discovery_methods/functional_based/OLC/olc.rst +++ b/docs/source/discovery_methods/functional_based/OLC/olc.rst @@ -1,2 +1,93 @@ -OLC (One latent Component) -================================= \ No newline at end of file +OLC (One-Component Latent Confounder Detection) +==================================================== + +Introduction +------------ + +OLC is a functional-based causal discovery method that detects latent confounders using higher-order cumulants. Based on the paper "Causal Discovery with Latent Confounders Based on Higher-Order Cumulants", this algorithm identifies causal relationships and latent confounders by leveraging the properties of higher-order cumulants and conditional independence tests. + +Usage +----- + +.. code-block:: python + + import numpy as np + from cdmir.discovery.funtional_based.one_component.olc import olc + + # Generate or load data + # Example: 1000 samples, 5 variables + data = np.random.randn(1000, 5) + + # Set significance thresholds + alpha = 0.05 # Primary significance level + beta = 0.01 # Secondary significance level for more stringent tests + + # Run OLC algorithm + adjmat, coef = olc(data, alpha=alpha, beta=beta, verbose=False) + + # Print results + print("Adjacency Matrix:") + print(adjmat) + print("\nCoefficient Matrix:") + print(coef) + +Parameters +---------- + +- **data**: Input data matrix of shape (n_samples, n_variables), where rows represent samples and columns represent variables. +- **alpha**: Significance threshold for initial edge orientation tests (default: 0.05). +- **beta**: Significance threshold for more stringent tests involving higher-order cumulants (default: 0.01). +- **verbose**: If True, prints detailed information during the algorithm execution (default: False). + +Returns +------- + +- **adjmat**: Adjacency matrix of the discovered causal graph. The matrix has shape (n_variables + n_latents, n_variables + n_latents), where: + - 0: No edge + - 1: Directed edge + - 2: Undirected edge (ambiguous direction) + - Latent variables are indexed from n_variables onwards. + +- **coef**: Coefficient matrix of the discovered causal relationships. It has the same shape as adjmat and contains the estimated coefficients for each directed edge. + +Algorithm Overview +------------------ + +OLC follows a structured approach to causal discovery with latent confounder detection: + +1. **Initialization** + - Create an undirected graph (UDG) with all possible edges + - Create an empty directed graph (CG) for causal relationships + - Initialize KCI (Kernel-based Conditional Independence) test for independence testing + +2. **Edge Orientation Phase** + - Test edge orientations using linear regression and KCI tests + - Remove edges and orient them in the directed graph based on significance tests + - Normalize residuals and update data + +3. **Clique Detection and Latent Confounder Detection** + - Identify cliques in the undirected graph + - Use surrogate regression to handle complex relationships + - Apply higher-order cumulant (4th order) analysis to detect latent confounders + - Update the adjacency matrix with detected latent confounders + +4. **Refinement** + - Iteratively refine the graph structure using conditional independence tests + - Update surrogate variables and exogenous variables + - Adjust edge orientations based on cumulant-based tests + +Key Techniques +-------------- + +- **Higher-Order Cumulants**: Uses 4th order cumulants to detect latent confounders that cannot be identified using traditional covariance-based methods. + +- **KCI Tests**: Employs Kernel-based Conditional Independence tests for robust independence testing between variables and residuals. + +- **Surrogate Regression**: Implements surrogate regression to handle complex causal relationships involving multiple variables. + +- **Fisher's Combination Test**: Combines multiple p-values to enhance statistical power. + +References +---------- + +.. [1] Cai R, Huang Z, Chen W, et al. Causal discovery with latent confounders based on higher-order cumulants[C]//International conference on machine learning. PMLR, 2023: 3380-3407. \ No newline at end of file diff --git a/docs/source/discovery_methods/index.rst b/docs/source/discovery_methods/index.rst index cf82edc..8ac5baf 100644 --- a/docs/source/discovery_methods/index.rst +++ b/docs/source/discovery_methods/index.rst @@ -9,3 +9,4 @@ In this section, we introduce discovery methods implemented in CDMIR. Constraint-based methods Functional-based methods Tensor-Rank methods + LaHiCaSI diff --git a/docs/source/effect_methods/DoublyRobust/DoublyRobust.rst b/docs/source/effect_methods/DoublyRobust/DoublyRobust.rst new file mode 100644 index 0000000..8f4e39f --- /dev/null +++ b/docs/source/effect_methods/DoublyRobust/DoublyRobust.rst @@ -0,0 +1,169 @@ +Doubly Robust Estimator +======================= + +Introduction +------------ + +The Doubly Robust Estimator is a causal effect estimation method that combines outcome regression and propensity score weighting. It is "doubly robust" because it only requires one of the two components (either the outcome model or the propensity score model) to be correctly specified for consistent estimation of the Average Treatment Effect (ATE). + +This implementation provides two versions: + +1. **Basic Doubly Robust Estimator**: A traditional implementation that works with tabular data. +2. **Network-Aware Doubly Robust Estimator**: An advanced implementation that incorporates network structure information using GCN encoders and B-spline components. + +Usage +----- + +Basic Doubly Robust Estimator +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: python + + from cdmir.effect.ate_estimator import double_robust_estimator + import numpy as np + from sklearn.linear_model import LinearRegression + + # Generate sample data + n, p = 1000, 5 + X = np.random.normal(1, 1, (n, p)) + T = np.random.binomial(1, 0.5, n) + tau = X[:, 0] + y0 = X @ np.array([1, 2, 0, 0, 0]) + np.random.normal(0, 1, n) + y1 = y0 + tau + Y = T * y1 + (1 - T) * y0 + T, Y = T[:, None], Y[:, None] + + # Estimate ATE using basic Doubly Robust Estimator + tau_dr = double_robust_estimator(X, T, Y, outcome_model=LinearRegression()) + print(f"Estimated ATE: {tau_dr}") + +Network-Aware Doubly Robust Estimator +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: python + + import torch + from cdmir.effect.DoublyRobust.src.targetedModel_DoubleBSpline import TargetedModel_DoubleBSpline + + # Generate sample network data + batch_size = 100 + Xshape = 5 + hidden = 32 + dropout = 0.1 + + # Adjacency matrix (batch_size x batch_size) + A = torch.rand(batch_size, batch_size) > 0.8 + A = A.float().cuda() + + # Individual features (batch_size x Xshape) + X = torch.randn(batch_size, Xshape).cuda() + + # Treatment variables (batch_size) + T = torch.randint(0, 2, (batch_size,)).cuda() + + # Initialize the network-aware Doubly Robust model + model = TargetedModel_DoubleBSpline(Xshape=Xshape, hidden=hidden, dropout=dropout).cuda() + + # Forward pass to get model outputs + g_T_hat, g_Z_hat, Q_hat, epsilon, embeddings, neighborAverageT = model(A, X, T) + + # Infer potential outcomes + potential_outcomes = model.infer_potential_outcome(A, X, T) + +Parameters +---------- + +Basic Doubly Robust Estimator Parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- **X**: numpy.ndarray, input data of shape (n_samples, n_features) + Covariates for each sample. + +- **T**: numpy.ndarray, treatment indicator of shape (n_samples,) or (n_samples, 1) + Binary treatment assignment (1 for treated, 0 for control). + +- **Y**: numpy.ndarray, outcome of shape (n_samples,) or (n_samples, 1) + Outcome variable of interest. + +- **outcome_model**: sklearn estimator, default=LinearRegression() + Regression model used to estimate the potential outcomes. + +Network-Aware Doubly Robust Estimator Parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- **Xshape**: int + Input feature dimension. + +- **hidden**: int + Hidden layer dimension for neural network components. + +- **dropout**: float + Dropout probability for regularization. + +- **num_grid**: int, default=None + Number of B-spline grids (defaults to 20). + +- **init_weight**: bool, default=True + Whether to initialize weights. + +- **tr_knots**: float, default=0.25 + Knot density for truncated power basis. + +Forward Method Parameters (Network-Aware) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- **A**: torch.tensor, adjacency matrix of shape (batch_size, batch_size) + Network adjacency matrix. + +- **X**: torch.tensor, individual features of shape (batch_size, Xshape) + Covariate features for each node. + +- **T**: torch.tensor, treatment variables of shape (batch_size) + Binary treatment assignment for each node. + +- **Z**: torch.tensor, neighbor exposure variables of shape (batch_size), optional + Pre-computed neighbor exposure (defaults to average of neighbors' treatments). + +Returns +------- + +Basic Doubly Robust Estimator Returns +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- **tau**: float + Estimated Average Treatment Effect (ATE). + +Network-Aware Doubly Robust Estimator Returns +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Forward Method Returns +^^^^^^^^^^^^^^^^^^^^^^ + +- **g_T_hat**: torch.tensor + Estimated treatment propensity scores. + +- **g_Z_hat**: torch.tensor + Estimated neighbor exposure probabilities. + +- **Q_hat**: torch.tensor + Estimated potential outcomes. + +- **epsilon**: torch.tensor + Perturbation terms for bias correction. + +- **embeddings**: torch.tensor + Node embeddings from GCN encoder. + +- **neighborAverageT**: torch.tensor + Average treatment of neighbors. + +Infer Potential Outcome Method Returns +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- **potential_outcomes**: torch.tensor + Adjusted potential outcomes with doubly robust correction. + +References +---------- + +.. [1] Chen W, Cai R, Yang Z, et al. Doubly robust causal effect estimation under networked interference via targeted learning[J]. arXiv preprint arXiv:2405.03342, 2024. \ No newline at end of file diff --git a/docs/source/effect_methods/DoublyRobust/index.rst b/docs/source/effect_methods/DoublyRobust/index.rst new file mode 100644 index 0000000..e2dee75 --- /dev/null +++ b/docs/source/effect_methods/DoublyRobust/index.rst @@ -0,0 +1,7 @@ +DoublyRobust +================= + +.. toctree:: + :maxdepth: 2 + + DoublyRobust diff --git a/docs/source/effect_methods/OTCI/OTCI.rst b/docs/source/effect_methods/OTCI/OTCI.rst new file mode 100644 index 0000000..a123413 --- /dev/null +++ b/docs/source/effect_methods/OTCI/OTCI.rst @@ -0,0 +1,106 @@ +OTCI (Optimal Transport-based Causal Inference) +================================================ + +Introduction +------------ + +OTCI is an Optimal Transport-based Causal Inference method for estimating the Average Treatment Effect on the Treated (ATT). It leverages optimal transport theory to construct weights for control group samples that best match the distribution of the treatment group samples. + +The algorithm provides two modes: + +1. **Basic Mode**: Uses only feature distance information +2. **GW-Enhanced Mode**: Incorporates Gromov-Wasserstein (GW) distance to preserve geometric structure in the data + +OTCI is implemented with CUDA acceleration for efficient computation on large datasets. + +Usage +----- + +.. code-block:: python + + import torch + from cdmir.effect.OTCI.src.otci import optimal_transport_weighting + + # Generate or load data (ensure data is on CUDA) + X_t = torch.randn(100, 10).cuda() # Treatment group features + X_c = torch.randn(200, 10).cuda() # Control group features + Y_t = torch.randn(100).cuda() # Treatment group outcomes + Y_c = torch.randn(200).cuda() # Control group outcomes + + # Basic usage with default parameters + pred_att, weights, transport_matrix = optimal_transport_weighting(X_t, X_c, Y_t, Y_c) + print(f"Estimated ATT: {pred_att.item()}") + + # Advanced usage with GW distance and custom parameters + pred_att, weights, transport_matrix = optimal_transport_weighting( + X_t, X_c, Y_t, Y_c, + gamma=1e-4, # Negative entropy regularization strength + eta_base=0.5, # Initial learning rate + eta_update_steps=20, # Learning rate update frequency + decay_rate=0.98, # Learning rate decay rate + max_iter=500, # Maximum number of iterations + abstol=1e-3, # Early stopping threshold + eps=1e-5, # Small value to avoid log(0) + with_GW=True, # Enable GW distance + alpha=0.95 # Weight between original cost and GW distance + ) + print(f"Estimated ATT with GW: {pred_att.item()}") + +Parameters +---------- + +- **X_t**: torch.Tensor, treatment group features of shape (n_t, d) + Features of samples in the treatment group. + +- **X_c**: torch.Tensor, control group features of shape (n_c, d) + Features of samples in the control group. + +- **Y_t**: torch.Tensor, treatment group outcomes of shape (n_t,) + Outcome values for samples in the treatment group. + +- **Y_c**: torch.Tensor, control group outcomes of shape (n_c,) + Outcome values for samples in the control group. + +- **gamma**: float, default=0.1 + Strength of negative entropy regularization. + +- **eta_base**: float, default=0.01 + Initial learning rate for updating the transport matrix. + +- **eta_update_steps**: int, default=10 + Frequency at which the learning rate is updated. + +- **decay_rate**: float, default=0.95 + Decay rate for the learning rate. + +- **max_iter**: int, default=2000 + Maximum number of iterations for the optimization process. + +- **abstol**: float, default=1e-5 + Early stopping threshold based on the absolute difference between consecutive transport matrices. + +- **eps**: float, default=1e-3 + Small value added to avoid log(0) operations. + +- **with_GW**: bool, default=True + Whether to incorporate Gromov-Wasserstein distance in the optimization. + +- **alpha**: float, default=0.1 + Weight parameter balancing the original cost and GW distance when with_GW is True. + +Returns +------- + +- **pred_att**: torch.Tensor, scalar + Estimated Average Treatment Effect on the Treated (ATT). + +- **weights**: torch.Tensor, shape (n_c,) + Optimal weights assigned to control group samples. + +- **transport_matrix**: torch.Tensor, shape (n_c, n_t) + Final optimal transport matrix between control and treatment groups. + +References +---------- + +.. [1] Yan Y, Yang Z, Chen W, et al. Exploiting geometry for treatment effect estimation via optimal transport[C]//Proceedings of the AAAI Conference on Artificial Intelligence. 2024, 38(15): 16290-16298. \ No newline at end of file diff --git a/docs/source/effect_methods/OTCI/index.rst b/docs/source/effect_methods/OTCI/index.rst new file mode 100644 index 0000000..f30b608 --- /dev/null +++ b/docs/source/effect_methods/OTCI/index.rst @@ -0,0 +1,7 @@ +OTCI (Optimal Transport Causal Inference) +================= + +.. toctree:: + :maxdepth: 2 + + OTCI \ No newline at end of file diff --git a/docs/source/effect_methods/index.rst b/docs/source/effect_methods/index.rst index 61f14f6..d506336 100644 --- a/docs/source/effect_methods/index.rst +++ b/docs/source/effect_methods/index.rst @@ -3,3 +3,8 @@ Effect methods In this section, we introduce effect methods implemented in CDMIR. +.. toctree:: + :maxdepth: 2 + + Doubly Robust Estimator + OTCI \ No newline at end of file