def test_invalid_max_weight(self): # Should fail when the max_weight is smaller than the uniform weight. with self.assertRaises(ValueError): ec.calibrate( covariates=self.covariates, target_covariates=self.target_covariates, max_weight=1.0 / (_SIZE + 1000))
def test_invalid_l2_norm(self): # Should fail with negative l2_norm. with self.assertRaises(ValueError): ec.calibrate( covariates=self.covariates, target_covariates=self.target_covariates, l2_norm=-0.01)
def test_autoscale(self, objective): weights_raw = ec.calibrate(covariates=self.covariates, target_covariates=self.target_covariates, autoscale=False, objective=objective)[0] weights_scaled = ec.calibrate(covariates=self.covariates, target_covariates=self.target_covariates, autoscale=True, objective=objective)[0] # With and without autoscale should give almost identical weight. self.assertAlmostEqual(0, np.linalg.norm(weights_raw - weights_scaled))
def test_quadratic_balancing_approximate(self): weights_exact = ec.calibrate(covariates=self.covariates, target_covariates=self.target_covariates, objective=ec.Objective.QUADRATIC, l2_norm=0.0)[0] weights_approximate = ec.calibrate( covariates=self.covariates, target_covariates=self.target_covariates, objective=ec.Objective.QUADRATIC, l2_norm=0.1)[0] # Approximate match should lead to a better objective. self.assertGreaterEqual(np.sum(np.square(weights_exact)), np.sum(np.square(weights_approximate)))
def test_entropy_balancing_approximate(self): weights_exact = ec.calibrate(covariates=self.covariates, target_covariates=self.target_covariates, objective=ec.Objective.ENTROPY, l2_norm=0.0)[0] weights_approximate = ec.calibrate( covariates=self.covariates, target_covariates=self.target_covariates, objective=ec.Objective.ENTROPY, l2_norm=0.1)[0] # Approximate match should lead to a better objective. self.assertGreaterEqual(-scipy.stats.entropy(weights_exact), -scipy.stats.entropy(weights_approximate))
def test_entropy_balancing_bounded(self): weights_unbounded = ec.calibrate( covariates=self.covariates, target_covariates=self.target_covariates, objective=ec.Objective.ENTROPY, max_weight=1.0)[0] weights_bounded = ec.calibrate( covariates=self.covariates, target_covariates=self.target_covariates, objective=ec.Objective.ENTROPY, max_weight=0.005)[0] # Imposing an upper bound on weights should lead to a worse objective. self.assertLessEqual(-scipy.stats.entropy(weights_unbounded), -scipy.stats.entropy(weights_bounded))
def test_quadratic_balancing_bounded(self): weights_unbounded = ec.calibrate( covariates=self.covariates, target_covariates=self.target_covariates, objective=ec.Objective.QUADRATIC, max_weight=1.0)[0] weights_bounded = ec.calibrate( covariates=self.covariates, target_covariates=self.target_covariates, objective=ec.Objective.QUADRATIC, max_weight=0.005)[0] # Imposing an upper bound on weights should lead to a worse objective. self.assertLessEqual(np.sum(np.square(weights_unbounded)), np.sum(np.square(weights_bounded)))
def test_uniform_weights(self, objective): # when covariates == target_covariates, uniform weights should be returned. covariates = target_covariates = np.random.normal(size=(100, 4)) weights, success = ec.calibrate(covariates=covariates, target_covariates=target_covariates, objective=objective) self.assertTrue(all(np.isclose(weights, 1.0 / 100)))
def test_calibrate(self, objective, max_weight, l2_norm): weights, success = ec.calibrate( covariates=self.covariates, target_covariates=self.target_covariates, objective=objective, max_weight=max_weight, l2_norm=l2_norm) self.assertTrue(success) self.assert_weights_constraints(weights, max_weight) self.assert_balancing_constraint(weights, l2_norm)
def test_baseline_weights(self, objective): covariates = target_covariates = np.random.normal(size=(100, 2)) repeats = np.repeat([2, 1], 50) weights, success = ec.calibrate(covariates=covariates, target_covariates=target_covariates, baseline_weights=repeats, target_weights=repeats, objective=ec.Objective.QUADRATIC) # First 50 rows should have 2 / 3 of the weights. expected = repeats * 2 / 3 / 100 self.assertTrue(all(np.isclose(weights, expected)))