AI-система персонализации фитнес-программ

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
AI-система персонализации фитнес-программ
Средняя
~2-4 недели
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1240
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1167
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    867
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1084
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    829

AI-система персонализации фитнес-программ

Персональный тренер — это дорого. AI-тренер доступен 24/7 и учитывает прогресс, восстановление, цели и ограничения. Приложения типа Freeletics, Whoop, Peloton используют ML для адаптации тренировочных планов в реальном времени на основе биометрических данных.

Адаптивный тренировочный план

import numpy as np
import pandas as pd
from dataclasses import dataclass
from typing import Optional
from anthropic import Anthropic
import json

@dataclass
class AthleteProfile:
    user_id: str
    age: int
    sex: str
    weight_kg: float
    height_cm: float
    fitness_level: str  # beginner, intermediate, advanced
    primary_goal: str   # weight_loss, muscle_gain, endurance, general_fitness
    available_days_per_week: int
    equipment: list    # ['dumbbells', 'barbell', 'pull_up_bar']
    injuries: list     # ['lower_back', 'knee']
    vo2max: Optional[float] = None

class FitnessPlanGenerator:
    """Генерация и адаптация тренировочного плана"""

    def __init__(self):
        self.llm = Anthropic()

    def calculate_training_zones(self, profile: AthleteProfile) -> dict:
        """Пульсовые зоны для кардио тренировок"""
        # Формула Танака (точнее чем 220-age)
        max_hr = 208 - 0.7 * profile.age

        return {
            'max_hr': int(max_hr),
            'zone1_recovery': (int(max_hr * 0.50), int(max_hr * 0.60)),
            'zone2_aerobic': (int(max_hr * 0.60), int(max_hr * 0.70)),
            'zone3_tempo': (int(max_hr * 0.70), int(max_hr * 0.80)),
            'zone4_threshold': (int(max_hr * 0.80), int(max_hr * 0.90)),
            'zone5_vo2max': (int(max_hr * 0.90), int(max_hr * 1.00)),
        }

    def generate_weekly_plan(self, profile: AthleteProfile,
                              recent_performance: list[dict]) -> list[dict]:
        """Недельный тренировочный план"""
        training_zones = self.calculate_training_zones(profile)

        # Периодизация: 3 недели нарастающей нагрузки + 1 неделя восстановления
        # Определяем текущую неделю периодизации из истории
        week_in_cycle = self._get_week_in_cycle(recent_performance)
        load_modifier = [0.85, 1.0, 1.15, 0.70][week_in_cycle % 4]

        response = self.llm.messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=700,
            messages=[{
                "role": "user",
                "content": f"""Create a personalized weekly training plan.

Profile:
- Fitness level: {profile.fitness_level}
- Goal: {profile.primary_goal}
- Available days: {profile.available_days_per_week}
- Equipment: {profile.equipment}
- Injuries to avoid: {profile.injuries}
- Age: {profile.age}, Weight: {profile.weight_kg}kg

Current training intensity: {load_modifier:.0%} of base load
Training zones: Zone 2 aerobic = {training_zones['zone2_aerobic']} bpm

Recent performance (last 5 sessions):
{json.dumps(recent_performance[-5:], ensure_ascii=False)[:400]}

Create {profile.available_days_per_week} training sessions. Return JSON array:
[{{
  "day": "Monday",
  "session_type": "strength|cardio|hiit|recovery",
  "duration_min": 45,
  "exercises": [{{"name": "...", "sets": 3, "reps": "8-10", "rest_sec": 90}}],
  "cardio_zone": "zone2",
  "notes": "..."
}}]"""
            }]
        )

        try:
            return json.loads(response.content[0].text)
        except Exception:
            return []

    def _get_week_in_cycle(self, performance: list[dict]) -> int:
        if not performance:
            return 0
        return len(set(p.get('week_number', 0) for p in performance)) % 4


