Complete2022

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.

FlaskPythonscikit-learnNearestNeighborsBootstrap 4REST APIHTML5JavaScript
View on GitHub

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

  1. 1
    Feature Extraction — Trek descriptions are vectorised using CountVectorizer, converting text into numerical feature vectors.
  2. 2
    Similarity Calculation — Cosine similarity is computed between all trek vectors, capturing how similar any two treks are based on description content.
  3. 3
    KNN Search — A NearestNeighbors model (scikit-learn) returns the k most similar treks to the query, using the cosine similarity matrix.
  4. 4
    Ranking — Results are sorted by similarity distance and returned with trek images, descriptions, type labels, and percentage match scores.
  5. 5
    Model Caching — The trained model is serialised to disk (minnn_rf.pkl) and loaded at startup, keeping response times under 1 second.

Core Algorithm

python
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 results

Screenshots

Home Page — search interface with autocomplete across 208+ trek names
Home Page — search interface with autocomplete across 208+ trek names
Results Page — 10 personalised recommendations with similarity scores, trek images, and descriptions
Results Page — 10 personalised recommendations with similarity scores, trek images, and descriptions

Technical Stack

Python 3.7+Flaskscikit-learn (NearestNeighbors)CountVectorizerpandasnumpyBootstrap 4HTML5 / CSS3 / JavaScriptPickle (model serialisation)REST API (JSON)

Features

FeatureStatus
Smart trek search with autocomplete (208+ destinations)Live
10 personalised recommendations per searchLive
Content-based filtering with cosine similarityLive
Similarity percentage score per recommendationLive
REST API — GET /api/treks and POST /api/recommendLive
Model caching for <1s response timesLive
Trek images, descriptions, and type labelsLive
Heroku / Railway / Render deployment supportLive

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