예제 #1
0
    def test_group_sequential(self):
        """ Check the group sequential function."""
        res = es.group_sequential(self.rand_s1, self.rand_s2)

        self.assertEqual(res.treatment_statistics.sample_size, 1000)
        self.assertEqual(res.control_statistics.sample_size, 1000)
        self.assertAlmostEqual(res.treatment_statistics.mean,
                               -0.045256707490195384)
        self.assertAlmostEqual(res.control_statistics.mean,
                               0.11361694031616358)
        self.assertAlmostEqual(res.treatment_statistics.variance,
                               0.9742344563121542)
        self.assertAlmostEqual(res.control_statistics.variance,
                               0.9373337542827797)

        self.assertAlmostEqual(res.delta, -0.15887364780635896)
        value025 = find_value_by_key_with_condition(res.confidence_interval,
                                                    'percentile', 2.5, 'value')
        value975 = find_value_by_key_with_condition(res.confidence_interval,
                                                    'percentile', 97.5,
                                                    'value')
        np.testing.assert_almost_equal(value025,
                                       -0.24461812530841959,
                                       decimal=5)
        np.testing.assert_almost_equal(value975,
                                       -0.07312917030429833,
                                       decimal=5)

        self.assertAlmostEqual(res.p, 0.0002863669955157941)
        self.assertAlmostEqual(res.statistical_power, 0.9529152504960496)
        self.assertEqual(res.stop, True)
예제 #2
0
    def test_group_sequential_multi_test_correction(self):
        """
        Test group sequential with multiple correction
        """
        res = es.group_sequential(self.rand_s1,
                                  self.rand_s2,
                                  multi_test_correction=True,
                                  num_tests=25)

        self.assertEqual(res['stop'], True)
        self.assertAlmostEqual(res['delta'], -0.15887364780635896)
        value025 = find_list_of_dicts_element(res['confidence_interval'],
                                              'percentile', 0.1, 'value')
        value975 = find_list_of_dicts_element(res['confidence_interval'],
                                              'percentile', 99.9, 'value')
        np.testing.assert_almost_equal(value025,
                                       -0.29416175390519078,
                                       decimal=5)
        np.testing.assert_almost_equal(value975,
                                       -0.023585541707525692,
                                       decimal=5)
        self.assertEqual(res['treatment_sample_size'], 1000)
        self.assertEqual(res['control_sample_size'], 1000)
        self.assertAlmostEqual(res['treatment_mean'], -0.045256707490195384)
        self.assertAlmostEqual(res['control_mean'], 0.11361694031616358)
예제 #3
0
    def test_group_sequential_actual_size_larger_than_estimated(self):
        """ Check the group sequential function with wrong input,
        such that the actual data size is already larger than estimated sample size.
        """
        res = es.group_sequential(self.rand_s1, self.rand_s2, estimated_sample_size=100)

        value025 = find_value_by_key_with_condition(res.confidence_interval, 'percentile', 2.5, 'value')
        value975 = find_value_by_key_with_condition(res.confidence_interval, 'percentile', 97.5, 'value')
        np.testing.assert_almost_equal (value025, -0.24461812530841959, decimal=5)
        np.testing.assert_almost_equal (value975, -0.07312917030429833, decimal=5)
예제 #4
0
	def group_sequential_delta(self,
							   result,
							   kpis_to_analyse,
							   spending_function='obrien_fleming',
					 		   information_fraction=1,
							   alpha=0.05,
					 		   cap=8,
					 		   **kwargs):
		"""
		Calculate the stopping criterion based on the group sequential design 
		and the effect size.

		Args:
			result: the initialized Results object
			kpis_to_analyse: list of KPIs to be analysed
			spending_function: name of the alpha spending function, currently
				supports: 'obrien_fleming'
			information_fraction: share of the information amount at the point 
				of evaluation, e.g. the share of the maximum sample size
			alpha: type-I error rate
			cap: upper bound of the adapted z-score

		Returns:
			a Results object
		"""
		if 'estimatedSampleSize' not in self.metadata:
			raise ValueError("Missing 'estimatedSampleSize' for the group sequential method!")

		for mname in kpis_to_analyse:
			metric_df = self.kpis.reset_index()[['entity', 'variant', mname]]
			baseline_metric = metric_df.iloc[:, 2][metric_df.iloc[:, 1] == self.baseline_variant]
			current_sample_size = float(sum(~metric_df[mname].isnull()))

			do_delta = (lambda f: early_stopping_to_dataframe(f.columns[2],
															  *es.group_sequential(
																  x=f.iloc[:, 2],
																  y=baseline_metric,
																  spending_function=spending_function,
					 											  information_fraction=current_sample_size/self.metadata['estimatedSampleSize'],
					 											  alpha=alpha,
					 											  cap=cap)))

			# Actual calculation
			df = metric_df.groupby('variant').apply(do_delta).unstack(0)
			# force the stop label of the baseline variant to 0
			df.loc[(mname,'-',slice(None),'stop'),('value',self.baseline_variant)] = 0

			if result.df is None:
				result.df = df
			else:
				result.df = result.df.append(df)

		return result
