CausalEGM安装使用

1代码来源

github:https://github.com/SUwonglab/CausalEGM/tree/main/src

pip:Tutorial for Python Users — CausalEGM documentation

安装:Installation — CausalEGM documentation

版本:

2原理

关于CausalEGM

根据观察数据,推断治疗的因果效应对于许多科学和工程问题至关重要,并引起了各个领域的巨大兴趣。了解因果关系的最有效方法是进行随机对照试验(RCT)。然而,RCT 耗时、昂贵且普遍性存在问题。相比之下,观察性研究可以提供有价值的证据并检查“现实世界”环境中的效果。在现实世界的应用中,由于混杂因素引入的选择偏差,治疗通常不是随机分配的。准确估计因果效应涉及处理混杂因素,这可能会影响治疗和结果。未能针对混杂效应进行调整可能会导致估计偏差和错误结论。

 Density estimation using deep generative neural networks

CausalEGM(Causal Effect Generative Model)是一种用于因果推断的方法,旨在从观察数据中估计因果效应。它结合了生成模型和因果推断的思想,可以用于处理因果关系的估计、预测和决策问题。以下是CausalEGM的一般原理:

  1. 生成模型基础: CausalEGM基于生成模型的思想,意味着它试图对数据生成的过程进行建模。它假设数据是从一个潜在的生成过程中产生的,这个生成过程可以包括真实的因果关系。

  2. 结构方程模型: CausalEGM使用结构方程模型(SEM)来描述数据的生成过程。SEM是一种用于建立潜在因果关系的模型,它描述了变量之间的依赖关系、直接影响和随机噪声。

  3. 因果图: CausalEGM可以通过因果图表示潜在的因果关系。因果图是一个有向图,节点代表变量,边代表因果关系。通过观察数据,CausalEGM可以估计因果图的结构和参数。

  4. 因果效应估计: CausalEGM的主要目标是估计因果效应,即某个变量对另一个变量的影响。它通过分析结构方程模型和因果图来估计不同变量之间的因果关系。

  5. 反事实推断: 一种重要的应用是反事实推断,即在观察数据的基础上估计干预的效果。通过修改因果图中的某些变量,CausalEGM可以估计如果某个干预发生了,会对数据产生什么样的影响。

  6. 数据生成和预测: 完成因果效应估计后,CausalEGM可以用来生成新的数据样本或进行预测。生成的数据样本可以用于模拟不同因果关系下的数据分布。

总之,CausalEGM是一种将生成模型与因果推断相结合的方法,通过对结构方程模型和因果图的分析,估计数据中的因果效应。它可以用于估计干预效果、预测和决策问题,特别是在具有潜在因果关系的情况下。请注意,CausalEGM的具体实现和算法可能因版本而异,因此在使用时应查阅相关文档或论文。

意义

密度估计是统计学中最基本的问题之一。由于“维数灾难”,估计高维数据的密度是出了名的困难。在这里,我们介绍一种基于深度生成神经网络的新型通用密度估计器。通过对通常分布在降维流形周围的数据进行建模,我们展示了如何利用双向生成神经网络(例如,cycleGAN)的功能来显式评估数据密度。模拟和真实数据实验表明我们的方法在广泛的问题上是有效的。这种方法在许多需要精确密度估计器的应用中应该很有帮助。

抽象的

密度估计是统计学和机器学习中的基本问题之一。在这项研究中,我们提出了 Roundtrip,一种基于深度生成神经网络的通用密度估计计算框架。Roundtrip 保留了生成对抗网络 (GAN) 等深度生成模型的生成能力,同时还提供密度值的估计,从而支持数据生成和密度估计。与之前的神经密度估计器对从潜在空间到数据空间的转换施加严格的条件不同,Roundtrip 可以使用更通用的映射,其中目标密度是通过学习从基本密度(例如高斯分布)导出的流形来建模的。Roundtrip 为 GAN 模型提供了一个统计框架,其中密度值的显式评估是可行的。在数值实验中,Roundtrip 在各种密度估计任务中都超越了最先进的性能。

