Example #1
0
    def test_deepiv_shape(self):
        """Make sure that arbitrary sizes for t, z, x, and y don't break the basic operations."""
        for _ in range(5):
            d_t = np.random.choice(range(1, 4))  # number of treatments
            d_z = np.random.choice(range(1, 4))  # number of instruments
            d_x = np.random.choice(range(1, 4))  # number of features
            d_y = np.random.choice(range(1, 4))  # number of responses
            n = 500
            # simple DGP only for illustration
            x = np.random.uniform(size=(n, d_x))
            z = np.random.uniform(size=(n, d_z))
            p_x_t = np.random.uniform(size=(d_x, d_t))
            p_z_t = np.random.uniform(size=(d_z, d_t))
            t = x @ p_x_t + z @ p_z_t
            p_xt_y = np.random.uniform(size=(d_x * d_t, d_y))
            y = (x.reshape(n, -1, 1) * t.reshape(n, 1, -1)).reshape(n, -1) @ p_xt_y

            # Define the treatment model neural network architecture
            # This will take the concatenation of one-dimensional values z and x as input,
            # so the input shape is (d_z + d_x,)
            # The exact shape of the final layer is not critical because the Deep IV framework will
            # add extra layers on top for the mixture density network
            treatment_model = keras.Sequential([keras.layers.Dense(128, activation='relu', input_shape=(d_z + d_x,)),
                                                keras.layers.Dropout(0.17),
                                                keras.layers.Dense(64, activation='relu'),
                                                keras.layers.Dropout(0.17),
                                                keras.layers.Dense(32, activation='relu'),
                                                keras.layers.Dropout(0.17)])

            # Define the response model neural network architecture
            # This will take the concatenation of one-dimensional values t and x as input,
            # so the input shape is (d_t + d_x,)
            # The output should match the shape of y, so it must have shape (d_y,) in this case
            # NOTE: For the response model, it is important to define the model *outside*
            #       of the lambda passed to the DeepIvEstimator, as we do here,
            #       so that the same weights will be reused in each instantiation
            response_model = keras.Sequential([keras.layers.Dense(128, activation='relu', input_shape=(d_t + d_x,)),
                                               keras.layers.Dropout(0.17),
                                               keras.layers.Dense(64, activation='relu'),
                                               keras.layers.Dropout(0.17),
                                               keras.layers.Dense(32, activation='relu'),
                                               keras.layers.Dropout(0.17),
                                               keras.layers.Dense(d_y)])

            deepIv = DeepIVEstimator(n_components=10,  # number of gaussians in our mixture density network
                                     m=lambda z, x: treatment_model(
                                         keras.layers.concatenate([z, x])),  # treatment model
                                     h=lambda t, x: response_model(keras.layers.concatenate([t, x])),  # response model
                                     n_samples=1,  # number of samples to use to estimate the response
                                     use_upper_bound_loss=False,  # whether to use an approximation to the true loss
                                     # number of samples to use in second estimate of the response
                                     # (to make loss estimate unbiased)
                                     n_gradient_samples=1,
                                     # Keras optimizer to use for training - see https://keras.io/optimizers/
                                     optimizer='adam')

            deepIv.fit(Y=y, T=t, X=x, Z=z)
            # do something with predictions...
            deepIv.predict(T=t, X=x)
            deepIv.effect(x, np.zeros_like(t), t)
Example #2
0
 def test_deepiv(self):
     X = TestPandasIntegration.df[TestPandasIntegration.features]
     Y = TestPandasIntegration.df[TestPandasIntegration.outcome]
     T = TestPandasIntegration.df[TestPandasIntegration.cont_treat]
     Z = TestPandasIntegration.df[TestPandasIntegration.instrument]
     # Test DeepIV
     treatment_model = keras.Sequential([
         keras.layers.Dense(128, activation='relu', input_shape=(3, )),
         keras.layers.Dropout(0.17),
         keras.layers.Dense(64, activation='relu'),
         keras.layers.Dropout(0.17),
         keras.layers.Dense(32, activation='relu'),
         keras.layers.Dropout(0.17)
     ])
     response_model = keras.Sequential([
         keras.layers.Dense(128, activation='relu', input_shape=(3, )),
         keras.layers.Dropout(0.17),
         keras.layers.Dense(64, activation='relu'),
         keras.layers.Dropout(0.17),
         keras.layers.Dense(32, activation='relu'),
         keras.layers.Dropout(0.17),
         keras.layers.Dense(1)
     ])
     est = DeepIVEstimator(
         n_components=
         10,  # Number of gaussians in the mixture density networks)
         m=lambda z, x: treatment_model(keras.layers.concatenate([z, x])
                                        ),  # Treatment model
         h=lambda t, x: response_model(keras.layers.concatenate([t, x])
                                       ),  # Response model
         n_samples=1  # Number of samples used to estimate the response
     )
     est.fit(Y, T, X=X, Z=Z)
     treatment_effects = est.effect(X)