|
15 | 15 | from unittest import mock |
16 | 16 | from absl.testing import absltest |
17 | 17 | from absl.testing import parameterized |
| 18 | +from meridian import backend |
18 | 19 | from meridian import constants |
19 | 20 | from meridian.model import model |
20 | 21 | from meridian.model import model_test_data |
@@ -4605,6 +4606,113 @@ def test_check_national_vif_has_correct_vif_value(self): |
4605 | 4606 | ] |
4606 | 4607 | self.assertAllClose(national_artifact.vif_da.values, expected_national_vif) |
4607 | 4608 |
|
| 4609 | + @parameterized.named_parameters( |
| 4610 | + dict( |
| 4611 | + testcase_name="has_variability", |
| 4612 | + population_scaled_stdev=1.0, |
| 4613 | + expected_result=True, |
| 4614 | + ), |
| 4615 | + dict( |
| 4616 | + testcase_name="no_variability", |
| 4617 | + population_scaled_stdev=0.0, |
| 4618 | + expected_result=False, |
| 4619 | + ), |
| 4620 | + ) |
| 4621 | + def test_kpi_has_variability(self, population_scaled_stdev, expected_result): |
| 4622 | + meridian = mock.Mock(spec=model.Meridian) |
| 4623 | + meridian.kpi_transformer.population_scaled_stdev = population_scaled_stdev |
| 4624 | + engine = eda_engine.EDAEngine(meridian) |
| 4625 | + self.assertEqual(engine.kpi_has_variability(), expected_result) |
| 4626 | + |
| 4627 | + @parameterized.named_parameters( |
| 4628 | + dict( |
| 4629 | + testcase_name="geo", |
| 4630 | + is_national=False, |
| 4631 | + expected_kpi_name="population_scaled_kpi", |
| 4632 | + ), |
| 4633 | + dict( |
| 4634 | + testcase_name="national", |
| 4635 | + is_national=True, |
| 4636 | + expected_kpi_name="kpi", |
| 4637 | + ), |
| 4638 | + ) |
| 4639 | + def test_check_overall_kpi_invariance_no_variability( |
| 4640 | + self, is_national, expected_kpi_name |
| 4641 | + ): |
| 4642 | + meridian = mock.Mock(spec=model.Meridian) |
| 4643 | + meridian.is_national = is_national |
| 4644 | + meridian.input_data.kpi = self.input_data_with_media_only.kpi |
| 4645 | + mock_kpi_transformer = mock.Mock() |
| 4646 | + mock_kpi_transformer.population_scaled_stdev = 0.0 |
| 4647 | + mock_kpi_transformer.population_scaled_mean = 100.0 |
| 4648 | + mock_kpi_transformer.population_scaled_kpi = backend.zeros( |
| 4649 | + (self._N_GEOS, self._N_TIMES), dtype=backend.float32 |
| 4650 | + ) |
| 4651 | + meridian.kpi_transformer = mock_kpi_transformer |
| 4652 | + engine = eda_engine.EDAEngine(meridian) |
| 4653 | + |
| 4654 | + outcome = engine.check_overall_kpi_invariance() |
| 4655 | + |
| 4656 | + self.assertEqual( |
| 4657 | + outcome.check_type, eda_outcome.EDACheckType.KPI_INVARIANCE |
| 4658 | + ) |
| 4659 | + self.assertLen(outcome.findings, 1) |
| 4660 | + self.assertEqual( |
| 4661 | + outcome.findings[0].severity, eda_outcome.EDASeverity.ERROR |
| 4662 | + ) |
| 4663 | + self.assertIn( |
| 4664 | + f"`{expected_kpi_name}` is constant across all geos and times", |
| 4665 | + outcome.findings[0].explanation, |
| 4666 | + ) |
| 4667 | + self.assertLen(outcome.analysis_artifacts, 1) |
| 4668 | + artifact = outcome.analysis_artifacts[0] |
| 4669 | + self.assertIsInstance(artifact, eda_outcome.KpiInvarianceArtifact) |
| 4670 | + self.assertEqual(artifact.level, eda_outcome.AnalysisLevel.OVERALL) |
| 4671 | + self.assertEqual(artifact.population_scaled_stdev, 0.0) |
| 4672 | + self.assertEqual(artifact.population_scaled_mean, 100.0) |
| 4673 | + self.assertAllClose( |
| 4674 | + artifact.population_scaled_kpi_da.values, |
| 4675 | + backend.to_tensor(mock_kpi_transformer.population_scaled_kpi), |
| 4676 | + ) |
| 4677 | + |
| 4678 | + def test_check_overall_kpi_invariance_has_variability(self): |
| 4679 | + meridian = mock.Mock(spec=model.Meridian) |
| 4680 | + meridian.is_national = False |
| 4681 | + meridian.input_data.kpi = self.input_data_with_media_only.kpi |
| 4682 | + mock_kpi_transformer = mock.Mock() |
| 4683 | + mock_kpi_transformer.population_scaled_stdev = 1.0 |
| 4684 | + mock_kpi_transformer.population_scaled_mean = 100.0 |
| 4685 | + mock_kpi_transformer.population_scaled_kpi = backend.to_tensor( |
| 4686 | + np.arange(self._N_GEOS * self._N_TIMES).reshape( |
| 4687 | + self._N_GEOS, self._N_TIMES |
| 4688 | + ), |
| 4689 | + dtype=backend.float32, |
| 4690 | + ) |
| 4691 | + meridian.kpi_transformer = mock_kpi_transformer |
| 4692 | + engine = eda_engine.EDAEngine(meridian) |
| 4693 | + |
| 4694 | + outcome = engine.check_overall_kpi_invariance() |
| 4695 | + |
| 4696 | + self.assertEqual( |
| 4697 | + outcome.check_type, eda_outcome.EDACheckType.KPI_INVARIANCE |
| 4698 | + ) |
| 4699 | + self.assertLen(outcome.findings, 1) |
| 4700 | + self.assertEqual(outcome.findings[0].severity, eda_outcome.EDASeverity.INFO) |
| 4701 | + self.assertIn( |
| 4702 | + "The KPI has variability across geos and times", |
| 4703 | + outcome.findings[0].explanation, |
| 4704 | + ) |
| 4705 | + self.assertLen(outcome.analysis_artifacts, 1) |
| 4706 | + artifact = outcome.analysis_artifacts[0] |
| 4707 | + self.assertIsInstance(artifact, eda_outcome.KpiInvarianceArtifact) |
| 4708 | + self.assertEqual(artifact.level, eda_outcome.AnalysisLevel.OVERALL) |
| 4709 | + self.assertEqual(artifact.population_scaled_stdev, 1.0) |
| 4710 | + self.assertEqual(artifact.population_scaled_mean, 100.0) |
| 4711 | + self.assertAllClose( |
| 4712 | + artifact.population_scaled_kpi_da.values, |
| 4713 | + backend.to_tensor(mock_kpi_transformer.population_scaled_kpi), |
| 4714 | + ) |
| 4715 | + |
4608 | 4716 |
|
4609 | 4717 | if __name__ == "__main__": |
4610 | 4718 | absltest.main() |
0 commit comments