Note
Go to the end to download the full example code.
Calculation of market shares¶
We use an estimated model to calculate market shares.
Michel Bierlaire, EPFL Sat Jun 28 2025, 18:06:27
import sys
from biogeme.biogeme import BIOGEME
from biogeme.data.optima import normalized_weight, read_data
from biogeme.models import nested
from biogeme.results_processing import EstimationResults
from scenarios import scenario
Obtain the specification for the default scenario
v, nests, _, _ = scenario()
Obtain the expression for the choice probability of each alternative.
prob_pt = nested(v, None, nests, 0)
prob_car = nested(v, None, nests, 1)
prob_sm = nested(v, None, nests, 2)
Read the estimation results from the file
try:
results = EstimationResults.from_yaml_file(
filename='saved_results/b02estimation.yaml'
)
except FileNotFoundError:
sys.exit(
'Run first the script b02simulation.py '
'in order to generate the '
'file b02estimation.yaml.'
)
Read the database
database = read_data()
We now simulate the choice probabilities and the weight
simulate = {
'weight': normalized_weight,
'Prob. PT': prob_pt,
'Prob. car': prob_car,
'Prob. SM': prob_sm,
}
the_biogeme = BIOGEME(database, simulate)
simulated_values = the_biogeme.simulate(results.get_beta_values())
We also calculate confidence intervals for the calculated quantities,
b = results.get_betas_for_sensitivity_analysis()
left, right = the_biogeme.confidence_intervals(b, 0.9)
0%| | 0/100 [00:00<?, ?it/s]
1%| | 1/100 [00:00<00:55, 1.79it/s]
2%|▏ | 2/100 [00:01<00:55, 1.77it/s]
3%|▎ | 3/100 [00:01<00:55, 1.76it/s]
4%|▍ | 4/100 [00:02<00:56, 1.70it/s]
5%|▌ | 5/100 [00:02<00:54, 1.73it/s]
6%|▌ | 6/100 [00:03<00:53, 1.75it/s]
7%|▋ | 7/100 [00:03<00:52, 1.77it/s]
8%|▊ | 8/100 [00:04<00:51, 1.78it/s]
9%|▉ | 9/100 [00:05<00:51, 1.78it/s]
10%|█ | 10/100 [00:05<00:50, 1.79it/s]
11%|█ | 11/100 [00:06<00:49, 1.80it/s]
12%|█▏ | 12/100 [00:06<00:48, 1.80it/s]
13%|█▎ | 13/100 [00:07<00:48, 1.81it/s]
14%|█▍ | 14/100 [00:07<00:47, 1.81it/s]
15%|█▌ | 15/100 [00:08<00:46, 1.82it/s]
16%|█▌ | 16/100 [00:08<00:46, 1.82it/s]
17%|█▋ | 17/100 [00:09<00:45, 1.82it/s]
18%|█▊ | 18/100 [00:10<00:45, 1.82it/s]
19%|█▉ | 19/100 [00:10<00:44, 1.82it/s]
20%|██ | 20/100 [00:11<00:44, 1.81it/s]
21%|██ | 21/100 [00:11<00:43, 1.81it/s]
22%|██▏ | 22/100 [00:12<00:42, 1.82it/s]
23%|██▎ | 23/100 [00:12<00:42, 1.82it/s]
24%|██▍ | 24/100 [00:13<00:41, 1.81it/s]
25%|██▌ | 25/100 [00:13<00:41, 1.81it/s]
26%|██▌ | 26/100 [00:14<00:40, 1.81it/s]
27%|██▋ | 27/100 [00:15<00:40, 1.82it/s]
28%|██▊ | 28/100 [00:15<00:39, 1.81it/s]
29%|██▉ | 29/100 [00:16<00:39, 1.82it/s]
30%|███ | 30/100 [00:16<00:38, 1.81it/s]
31%|███ | 31/100 [00:17<00:38, 1.81it/s]
32%|███▏ | 32/100 [00:17<00:37, 1.81it/s]
33%|███▎ | 33/100 [00:18<00:36, 1.81it/s]
34%|███▍ | 34/100 [00:18<00:36, 1.82it/s]
35%|███▌ | 35/100 [00:19<00:35, 1.82it/s]
36%|███▌ | 36/100 [00:19<00:35, 1.82it/s]
37%|███▋ | 37/100 [00:20<00:34, 1.82it/s]
38%|███▊ | 38/100 [00:21<00:34, 1.82it/s]
39%|███▉ | 39/100 [00:21<00:33, 1.82it/s]
40%|████ | 40/100 [00:22<00:32, 1.83it/s]
41%|████ | 41/100 [00:22<00:32, 1.83it/s]
42%|████▏ | 42/100 [00:23<00:31, 1.82it/s]
43%|████▎ | 43/100 [00:23<00:31, 1.80it/s]
44%|████▍ | 44/100 [00:26<01:07, 1.21s/it]
45%|████▌ | 45/100 [00:27<00:55, 1.01s/it]
46%|████▌ | 46/100 [00:27<00:47, 1.15it/s]
47%|████▋ | 47/100 [00:28<00:41, 1.29it/s]
48%|████▊ | 48/100 [00:28<00:36, 1.42it/s]
49%|████▉ | 49/100 [00:29<00:33, 1.52it/s]
50%|█████ | 50/100 [00:29<00:31, 1.60it/s]
51%|█████ | 51/100 [00:30<00:29, 1.65it/s]
52%|█████▏ | 52/100 [00:30<00:28, 1.70it/s]
53%|█████▎ | 53/100 [00:31<00:27, 1.73it/s]
54%|█████▍ | 54/100 [00:32<00:26, 1.76it/s]
55%|█████▌ | 55/100 [00:32<00:25, 1.78it/s]
56%|█████▌ | 56/100 [00:33<00:24, 1.79it/s]
57%|█████▋ | 57/100 [00:33<00:23, 1.79it/s]
58%|█████▊ | 58/100 [00:34<00:23, 1.80it/s]
59%|█████▉ | 59/100 [00:34<00:22, 1.80it/s]
60%|██████ | 60/100 [00:35<00:22, 1.78it/s]
61%|██████ | 61/100 [00:35<00:21, 1.78it/s]
62%|██████▏ | 62/100 [00:36<00:21, 1.78it/s]
63%|██████▎ | 63/100 [00:37<00:20, 1.79it/s]
64%|██████▍ | 64/100 [00:37<00:20, 1.79it/s]
65%|██████▌ | 65/100 [00:38<00:19, 1.80it/s]
66%|██████▌ | 66/100 [00:38<00:18, 1.80it/s]
67%|██████▋ | 67/100 [00:39<00:18, 1.81it/s]
68%|██████▊ | 68/100 [00:39<00:17, 1.81it/s]
69%|██████▉ | 69/100 [00:40<00:17, 1.81it/s]
70%|███████ | 70/100 [00:40<00:16, 1.81it/s]
71%|███████ | 71/100 [00:41<00:16, 1.81it/s]
72%|███████▏ | 72/100 [00:42<00:15, 1.81it/s]
73%|███████▎ | 73/100 [00:42<00:14, 1.81it/s]
74%|███████▍ | 74/100 [00:43<00:14, 1.81it/s]
75%|███████▌ | 75/100 [00:43<00:13, 1.81it/s]
76%|███████▌ | 76/100 [00:44<00:13, 1.81it/s]
77%|███████▋ | 77/100 [00:44<00:12, 1.81it/s]
78%|███████▊ | 78/100 [00:45<00:12, 1.81it/s]
79%|███████▉ | 79/100 [00:45<00:11, 1.81it/s]
80%|████████ | 80/100 [00:46<00:11, 1.80it/s]
81%|████████ | 81/100 [00:47<00:10, 1.80it/s]
82%|████████▏ | 82/100 [00:47<00:09, 1.80it/s]
83%|████████▎ | 83/100 [00:48<00:09, 1.81it/s]
84%|████████▍ | 84/100 [00:48<00:08, 1.80it/s]
85%|████████▌ | 85/100 [00:49<00:08, 1.80it/s]
86%|████████▌ | 86/100 [00:49<00:07, 1.80it/s]
87%|████████▋ | 87/100 [00:50<00:07, 1.81it/s]
88%|████████▊ | 88/100 [00:50<00:06, 1.81it/s]
89%|████████▉ | 89/100 [00:51<00:06, 1.81it/s]
90%|█████████ | 90/100 [00:52<00:05, 1.79it/s]
91%|█████████ | 91/100 [00:54<00:11, 1.24s/it]
92%|█████████▏| 92/100 [00:55<00:08, 1.03s/it]
93%|█████████▎| 93/100 [00:55<00:06, 1.13it/s]
94%|█████████▍| 94/100 [00:56<00:04, 1.27it/s]
95%|█████████▌| 95/100 [00:57<00:03, 1.40it/s]
96%|█████████▌| 96/100 [00:57<00:02, 1.50it/s]
97%|█████████▋| 97/100 [00:58<00:01, 1.58it/s]
98%|█████████▊| 98/100 [00:58<00:01, 1.64it/s]
99%|█████████▉| 99/100 [00:59<00:00, 1.69it/s]
100%|██████████| 100/100 [00:59<00:00, 1.72it/s]
100%|██████████| 100/100 [00:59<00:00, 1.67it/s]
Market shares are calculated using the weighted mean of the individual probabilities.
Alternative car
simulated_values['Weighted prob. car'] = (
simulated_values['weight'] * simulated_values['Prob. car']
)
left['Weighted prob. car'] = left['weight'] * left['Prob. car']
right['Weighted prob. car'] = right['weight'] * right['Prob. car']
market_share_car = simulated_values['Weighted prob. car'].mean()
market_share_car_left = left['Weighted prob. car'].mean()
market_share_car_right = right['Weighted prob. car'].mean()
Alternative public transportation
simulated_values['Weighted prob. PT'] = (
simulated_values['weight'] * simulated_values['Prob. PT']
)
left['Weighted prob. PT'] = left['weight'] * left['Prob. PT']
right['Weighted prob. PT'] = right['weight'] * right['Prob. PT']
market_share_pt = simulated_values['Weighted prob. PT'].mean()
market_share_pt_left = left['Weighted prob. PT'].mean()
market_share_pt_right = right['Weighted prob. PT'].mean()
Alternative slow modes
simulated_values['Weighted prob. SM'] = (
simulated_values['weight'] * simulated_values['Prob. SM']
)
left['Weighted prob. SM'] = left['weight'] * left['Prob. SM']
right['Weighted prob. SM'] = right['weight'] * right['Prob. SM']
market_share_sm = simulated_values['Weighted prob. SM'].mean()
market_share_sm_left = left['Weighted prob. SM'].mean()
market_share_sm_right = right['Weighted prob. SM'].mean()
Reporting.
Car.
print(
f'Market share for car: {100 * market_share_car:.1f}% '
f'[{100 * market_share_car_left:.1f}%, '
f'{100 * market_share_car_right:.1f}%]'
)
Market share for car: 65.2% [61.4%, 68.8%]
Public transportation.
print(
f'Market share for PT: {100 * market_share_pt:.1f}% '
f'[{100 * market_share_pt_left:.1f}%, '
f'{100 * market_share_pt_right:.1f}%]'
)
Market share for PT: 28.2% [24.5%, 32.2%]
Slow modes.
print(
f'Market share for SM: {100 * market_share_sm:.1f}% '
f'[{100 * market_share_sm_left:.1f}%, '
f'{100 * market_share_sm_right:.1f}%]'
)
Market share for SM: 6.6% [4.3%, 9.2%]
Total running time of the script: (1 minutes 1.181 seconds)