An end-to-end machine learning recommendation system designed to reduce decision fatigue on food delivery platforms by 40%
๐ปLive Demo | ๐ Documentation | ๐ Full PRD | ๐ Report Bug
Food delivery users face significant friction in the ordering process due to overwhelming restaurant choices and lack of contextual prioritization. This increases:
- โฑ๏ธ Decision Fatigue: Users spend 8-12 minutes browsing 200+ restaurant options and get overwhelmed
- ๐ Cart Abandonment: ~30% of users add items but don't complete checkout
- ๐ Low Discovery: 65% of orders are repeat orders from the same 3-5 restaurants
- ๐ธ Revenue Loss: High-quality restaurants with availability go undiscovered
Root Cause: Current "Sort by: Distance/Rating/Delivery Time" approach is too generic and doesn't consider:
- User's historical preferences (cuisine, price, dietary needs)
- Contextual factors (time of day, weather, occasion)
- Real-time constraints (restaurant availability, delivery capacity)
An ML-powered hybrid recommendation system specifically for the home feed that combines:
- Learns from similar users' preferences
- "Users like you ordered from these restaurants"
- Enables discovery of unexpected matches
- Matches restaurant attributes to user profile
- Considers cuisine, price, rating, dietary restrictions
- Works even for new users (cold start handling)
- Time of Day: Breakfast โ South Indian/Cafe, Dinner โ Biryani/Chinese
- Weather: Rainy โ Comfort food, Hot โ Beverages/Desserts
- Distance: Exponential decay penalty for far restaurants
- Popularity: Slight boost for trending restaurants
Hybrid Score Calculation:
Final Score = 0.40 ร CF_Score + 0.35 ร CB_Score + 0.25 ร Context_ScorePrimary Metric (Hero Metric):
- Time to Order: Reduce by 40% (10 minutes โ 6 minutes)
Secondary Metrics:
- Order conversion rate: +15% improvement
- Restaurant discovery: 2+ new restaurants per user per month
- Repeat order rate: Decrease from 65% to 55%
Guardrail Metrics:
- Average delivery time: โค38 minutes
- Order cancellation rate: โค6%
- User dissatisfaction: โค10%
|
|
ml-restaurant-recommendations/
โ
โโโ data/ # All datasets
โ โโโ synthetic/ # Generated data
โ โ โโโ users.csv # 50K users
โ โ โโโ restaurants.csv # 500 restaurants
โ โ โโโ orders.csv # 200K orders
โ โโโ processed/ # Engineered features
โ โโโ user_features.csv
โ โโโ restaurant_features.csv
โ โโโ interaction_matrix.csv
โ
โโโ src/ # Source code
โ โโโ config.py # Configuration
โ โโโ data_generator.py # Synthetic data creation
โ โโโ feature_engineering.py # Feature engineering
โ โโโ collaborative_filtering.py # CF model
โ โโโ content_based_filtering.py # CBF model
โ โโโ hybrid_recommender.py # Hybrid system
โ โโโ explainability.py # Explanation engine
โ โโโ cold_start_handler.py # New user handling
โ โโโ evaluation.py # Model evaluation
โ
โโโ app/ # Streamlit application
โ โโโ streamlit_app.py # Interactive demo
โ
โโโ models/ # Saved models
โ โโโ collaborative_model.pkl
โ โโโ content_based_model.pkl
โ โโโ hybrid_model.pkl
โ
โโโ prd/ # Product documentation
โ โโโ ab_test_plan.md # A/B testing strategy
โ โโโ edge_cases.md # Handling edge cases
โ โโโ restaurant_recommendations_prd.md # Full PRD
โ
โโโ scripts/ # Utility scripts
โ โโโ train_models.py # Master training script
โ
โโโ tests/ # Unit tests
โ โโโ test_recommender.py
โ โโโ test_cold_start.py
โ โโโ test_explainability.py
โ
โโโ docs/ # Technical documentation
โ โโโ architecture.md # System design and data flow
โ โโโ methodology.md # ML approach and evaluation
โ โโโ lab_logbook.md # Development log
โ
โโโ .gitignore # Git ignore patterns
โโโ requirements.txt # Dependencies
โโโ LICENSE # MIT License
โโโ README.md # This file
- Python 3.13 or higher
- pip package manager
- 4GB RAM minimum
- 500MB disk space
Step 1: Clone the repository
git clone https://github.com/iamAyushSaxena/ML-Restaurant-Recommendations.git
cd ml-restaurant-recommendationsStep 2: Setup environment
# Create virtual environment
python -m venv venv
# Activate virtual environment
source venv/bin/activate # On MacOS
# OR
venv\Scripts\activate # On WindowsStep 3: Install dependencies
pip install -r requirements.txtStep 4: Generate Data & Train Models
# Run the master training script to generate data and train all models
python scripts/train_models.pyThis will:
- Generate synthetic dataset (50K users, 500 restaurants, 200K orders)
- Engineer features for users and restaurants
- Train collaborative filtering model
- Train content-based filtering model
- Create hybrid recommendation system
Expected runtime: ~3-5 minutes
Step 5: Running the Demo
# Launch the interactive Streamlit application
streamlit run app/streamlit_app.pyThe app will open in your browser at http://localhost:8501
๐ Try the Interactive Demo on Streamlit Cloud
User Request
โ
Extract Context (time, location, weather)
โ
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโ
โ โ โ โ
โผ โผ โผ โผ
Collaborative Content-Based Contextual Business
Filtering Filtering Scoring Rules
(40%) (35%) (25%)
โ โ โ โ
โโโโโโโโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโโโโ
โ
Hybrid Ranker
โ
Apply Filters & Diversity
โ
Generate Explanations
โ
Return Top-N Recommendations
Collaborative Filtering:
- User-based CF with cosine similarity
- Top-30 similar users for recommendation
- Handles sparsity with sparse matrix representation
Content-Based Filtering:
- Weighted feature matching (cuisine 40%, price 25%, rating 20%, delivery 15%)
- StandardScaler normalization
- Dietary restriction hard filters
Contextual Scoring:
- Time-based cuisine boosting (1.3-1.5ร multiplier)
- Weather-based adjustments
- Distance decay (exponential: e^(-dist/3km))
Hybrid Combination:
if user_order_count >= 3:
final_score = 0.40*cf + 0.35*cb + 0.25*context
else: # Cold start
final_score = 0.75*cb + 0.25*contextEvaluated on 100 test users with temporal train-test split:
| Metric | @5 | @10 | @20 | Interpretation |
|---|---|---|---|---|
| Precision | 0.0842 | 0.0756 | 0.0621 | 7.6% of top-10 were ordered |
| Recall | 0.1234 | 0.2145 | 0.3521 | 21.5% of actual orders in top-10 |
| Hit Rate | 0.3156 | 0.4823 | 0.6421 | 48.2% users ordered from top-10 |
| NDCG | 0.2134 | 0.2567 | - | Good ranking quality |
| Metric | Score | Interpretation |
|---|---|---|
| Diversity | 0.7234 | 7+ cuisines in top-10 recommendations |
| Novelty | 0.6421 | 64% are new restaurants for user |
| Coverage | 0.4523 | 45% of catalog recommended across all users |
| Approach | Hit Rate@10 | Diversity | Trade-off Decision |
|---|---|---|---|
| Random | 0.05 | 0.85 | โ Too low accuracy |
| Popular Only | 0.32 | 0.23 | โ No personalization |
| Pure CF | 0.51 | 0.58 | |
| Hybrid (Ours) | 0.48 | 0.72 | โ Best balance |
Decision Rationale: Traded 3% hit rate for 24% more diversity to prevent recommendation fatigue.
โ Could have optimized for: Click-through rate (common ML metric)
โ
Chose instead: Time-to-order
Why: CTR is a vanity metric. It doesn't address the user's real pain: decision fatigue. Time-to-order directly measures whether we're solving the problem.
PM Perspective:
"I could have optimized for CTRโthat's what most ML projects do. But CTR doesn't address the user's pain point. A user clicking through 50 restaurants still takes 10 minutes to order. Time-to-order measures what actually matters: are we reducing decision fatigue?"
โ Could have used: Deep learning (2-3% better accuracy)
โ
Chose instead: Simple models with clear explanations
Why: Food recommendations require trust. Users won't order from a restaurant they don't understand why it was suggested. Explainability isn't optionalโit's core to adoption.
PM Perspective:
"I deliberately chose simpler models over deep learning. Why? Because food needs trust. Users won't order from a 'black box' recommendation. Every suggestion has a clear reason: 'You've ordered South Indian 3 times, rated 4.5/5 by 856 customers.' That's worth more than 2% accuracy."
โ Could have shown: Top-10 all from user's favorite cuisine
โ
Chose instead: Max 3 restaurants per cuisine
Why: Pure precision creates a filter bubble. Long-term user satisfaction requires variety. Prevent recommendation fatigue.
PM Perspective:
"I enforce a max of 3 restaurants per cuisine in the top-10. This costs some precision but prevents the filter bubble. If I only showed North Indian because that's what you ordered before, you'd get bored fast. Discovery matters for retention."
Primary Metric (North Star):
- Time to Order: 40% reduction (10 min โ 6 min)
- Why Primary: Directly addresses user pain point
Secondary Metrics:
- Order conversion rate: +15%
- Restaurant discovery: 2+ new restaurants/month
- Why Secondary: Important but not the core problem
Guardrail Metrics:
- Average delivery time: โค38 minutes
- Order cancellation rate: โค6%
- User dissatisfaction: โค10%
- Why Guardrails: Prevent quality degradation while optimizing primary metric
Stakeholder Balance:
- Users: Want relevance + variety (conflicting!)
- Restaurants: Want visibility (but fair distribution)
- Platform: Wants revenue (but not at cost of trust)
Trade-offs Made:
- Explainability > Accuracy: Users need reasons before ordering food
- Diversity > Precision: Prevent recommendation fatigue
- Speed > Perfection: 6-minute decision time is "good enough"
- Complete PRD - Full product requirements document
- A/B Test Plan - Statistical testing methodology
- Edge Cases - Error handling and fallback strategies
- Methodology - ML approach, feature engineering, evaluation
- Architecture - System design and data flow
- Lab Logbook - Step-by-step development process
Run unit tests:
# Install pytest
pip install pytest pytest-cov
# Run all tests
pytest tests/ -v
# Run with coverage
pytest tests/ --cov=src --cov-report=html
# Run specific test file
pytest tests/test_recommender.py -v- โ Dynamic pricing optimization
- โ Restaurant commission strategies
- โ Courier assignment logic
- โ Long-term personalization (cross-month)
- โ Multi-city rollout strategy
- Real-time availability filtering
- Group ordering recommendations
- Dietary restriction hard filters (allergies)
- A/B test framework implementation
- Multi-armed bandit for exploration
Contributions are welcome! This is a portfolio project, but I'm happy to accept improvements.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
TL;DR: You can freely use, modify, and distribute this project, even commercially, as long as you include the original license.
๐คAuthor: Ayush Saxena
- ๐ LinkedIn: Ayush Saxena
- ๐ GitHub: iamAyushSaxena
- ๐ง Email: aysaxena8880@gmail.com
- Problem Inspiration: Real-world challenges in food delivery personalization
- Educational Value: Demonstrates end-to-end ML product development
- Portfolio Purpose: Showcases product thinking + technical execution for PM roles
If you found this project helpful or impressive, please consider:
- โญ Starring the repository (helps others discover it)
- ๐ Sharing on LinkedIn (tag me!)
- ๐ฌ Providing feedback (open an issue with suggestions)
- ๐ด Forking for your own research (with attribution)
โญ Star this repository if you found it valuable!
๐ฌ Questions? Open an issue
๐ค Feedback? Start a discussion
Built with product thinking๐, not just algorithms!



