From d17f4c5aa84fae071cc67d54c324575e9e5dd160 Mon Sep 17 00:00:00 2001 From: Bryan Andrews Date: Sat, 23 Nov 2024 10:52:55 -0600 Subject: [PATCH 1/2] updated and added documentation for grasp and boss respectively --- causallearn/search/PermutationBased/BOSS.py | 16 ++--- causallearn/search/PermutationBased/GRaSP.py | 16 ++--- .../GRaSP.rst | 6 +- .../boss.rst | 68 +++++++++++++++++++ 4 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 docs/source/search_methods_index/Permutation-based causal discovery methods/boss.rst diff --git a/causallearn/search/PermutationBased/BOSS.py b/causallearn/search/PermutationBased/BOSS.py index 465d3659..85551b8e 100644 --- a/causallearn/search/PermutationBased/BOSS.py +++ b/causallearn/search/PermutationBased/BOSS.py @@ -53,7 +53,7 @@ def boss( if n < p: warnings.warn("The number of features is much larger than the sample size!") - if score_func == "local_score_CV_general": + if score_func == "local_score_CV_general": # % k-fold negative cross validated likelihood based on regression in RKHS if parameters is None: parameters = { @@ -63,13 +63,13 @@ def boss( localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_cv_general, parameters=parameters ) - elif score_func == "local_score_marginal_general": + elif score_func == "local_score_marginal_general": # negative marginal likelihood based on regression in RKHS parameters = {} localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_marginal_general, parameters=parameters ) - elif score_func == "local_score_CV_multi": + elif score_func == "local_score_CV_multi": # k-fold negative cross validated likelihood based on regression in RKHS # for data with multi-variate dimensions if parameters is None: @@ -83,7 +83,7 @@ def boss( localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_cv_multi, parameters=parameters ) - elif score_func == "local_score_marginal_multi": + elif score_func == "local_score_marginal_multi": # negative marginal likelihood based on regression in RKHS # for data with multi-variate dimensions if parameters is None: @@ -93,7 +93,7 @@ def boss( localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_marginal_multi, parameters=parameters ) - elif score_func == "local_score_BIC": + elif score_func == "local_score_BIC": # SEM BIC score warnings.warn("Please use 'local_score_BIC_from_cov' instead") if parameters is None: @@ -101,14 +101,14 @@ def boss( localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_BIC, parameters=parameters ) - elif score_func == "local_score_BIC_from_cov": + elif score_func == "local_score_BIC_from_cov": # SEM BIC score if parameters is None: parameters = {"lambda_value": 2} localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_BIC_from_cov, parameters=parameters ) - elif score_func == "local_score_BDeu": + elif score_func == "local_score_BDeu": # BDeu score localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_BDeu, parameters=None @@ -204,4 +204,4 @@ def better_mutation(v, order, gsts): order.remove(v) order.insert(best - int(best > i), v) - return True \ No newline at end of file + return True diff --git a/causallearn/search/PermutationBased/GRaSP.py b/causallearn/search/PermutationBased/GRaSP.py index f4d4aa14..2ac106bd 100644 --- a/causallearn/search/PermutationBased/GRaSP.py +++ b/causallearn/search/PermutationBased/GRaSP.py @@ -16,7 +16,7 @@ local_score_marginal_general, local_score_marginal_multi, ) -from causallearn.search.PermutationBased.gst import GST; +from causallearn.search.PermutationBased.gst import GST from causallearn.score.LocalScoreFunctionClass import LocalScoreClass from causallearn.utils.DAG2CPDAG import dag2cpdag @@ -111,7 +111,7 @@ def grasp( if n < p: warnings.warn("The number of features is much larger than the sample size!") - if score_func == "local_score_CV_general": + if score_func == "local_score_CV_general": # k-fold negative cross validated likelihood based on regression in RKHS if parameters is None: parameters = { @@ -127,7 +127,7 @@ def grasp( localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_marginal_general, parameters=parameters ) - elif score_func == "local_score_CV_multi": + elif score_func == "local_score_CV_multi": # k-fold negative cross validated likelihood based on regression in RKHS # for data with multi-variate dimensions if parameters is None: @@ -141,7 +141,7 @@ def grasp( localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_cv_multi, parameters=parameters ) - elif score_func == "local_score_marginal_multi": + elif score_func == "local_score_marginal_multi": # negative marginal likelihood based on regression in RKHS # for data with multi-variate dimensions if parameters is None: @@ -151,7 +151,7 @@ def grasp( localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_marginal_multi, parameters=parameters ) - elif score_func == "local_score_BIC": + elif score_func == "local_score_BIC": # SEM BIC score warnings.warn("Please use 'local_score_BIC_from_cov' instead") if parameters is None: @@ -159,14 +159,14 @@ def grasp( localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_BIC, parameters=parameters ) - elif score_func == "local_score_BIC_from_cov": + elif score_func == "local_score_BIC_from_cov": # SEM BIC score if parameters is None: parameters = {"lambda_value": 2} localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_BIC_from_cov, parameters=parameters ) - elif score_func == "local_score_BDeu": + elif score_func == "local_score_BDeu": # BDeu score localScoreClass = LocalScoreClass( data=X, local_score_fun=local_score_BDeu, parameters=None @@ -204,7 +204,7 @@ def grasp( sys.stdout.flush() runtime = time.perf_counter() - runtime - + if verbose: sys.stdout.write("\nGRaSP completed in: %.2fs \n" % runtime) sys.stdout.flush() diff --git a/docs/source/search_methods_index/Permutation-based causal discovery methods/GRaSP.rst b/docs/source/search_methods_index/Permutation-based causal discovery methods/GRaSP.rst index 1e80fb6a..a36080f2 100644 --- a/docs/source/search_methods_index/Permutation-based causal discovery methods/GRaSP.rst +++ b/docs/source/search_methods_index/Permutation-based causal discovery methods/GRaSP.rst @@ -6,7 +6,7 @@ GRaSP Algorithm Introduction -------------------------------------- -Greedy relaxation of the sparsest permutation (GRaSP) algorithm [1]_. +Greedy relaxations of the sparsest permutation (GRaSP) algorithm [1]_. Usage @@ -19,7 +19,7 @@ Usage G = grasp(X) # or customized parameters - G = grasp(X, score_func, depth, maxP, parameters) + G = grasp(X, score_func, depth, parameters) # Visualization using pydot from causallearn.utils.GraphUtils import GraphUtils @@ -50,8 +50,6 @@ and n_features is the number of features. - ":ref:`local_score_CV_multi `": Generalized score with cross validation for data with multi-dimensional variables [2]_. - ":ref:`local_score_marginal_multi `": Generalized score with marginal likelihood for data with multi-dimensional variables [2]_. -**maxP**: Allowed maximum number of parents when searching the graph. Default: None. - **parameters**: Needed when using CV likelihood. Default: None. - parameters['kfold']: k-fold cross validation. - parameters['lambda']: regularization parameter. diff --git a/docs/source/search_methods_index/Permutation-based causal discovery methods/boss.rst b/docs/source/search_methods_index/Permutation-based causal discovery methods/boss.rst new file mode 100644 index 00000000..0e9ba440 --- /dev/null +++ b/docs/source/search_methods_index/Permutation-based causal discovery methods/boss.rst @@ -0,0 +1,68 @@ +.. _GRaSP: + +GRaSP +============================================== + +Algorithm Introduction +-------------------------------------- + +Best order score search (BOSS) algorithm [1]_. + + +Usage +---------------------------- +.. code-block:: python + + from causallearn.search.PermutationBased.BOSS import boss + + # default parameters + G = boss(X) + + # or customized parameters + G = boss(X, score_func, parameters) + + # Visualization using pydot + from causallearn.utils.GraphUtils import GraphUtils + import matplotlib.image as mpimg + import matplotlib.pyplot as plt + import io + + pyd = GraphUtils.to_pydot(G) + tmp_png = pyd.create_png(f="png") + fp = io.BytesIO(tmp_png) + img = mpimg.imread(fp, format='png') + plt.axis('off') + plt.imshow(img) + plt.show() + +Visualization using pydot is recommended (`usage example `_). If specific label names are needed, please refer to this `usage example `_ (e.g., GraphUtils.to_pydot(G, labels=["A", "B", "C"]). + +Parameters +------------------- +**X**: numpy.ndarray, shape (n_samples, n_features). Data, where n_samples is the number of samples +and n_features is the number of features. + +**score_func**: The score function you would like to use, including (see :ref:`score_functions`.). Default: 'local_score_BIC'. + - ":ref:`local_score_BIC `": BIC score [3]_. + - ":ref:`local_score_BDeu `": BDeu score [4]_. + - ":ref:`local_score_CV_general `": Generalized score with cross validation for data with single-dimensional variables [2]_. + - ":ref:`local_score_marginal_general `": Generalized score with marginal likelihood for data with single-dimensional variables [2]_. + - ":ref:`local_score_CV_multi `": Generalized score with cross validation for data with multi-dimensional variables [2]_. + - ":ref:`local_score_marginal_multi `": Generalized score with marginal likelihood for data with multi-dimensional variables [2]_. + +**parameters**: Needed when using CV likelihood. Default: None. + - parameters['kfold']: k-fold cross validation. + - parameters['lambda']: regularization parameter. + - parameters['dlabel']: for variables with multi-dimensions, indicate which dimensions belong to the i-th variable. + + + +Returns +------------------- +- **G**: learned general graph, where G.graph[j,i]=1 and G.graph[i,j]=-1 indicate i --> j; G.graph[i,j] = G.graph[j,i] = -1 indicates i --- j. + + +.. [1] Andrews, B., Ramsey, J., Sanchez Romero, R., Camchong, J., & Kummerfeld, E. (2023). Fast scalable and accurate discovery of dags using the best order score search and grow shrink trees. Advances in Neural Information Processing Systems, 36, 63945-63956. +.. [2] Huang, B., Zhang, K., Lin, Y., Schölkopf, B., & Glymour, C. (2018, July). Generalized score functions for causal discovery. In Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining (pp. 1551-1560). +.. [3] Schwarz, G. (1978). Estimating the dimension of a model. The annals of statistics, 461-464. +.. [4] Buntine, W. (1991). Theory refinement on Bayesian networks. In Uncertainty proceedings 1991 (pp. 52-60). Morgan Kaufmann. From 2933d13fed7c85cada728dabe3025b0adeeedf9c Mon Sep 17 00:00:00 2001 From: Bryan Andrews Date: Sat, 23 Nov 2024 10:55:02 -0600 Subject: [PATCH 2/2] fixing typo in boss docs --- .../Permutation-based causal discovery methods/boss.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/search_methods_index/Permutation-based causal discovery methods/boss.rst b/docs/source/search_methods_index/Permutation-based causal discovery methods/boss.rst index 0e9ba440..0436e80e 100644 --- a/docs/source/search_methods_index/Permutation-based causal discovery methods/boss.rst +++ b/docs/source/search_methods_index/Permutation-based causal discovery methods/boss.rst @@ -1,6 +1,6 @@ -.. _GRaSP: +.. _BOSS: -GRaSP +BOSS ============================================== Algorithm Introduction