예제 #5
0
    def test_group_sequential(self):
        """
        Check the group sequential function.
        """
        res = es.group_sequential(self.rand_s1, self.rand_s2)

        self.assertEqual               (res['stop'],                  True)
        self.assertAlmostEqual         (res['delta'],                -0.15887364780635896)
        value025 = find_list_of_dicts_element(res['confidence_interval'], 'percentile',  2.5, 'value')
        value975 = find_list_of_dicts_element(res['confidence_interval'], 'percentile', 97.5, 'value')
        np.testing.assert_almost_equal (value025,                     -0.24461812530841959, decimal=5)
        np.testing.assert_almost_equal (value975,                     -0.07312917030429833, decimal=5)
        self.assertEqual               (res['treatment_sample_size'],  1000)
        self.assertEqual               (res['control_sample_size'],    1000)
        self.assertAlmostEqual         (res['treatment_mean'],        -0.045256707490195384)
        self.assertAlmostEqual         (res['control_mean'],           0.11361694031616358)
예제 #6
0
    def test_group_sequential(self):
        """
        Check the group sequential function.
        """
        res = es.group_sequential(self.rand_s1, self.rand_s2)

        self.assertEqual(res['stop'], True)
        self.assertAlmostEqual(res['delta'], -0.15887364780635896)
        np.testing.assert_almost_equal(res['interval'][02.5],
                                       -0.24461812530841959,
                                       decimal=5)
        np.testing.assert_almost_equal(res['interval'][97.5],
                                       -0.07312917030429833,
                                       decimal=5)
        self.assertEqual(res['n_x'], 1000)
        self.assertEqual(res['n_y'], 1000)
        self.assertAlmostEqual(res['mu_x'], -0.045256707490195384)
        self.assertAlmostEqual(res['mu_y'], 0.11361694031616358)
예제 #7
0
    def test_group_sequential_actual_size_larger_than_estimated(self):
        """ Check the group sequential function with wrong input,
        such that the actual data size is already larger than estimated sample size.
        """
        res = es.group_sequential(self.rand_s1,
                                  self.rand_s2,
                                  estimated_sample_size=100)

        value025 = find_value_by_key_with_condition(res.confidence_interval,
                                                    'percentile', 2.5, 'value')
        value975 = find_value_by_key_with_condition(res.confidence_interval,
                                                    'percentile', 97.5,
                                                    'value')
        np.testing.assert_almost_equal(value025,
                                       -0.24461812530841959,
                                       decimal=5)
        np.testing.assert_almost_equal(value975,
                                       -0.07312917030429833,
                                       decimal=5)
 def test_group_sequential(self):
     """
 	Check the group sequential function.
 	"""
     stop, delta, CI, n_x, n_y, mu_x, mu_y = es.group_sequential(
         self.rand_s1, self.rand_s2)
     self.assertEqual(stop, 1)
     self.assertAlmostEqual(delta, -0.15887364780635896)
     # np.testing.assert_almost_equal(CI.values(), [-0.24461812530841959, -0.07312917030429833], decimal=5)
     np.testing.assert_almost_equal(CI[97.5],
                                    -0.07312917030429833,
                                    decimal=5)
     np.testing.assert_almost_equal(CI[2.5000000000000022],
                                    -0.24461812530841959,
                                    decimal=5)
     self.assertEqual(n_x, 1000)
     self.assertEqual(n_y, 1000)
     self.assertAlmostEqual(mu_x, -0.045256707490195384)
     self.assertAlmostEqual(mu_y, 0.11361694031616358)
예제 #9
0
    def test_group_sequential(self):
        """ Check the group sequential function."""
        res = es.group_sequential(self.rand_s1, self.rand_s2)

        self.assertEqual(res.treatment_statistics.sample_size,     1000)
        self.assertEqual(res.control_statistics.sample_size,       1000)
        self.assertAlmostEqual(res.treatment_statistics.mean,     -0.045256707490195384)
        self.assertAlmostEqual(res.control_statistics.mean,        0.11361694031616358)
        self.assertAlmostEqual(res.treatment_statistics.variance,  0.9742344563121542)
        self.assertAlmostEqual(res.control_statistics.variance,    0.9373337542827797)

        self.assertAlmostEqual(res.delta, -0.15887364780635896)
        value025 = find_value_by_key_with_condition(res.confidence_interval, 'percentile', 2.5, 'value')
        value975 = find_value_by_key_with_condition(res.confidence_interval, 'percentile', 97.5, 'value')
        np.testing.assert_almost_equal(value025, -0.24461812530841959, decimal=5)
        np.testing.assert_almost_equal(value975, -0.07312917030429833, decimal=5)

        self.assertAlmostEqual(res.p,                 0.0002863669955157941)
        self.assertAlmostEqual(res.statistical_power, 0.9529152504960496)
        self.assertEqual(res.stop,                    True)