ML Simulator Lab
Тема програмування

Симулятор тренування ML-моделі для прогнозу цін квартир

Інформативна сторінка-лабораторія про те, як програмується симулятор машинного навчання: генерація даних, feature engineering, цикл навчання, метрики, аналіз стабільності та перехід до продакшен-сценарію.

Python NumPy / Pandas Gradient Descent MSE, MAE, R²

Що ми симулюємо і навіщо

Базовий кейс: оцінка ринкової вартості квартири за ознаками об'єкта і району. У реальних даних багато шуму, пропусків та неідеальних розподілів. Тому симулятор дає безпечний майданчик, де можна відлагодити логіку навчання ще до інтеграції в API або продукт.

01

Синтетичний датасет

Створюємо керований набір даних: площа, поверх, район, вік будинку, індекс попиту. Це дозволяє тестувати сценарії, для яких поки немає реальних даних.

02

Керовані гіперпараметри

Змінюємо `learning rate`, кількість епох, обсяг вибірки та шум. Так можна швидко побачити, які режими призводять до збіжності, а які ламають навчання.

03

Метрики і висновки

Порівнюємо MSE/MAE/R² між запуском експериментів, зберігаємо конфігурації та формуємо технічний висновок для наступної ітерації моделі.

Пайплайн симулятора: від даних до прогнозу

В інженерній реалізації кожен крок має логування, перевірки якості, контроль random seed і версіювання артефактів. Це обов'язково для репродуктивних експериментів.

Імпорт + валідація
Feature Engineering
Тренування
Оцінка та звіт

Контроль якості даних

Перевіряємо пропуски, викиди, неправильні типи, а також зсуви розподілів. Якщо ключова ознака містить занадто багато NaN, симулятор має попередити, що метрики будуть недостовірні.

Репродуктивність

Фіксуємо версію коду, seed і конфіг запуску. Без цього неможливо чесно порівняти EXP-01 та EXP-02, навіть якщо вони виглядають схожими.

Інтерактивний міні-симулятор тренування

Блок нижче не запускає повну модель на сервері, але добре ілюструє вплив гіперпараметрів на форму кривої loss та ключові метрики.

Надто високий `learning rate` (0.12+) часто погіршує стабільність.
Train Loss 0.0000
MAE 0
0.000
Стабільність -
Крива навчання: Loss vs Epoch

Псевдокод структури симулятора (Python)

Типова організація: окремі модулі генерації даних, тренування та оцінки. Така декомпозиція робить код масштабованим і тестованим.

# generator.py
+import numpy as np
+
+def make_dataset(n_samples: int, noise: float, seed: int = 42):
+    rng = np.random.default_rng(seed)
+    area = rng.normal(62, 18, size=n_samples).clip(18, 180)
+    district = rng.integers(1, 6, size=n_samples)
+    age = rng.integers(0, 50, size=n_samples)
+    demand = rng.uniform(0.8, 1.4, size=n_samples)
+
+    y = (
+        38000 + area * 1350 + district * 5200 - age * 420
+        + demand * 11000 + rng.normal(0, noise * 18000, size=n_samples)
+    )
+    X = np.column_stack([area, district, age, demand])
+    return X, y
# train.py
+import numpy as np
+
+def train_linear(X, y, lr=0.01, epochs=100):
+    n, f = X.shape
+    w = np.zeros(f)
+    b = 0.0
+    history = []
+
+    for _ in range(epochs):
+        y_pred = X @ w + b
+        err = y_pred - y
+        loss = (err ** 2).mean()
+        dw = (2 / n) * (X.T @ err)
+        db = (2 / n) * err.sum()
+        w -= lr * dw
+        b -= lr * db
+        history.append(loss)
+
+    return w, b, history

Приклад порівняння експериментів

Симулятор дозволяє швидко формувати таблицю запусків та приймати рішення на основі метрик, а не інтуїції.

ID Samples Noise LR Epochs MAE Висновок
EXP-01 800 0.10 0.030 70 7 400 0.93 Сильна базова лінія
EXP-02 1200 0.18 0.045 60 8 100 0.90 Баланс якості та швидкості
EXP-03 1200 0.32 0.120 40 12 900 0.72 Нестабільний режим
EXP-04 3000 0.14 0.018 120 6 950 0.95 Оптимальний компроміс

