A production-ready course recommendation system using clustering + similarity scoring with a MERN + Python stack.
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β React βββββββΆβ Node.js βββββββΆβ Python β
β Frontend β β Backend β β ML Service β
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
- Frontend: React application for user interaction
- Backend: Node.js/Express API middleware
- ML Service: Python FastAPI service with KMeans clustering and cosine similarity
π For detailed step-by-step instructions, see STEP_BY_STEP_GUIDE.md
β‘ For quick commands, see RUN.md
- Python 3.8+
- Node.js 16+
- npm or yarn
cd ml-service
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
# Train the model
python train.py
# Start ML service
python app.pyThe ML service will run on http://localhost:8000
cd backend
npm install
# Copy environment file
cp .env.example .env
# Start server
npm startThe backend will run on http://localhost:3001
cd frontend
npm install
# Create .env file with:
# REACT_APP_API_URL=http://localhost:3001
npm startThe frontend will run on http://localhost:3000
The dataset (data/courses.csv) contains 890 courses with:
course_title: Course namecourse_organization: Offering organizationcourse_Certificate_type: Certificate typecourse_rating: Rating (0-5)course_difficulty: Beginner/Intermediate/Advanced/Mixedcourse_students_enrolled: Enrollment count (e.g., "1.2M")
- Numeric Normalization: Ratings and enrollments scaled using StandardScaler
- Categorical Encoding: One-hot encoding for organizations and certificate types
- Text Features: TF-IDF vectorization on course titles
- Ordinal Encoding: Difficulty mapped to numeric scale (Beginner=1, Intermediate=2, Advanced=3, Mixed=2.5)
- Algorithm: KMeans
- K Selection: Elbow Method (automatic)
- Output: Each course assigned to a cluster
-
User Profile Creation: Synthetic profile based on:
- Preferred difficulty
- Liked courses (TF-IDF similarity)
- Preferred organizations
- Rating bias weight
-
Similarity Calculation:
- Cosine similarity between user profile and all courses
- Primary boost: Same cluster courses (1.2x multiplier)
- Secondary boost: Higher ratings (+0.05 per normalized rating)
- Tertiary boost: Higher enrollments (+0.03 per normalized enrollment)
-
Ranking: Sort by final similarity score
GET /health- Service health checkPOST /recommend- Get recommendationsGET /courses- List all courses (paginated)GET /clusters/{cluster_id}- Get cluster information
GET /health- Health checkPOST /api/recommend- Get recommendations (validates and forwards to ML service)GET /api/courses- List coursesGET /api/clusters/:clusterId- Get cluster info
POST /api/recommend
{
"preferred_difficulty": "Intermediate",
"liked_courses": ["Machine Learning", "Python for Everybody"],
"preferred_organizations": ["Stanford University"],
"limit": 10,
"rating_bias": 0.1
}{
"success": true,
"recommendations": [
{
"course_title": "Deep Learning",
"organization": "deeplearning.ai",
"certificate_type": "Specialization",
"rating": 4.7,
"difficulty": "Advanced",
"students_enrolled": "1.8M",
"similarity_score": 0.91,
"cluster": 2,
"explanation": "Same cluster as your preferences; Highly rated course"
}
],
"count": 10
}After training, the model outputs:
- Silhouette Score: Measures cluster quality (-1 to 1, higher is better)
- Intra-Cluster Similarity: Average cosine similarity within clusters
- Optimal K: Automatically selected via Elbow Method
View metrics in ml-service/model_metrics.json and ml-service/elbow_curve.png
β
Production-Ready: Error handling, input validation, clean architecture
β
Explainable: Each recommendation includes explanation
β
Scalable: Modular design, easy to extend
β
Real ML: Actual clustering and similarity, not hardcoded
β
User Behavior Simulation: Synthetic profiles from preferences
.
βββ ml-service/
β βββ preprocessing.py # Feature engineering
β βββ train.py # Model training
β βββ recommender.py # Recommendation engine
β βββ app.py # FastAPI service
β βββ requirements.txt
β βββ *.pkl # Trained models (generated)
βββ backend/
β βββ server.js # Express API
β βββ package.json
β βββ .env
βββ frontend/
β βββ src/
β β βββ components/ # React components
β β βββ App.js
β β βββ index.js
β βββ package.json
βββ data/
β βββ courses.csv # Dataset
βββ README.md
Backend (.env):
PORT=3001
ML_SERVICE_URL=http://localhost:8000
Frontend (.env):
REACT_APP_API_URL=http://localhost:3001
- Train Model: Run
python ml-service/train.py - Start Services: Start ML service, backend, and frontend
- Test API: Use the frontend or curl:
curl -X POST http://localhost:3001/api/recommend \
-H "Content-Type: application/json" \
-d '{
"preferred_difficulty": "Intermediate",
"liked_courses": ["Machine Learning"],
"limit": 5
}'- Hybrid Architecture: Python ML + Node.js API + React UI
- Real ML Pipeline: Feature engineering, clustering, similarity scoring
- Production Patterns: Error handling, validation, clean separation
- Explainable AI: Recommendations include reasoning
- Scalable Design: Modular, extensible architecture
- Model artifacts (
.pklfiles) are generated after training - The dataset is included in
data/courses.csv - All services must be running for full functionality
- First run requires training the model (
train.py)
ML Service won't start: Ensure model is trained first (python train.py)
Backend can't connect to ML service: Check ML_SERVICE_URL in backend .env
Frontend can't connect to backend: Check REACT_APP_API_URL in frontend .env
No recommendations returned: Verify dataset is loaded and model is trained
Built with β€οΈ for production ML systems