Machine learning
Delivery Time Prediction
- Company
DoorDash- Job positions
- Data ScientistML Engineer
- Topics
- RegressionFeature engineeringscikit-learnModel evaluationModel explanation
The scenario
DoorDash: Build and evaluate a model that predicts food delivery times, then explain what makes deliveries slow.
DoorDash shows customers an estimated delivery time when they place an order. You're a data scientist on the logistics team. The current estimate is a flat average that's often far off, and late deliveries lead to refunds and bad reviews, so the product team wants a model that predicts delivery time from what's known when the order is placed.
Your task
Train a model that predicts delivery time in minutes, evaluate it honestly, predict the held-out test orders, and explain which factors matter most.
Instructions
- 1Explore the training data: look at the target's distribution, extreme values, missing values and how each feature relates to delivery time.
- 2Handle missing values and extreme delivery times, and explain your choices. Only use information that would be known when the order is placed.
- 3Engineer useful features, such as time of day and day of week from the order time, and combinations of features that make physical sense.
- 4Set up a validation approach on the training data and a simple baseline to beat, such as predicting the average delivery time.
- 5Train at least two different models, compare them using mean absolute error (MAE) in minutes, and pick one.
- 6Explain what drives delivery time in your chosen model, and show where it makes its largest errors.
- 7Predict delivery_minutes for every order in deliveries_test.csv and save the results as predictions.csv with the columns order_id and predicted_minutes.
Datasets
The data is synthetic and does not come from DoorDash, but it's modeled on how real companies record it, including the mess. All files come in one download.
deliveries_train.csv
8,000 delivered orders from March to August 2025, with the actual delivery time.
8,000 rows · 13 columns · 635 KB
| Column | Type | Description |
|---|---|---|
| order_id | integer | Unique ID of the order. |
| order_placed_at | datetime | When the customer placed the order (local time). |
| restaurant_id | integer | The restaurant. |
| cuisine | text | Type of food the restaurant serves. |
| restaurant_avg_prep_minutes | decimal | The restaurant's average food prep time from past orders. |
| city_zone | text | Part of the city the restaurant is in. |
| distance_km | decimal | Route distance from restaurant to customer, in kilometers. |
| items_count | integer | Number of items in the order. |
| order_subtotal | decimal | Food total before fees, in USD. |
| courier_vehicle | text | How the assigned courier travels: bike, scooter or car. |
| courier_trips_completed | integer | Deliveries the courier had completed before this one. |
| weather | text | Weather when the order was placed. |
| delivery_minutes | integer | Minutes from order placed to delivered. This is what you predict. |
Preview the first 5 rowsHide preview
| order_id | order_placed_at | restaurant_id | cuisine | restaurant_avg_prep_minutes | city_zone | distance_km | items_count | order_subtotal | courier_vehicle | courier_trips_completed | weather | delivery_minutes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 700001 | 2025-03-01 10:00:00 | 10 | pizza | 12.9 | suburbs_north | 2.2 | 2 | 19.24 | scooter | 50 | cloudy | 29 |
| 700003 | 2025-03-01 11:06:00 | 5 | mexican | 12.4 | uptown | 5.3 | 1 | 8.36 | bike | 1255 | clear | 36 |
| 700004 | 2025-03-01 11:15:00 | 59 | pizza | 11.7 | suburbs_south | 2.6 | 3 | 27.38 | scooter | 276 | clear | 31 |
| 700005 | 2025-03-01 11:28:00 | 51 | indian | 17 | downtown | 3.3 | 1 | 8 | bike | 664 | cloudy | 34 |
| 700006 | 2025-03-01 11:40:00 | 104 | thai | 11.5 | suburbs_south | 11.6 | 2 | 18.96 | car | 38 | rain | 54 |
deliveries_test.csv
2,000 held-out orders from the same period, without the delivery time.
2,000 rows · 12 columns · 153 KB
| Column | Type | Description |
|---|---|---|
| order_id | integer | Unique ID of the order. |
| order_placed_at | datetime | When the customer placed the order (local time). |
| restaurant_id | integer | The restaurant. |
| cuisine | text | Type of food the restaurant serves. |
| restaurant_avg_prep_minutes | decimal | The restaurant's average food prep time from past orders. |
| city_zone | text | Part of the city the restaurant is in. |
| distance_km | decimal | Route distance from restaurant to customer, in kilometers. |
| items_count | integer | Number of items in the order. |
| order_subtotal | decimal | Food total before fees, in USD. |
| courier_vehicle | text | How the assigned courier travels: bike, scooter or car. |
| courier_trips_completed | integer | Deliveries the courier had completed before this one. |
| weather | text | Weather when the order was placed. |
Preview the first 5 rowsHide preview
| order_id | order_placed_at | restaurant_id | cuisine | restaurant_avg_prep_minutes | city_zone | distance_km | items_count | order_subtotal | courier_vehicle | courier_trips_completed | weather |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 700002 | 2025-03-01 11:04:00 | 15 | indian | 18.1 | midtown | 1.4 | 2 | 22.03 | car | 181 | rain |
| 700007 | 2025-03-01 11:52:00 | 37 | pizza | 17.5 | midtown | 1.8 | 3 | 45.44 | car | 501 | cloudy |
| 700013 | 2025-03-01 12:30:00 | 3 | pizza | 20.9 | suburbs_north | 4.3 | 2 | 16.97 | bike | 235 | rain |
| 700029 | 2025-03-01 16:15:00 | 4 | pizza | 14 | suburbs_south | 3.2 | 2 | 15.96 | scooter | 28 | rain |
| 700030 | 2025-03-01 16:17:00 | 145 | pizza | 12.3 | suburbs_south | 4.4 | 2 | 28.96 | car | 108 | heavy_rain |
Hint
Learn missing-value fills and category encodings from the training data only, then apply the same steps to the test orders. A scikit-learn pipeline does both in one object.
model = make_pipeline(preprocess, GradientBoostingRegressor()) model.fit(X_train, y_train) predictions = model.predict(X_test)
Deliverable
A public GitHub repo with your notebook or scripts, a predictions.csv file for the test orders, and a README explaining your approach, validation results and the main drivers of delivery time.
When you're done, post your repo in the Solutions tab to share it with other learners.
What grading checks
Use this checklist to review your own work before you post and share it.
- Submitted GitHub repo is public and reachable.
- Repo contains at least one notebook or script file.
- Repo contains predictions.csv with order_id and predicted_minutes for all 2,000 test orders.
- Predictions have a mean absolute error at least 30% lower than always predicting the training average.
- A validation approach and a baseline are used to compare at least two models.
- Missing values and extreme delivery times are handled with explained choices.
- README explains the main drivers of delivery time and where the model makes its largest errors.