因果机器学习:如何在不依赖领域知识的情况下构建因果图并定义因果关系

机器学习大数据算法

picture.image

✨ 欢迎关注Python机器学习AI ✨

本节介绍: 如何在不依赖领域知识的情况下构建因果图并定义因果关系 。数据采用模拟数据,作者根据个人对机器学习的理解进行代码实现与图表输出,细节并不保证与原文一定相同,仅供参考。 详细数据和代码、文献将在稍后上传至交流群,付费成员可在交流群中获取下载。需要的朋友可关注公众文末提供的购买方式。 购买前请咨询,避免不必要的问题。 文末点赞、推荐、转发参与免费包邮赠书~

✨ 背景 ✨

在 DoWhy因果机器学习中, 构建一个DAG(有向无环图) 是基础步骤。DAG的核心特点是:

  • 有向:图中的边有方向,表示变量之间的因果关系或依赖关系。箭头的方向代表因果因素指向结果变量,即从原因指向后果
  • 无环:图中没有环路,意味着从某个节点出发不能回到自己。这保证了因果关系是单向的,不会形成自我循环的因果链

通常,DAG 是通过领域知识构建的,专家通过经验和理论来定义哪些变量之间有因果关系。但在实际应用中,很多时候我们无法依赖领域知识或明确的外部信息来构建因果图。这时,我们可以利用 图发现算法 ,通过数据本身发现潜在的因果关系,从而自动生成候选因果图。然而,图发现算法通常会做出一些假设来学习图,但并不能保证学到的图一定是有效的,因此需要进一步验证和调整

picture.image

这张图展示了基于不同因果发现方法得到的因果图,包括 PC 算法(约束方法)、GES 算法(评分方法)和 LiNGAM 模型(基于 FCM 的方法)。可以看到,使用不同方法得到的因果图结构不同,这在实际应用中并不罕见,因为数据生成过程中的假设难以验证。此外,PC 和 GES 返回的图是 CPDAG,而非 DAG,这可能导致无向边缘的出现(例如 GES 返回的结果)。这些差异使得因果效应估计变得更加复杂。除了这些方法, causal-learn 还提供了其他搜索方法,如 Granger 因果性测试、FCI等,提供更多选择来处理实际数据中的因果关系。接下来看看代码如何实现

✨ 基础代码 ✨

  
import dowhy  
from dowhy import CausalModel  
  
import numpy as np  
import pandas as pd  
import graphviz  
import networkx as nx  
  
np.set_printoptions(precision=3, suppress=True)  
np.random.seed(0)  
  
data_mpg = pd.read_excel("2025-4-27公众号python机器学习AI.xlsx")  
data_mpg.head()

picture.image

导入必要的库,并读取名为 "auto_mpg.xlsx" 的数据文件,以准备进行因果推断分析

  
# 导入PC算法(约束方法)从causallearn库  
from causallearn.search.ConstraintBased.PC import pc  
  
# 使用数据的列名来生成标签  
labels = [f'{col}' for i, col in enumerate(data_mpg.columns)]  
# 将数据转换为numpy数组  
data = data_mpg.to_numpy()  
  
# 使用PC算法来计算因果关系图(causal graph)  
cg = pc(data)  
  
# 可视化部分,使用pydot来展示图  
from causallearn.utils.GraphUtils import GraphUtils  
import matplotlib.image as mpimg  
import matplotlib.pyplot as plt  
import io  
  
# 将因果关系图转换为pydot格式,使用之前定义的标签  
pyd = GraphUtils.to_pydot(cg.G, labels=labels)  
# 将pydot图转换为PNG格式并保存在临时变量中  
tmp_png = pyd.create_png(f="png")  
# 使用BytesIO从内存读取图片数据  
fp = io.BytesIO(tmp_png)  
# 使用matplotlib读取PNG图像  
img = mpimg.imread(fp, format='png')  
  
# 关闭坐标轴显示  
plt.axis('off')  
# 显示图片  
plt.imshow(img)  
plt.savefig("PC.pdf", format='pdf',bbox_inches='tight',dpi=1200)  
plt.show()

picture.image

使用 PC 算法从 causallearn 库计算数据集中的因果关系图,并通过 matplotlib 和 pydot 可视化该图形

  
# 导入GES算法(评分方法)从causallearn库  
from causallearn.search.ScoreBased.GES import ges  
  
# 使用默认参数运行GES算法,得到因果图的结构(Record包含因果图信息)  
Record = ges(data)  
  
# 可视化部分,使用pydot来展示图  
from causallearn.utils.GraphUtils import GraphUtils  
import matplotlib.image as mpimg  
import matplotlib.pyplot as plt  
import io  
  
# 将因果关系图转换为pydot格式,使用之前定义的标签  
pyd = GraphUtils.to_pydot(Record['G'], labels=labels)  
# 将pydot图转换为PNG格式并保存在临时变量中  
tmp_png = pyd.create_png(f="png")  
# 使用BytesIO从内存读取图片数据  
fp = io.BytesIO(tmp_png)  
# 使用matplotlib读取PNG图像  
img = mpimg.imread(fp, format='png')  
  
# 关闭坐标轴显示  
plt.axis('off')  
# 显示图片  
plt.imshow(img)  
plt.savefig("GES.pdf", format='pdf',bbox_inches='tight',dpi=1200)  
plt.show()

picture.image

使用 GES 算法从 causallearn 库计算数据集中的因果关系图,并通过 matplotlib 和 pydot 可视化该图形

  
# 导入LiNGAM模型(基于FCM的方法)  
from causallearn.search.FCMBased import lingam  
  
# 创建并初始化一个ICALiNGAM模型对象  
model_lingam = lingam.ICALiNGAM()  
  
# 使用数据拟合模型,学习因果关系  
model_lingam.fit(data)  
  
# 导入用于可视化LiNGAM模型结果的make_dot函数  
from causallearn.search.FCMBased.lingam.utils import make_dot  
  
# 使用make_dot函数根据模型的邻接矩阵(adjacency matrix)生成因果图,labels为节点标签  
dot_graph = make_dot(model_lingam.adjacency_matrix_, labels=labels)  
dot_graph.render("lingam_causal_graph", format="pdf")  
dot_graph

picture.image

使用 LiNGAM 模型(基于 FCM 的方法)拟合数据并生成因果关系图,该图通过邻接矩阵可视化。由于输出的是一个 DAG(有向无环图),因此接下来基于该图进行因果效应估计。

当然用户可以在此基础上检查、编辑和修改因果图,以使其更符合他们的领域专业知识或世界知识。尽管因果图是基于数据和算法生成的,但这些图表可能与实际的领域知识有所出入。因此,用户可以根据他们对问题的理解和经验,调整因果图的结构、关系和系数,以更准确地反映实际的因果机制。这样做有助于提高因果推断的可靠性和应用性,确保因果效应估计能够更好地与实际情况相符

  
import warnings  
warnings.filterwarnings("ignore")  # 忽略所有警告  
# 使用make_graph函数根据LiNGAM模型的邻接矩阵生成图的dot格式  
graph_dot = make_graph(model_lingam.adjacency_matrix_, labels=labels)  
  
# 定义因果模型  
model = CausalModel(  
        data=data_mpg,  # 输入数据  
        treatment='mpg',  # 定义治疗(自变量)为'mpg'(英里每加仑)  
        outcome='weight',  # 定义结果(因变量)为'weight'(汽车重量)  
        graph=str_to_dot(graph_dot.source))  # 将图的dot格式转换为CausalModel所需的格式  
  
# 识别因果效应(Identification)  
identified_estimand = model.identify_effect(proceed_when_unidentifiable=True)  # 识别因果效应的估计量  
print(identified_estimand)  # 打印识别的因果效应估计量  
  
# 估计因果效应(Estimation)  
estimate = model.estimate_effect(  
    identified_estimand,  # 使用之前识别的因果效应估计量  
    method_name="backdoor.linear_regression",  # 使用backdoor方法(通过线性回归估计)  
    control_value=0,  # 控制变量(例如,将'mpg'设为0)  
    treatment_value=1,  # 处理变量(例如,将'mpg'设为1)  
    confidence_intervals=True,  # 计算置信区间  
    test_significance=True  # 进行显著性检验  
)  
  
# 打印因果效应估计值  
print("Causal Estimate is " + str(estimate.value))

picture.image

使用 LiNGAM 模型生成因果图,并基于该图在 DoWhy 中定义因果模型,通过回归方法估计 "mpg" 对 "weight" 的因果效应,同时进行显著性检验并输出估计值

通过后门准则(backdoor criterion)估计 "mpg"(英里每加仑)对 "weight"(汽车重量)的因果效应,得到的值为 -38.94,意味着每增加一单位的 "mpg",汽车的重量将减少约 38.94 单位。这是基于非参数化的平均处理效应(ATE)估计的结果,假设 "mpg" 和 "weight" 之间的关系不受其他未控制的混杂因素影响

接下来就需要进行反驳测试(如引入随机共同原因等)是为了验证因果效应估算的稳健性和可靠性。在因果推断中,虽然我们使用数据和模型估计了因果效应,但这些估算可能会受到一些未观察到的混杂因素的影响,或者模型假设不完全符合现实。因此,反驳测试是确保因果推断结果的可信度和稳定性的重要步骤

  
# 使用随机共同原因方法来反驳因果估算  
refute1_results = model.refute_estimate(identified_estimand, estimate,  
        method_name="random_common_cause")  # 通过引入随机共同原因来测试因果估算的稳定性  
  
# 打印反驳结果  
print(refute1_results)  # 输出反驳结果,查看因果估算是否受到随机共同原因的影响

picture.image

