def test_estimate_class_level_struct(self): utilities = {'fare1': -2.8564, 'fare2': -2.5684} probs, nofly_prob = mfrm.selection_probs(utilities, 0.5) estimations = mfrm.estimate_class_level({ 'fare1': 3, 'fare2': 0 }, { 'fare1': 1, 'fare2': 0. }, probs, nofly_prob) self.assertIsInstance(estimations, dict) self.assertEqual(len(estimations), 2) self.assertEqual(sorted(estimations.keys()), ['fare1', 'fare2']) self.assertEqual(sorted(estimations['fare1'].keys()), ['demand', 'recapture', 'spill'])
def test_estimate_class_level_ex1(self): utilities = {'fare1': -2.8564, 'fare2': -2.5684} probs, nofly_prob = mfrm.selection_probs(utilities, 0.5) estimations = mfrm.estimate_class_level({ 'fare1': 3, 'fare2': 0 }, { 'fare1': 1, 'fare2': 0. }, probs, nofly_prob) self.assertAlmostEqual(estimations['fare1']['spill'], 0, places=2) self.assertAlmostEqual(estimations['fare1']['recapture'], 0.86, 2) self.assertAlmostEqual(estimations['fare1']['demand'], 2.14, 2) self.assertAlmostEqual(estimations['fare2']['spill'], 2.86, places=2) self.assertAlmostEqual(estimations['fare2']['recapture'], 0, 2) self.assertAlmostEqual(estimations['fare2']['demand'], 2.86, 2)
def test_estimate_paper_ex1(self): """This test is based on the exaple #1 in the paper""" utilities = {'fare1': -2.8564, 'fare2': -2.5684} probs, nofly_prob = mfrm.selection_probs(utilities, 0.5) estimations = mfrm.estimate_host_level({ 'fare1': 3, 'fare2': 0 }, { 'fare1': 1, 'fare2': 0. }, probs, nofly_prob) self.assertIsInstance(estimations, tuple) self.assertEqual(len(estimations), 3) # round numbers estimations = round_tuple(estimations) self.assertTupleEqual(estimations, (5, 2.86, 0.86))
def test_estimate_class_level_regression_2(self): utilities = { '25169088_1990': -0.32789022, '25177238_2490': 0.74647802, '30920878_3590': 1.1093128, '30921208_3590': -0.95266426, '25176068_2990': 0.60245919, '27334408_3590': 1.3004869, '27336048_2490': -0.72204816, '25176068_2490': 1.1348069, '27330978_3950': -0.95266426, '27331818_2490': 1.1348069, '25174968_2990': -0.95266426, '27331818_3590': 0.60245919, '25172878_2990': 1.3004869, '27330978_3590': -0.95266426, '25174968_3590': -0.95266426, '27334408_3950': 1.3004869, '30920428_2490': -0.72204816, '27331818_2990': 0.60245919, '25168168_1990': -0.86685419, '25168168_3590': 0.028352857, '25177238_2990': 0.37813818, '25170958_1990': 0.43109083, '25178118_1500': 1.557166, '25172878_3590': 1.3004869, '25173528_2990': -0.86880505, '25173528_2490': 0.77468485, '27332988_2990': 0.59399945, '25168168_2490': -0.72204816, '25170958_2490': 0.5758968, '27332988_2490': -0.18308425, '25168168_2990': 0.028352857 } observed = { '25169088_1990': 2, '25177238_2490': 5, '25176068_2990': 1, '25177238_2990': 1, '25170958_1990': 7, '25176068_2490': 5, '25168168_1990': 1, '25174968_2990': 2, '25173528_2990': 2, '25173528_2490': 1, '25172878_2990': 3, '25168168_2490': 3, '25170958_2490': 3, '25178118_1500': 5 } availability = { '25177238_2490': 0.954545454545455, '25169088_1990': 1.0, '30920878_3590': 1.0, '30921208_3590': 1.0, '25176068_2990': 0.272727272727273, '27334408_3590': 0.409090909090909, '27334408_3950': 0.590909090909091, '25176068_2490': 0.909090909090909, '27331818_2990': 0.363636363636364, '27331818_2490': 0.590909090909091, '25172878_3590': 0.136363636363636, '27331818_3590': 0.136363636363636, '25172878_2990': 0.909090909090909, '27330978_3590': 0.454545454545455, '25174968_3590': 0.0454545454545455, '27336048_2490': 1.0, '30920428_2490': 1.0, '27330978_3950': 0.590909090909091, '25168168_1990': 0.727272727272727, '25168168_3590': 0.0454545454545455, '25177238_2990': 0.0909090909090909, '25170958_1990': 0.590909090909091, '25178118_1500': 1.0, '25174968_2990': 1.0, '25173528_2990': 0.590909090909091, '25173528_2490': 0.5, '27332988_2990': 0.545454545454545, '25168168_2490': 0.454545454545455, '25170958_2490': 0.454545454545455, '27332988_2490': 0.681818181818182, '25168168_2990': 0.0454545454545455 } probs, nofly_prob = mfrm.selection_probs(utilities, 0.7) class_level = mfrm.estimate_class_level(observed, availability, probs, nofly_prob) self.assertEqual(class_level['25168168_2990'], { 'demand': 0, 'spill': 0, 'recapture': 0 }) total_demand = sum([round(d['demand']) for d in class_level.values()]) self.assertEqual(total_demand, 50) total_demand = sum([round(d['spill']) for d in class_level.values()]) self.assertEqual(total_demand, 20)
def test_estimate_class_level_regression_1(self): utilities = { '29255588_3950': 1.4659572, '27330948_3950': 2.16431, '29255588_2490': 1.1630461, '29255578_2990': 1.3300509, '29255508_3950': 0.43902999, '29255578_3590': 0.83872116, '29255578_3950': 0.70265454, '29255528_3590': 0.52609205, '29255518_3590': 0.52609205, '30920848_3950': -0.19642138, '27331928_3950': 0.096954226, '27337358_3590': 0.52609205, '27334478_3590': -0.12226862, '29255548_3950': 1.4128097, '29255558_3590': 0.2330209, '29255588_2990': 0.99219722, '29255538_3590': 0.76555932, '27341178_3590': 0.61577702, '29255548_3590': 1.3927615, '29255558_2990': 0.72435057 } observed = { '29255588_3950': 3, '27330948_3950': 1, '29255578_2990': 7, '27331928_2450': 1, '27331928_3200': 4, # missing in 'utilities' '27331928_2490': 1, '29255588_3018': 1, '29255588_2490': 6, '29255518_3950': 1, '29255578_3018': 1, '27331928_3950': 2, '29255578_3950': 3, '29255548_3950': 2, '29255588_2518': 1, '29255538_3590': 1, '29255578_3590': 1, '29255588_2241': 1 } availability = { '29255588_3950': 0.650909090909091, '27330948_3950': 0.634146341463415, '29255578_2990': 0.1875, '27331928_2450': 0.00436681222707424, '30920848_3950': 0.5, '29255538_3950': 0.0411764705882353, '29255528_3590': 0.796875, '29255518_3950': 0.032967032967033, '29255588_3590': 0.0254545454545455, '29255518_3590': 0.648351648351648, '29255558_3950': 0.00436681222707424, '27334478_3590': 0.753246753246753, '27334478_3950': 0.0779220779220779, '29255528_3950': 0.0703125, '29255548_3950': 0.521951219512195, '29255558_3590': 0.148471615720524, '29255578_3018': 0.00436681222707424, '27331928_2490': 0.00436681222707424, '29255548_3590': 0.268292682926829, '29255588_2241': 0.00436681222707424, '29255508_3950': 0.714285714285714, '27331928_3200': 0.00436681222707424, '29255588_2518': 0.00436681222707424, '29255588_3018': 0.00436681222707424, '29255588_2490': 0.0872727272727273, '27331928_3950': 0.370517928286853, '27337358_3590': 0.774193548387097, '29255578_3950': 0.213235294117647, '29255578_3590': 0.132352941176471, '29255588_2990': 0.236363636363636, '29255538_3590': 0.911764705882353, '27341178_3590': 0.971428571428571, '29255558_2990': 0.152838427947598 } probs, nofly_prob = mfrm.selection_probs(utilities, 0.7) class_level = mfrm.estimate_class_level(observed, availability, probs, nofly_prob) # no utility self.assertTrue('27331928_2490' not in class_level) # low utility and no observed demand self.assertEqual(class_level['27334478_3590'], { 'demand': 0, 'spill': 0, 'recapture': 0 }) # one observation and low utility self.assertLess(class_level['29255538_3590']['demand'], observed['29255538_3590']) self.assertLess(class_level['29255538_3590']['spill'], 0.1) # high utility, many bookings, low availability self.assertGreater(class_level['29255578_2990']['demand'], observed['29255578_2990']) self.assertGreater(class_level['29255578_2990']['spill'], observed['29255578_2990']) # moderate utility, many bookings, moderate availability self.assertGreater(class_level['29255578_3950']['demand'], observed['29255578_3950'])