class RecoveryMonitor:
    """Мониторинг восстановления из биометрии"""

    def compute_readiness_score(self, biometrics: dict) -> dict:
        """
        Скор готовности к тренировке (0-100).
        Данные: HRV, RHR, sleep_score, previous_day_load.
        """
        score = 100.0
        factors = []

        # HRV (Heart Rate Variability) — главный индикатор
        hrv = biometrics.get('hrv_ms')
        hrv_baseline = biometrics.get('hrv_baseline_ms', 50)
        if hrv and hrv_baseline:
            hrv_ratio = hrv / hrv_baseline
            if hrv_ratio < 0.85:
                score -= 25
                factors.append(f'HRV снижен ({hrv:.0f}ms vs {hrv_baseline:.0f}ms baseline)')
            elif hrv_ratio > 1.15:
                score += 5  # Хорошее восстановление

        # Resting Heart Rate
        rhr = biometrics.get('resting_hr_bpm')
        rhr_baseline = biometrics.get('rhr_baseline_bpm', 60)
        if rhr and rhr_baseline:
            if rhr > rhr_baseline + 5:
                score -= 15
                factors.append(f'RHR повышен ({rhr} vs {rhr_baseline} baseline)')

        # Сон
        sleep_score = biometrics.get('sleep_score', 80)  # 0-100
        if sleep_score < 60:
            score -= 20
            factors.append(f'Плохой сон (скор: {sleep_score})')
        elif sleep_score < 75:
            score -= 10

        # Нагрузка предыдущего дня
        previous_load = biometrics.get('yesterday_training_load', 0)  # AU (Arbitrary Units)
        high_load_threshold = biometrics.get('weekly_avg_load', 300) * 0.4
        if previous_load > high_load_threshold:
            score -= 10
            factors.append('Высокая нагрузка вчера')

        score = float(np.clip(score, 0, 100))

        if score > 75:
            recommendation = 'Отличный день для интенсивной тренировки'
            intensity_modifier = 1.0
        elif score > 55:
            recommendation = 'Умеренная тренировка — снизьте интенсивность на 15%'
            intensity_modifier = 0.85
        elif score > 35:
            recommendation = 'Только лёгкое восстановительное занятие или отдых'
            intensity_modifier = 0.60
        else:
            recommendation = 'Активный отдых или выходной'
            intensity_modifier = 0.0

        return {
            'readiness_score': round(score),
            'recommendation': recommendation,
            'intensity_modifier': intensity_modifier,
            'limiting_factors': factors
        }


class ProgressTracker:
    """Отслеживание прогресса и корректировка плана"""

    def analyze_progress(self, training_logs: pd.DataFrame,
                          profile: AthleteProfile,
                          weeks: int = 8) -> dict:
        """Анализ прогресса за период"""
        recent = training_logs[
            training_logs['date'] >= pd.Timestamp.now() - pd.Timedelta(weeks=weeks)
        ]

        if recent.empty:
            return {}

        return {
            'sessions_completed': len(recent),
            'sessions_planned': weeks * profile.available_days_per_week,
            'adherence_rate': len(recent) / (weeks * profile.available_days_per_week),

            # Прогресс по ключевым упражнениям
            'strength_progress': self._compute_strength_progress(recent),
            'endurance_progress': self._compute_endurance_progress(recent),

            'avg_session_duration_min': recent.get('duration_minutes', pd.Series([45])).mean(),
            'total_volume_kg': recent.get('total_volume_kg', pd.Series([0])).sum(),
        }

    def _compute_strength_progress(self, logs: pd.DataFrame) -> dict:
        """Изменение максимальных весов в основных упражнениях"""
        if 'exercise_name' not in logs.columns:
            return {}

        key_exercises = ['squat', 'bench_press', 'deadlift', 'overhead_press']
        progress = {}

        for exercise in key_exercises:
            exercise_logs = logs[logs['exercise_name'] == exercise]
            if len(exercise_logs) < 2:
                continue
            first_max = exercise_logs.nsmallest(3, 'date')['max_weight_kg'].mean()
            last_max = exercise_logs.nlargest(3, 'date')['max_weight_kg'].mean()
            progress[exercise] = round((last_max - first_max) / max(first_max, 1) * 100, 1)

        return progress

    def _compute_endurance_progress(self, logs: pd.DataFrame) -> dict:
        if 'pace_min_per_km' not in logs.columns:
            return {}
        cardio = logs[logs['session_type'] == 'cardio']
        if cardio.empty:
            return {}
        early = cardio.head(3)['pace_min_per_km'].mean()
        recent = cardio.tail(3)['pace_min_per_km'].mean()
        improvement = (early - recent) / early * 100  # Снижение темпа = улучшение
        return {'pace_improvement_pct': round(improvement, 1)}

Персонализированные фитнес-планы с адаптацией на основе биометрии повышают adherence rate с 35-45% до 65-75% по данным Whoop и Oura. Ключевая метрика: не количество тренировок, а соответствие нагрузки уровню восстановления — это снижает риск травм на 30-40%.