# Kenya Hotel Recommender
A content-based recommendation system for hotels across Kenya. Tell it where you
want to go and what you care about — a pool, a beach, a gym, a minimum rating —
and it ranks the best-matching hotels, each shown with its star rating, reviews,
photos, amenities, a location map, and a link to the hotel's website.
---
## Overview
The system covers **240 hotels across 12 Kenyan destinations** (Nairobi,
Mombasa, Diani, Nakuru, Kisumu, Naivasha, the Maasai Mara, Eldoret, Malindi,
Watamu, Nanyuki, and Amboseli). Hotel data — ratings, reviews, photos, and
amenities — is pulled once from the Google Places API and cached locally, so the
app runs fast and offline at request time.
It uses **content-based filtering**: rather than learning from user behaviour
(which would need a history of bookings we don't have), it matches each hotel's
own attributes to what the user asks for. That means it works from day one with
no user history.
## Features
- **Preference-based search** — filter by destination, minimum rating, and any
combination of amenities.
- **Transparent ranking** — results are scored on how well their amenities match
the request, blended with the hotel's rating and popularity.
- **"Similar stays"** — every hotel links to others like it, via item-to-item
similarity.
- **Rich detail view** — photo gallery, guest reviews, an OpenStreetMap location
pin, full amenity list, and a website link.
- **Documented end to end** — a CRISP-DM notebook covers the data exploration,
modelling, and evaluation.
## How it works
```
Google Places API ──> build_dataset.py ──> data/hotels.json + data/photos/
│
▼
recommender.py (the model)
│
▼
app.py (FastAPI)
│
▼
frontend/ (React) (the UI)
```
**The recommender.** Each hotel is turned into a feature vector: a multi-hot
encoding of its amenities, plus a normalised rating and a log-scaled popularity
(review count). A search produces a score for every hotel:
```
score = 0.50 · amenity_ma …