loss

    def train_step(self, data_z, data_v, data_x, data_y):
        """Training step in the Variational CausalEGM model.

        Parameters
        ----------
        data_z
            Numpy.ndarray denoting latent features with shape [batch_size, z_dim]. 
        data_v
            Numpy.ndarray denoting covariants with shape [batch_size, v_dim]. 
        data_x
            Numpy.ndarray denoting treatment data with shape [batch_size, 1]. 
        data_y
            Numpy.ndarray denoting outcome data with shape [batch_size, 1]. 

        Returns
        --------
        logpv_z
            Float denoting likelihood for covariates.
        kl_loss
            Float denoting KL-divengence between p(z) and q(z|v).
        elbo
            Float denoting evidence lower bound (ELBO) loss.
        l2_loss_x
            Float denoting treatment reconstruction loss.
        l2_loss_y
            Float denoting outcome reconstruction loss.   
        g_e_loss
            Float denoting G E combined loss.      
        """ 
        with tf.GradientTape(persistent=True) as gen_tape:
            data_v_ = self.g_net(data_z)
            mean, logvar = self.encode(data_v)
            data_z_ = self.reparameterize(mean, logvar)
            data_v__ = self.g_net(data_z_)

            logpv_z = -tf.reduce_mean((data_v - data_v__)**2,axis=1)
            
            logqz_v = self.log_normal_pdf(data_z_, mean, logvar)
            logpz = self.log_normal_pdf(data_z_, 0., 0.)
            kl_loss = logqz_v-logpz # here it is not the formula of KL_loss, so will result in negative values
            elbo = tf.reduce_mean(logpv_z - kl_loss)
            
            data_z0 = data_z_[:,:self.params['z_dims'][0]]
            data_z1 = data_z_[:,self.params['z_dims'][0]:sum(self.params['z_dims'][:2])]
            data_z2 = data_z_[:,sum(self.params['z_dims'][:2]):sum(self.params['z_dims'][:3])]
            data_z3 = data_z_[:-self.params['z_dims'][3]:]

            data_y_ = self.f_net(tf.concat([data_z0, data_z2, data_x], axis=-1))
            data_x_ = self.h_net(tf.concat([data_z0, data_z1], axis=-1))
            if self.params['binary_treatment']:
                data_x_ = tf.sigmoid(data_x_)
            l2_loss_x = tf.reduce_mean((data_x_ - data_x)**2)
            l2_loss_y = tf.reduce_mean((data_y_ - data_y)**2)
            g_e_loss = -elbo + self.params['beta']*(l2_loss_x+l2_loss_y)

        # Calculate the gradients for generators and discriminators
        g_e_gradients = gen_tape.gradient(g_e_loss, self.g_net.trainable_variables+self.e_net.trainable_variables+\
                                        self.f_net.trainable_variables+self.h_net.trainable_variables)
        
        # Apply the gradients to the optimizer
        self.g_e_optimizer.apply_gradients(zip(g_e_gradients, self.g_net.trainable_variables+self.e_net.trainable_variables+\
                                            self.f_net.trainable_variables+self.h_net.trainable_variables))
        return tf.reduce_mean(logpv_z), tf.reduce_mean(kl_loss), elbo, l2_loss_x, l2_loss_y, g_e_loss

CausalEGM能非常灵活处理不同类型的干预,只需要调整 H网络的最后一层的激活函数。

parser.add_argument('-beta', dest='beta', type=float, default=1.,
help="Coefficient for treatment and outcome MSE loss (default: 1).")

