{"id":19437714,"url":"https://github.com/renovamen/pcalg-py","last_synced_at":"2025-09-08T00:05:50.805Z","repository":{"id":41317925,"uuid":"161022262","full_name":"Renovamen/pcalg-py","owner":"Renovamen","description":"Implement PC algorithm in Python | PC 算法的 Python 实现","archived":false,"fork":false,"pushed_at":"2023-10-29T07:33:03.000Z","size":682,"stargazers_count":117,"open_issues_count":2,"forks_count":29,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-24T21:52:20.147Z","etag":null,"topics":["bayesian-network","causal-inference","pc-algorithm"],"latest_commit_sha":null,"homepage":"https://zhuanlan.zhihu.com/p/368010458","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Renovamen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-12-09T09:04:59.000Z","updated_at":"2025-04-11T07:55:43.000Z","dependencies_parsed_at":"2025-04-24T21:34:08.111Z","dependency_job_id":"a5c49043-9904-4477-af54-1d40b2af3e79","html_url":"https://github.com/Renovamen/pcalg-py","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Renovamen/pcalg-py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Renovamen%2Fpcalg-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Renovamen%2Fpcalg-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Renovamen%2Fpcalg-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Renovamen%2Fpcalg-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Renovamen","download_url":"https://codeload.github.com/Renovamen/pcalg-py/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Renovamen%2Fpcalg-py/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274113090,"owners_count":25224335,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bayesian-network","causal-inference","pc-algorithm"],"created_at":"2024-11-10T15:15:41.182Z","updated_at":"2025-09-08T00:05:50.779Z","avatar_url":"https://github.com/Renovamen.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PC 算法\n\n## 如何使用\n\n1. 安装依赖：\n\n    ```bash\n    pip install -r requirements.txt\n    ```\n\n2. 修改 [`data/test.csv`](data/test.csv) 中的数据\n\n3. 运行：\n\n    ```bash\n    python run.py\n    ```\n\n\n\u0026nbsp;\n\n## 算法\n\n### 博客\n\n这里只是简要解释了一下 PC 算法的流程，如果想看更详细的说明（或无法加载公式），可以看我的博客：[博客](https://blog.zxh.io/post/2021/04/26/pc-algorithm/) / [知乎](https://zhuanlan.zhihu.com/p/368010458)\n\n\n\u0026nbsp;\n\n### 依赖关系确立\n\n![skeleton](assets/1.png)\n\n图片来源：[Estimating High-Dimensional Directed Acyclic Graphs with the PC-Algorithm](http://www.jmlr.org/papers/volume8/kalisch07a/kalisch07a.pdf)\n\nline 11: 需要条件独立关系\n\n\n\u0026nbsp;\n\n#### 条件独立性 -\u003e 偏相关系数\n\n偏相关系数：校正其它变量后某一变量与另一变量的相关关系，校正的意思可以理解为假定其它变量都取值为均数。\n\nPC 算法默认随机变量服从多元高斯分布，这时条件独立性与偏相关系数为 0 等价。\n\n表述得更准确一点：假设随机变量 $X$ 服从多元高斯分布，对于 $i \\not = j \\in (1, \\dots, p), k \\in (1, \\dots, p) \\backslash \\{i, j\\}$，用 $\\rho_{i, j \\mid k}$ 表示 $X(i)$ 和 $X(j)$ 与 $X^{(r)} (r \\in k)$ 之间的偏相关系数。当且仅当 $X(i)$ 和 $X(j)$ 条件独立与 $X^{(r)} (r \\in k)$ 时，$\\rho_{i, j \\in k} = 0$。\n\n\n这个结论是多元高斯分布的基本特性，证明过程可以参考 [Elements of Graphical Models](http://www.stats.ox.ac.uk/~steffen/teaching/gm10/stflournotes.pdf) 第 4.2.1 节。\n\n所以条件独立性可由偏相关估计出来，所以条件独立性检验转偏相关系数检验。\n\n任意两个变量 $i, j$ 的 $h$（排除其他 $h$ 个变量的影响后，$h\u003c=k-2$）阶样本偏相关系数：\n\n$$\n\\rho_{i,j \\mid K} = \\frac{\\rho_{i,j \\mid K \\backslash h} - \\rho_{i,h \\mid K \\backslash h} \\rho_{j,h \\mid K \\backslash h}}{\\sqrt{(1 - \\rho^2_{i,h \\mid K \\backslash h}) (1 - \\rho^2_{j,h \\mid K \\backslash h})}}\n$$\n\n\n\u0026nbsp;\n\n#### Fisher Z Test\n\n用 Fisher Z Test 来判断 $\\rho$ 是否为 0。显著性检验要求 $\\rho$ 为正态分布，所以需要先将 $\\rho$ 进行 Fisher's z-transformation，转换后可以认为是正态分布：\n\n$$\nZ(i, j \\mid K) = \\frac{1}{2} \\log (\\frac{1 + \\hat{\\rho}_{i,j \\mid K}}{1 - \\hat{\\rho}_{i,j \\mid K}})\n$$\n\n- 零假设：$H_0(i, j \\mid K): \\rho_{i, j \\mid K} \\not= 0$\n- 对立假设：$H_1(i, j \\mid K): \\rho_{i, j \\mid K} = 0$\n\n检验规则为：当 $\\sqrt{n - |K| - 3}| Z(i,j \\mid K) \\leq \\Phi^{-1} (1 - \\alpha/2)$ 时（其中 $\\Phi(\\cdot)$ 为 $\\mathcal{N}(0, 1)$ 的累积分布函数），拒绝 $H_0$，$H_1$ 成立，$i, k$ 关于 $K$ 条件独立。\n\n所以将上面伪代码的 line 11 替换为 $\\sqrt{n - |K| - 3}| Z(i,j \\mid K) \\leq \\Phi^{-1} (1 - \\alpha/2)$。\n\n\n\u0026nbsp;\n\n### 依赖方向确立：骨架 -\u003e CPDAGE\n\n依赖关系确立后，得到了一个无向图（骨架），现在需要确立依赖方向，把无向边变成有向边。\n\n![extend-to-cpdag](assets/2.png)\n\n图片来源：[Estimating High-Dimensional Directed Acyclic Graphs with the PC-Algorithm](http://www.jmlr.org/papers/volume8/kalisch07a/kalisch07a.pdf)\n\n得到一个完全部分有向无环图（CPDAG）。\n\n可以看到 PC 算法得到的图是含有无向边的，这个图只是一个 CPDAG（依然有无向边），而不是真正意义上的贝叶斯网络（有向无环图），具体原因可以参考[我的博客](https://blog.zxh.io/post/2021/04/26/pc-algorithm/#马尔科夫等价类)。\n\n但任意贝叶斯网络都存在唯一的 CPDAG 与之马尔科夫等价，因此，CPDAG 可以作为贝叶斯网络的表示。\n\n\n\u0026nbsp;\n\n### 一些定义\n\n- **部分有向无环图**（Partially Directed Acyclic Graph，PDAG）：假设 $G = (V, E)$ 是一个图，若边集 $E$ 中包含有向边和无向边，且不存在有向环，则称 $G$ 是一个部分有向无环图\n\n- **马尔科夫等价类**（Markov Equivalence Class）：$G_1 = (V, E_1)$ 和 $G_2 = (V, E_2)$ 马尔科夫等价, 当且仅当 $G_1$ 和 $G_2$ 具有相同的骨架和 $V$ 结构\n\n- **可逆**：\n\n    - 有向无环图 $G = (V, E)$，任意有向边 $V_i \\rightarrow V_j \\in E$，若存在图 $G' = (V, E')$ 与 $G$ 等价，且 $V_j \\rightarrow V_i \\in E'$，则称有向边 $V_i \\rightarrow V_j$ 在 $G$ 中是可逆的，否则是不可逆的\n\n    - 同理，对任意无向边 $V_i - V_j \\in E$，若存在 $G_1 = (V, E_1)$、$G_2 = (V, E_2)$ 均与 $G$ 等价，且 $V_i \\rightarrow V_j \\in E_1$、$V_j \\rightarrow V_i \\in E_2$，则称无向边 $V_i - V_j$ 在 $G$ 中是可逆的，否则是不可逆的\n\n- **完全部分有向无环图**（Completed Partially Directed Acyclic Graph，CPDAG：设 $G = (V, E)$ 是一个部分有向无环图，若 $E$ 中的有向边都是不可逆的，并且 $E$ 中的无向边都是可逆的，则称 $G$ 是一个完全部分有向无环图（CPDAG）\n\n\n\u0026nbsp;\n\n## 参考\n\n- [Estimating High-Dimensional Directed Acyclic Graphs with the PC-Algorithm.](http://www.jmlr.org/papers/volume8/kalisch07a/kalisch07a.pdf) *Markus Kalisch and Peter Buhlmann.* JMLR 2007.\n- [An Algorithm for Fast Recovery of Sparse Causal Graphs.](http://shelf2.library.cmu.edu/Tech/28463803.pdf) *Peter Spirtes and Clark Glymour.* Social Science Computer Review 1991. \n- [d-Separation: From Theorems to Algorithms.](https://arxiv.org/pdf/1304.1505.pdf) *Dan Geiger, et al.* UAI 1989.\n- [Frequency Distribution of the Values of the Correlation Coefficient in Samples from an Indefinitely Large Population.](https://www.quantresearch.org/Fisher%20transform%20seminal%20paper.pdf*) *R. A. Fisher.* Biometrika 1915.\n- [Elements of Graphical Models.](http://www.stats.ox.ac.uk/~steffen/teaching/gm10/stflournotes.pdf) *Steffen L. Lauritzen.* 2011. ↩︎\n- [Wikipedia: Fisher transformation](https://en.wikipedia.org/wiki/Fisher_transformation)\n- R 语言实现：[pcalg: Methods for Graphical Models and Causal Inference](https://cran.r-project.org/web/packages/pcalg/)\n    - `zStat(x, y, S, C)`: 计算并返回 $\\sqrt{n - |K| - 3}| Z(i,j \\mid K)$ 的值\n    - `pcorOrder(i, j, k, C)`: 计算并返回 $i$ 和 $j$ 与 $k$ 的偏相关系数\n    - `condIndFisherZ(x, y, S, C)`: 计算 $\\sqrt{n - |K| - 3}| Z(i,j \\mid K)$，返回它是否 \u003c= `cutoff`\n    - `gaussCItest(x, y, S, suffStat)`: 计算并返回 $\\Phi^{-1} (1 - \\alpha/2)$\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenovamen%2Fpcalg-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenovamen%2Fpcalg-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenovamen%2Fpcalg-py/lists"}