Skip to content

Commit

Permalink
Estimate margins of error for the sample mean using a bootstrap
Browse files Browse the repository at this point in the history
returns results through the frontend and adds some fields to the backend response
The unit of observation is the "one hour average" which, while not statistically valid, should be a decent starting point, and demonstrates how margins of error can be calculated from a sample of observations
  • Loading branch information
Nate-Wessel committed Jun 5, 2024
1 parent 210c914 commit 6168c80
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
26 changes: 24 additions & 2 deletions backend/app/get_travel_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from app.db import getConnection
from app.get_links import get_links
import numpy, math
import numpy, math, random

# the way we currently do it
def mean_daily_mean(obs):
Expand Down Expand Up @@ -87,8 +87,30 @@ def get_travel_time(start_node, end_node, start_time, end_time, start_date, end_

tt_seconds = mean_daily_mean(sample)

reported_intervals = None
if len(sample) > 1:
# bootstrap for synthetic sample distribution
sample_distribution = []
for i in range(0,100):
bootstrap_sample = random.choices( sample, k = len(sample) )
sample_distribution.append( mean_daily_mean(bootstrap_sample) )
p95lower, p95upper = numpy.percentile(sample_distribution, [2.5, 97.5])
reported_intervals = {
'p=0.95': {
'lower': timeFormat(p95lower),
'upper': timeFormat(p95upper)
}
}

return {
'results': {'travel_time': timeFormat(tt_seconds)},
'results': {
'travel_time': timeFormat(tt_seconds),
'confidence': {
'sample': len(sample),
'intervals': reported_intervals
},
'observations': [timeFormat(tt) for (dt,tt) in sample]
},
'query': {
'corridor': {'links': links},
'query_params': query_params
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/travelTimeQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export class TravelTimeQuery {
record.set('hoursInRange', this.hoursInRange)
record.set('mean_travel_time_minutes', this.#results?.travel_time?.minutes)
record.set('mean_travel_time_seconds', this.#results?.travel_time?.seconds)
record.set('moe_lower_p95', this.#results?.confidence?.intervals?.['p=0.95']?.lower?.seconds)
record.set('moe_upper_p95', this.#results?.confidence?.intervals?.['p=0.95']?.upper?.seconds)

if(type=='json'){
return Object.fromEntries(record) // can't JSONify maps
Expand Down

0 comments on commit 6168c80

Please sign in to comment.