if self.params['binary_treatment']:
data_x_pred = tf.sigmoid(data_x_pred)
mse_x = np.mean((data_x-data_x_pred)**2)
mse_y = np.mean((data_y-data_y_pred)**2)

    def evaluate(self, data, nb_intervals=200):
        """Internal evaluation in the training process of variational CausalEGM.

        Parameters
        ----------
        data
            List denoting the triplet data [X,Y,V] to be evaluated.
        nb_intervals
            Int object denoting number of intervals in continous treatment settings. Default: ``200``.

        Returns
        --------
        causal_pre
            Numpy.ndarray denoting the predicted individual treatment effect (ITE) or 
            values of average dose response function (ADRF).
        mse_x
            Float denoting treatment reconstruction loss.
        mse_y
            Float denoting outcome reconstruction loss.
        """ 
        data_x, data_y, data_v = data
        data_z = self.z_sampler.get_batch(len(data_x))
        mean, logvar = self.encode(data_v)
        data_z_ = self.reparameterize(mean, logvar)
        data_z0 = data_z_[:,:self.params['z_dims'][0]]
        data_z1 = data_z_[:,self.params['z_dims'][0]:sum(self.params['z_dims'][:2])]
        data_z2 = data_z_[:,sum(self.params['z_dims'][:2]):sum(self.params['z_dims'][:3])]
        data_y_pred = self.f_net.predict(tf.concat([data_z0, data_z2, data_x], axis=-1),verbose=0)
        data_x_pred = self.h_net.predict(tf.concat([data_z0, data_z1], axis=-1),verbose=0)
        if self.params['binary_treatment']:
            data_x_pred = tf.sigmoid(data_x_pred)
        mse_x = np.mean((data_x-data_x_pred)**2)
        mse_y = np.mean((data_y-data_y_pred)**2)
        if self.params['binary_treatment']:
            #individual treatment effect (ITE) && average treatment effect (ATE)
            y_pred_pos = self.f_net.predict(tf.concat([data_z0, data_z2, np.ones((len(data_x),1))], axis=-1),verbose=0)
            y_pred_neg = self.f_net.predict(tf.concat([data_z0, data_z2, np.zeros((len(data_x),1))], axis=-1),verbose=0)
            ite_pre = y_pred_pos-y_pred_neg
            return ite_pre, mse_x, mse_y
        else:
            #average dose response function (ADRF)
            dose_response = []
            for x in np.linspace(self.params['x_min'], self.params['x_max'], nb_intervals):
                data_x = np.tile(x, (len(data_x), 1))
                y_pred = self.f_net.predict(tf.concat([data_z0, data_z2, data_x], axis=-1),verbose=0)
                dose_response.append(np.mean(y_pred))
            return np.array(dose_response), mse_x, mse_y

3配置 CausalEGM 模型

在创建 CausalEGM 模型之前,dict应创建一个 python 对象来部署 CausalEGM 模型的超参数,其中包括潜在特征的维度、神经网络架构等。

详细的超参数描述如下。

配置参数

描述

输出目录

输出目录用于保存模型训练过程中的结果。默认: ”。”

数据集

用于指示输入数据的数据集名称。默认值:“我的数据”

z_尺寸

编码器输出的潜在维度 (e(V)_0~3)。默认值:[3,3,6,6]

v_dim

协变量的维度。

LR

学习率。默认值:0.0002

g_单位

解码器/生成器网络 G 的单元数量。默认值: [64,64,64,64,64]

e_单位

编码器网络 E 的单元数量。默认值: [64,64,64,64,64]

f_单位

F 网络的单元数量。默认值:[64,32,8]

h_单位

H 网络的单元数量。默认值:[64,32,8]

dz_单位

潜在空间中鉴别器网络的单元数量。默认值:[64,32,8]

dz_单位

协变量空间中鉴别器网络的单元数。默认值:[64,32,8]

α

重建损失系数。 默认值:1

贝塔

往返损耗系数。默认值:1

伽玛

梯度惩罚损失系数。默认值:10

g_d_频率

更新鉴别器和生成器的频率。默认值:5

保存资源

模型训练过程中是否保存结果。 默认值: True

保存模型

是否保存模型权重。默认值: False

二进制处理

是否使用二元处理设置。 默认值: True

使用_z_rec

使用潜在特征的重建。默认值: True

使用_v_gan

使用协变量的 GAN 分布匹配。 默认值: True

x_最小值

连续治疗环境中剂量反应间隔的左界。默认值:0

最大x