Типові помилки під час створення ML-симулятора

  • Використання однієї метрики без аналізу кривої loss.
  • Відсутність контролю `random seed`, що ускладнює порівняння.
  • Недостатня обробка пропусків і викидів перед тренуванням.
  • Змішування train і validation логіки в одному скрипті.
  • Ігнорування стабільності моделі при зміні шуму даних.

Дорожня карта до продакшену

Крок 1: Локальна валідація

Тест на кількох seed і різних рівнях шуму.

Крок 2: API сервіс

Інтеграція моделі у FastAPI або Flask з логуванням.

Крок 3: Моніторинг

Контроль data drift і періодичний retraining.

Крок 4: CI/CD для ML

Автотести якості, версіювання моделей, release-процес.

FAQ

Чи можна адаптувати цей шаблон для класифікації?

Так, безумовно. Базова структура пайплайну (підготовка даних → тренування → оцінка) залишається незмінною. Вам потрібно лише:

  • Замінити функцію втрат (MSE на Log Loss або Cross-Entropy).
  • Використати інші метрики оцінки (Accuracy, F1-score, ROC-AUC замість R²).
  • Додати фінальну функцію активації (Sigmoid для бінарної, Softmax для багатокласової).
  • Переконатися, що цільова змінна y є категоріальною (0/1 або класи).
Коли додавати регуляризацію?

Регуляризація необхідна, коли модель показує ознаки перенавчання (overfitting): помилка на тренувальних даних продовжує падати, а на валідаційних — починає зростати. Це часто трапляється, коли у вас мало даних або занадто багато ознак.

  • L2 (Ridge): Штрафує за великі ваги, роблячи модель більш "плавною". Добре підходить як стандартний вибір.
  • L1 (Lasso): Може зануляти деякі ваги, фактично виконуючи автоматичний відбір ознак.
Яка мінімальна структура директорій для такого проєкту?

Для відтворюваного ML-проєкту рекомендується стандартна структура (наприклад, Cookiecutter Data Science):

  • data/: розбита на raw (сирі) та processed (готові до навчання).
  • notebooks/: для EDA (Exploratory Data Analysis) та швидких прототипів.
  • src/: модульний вихідний код (генерація, тренування, оцінка).
  • models/: збережені ваги навчених моделей (.pkl, .pt).
  • reports/: графіки, метрики та звіти експериментів.
Чому важливо масштабувати ознаки (Feature Scaling)?

Градієнтний спуск працює набагато швидше і стабільніше, коли всі ознаки мають схожий масштаб (наприклад, 0-1 або Standard Scaler). Якщо одна ознака вимірюється в тисячах (площа), а інша в одиницях (кількість кімнат), оптимізатор буде "блукати" у витягнутому просторі помилок, і збіжність займе набагато більше часу.

Як вибрати правильну модель?

Дотримуйтесь принципу "Бритви Оккама" — починайте з найпростішого:

  • Для табличних даних спершу спробуйте лінійну/логістичну регресію.
  • Якщо точності недостатньо, переходьте до дерев рішень (Decision Trees) або ансамблів (Random Forest, Gradient Boosting: XGBoost, LightGBM).
  • Нейромережі варто використовувати для неструктурованих даних (зображення, текст, аудіо) або дуже великих складних датасетів.
Моя модель недонавчається або перенавчається. Що робити?

Underfitting (високий bias): Модель занадто проста.

  • Додайте нові ознаки (feature engineering).
  • Спробуйте складнішу модель (наприклад, поліноміальну регресію).
  • Зменшіть регуляризацію.

Overfitting (високий variance): Модель "завчила" шум.

  • Зберіть більше даних.
  • Спростіть модель (менше параметрів/глибини).
  • Додайте регуляризацію (L1/L2, Dropout).

Глосарій основних термінів

Target Variable (y)

Величина, яку ми хочемо передбачити (ціна квартири). У навчанні це "відповідь", з якою модель порівнює свій прогноз.

Features (X)

Вхідні параметри (площа, поверх, район), на основі яких модель робить прогноз. Чим якісніші ознаки, тим краща модель.

Weights & Bias (w, b)

Внутрішні параметри моделі. Ваги (weights) показують важливість кожної ознаки, а зміщення (bias) коригує базовий рівень прогнозу.

Learning Rate

Крок навчання. Завеликий крок робить навчання нестабільним, а замалий — надто повільним.

Epochs

Кількість повних проходів алгоритму через весь набір даних. Більше епох — точніша підгонка, але є ризик перенавчання.

Training Loss

Показник помилки на навчальних даних. Мета навчання — мінімізувати це значення.