通过引入随机共同原因进行反驳后,因果效应估算值几乎没有变化(从 -38.94 变为 -38.94),且 p 值为 1.0,表明即使加入随机噪声,因果效应估算依然稳健可靠,未受到外部假设的显著影响,验证了估算结果的稳定性

  
# 使用安慰剂处理反驳器来反驳因果估算  
refute2_results = model.refute_estimate(identified_estimand, estimate,  
        method_name="placebo_treatment_refuter")  # 随机将一个协变量作为处理,并重新估算  
  
# 打印反驳结果  
print(refute2_results)  # 输出反驳结果,查看安慰剂处理是否导致因果估算接近 0

picture.image

结果表明,使用安慰剂处理方法进行反驳后,新的因果效应估算值变为 0.0,且 p 值为 1.0,说明因果效应估算并未受到随机噪声的显著影响,验证了原始因果效应估算的稳定性和可信度。如果安慰剂处理导致的效应接近零,且 p 值很高,那么可以确认原始的因果效应估算结果是可靠的

  
# 使用数据子集反驳器来反驳因果估算  
refute3_results = model.refute_estimate(identified_estimand, estimate,  
        method_name="data_subset_refuter")  # 创建数据子集并检查因果估算的变化  
  
# 打印反驳结果  
print(refute3_results)  # 输出反驳结果,查看因果估算在不同子集中的变化情况

picture.image

这个结果表明,使用数据子集反驳方法进行反驳后,因果效应估算值从 -38.94 变为 -39.09,但变化非常小,且 p 值为 0.96,表明因果效应估算在数据子集之间几乎没有显著变化。这表明原始的因果效应估算在不同的数据子集上是稳健的,未受到数据选择或分布的显著影响

这三种反驳方法均未显著改变因果效应的估算结果,且 p 值表明估算结果是稳定且可靠的。因此,可以确认原始的因果效应估算(即 "mpg" 对 "weight" 的影响为 -38.94)在不同情境下均是稳健的,未受到外部因素的显著干扰

✨ 该文章案例 ✨

picture.image

在上传至交流群的文件中,像往期文章一样,将对案例进行逐步分析,确保读者能够达到最佳的学习效果。内容都经过详细解读,帮助读者深入理解模型的实现过程和数据分析步骤,从而最大化学习成果。

同时,结合提供的免费AI聚合网站进行学习,能够让读者在理论与实践之间实现融会贯通,更加全面地掌握核心概念。

✨ 购买介绍 ✨

本节介绍到此结束,有需要学习数据分析和Python机器学习相关的朋友欢迎到淘宝店铺:Python机器学习AI,或添加作者微信deep_ML联系,购买作者的公众号合集。截至目前为止,合集已包含200多篇文章,购买合集的同时,还将提供免费稳定的AI大模型使用,包括但不限于ChatGPT、Deepseek、Claude等。

更新的内容包含数据、代码、注释和参考资料。 作者仅分享案例项目,不提供额外的答疑服务。项目中将提供详细的代码注释和丰富的解读,帮助您理解每个步骤 。 购买前请咨询,避免不必要的问题。

✨ 群友反馈 ✨

picture.image

✨ 淘宝店铺 ✨

picture.image

请大家打开淘宝扫描上方的二维码,进入店铺,获取更多Python机器学习和AI相关的内容,或者添加作者微信deep_ML联系 避免淘宝客服漏掉信息 ,希望能为您的学习之路提供帮助!

✨ 免费赠书 ✨

picture.image

picture.image

支持知识分享,畅享学习乐趣!特别感谢清华大学出版社 对本次赠书活动的鼎力支持!即日起,只需点赞、推荐、转发 此文章,作者将从后台随机抽取一位幸运儿,免费包邮赠送清华出版社提供的《LangChain核心技术与LLM项目实践》这本精彩书籍📚!

💡 赶快参与,一键三连,说不定你就是那位幸运读者哦!

往期推荐

Frontiers in Oncology:利用生存机器学习RSF模型预测患者预后模拟实现

因果推断:注册行为对后续消费影响的因果推断分析案例

因果推断与机器学习结合:探索酒店预订取消的影响因素

期刊配图:通过SHAP组图解读模型探索不同类型特征和分组对模型的影响

机器学习在临床数据分析中的应用:从数据预处理到Web应用实现的完整流程教学

期刊配图:一区SCI常用数据缺失率展示图可视化

Psychiatry Research基于SHAP可解释性的机器学习模型构建与评估:混淆矩阵、ROC曲线、DCA与校准曲线分析

因果推断:注册行为对后续消费影响的因果推断分析案例

nature communications:基于Light GBM与随机森林结合的多模型特征选择方法

因果推断与机器学习结合:探索酒店预订取消的影响因素

期刊配图:回归模型性能与数据分布(核密度)可视化

picture.image

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

个人观点,仅供参考

0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
火山引擎大规模机器学习平台架构设计与应用实践
围绕数据加速、模型分布式训练框架建设、大规模异构集群调度、模型开发过程标准化等AI工程化实践,全面分享如何以开发者的极致体验为核心,进行机器学习平台的设计与实现。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论