11
11
from statistics import StatisticsError
12
12
13
13
import pandas as pd
14
- import scipy
15
- from fitter import Fitter , get_common_distributions
16
14
17
- from causal_testing .generation .abstract_causal_test_case import AbstractCausalTestCase
18
15
from causal_testing .specification .causal_dag import CausalDAG
19
16
from causal_testing .specification .causal_specification import CausalSpecification
20
17
from causal_testing .specification .scenario import Scenario
@@ -90,33 +87,6 @@ def setup(self, scenario: Scenario, ignore_cycles=False):
90
87
)
91
88
self ._populate_metas ()
92
89
93
- def _create_abstract_test_case (self , test , mutates , effects ):
94
- assert len (test ["mutations" ]) == 1
95
- treatment_var = next (self .scenario .variables [v ] for v in test ["mutations" ])
96
-
97
- if not treatment_var .distribution :
98
- fitter = Fitter (self .df [treatment_var .name ], distributions = get_common_distributions ())
99
- fitter .fit ()
100
- (dist , params ) = list (fitter .get_best (method = "sumsquare_error" ).items ())[0 ]
101
- treatment_var .distribution = getattr (scipy .stats , dist )(** params )
102
- self ._append_to_file (treatment_var .name + f" { dist } ({ params } )" , logging .INFO )
103
-
104
- abstract_test = AbstractCausalTestCase (
105
- scenario = self .scenario ,
106
- intervention_constraints = [mutates [v ](k ) for k , v in test ["mutations" ].items ()],
107
- treatment_variable = treatment_var ,
108
- expected_causal_effect = {
109
- self .scenario .variables [variable ]: effects [effect ]
110
- for variable , effect in test ["expected_effect" ].items ()
111
- },
112
- effect_modifiers = (
113
- {self .scenario .variables [v ] for v in test ["effect_modifiers" ]} if "effect_modifiers" in test else {}
114
- ),
115
- estimate_type = test ["estimate_type" ],
116
- effect = test .get ("effect" , "total" ),
117
- )
118
- return abstract_test
119
-
120
90
def run_json_tests (self , effects : dict , estimators : dict , f_flag : bool = False , mutates : dict = None ):
121
91
"""Runs and evaluates each test case specified in the JSON input
122
92
@@ -139,9 +109,7 @@ def run_json_tests(self, effects: dict, estimators: dict, f_flag: bool = False,
139
109
test = test , f_flag = f_flag , effects = effects , estimate_type = test ["estimate_type" ]
140
110
)
141
111
else :
142
- failed , msg = self ._run_metamorphic_tests (
143
- test = test , f_flag = f_flag , effects = effects , mutates = mutates
144
- )
112
+ raise NotImplementedError ("Tried to call deprecated method _run_metamorphic_tests" )
145
113
test ["failed" ] = failed
146
114
test ["result" ] = msg
147
115
return self .test_plan ["tests" ]
@@ -189,8 +157,6 @@ def _run_concrete_metamorphic_test(self, test: dict, f_flag: bool, effects: dict
189
157
causal_test_case = CausalTestCase (
190
158
base_test_case = base_test_case ,
191
159
expected_causal_effect = effects [test ["expected_effect" ][outcome_variable ]],
192
- control_value = test ["control_value" ],
193
- treatment_value = test ["treatment_value" ],
194
160
estimate_type = test ["estimate_type" ],
195
161
)
196
162
failed , msg = self ._execute_test_case (causal_test_case = causal_test_case , test = test , f_flag = f_flag )
@@ -205,41 +171,6 @@ def _run_concrete_metamorphic_test(self, test: dict, f_flag: bool, effects: dict
205
171
self ._append_to_file (msg , logging .INFO )
206
172
return failed , msg
207
173
208
- def _run_metamorphic_tests (self , test : dict , f_flag : bool , effects : dict , mutates : dict ):
209
- """Builds structures and runs test case for tests with an estimate_type of 'ate'.
210
-
211
- :param test: Single JSON test definition stored in a mapping (dict)
212
- :param f_flag: Failure flag that if True the script will stop executing when a test fails.
213
- :param effects: Dictionary mapping effect class instances to string representations.
214
- :param mutates: Dictionary mapping mutation functions to string representations.
215
- :return: String containing the message to be outputted
216
- """
217
- if "sample_size" in test :
218
- sample_size = test ["sample_size" ]
219
- else :
220
- sample_size = 5
221
- if "target_ks_score" in test :
222
- target_ks_score = test ["target_ks_score" ]
223
- else :
224
- target_ks_score = 0.05
225
- abstract_test = self ._create_abstract_test_case (test , mutates , effects )
226
- concrete_tests , _ = abstract_test .generate_concrete_tests (
227
- sample_size = sample_size , target_ks_score = target_ks_score
228
- )
229
- failures , _ = self ._execute_tests (concrete_tests , test , f_flag )
230
-
231
- msg = (
232
- f"Executing test: { test ['name' ]} \n "
233
- + " abstract_test \n "
234
- + f" { abstract_test } \n "
235
- + f" { abstract_test .treatment_variable .name } ,"
236
- + f" { abstract_test .treatment_variable .distribution } \n "
237
- + f" Number of concrete tests for test case: { str (len (concrete_tests ))} \n "
238
- + f" { failures } /{ len (concrete_tests )} failed for { test ['name' ]} "
239
- )
240
- self ._append_to_file (msg , logging .INFO )
241
- return failures , msg
242
-
243
174
def _execute_tests (self , concrete_tests , test , f_flag ):
244
175
failures = 0
245
176
details = []
@@ -274,7 +205,8 @@ def _execute_test_case(
274
205
failed = False
275
206
276
207
estimation_model = self ._setup_test (causal_test_case = causal_test_case , test = test )
277
- causal_test_result = causal_test_case .execute_test (estimator = estimation_model )
208
+ causal_test_case .estimator = estimation_model
209
+ causal_test_result = causal_test_case .execute_test ()
278
210
test_passes = causal_test_case .expected_causal_effect .apply (causal_test_result )
279
211
280
212
if "coverage" in test and test ["coverage" ]:
@@ -307,6 +239,7 @@ def _setup_test(self, causal_test_case: CausalTestCase, test: Mapping) -> Estima
307
239
- estimation_model - Estimator instance for the test being run
308
240
"""
309
241
estimator_kwargs = {}
242
+ treatment_variable = next (self .scenario .variables [v ] for v in test ["mutations" ])
310
243
if "formula" in test :
311
244
if test ["estimator" ] != (LinearRegressionEstimator or LogisticRegressionEstimator ):
312
245
raise TypeError (
@@ -319,14 +252,14 @@ def _setup_test(self, causal_test_case: CausalTestCase, test: Mapping) -> Estima
319
252
minimal_adjustment_set = self .causal_specification .causal_dag .identification (
320
253
causal_test_case .base_test_case
321
254
)
322
- minimal_adjustment_set = minimal_adjustment_set - {causal_test_case . treatment_variable }
255
+ minimal_adjustment_set = minimal_adjustment_set - {treatment_variable }
323
256
estimator_kwargs ["adjustment_set" ] = minimal_adjustment_set
324
257
325
258
estimator_kwargs ["query" ] = test ["query" ] if "query" in test else ""
326
- estimator_kwargs ["treatment" ] = causal_test_case . treatment_variable .name
327
- estimator_kwargs ["treatment_value" ] = causal_test_case . treatment_value
328
- estimator_kwargs ["control_value" ] = causal_test_case . control_value
329
- estimator_kwargs ["outcome" ] = causal_test_case . outcome_variable . name
259
+ estimator_kwargs ["treatment" ] = treatment_variable .name
260
+ estimator_kwargs ["treatment_value" ] = test . get ( " treatment_value" )
261
+ estimator_kwargs ["control_value" ] = test . get ( " control_value" )
262
+ estimator_kwargs ["outcome" ] = next ( v for v in test [ "expected_effect" ])
330
263
estimator_kwargs ["effect_modifiers" ] = causal_test_case .effect_modifier_configuration
331
264
estimator_kwargs ["df" ] = self .df
332
265
estimator_kwargs ["alpha" ] = test ["alpha" ] if "alpha" in test else 0.05
0 commit comments