连续治疗环境中剂量反应间隔的右界。默认值:3

配置参数对于创建 CausalEGM 模型是必需的。以下是配置参数的一些技巧。

  1. z_dims对性能有显着影响,请参阅src/configs获取指导。

  2. 如果save_resTrue,训练期间的结果将保存在output_dir中

  3. 建议use_v_gan在二元治疗设置下为True ,在连续治疗设置下为False

4baseline 

import CausalEGM as cegm
print("Currently use version v%s of CausalEGM."%cegm.__version__)
import yaml
params = yaml.safe_load(open('../../src/configs/Semi_acic.yaml', 'r'))
print(params)
#{'dataset': 'Semi_acic', 'output_dir': '.', 'v_dim': 100, 'z_dims': [3, 3, 6, 6], 'lr': 0.0002, 'alpha': 1, 'beta': 1, 'gamma': 10, 'g_d_freq': 5, 'g_units': [64, 64, 64, 64, 64], 'e_units': [64, 64, 64, 64, 64], 'f_units': [64, 32, 8], 'h_units': [64, 32, 8], 'dz_units': [64, 32, 8], 'dv_units': [64, 32, 8], 'save_res': True, 'save_model': False, 'binary_treatment': False, 'use_z_rec': True, 'use_v_gan': True, 'x_min': 0, 'x_max': 3}
model = cegm.CausalEGM(params=params,random_seed=123)
#get the data from the ACIC 2018 competition dataset with a specified ufid.
#ds = Semi_acic_sampler(path='../data/ACIC_2018',ufid='d5bd8e4814904c58a79d7cdcd7c2a1bb')
# >>> ds = Base_sampler(x=x,y=y,v=v)
# >>> batch = ds.next_batch() # get a batch of data
# >>> data = ds.load_all() # get all data as a triplet
# x,y,v = cegm.Semi_acic_sampler(path='../../../../data/ACIC_2018',ufid='d5bd8e4814904c58a79d7cdcd7c2a1bb').load_all()
#x,y,v = cegm.Semi_acic_sampler(path='../../../../data/ACIC_2018',ufid='d5bd8e4814904c58a79d7cdcd7c2a1bb').load_all()
import numpy as np
x = np.random.normal(size=(2000,))
y = np.random.normal(size=(2000,))
v = np.random.normal(size=(2000,100))
print(x.shape,y.shape,v.shape)
model.train(data=[x,y,v],n_iter=100,save_format='npy',verbose=False)

错误

这个错误信息表明在你的代码中存在一个占位符张量(placeholder tensor) 'Placeholder/_10',它的 dtype 是 float,形状是 [2000, 10],但是在执行过程中没有为它提供必要的数据值。

在 TensorFlow 中,占位符张量是一种特殊的张量,它在图构建阶段没有具体的值,而是在运行阶段通过 feed_dict 或者 tf.data 来提供数据。根据错误信息,你需要在执行代码时,确保为占位符 'Placeholder/_10' 提供一个正确形状和 dtype 的数据值。

要解决这个问题,你可以使用 feed_dict 来为占位符提供数据,例如:

import tensorflow as tf

# 创建占位符
placeholder = tf.placeholder(dtype=tf.float32, shape=[2000, 10], name='Placeholder')

# 创建一个 TensorFlow 会话
with tf.Session() as sess:
    # 使用 feed_dict 为占位符提供数据
    data = ...  # 替换成你的数据
    result = sess.run(placeholder, feed_dict={placeholder: data})

5ACIC 

  • Estimating Treatment Effects over Time with Causal Forests:An application to the ACIC 2022 Data Challenge

参考

  1. CausalEGM:通过编码生成建模的通用因果推理框架
  2. Project MUSE - Estimating Treatment Effects over Time with Causal Forests: An application to the ACIC 2022 Data Challenge
  3. Estimating Treatment Effects over Time with Causal Forests:An application to the ACIC 2022 Data Challenge

  4. https://github.com/SUwonglab/CausalEGM/blob/main/src/CausalEGM/causalEGM.py

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值