Trek Recommendation System
Trekking Destination Recommender
Built as a freelance project in March 2022 — a recommendation system for trekking destinations in India. Put in a trek you know and it returns 10 similar ones, ranked by cosine similarity across description vectors. 208+ treks in the database.
Background
You search for a trek you've done and the system returns 10 similar ones based on description content. Built on CountVectorizer + NearestNeighbors with cosine similarity — the core recommendation logic is about 30 lines.
Freelance project from March 2022. Open-sourced in 2024 after the NDA expired. The codebase is refactored and documented if you want to run it locally.
How the Recommendation Engine Works
- 1Feature Extraction — Trek descriptions are vectorised using CountVectorizer, converting text into numerical feature vectors.
- 2Similarity Calculation — Cosine similarity is computed between all trek vectors, capturing how similar any two treks are based on description content.
- 3KNN Search — A NearestNeighbors model (scikit-learn) returns the k most similar treks to the query, using the cosine similarity matrix.
- 4Ranking — Results are sorted by similarity distance and returned with trek images, descriptions, type labels, and percentage match scores.
- 5Model Caching — The trained model is serialised to disk (minnn_rf.pkl) and loaded at startup, keeping response times under 1 second.
Core Algorithm
from sklearn.neighbors import NearestNeighbors
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
import pickle
# Load trek dataset
df = pd.read_csv('b1.csv')
# Vectorise trek descriptions
vectorizer = CountVectorizer()
vectors = vectorizer.fit_transform(df['description'])
# Fit NearestNeighbors with cosine similarity
model = NearestNeighbors(metric='cosine', algorithm='brute')
model.fit(vectors)
# Get recommendations for a given trek
def recommend(trek_name, n=10):
idx = df[df['title'] == trek_name].index[0]
distances, indices = model.kneighbors(
vectors[idx], n_neighbors=n + 1
)
results = []
for i, dist in zip(indices[0][1:], distances[0][1:]):
results.append({
'title': df.iloc[i]['title'],
'similarity': round((1 - dist) * 100, 2),
'image': df.iloc[i]['image'],
'type': df.iloc[i]['treck type']
})
return resultsScreenshots


Technical Stack
Features
| Feature | Status |
|---|---|
| Smart trek search with autocomplete (208+ destinations) | Live |
| 10 personalised recommendations per search | Live |
| Content-based filtering with cosine similarity | Live |
| Similarity percentage score per recommendation | Live |
| REST API — GET /api/treks and POST /api/recommend | Live |
| Model caching for <1s response times | Live |
| Trek images, descriptions, and type labels | Live |
| Heroku / Railway / Render deployment support | Live |
Open Source
The project is fully open source under the MIT License. Contributions welcome — especially around expanding the trek database, improving the recommendation model, or adding new UI features.
Useful backgrounds:
- Expanding the trek dataset beyond 208 destinations
- Improving the recommendation model (collaborative filtering, hybrid approaches)
- Adding user preference inputs to personalise beyond a single trek query
- Mobile-responsive design improvements