Machine Learning для початківців: від математики до нейромереж
27 лютого 2026 | 30 хв читання
У 1959 році Артур Семюел з IBM написав програму, яка грала в шашки і покращувала свою гру з кожною партією. Він назвав це "Machine Learning" — машинне навчання. Сьогодні, майже 70 років потому, ця технологія визначає майбутнє людства. ChatGPT, автопілоти Tesla, системи розпізнавання обличчя — все це ML. У цій статті ми розберемо фундаментальні концепції, які дозволять вам не просто використовувати готові бібліотеки, а розуміти, що відбувається "під капотом".
Що насправді означає "навчання" машини?
Коли ми кажемо, що машина "навчається", ми маємо на увазі математичну оптимізацію. Модель — це функція з параметрами. Навчання — це процес підбору таких параметрів, які мінімізують помилку передбачень.
Проста аналогія
Уявіть, що ви налаштовуєте еквалайзер на аудіосистемі. У вас є кілька "ручок" (параметрів), і ви крутите їх, поки звук не стане ідеальним. ML робить те саме, але автоматично і з мільйонами "ручок".
Формально, ми шукаємо параметри θ (тета), які мінімізують функцію втрат L:
θ* = argmin L(f(x; θ), y)
де f — модель, x — вхідні дані, y — правильні відповіді
Три парадигми машинного навчання
Supervised Learning
Навчання з учителем. Є правильні відповіді (labels). Модель вчиться відтворювати зв'язок між входом і виходом.
Приклад: Визначення спаму в email
Unsupervised Learning
Навчання без учителя. Немає правильних відповідей. Модель шукає приховані структури в даних.
Приклад: Сегментація клієнтів
Reinforcement Learning
Навчання з підкріпленням. Агент вчиться через взаємодію з середовищем, отримуючи нагороди.
Приклад: AlphaGo, роботи
Математичний фундамент: що потрібно знати
Багато початківців лякає математика в ML. Але насправді вам потрібні лише три області:
Дані в ML представлені як матриці та вектори. Ключові концепції:
- Вектори — одновимірні масиви чисел. Наприклад, ознаки одного об'єкта.
- Матриці — двовимірні масиви. Датасет — це матриця, де рядки = об'єкти, стовпці = ознаки.
- Множення матриць — основа нейронних мереж. y = Wx + b
- Транспонування, інверсія — для оптимізації та перетворень.
import numpy as np
# Вектор ознак
x = np.array([1.0, 2.0, 3.0])
# Матриця ваг (3 входи → 2 виходи)
W = np.array([[0.1, 0.2, 0.3],
[0.4, 0.5, 0.6]])
# Лінійне перетворення
y = W @ x # [1.4, 3.2]
Градієнтний спуск — серце оптимізації в ML. Для цього потрібні похідні:
- Похідна — швидкість зміни функції. Показує напрямок "вниз".
- Градієнт — вектор часткових похідних. Показує напрямок найшвидшого зростання.
- Ланцюгове правило — для обчислення похідних складних функцій (backpropagation).
θ_new = θ_old - α * ∇L(θ)
α — learning rate (крок навчання)
ML має справу з невизначеністю. Статистика допомагає її моделювати:
- Розподіли — нормальний, Бернуллі, категоріальний.
- Теорема Баєса — P(A|B) = P(B|A) * P(A) / P(B). Основа багатьох алгоритмів.
- Maximum Likelihood — пошук параметрів, які максимізують ймовірність даних.
- Bias-Variance tradeoff — баланс між переобучанням і недонавчанням.
Ваш перший алгоритм: лінійна регресія
Лінійна регресія — найпростіший ML алгоритм, але він закладає основу для розуміння всіх інших. Задача: знайти пряму лінію, яка найкраще описує дані.
import numpy as np
import matplotlib.pyplot as plt
# Генеруємо синтетичні дані
np.random.seed(42)
X = 2 * np.random.rand(100, 1) # 100 точок
y = 4 + 3 * X + np.random.randn(100, 1) # y = 4 + 3x + шум
# Додаємо стовпець одиниць для bias (intercept)
X_b = np.c_[np.ones((100, 1)), X]
# Аналітичне рішення (Normal Equation)
# θ = (X^T * X)^(-1) * X^T * y
theta_best = np.linalg.inv(X_b.T @ X_b) @ X_b.T @ y
print(f"Intercept: {theta_best[0][0]:.2f}") # ≈ 4
print(f"Slope: {theta_best[1][0]:.2f}") # ≈ 3
# Передбачення
X_new = np.array([[0], [2]])
X_new_b = np.c_[np.ones((2, 1)), X_new]
y_predict = X_new_b @ theta_best
# Візуалізація
plt.scatter(X, y, alpha=0.5)
plt.plot(X_new, y_predict, "r-", linewidth=2, label="Prediction")
plt.xlabel("X")
plt.ylabel("y")
plt.legend()
plt.title("Linear Regression: Manual Implementation")
plt.show()
Чому це працює?
Normal Equation знаходить таке θ, при якому похідна функції втрат (MSE) дорівнює нулю. Це точка мінімуму — найкраща пряма лінія для наших даних.
Gradient Descent: коли аналітика не працює
Normal Equation чудова для маленьких датасетів, але для мільйонів точок або нелінійних моделей потрібен ітеративний підхід — градієнтний спуск.
def gradient_descent(X, y, learning_rate=0.1, n_iterations=1000):
"""
Batch Gradient Descent для лінійної регресії.
Ідея: рухаємось у напрямку, протилежному градієнту,
поки не досягнемо мінімуму функції втрат.
"""
m = len(y) # кількість прикладів
theta = np.random.randn(2, 1) # випадкова ініціалізація
history = [] # для візуалізації процесу навчання
for iteration in range(n_iterations):
# Передбачення
y_pred = X_b @ theta
# Градієнт MSE: ∇L = (2/m) * X^T * (X*θ - y)
gradients = (2/m) * X_b.T @ (y_pred - y)
# Оновлення параметрів
theta = theta - learning_rate * gradients
# Зберігаємо MSE для графіка
mse = np.mean((y_pred - y) ** 2)
history.append(mse)
return theta, history
# Запуск
theta_gd, loss_history = gradient_descent(X_b, y)
# Графік збіжності
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(loss_history)
plt.xlabel("Iteration")
plt.ylabel("MSE")
plt.title("Loss Convergence")
plt.subplot(1, 2, 2)
plt.scatter(X, y, alpha=0.5)
plt.plot(X_new, X_new_b @ theta_gd, "g-", linewidth=2)
plt.title("Gradient Descent Result")
plt.show()
Класифікація: логістична регресія
Логістична регресія — це класифікатор, попри назву. Вона передбачає ймовірність належності до класу.
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
# Завантаження датасету Iris (класика ML)
iris = load_iris()
X, y = iris.data, iris.target
# Розділення на train/test
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# Навчання моделі
model = LogisticRegression(max_iter=200)
model.fit(X_train, y_train)
# Оцінка
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred, target_names=iris.target_names))
# Confusion Matrix
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=iris.target_names,
yticklabels=iris.target_names)
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
# Ймовірності для одного прикладу
sample = X_test[0:1]
probs = model.predict_proba(sample)
print(f"\nЙмовірності: {dict(zip(iris.target_names, probs[0].round(3)))}")
Метрики оцінки моделей
Accuracy — це ще не все. Різні задачі потребують різних метрик:
| Accuracy | % правильних передбачень |
| Precision | TP / (TP + FP) — точність |
| Recall | TP / (TP + FN) — повнота |
| F1-Score | Гармонічне середнє P і R |
| ROC-AUC | Площа під ROC-кривою |
| MSE | Mean Squared Error |
| RMSE | √MSE — в одиницях y |
| MAE | Mean Absolute Error |
| R² | Коефіцієнт детермінації |
| MAPE | Mean Absolute % Error |
Коли Accuracy брехе
При незбалансованих класах (95% негативних, 5% позитивних) модель може досягти 95% accuracy, просто передбачаючи завжди "негатив". Використовуйте F1-Score або ROC-AUC для таких випадків.
Потрібна допомога з проектом?
Курсова з Machine Learning вимагає глибокого розуміння алгоритмів та математики. Наші ML-інженери допоможуть з вибором моделі, навчанням та документацією.
Замовити ML проектOverfitting та Underfitting: головний біль ML-інженера
Це фундаментальна проблема ML — баланс між складністю моделі та її здатністю узагальнювати.
Модель занадто проста. Не може вловити закономірності навіть на тренувальних даних.
Ознаки: Низька accuracy і на train, і на test.
Рішення: Складніша модель, більше features, менше регуляризації.
Ідеальний баланс. Модель добре працює і на тренувальних, і на нових даних.
Ознаки: Висока accuracy на обох наборах, мала різниця між ними.
Мета: Досягти цього стану!
Модель "завчила" тренувальні дані разом із шумом. Не може узагальнювати.
Ознаки: Висока accuracy на train, низька на test.
Рішення: Регуляризація, dropout, більше даних.
Decision Trees та Random Forest
Дерева рішень — інтуїтивно зрозумілий алгоритм. Модель задає питання і розгалужується на основі відповідей. Random Forest — ансамбль багатьох дерев.
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier, plot_tree
# Один Decision Tree (для візуалізації)
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X_train, y_train)
plt.figure(figsize=(20, 10))
plot_tree(tree, feature_names=iris.feature_names,
class_names=iris.target_names, filled=True, rounded=True)
plt.title("Decision Tree для класифікації Iris")
plt.show()
# Random Forest — ансамбль дерев
forest = RandomForestClassifier(
n_estimators=100, # кількість дерев
max_depth=None, # без обмеження глибини
min_samples_split=2, # мін. зразків для розбиття
random_state=42,
n_jobs=-1 # паралельне навчання
)
forest.fit(X_train, y_train)
# Feature Importance — які ознаки найважливіші?
importances = forest.feature_importances_
indices = np.argsort(importances)[::-1]
plt.figure(figsize=(10, 6))
plt.bar(range(X.shape[1]), importances[indices])
plt.xticks(range(X.shape[1]), [iris.feature_names[i] for i in indices], rotation=45)
plt.title("Feature Importance (Random Forest)")
plt.show()
print(f"Random Forest Accuracy: {forest.score(X_test, y_test):.2%}")
Нейронні мережі: основи Deep Learning
Нейронна мережа — це послідовність лінійних перетворень з нелінійними активаціями між ними. Кожен шар "витягує" все більш абстрактні ознаки.
import tensorflow as tf
from tensorflow.keras import layers, models
# Створення Sequential моделі
model = models.Sequential([
# Вхідний шар
layers.Input(shape=(4,)), # 4 ознаки Iris
# Прихований шар 1
layers.Dense(64, activation='relu'), # 64 нейрони, ReLU активація
layers.Dropout(0.2), # Регуляризація — випадково "вимикаємо" 20% нейронів
# Прихований шар 2
layers.Dense(32, activation='relu'),
layers.Dropout(0.2),
# Вихідний шар
layers.Dense(3, activation='softmax') # 3 класи, ймовірності
])
# Компіляція
model.compile(
optimizer='adam', # Адаптивний gradient descent
loss='sparse_categorical_crossentropy', # Для multi-class
metrics=['accuracy']
)
# Навчання
history = model.fit(
X_train, y_train,
epochs=100,
batch_size=16,
validation_split=0.2,
verbose=0
)
# Візуалізація навчання
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Train')
plt.plot(history.history['val_loss'], label='Validation')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.title('Training Loss')
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Train')
plt.plot(history.history['val_accuracy'], label='Validation')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.title('Training Accuracy')
plt.show()
# Оцінка
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"Test Accuracy: {test_acc:.2%}")
Практичний проект: класифікація зображень
Завершимо реальним проектом — класифікацією рукописних цифр (MNIST). Це "Hello World" Deep Learning.
from tensorflow.keras.datasets import mnist
# Завантаження даних
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# Нормалізація (0-255 → 0-1)
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0
# Reshape для CNN: (batch, height, width, channels)
X_train = X_train.reshape(-1, 28, 28, 1)
X_test = X_test.reshape(-1, 28, 28, 1)
# Convolutional Neural Network
cnn_model = models.Sequential([
# Перший convolutional блок
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
# Другий convolutional блок
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
# Третій convolutional блок
layers.Conv2D(64, (3, 3), activation='relu'),
# Flatten та Dense шари
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax') # 10 цифр
])
cnn_model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# Навчання
cnn_model.fit(X_train, y_train, epochs=5, batch_size=64,
validation_split=0.1, verbose=1)
# Результат
test_loss, test_acc = cnn_model.evaluate(X_test, y_test)
print(f"\nMNIST Test Accuracy: {test_acc:.2%}") # ~99%
Замовити курсову з Machine Learning
Класифікація, регресія, нейронні мережі — зробимо для вас без передоплати!
ДетальнішеRoadmap вивчення ML у 2026
-
1-2 місяціМатематичний фундаментЛінійна алгебра, calculus, статистика. Khan Academy, 3Blue1Brown.
-
1 місяцьPython для Data ScienceNumPy, Pandas, Matplotlib. Обробка та візуалізація даних.
-
2-3 місяціКласичний ML (scikit-learn)Регресія, класифікація, кластеризація. Kaggle competitions.
-
3-6 місяцівDeep LearningTensorFlow/PyTorch. CNN, RNN, Transformers.
-
ongoingMLOps та ProductionDocker, MLflow, deployment. Реальні проекти.