How to Build a Machine Learning Recommendation System for Exercises
The Exercises Dataset repository provides a fully-featured, multilingual catalog of 1,324 exercises with JSON schema validation, enabling you to build content-based or collaborative filtering recommenders using TF-IDF vectors, categorical encodings, and cosine similarity.
The hasaneyldrm/exercises-dataset repository offers a production-ready foundation for building a machine learning recommendation system for exercises. With structured data covering equipment requirements, target muscles, and multilingual instructions, you can rapidly prototype fitness applications that suggest relevant workouts based on user constraints. This guide walks through the complete architecture—from ingesting data/exercises.json to deploying a FastAPI recommendation service.
Data Ingestion and Schema Validation
Every recommendation pipeline begins with reliable data loading. The repository stores the master catalog in data/exercises.json, which contains 1,324 exercise records with fields for category, equipment, target, and muscle_group. To ensure data integrity, validate incoming JSON against data/exercises.schema.json before processing.
import json
# Load and validate the exercise catalog
with open("data/exercises.json", "r", encoding="utf-8") as f:
exercises = json.load(f)
print(f"Loaded {len(exercises)} exercises") # Output: 1324
Validating against the schema guarantees that each record contains required multilingual instruction sets and media references. This step prevents runtime errors when processing text fields or categorical attributes later in the pipeline.
Feature Engineering for Exercise Recommendations
Transforming raw exercise data into numeric vectors requires handling both textual instructions and categorical metadata. The dataset supports multilingual text in the instructions field, allowing you to build language-aware recommenders.
Text Vectorization with TF-IDF
Extract features from exercise descriptions using TF-IDF (Term Frequency-Inverse Document Frequency) on the instruction text. The repository stores instructions as nested objects by language code (e.g., instructions.en for English).
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
df = pd.DataFrame(exercises)
# Extract English instructions (swap .en for other language codes)
texts = df["instructions"].apply(lambda x: x["en"])
tfidf = TfidfVectorizer(stop_words="english", max_features=2000)
text_matrix = tfidf.fit_transform(texts)
Encoding Categorical Attributes
Convert structured fields into machine-readable formats using one-hot encoding. The key categorical columns include category, equipment, target, and muscle_group.
from sklearn.preprocessing import OneHotEncoder
cat_features = df[["category", "equipment", "target", "muscle_group"]]
encoder = OneHotEncoder(sparse=True)
cat_matrix = encoder.fit_transform(cat_features)
Combine text and categorical features into a single sparse matrix for efficient similarity computation.
from scipy.sparse import hstack
# Horizontally stack TF-IDF and categorical features
X = hstack([text_matrix, cat_matrix])
print(f"Feature matrix shape: {X.shape}") # Output: (1324, ~2500)
Implementing the Recommendation Engine
With feature vectors prepared, implement either content-based filtering or collaborative filtering to generate recommendations.
Content-Based Filtering with Cosine Similarity
For equipment-constrained recommendations, compute cosine similarity between a query vector (representing user preferences) and all exercise vectors. This approach requires no historical user interaction data.
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
def recommend_by_equipment_target(equipment, target, top_k=5):
# Build query vector from categorical encodings
query_df = pd.DataFrame([{
"category": "", "equipment": equipment,
"target": target, "muscle_group": ""
}])
q_cat = encoder.transform(query_df)
# Zero-vector for text component
q_text = np.zeros((1, text_matrix.shape[1]))
q = hstack([q_text, q_cat])
sims = cosine_similarity(q, X).flatten()
idx = sims.argsort()[::-1][:top_k]
return df.iloc[idx][["name", "equipment", "target"]]
# Example: Find dumbbell exercises for biceps
print(recommend_by_equipment_target("dumbbell", "biceps"))
Collaborative Filtering Approaches
When user interaction data (e.g., workout history) is available, train matrix factorization models such as LightFM or implicit. These algorithms incorporate the engineered TF-IDF and categorical features as side-information to handle cold-start scenarios for new exercises.
Deploying Your Exercise Recommender API
The repository includes setup.html, a developer wizard that generates SQL import scripts and API client code for multiple frameworks including FastAPI, Express.js, and Spring Boot. Export your trained model using joblib and serve predictions via a lightweight endpoint.
from fastapi import FastAPI
import joblib
app = FastAPI()
model = joblib.load("model.pkl") # Trained LightFM or similarity matrix
features = joblib.load("features.pkl") # TF-IDF + one-hot matrix
@app.get("/recommend")
def recommend(equipment: str, target: str, k: int = 5):
# Compute similarity and return top-k exercises
# Implementation uses encoder and cosine similarity as shown above
pass
For client-side validation of recommendations, use index.html to browse the dataset interactively before deployment.
Summary
- Data Validation: Always validate
data/exercises.jsonagainstdata/exercises.schema.jsonto ensure 1,324 records contain complete multilingual instructions and media references. - Feature Engineering: Combine TF-IDF vectors from instruction text with one-hot encoded categorical fields (
equipment,target,muscle_group) to create a sparse feature matrix of approximately 2,500 dimensions. - Content-Based Filtering: Use cosine similarity on the combined feature matrix to recommend exercises matching specific equipment and muscle targets without requiring user history.
- Deployment: Leverage
setup.htmlto generate boilerplate API code for FastAPI, Express.js, or other frameworks, exporting models viajoblibfor production serving.
Frequently Asked Questions
How do I handle multilingual recommendations in the Exercises Dataset?
The dataset stores instructions as nested objects by language code (e.g., instructions.en, instructions.tr). Extract the desired language field before applying TF-IDF vectorization, or concatenate multiple languages into a single text field to build cross-lingual recommendation models.
What is the recommended approach for cold-start users with no workout history?
Use the content-based filtering approach described in hasaneyldrm/exercises-dataset. By encoding the user's available equipment and target muscles into the one-hot categorical matrix, you can compute cosine similarity against all 1,324 exercises immediately, without requiring historical interaction data.
Can I use the dataset for commercial fitness applications?
According to the repository's LICENSE and NOTICE.md files, the dataset is available for commercial use provided you comply with media attribution requirements for the exercise GIFs and thumbnails. Always verify the specific license terms in NOTICE.md before deploying commercially.
How do I validate that my JSON data matches the expected schema?
Load both data/exercises.json and data/exercises.schema.json, then use a JSON Schema validator library (such as jsonschema for Python) to verify each record contains required fields including category, equipment, target, and multilingual instructions. This prevents processing errors during feature engineering.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →