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.json against data/exercises.schema.json to 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.html to generate boilerplate API code for FastAPI, Express.js, or other frameworks, exporting models via joblib for 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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →