Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Введение в ML

🎯 Цель

После прочтения этой главы:

  • Поймёте, что такое Machine Learning и когда его нужно использовать
  • Узнаете разницу между Supervised, Unsupervised и Reinforcement learning
  • Узнаете, зачем нужны Training, Validation, Test sets
  • Распознаете проблемы Overfitting и Underfitting
  • Напишете один полный ML pipeline (idea → data → model → evaluation)

Что нужно изучить

  • Что такое ML и когда он нужен(когда не стоит отказываться)
  • Типы ML-задач — supervised vs unsupervised vs reinforcement
  • Supervised tasks — regression vs classification
  • Train / Validation / Test — почему делим на 3 части
  • Overfitting и Underfitting — bias-variance tradeoff
  • Cross-validation — стратегия k-fold
  • Scikit-learn API designfit, predict, transform, fit_transform
  • Pipeline и ColumnTransformer

Библиотеки

pip install scikit-learn pandas numpy matplotlib seaborn joblib

Основная версия: scikit-learn 1.4+.

Важные темы

Когда ML не нужен?

Как backend dev, если работают простые правила if/else — не используйте ML. Случаи, когда ML нужен:

✅ Правил очень много и они меняются (spam filter) ✅ Сложный паттерн (распознавание изображений, перевод) ✅ Персонализация (отдельно для каждого пользователя) ✅ Прогноз (будущие продажи, риск заболевания)

❌ Есть точная формула (area = π * r²) ❌ Мало данных (10 примеров — не ML, пишите правила) ❌ Critical safety (бесконтрольный ML — опасно) ❌ Требуется explainability, а ML — чёрный ящик

Типы ML-задач

1. Supervised Learning (input → output mavjud)
   ├── Regression: continuous output
   │   └── Misol: uy narxi, harorat, foydalanuvchi LTV
   └── Classification: discrete classes
       ├── Binary: spam/not-spam, churn/retain
       └── Multi-class: rasm turi, kasallik turi

2. Unsupervised Learning (faqat input)
   ├── Clustering: o'xshashlarni guruhlash
   ├── Dimensionality reduction: PCA, t-SNE
   └── Anomaly detection: g'ayrioddiy nuqtalar

3. Reinforcement Learning (agent + reward)
   └── O'yinlar, robotics, recommendation systems

Разделение Train / Validation / Test

**Зачем?**Чтобы оценить, как модель будет работать на «будущих» данных.

Hammasi (100%)
├── Training set (60-70%)    — model o'rganadi
├── Validation set (15-20%)  — hyperparameter tuning
└── Test set (15-20%)        — yakuniy baholash (faqat 1 marta!)

**Важное правило:**Test set нельзя видеть при обучении модели. Иначе — data leakage и некорректный результат.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

Overfitting vs Underfitting

Underfitting          Just right            Overfitting
   .                     .                     .
  / \                   / \                   /\/\
 /   \                 /   \                 /    \
/     \               /     \               /      \
Model juda             Model muvozanatda      Model trainni
oddiy                                         yodlab olgan
Training accuracyTest accuracy
UnderfittingНизкаяНизкая
Just rightВысокаяВысокая
OverfittingОчень высокаяНизкая

Решения:

  • Underfitting: более сложная модель, больше features
  • Overfitting: regularization, больше data, более простая модель, cross-validation

Cross-validation

Один train/test split иногда несправедлив. Решение — k-fold cross-validation:

5-fold CV:
Fold 1: Test=[1], Train=[2,3,4,5]
Fold 2: Test=[2], Train=[1,3,4,5]
Fold 3: Test=[3], Train=[1,2,4,5]
Fold 4: Test=[4], Train=[1,2,3,5]
Fold 5: Test=[5], Train=[1,2,3,4]
→ 5 ta accuracy → mean ± std

Примеры кода

Полный пример pipeline (Iris classification)

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score, classification_report
import joblib

# 1. Загрузка data
iris = load_iris(as_frame=True)
X, y = iris.data, iris.target

# 2. Train/test split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 3. Создание pipeline (preprocessing + model вместе)
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("classifier", LogisticRegression(max_iter=1000, random_state=42)),
])

# 4. Train
pipeline.fit(X_train, y_train)

# 5. Predict и оценка
y_pred = pipeline.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.3f}")
print(classification_report(y_test, y_pred, target_names=iris.target_names))

# 6. Сохранение
joblib.dump(pipeline, "iris_model.joblib")

Cross-validation

from sklearn.model_selection import cross_val_score

scores = cross_val_score(pipeline, X, y, cv=5, scoring="accuracy")
print(f"CV accuracy: {scores.mean():.3f} ± {scores.std():.3f}")
print(f"Each fold: {scores}")

ColumnTransformer (mixed types)

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder

# Отдельный preprocessing для числовых и categorical столбцов
preprocessor = ColumnTransformer([
    ("num", StandardScaler(), ["age", "salary"]),
    ("cat", OneHotEncoder(handle_unknown="ignore"), ["city", "department"]),
])

full_pipeline = Pipeline([
    ("preprocess", preprocessor),
    ("classifier", LogisticRegression()),
])

full_pipeline.fit(X_train, y_train)

Интеграция с backend

Serve ML-модели в FastAPI (минимально)

# main.py
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
import numpy as np

app = FastAPI()
model = joblib.load("iris_model.joblib")

CLASS_NAMES = ["setosa", "versicolor", "virginica"]

class IrisInput(BaseModel):
    sepal_length: float
    sepal_width: float
    petal_length: float
    petal_width: float

class IrisPrediction(BaseModel):
    class_name: str
    confidence: float

@app.post("/predict", response_model=IrisPrediction)
def predict(data: IrisInput):
    X = np.array([[data.sepal_length, data.sepal_width, 
                   data.petal_length, data.petal_width]])
    pred = model.predict(X)[0]
    proba = model.predict_proba(X)[0]
    return IrisPrediction(
        class_name=CLASS_NAMES[pred],
        confidence=float(proba.max()),
    )

@app.get("/health")
def health():
    return {"status": "ok", "model_version": "v1"}
uvicorn main:app --reload
# POST http://localhost:8000/predict
# {"sepal_length": 5.1, "sepal_width": 3.5, "petal_length": 1.4, "petal_width": 0.2}

Best practices for ML serving

from contextlib import asynccontextmanager
from fastapi import FastAPI

# Загружать модель только один раз (lifespan)
@asynccontextmanager
async def lifespan(app: FastAPI):
    app.state.model = joblib.load("iris_model.joblib")
    app.state.model_version = "v1.2.0"
    yield
    # cleanup if needed

app = FastAPI(lifespan=lifespan)

Ресурсы

  • Scikit-learn User Guidescikit-learn.org/stable/user_guide.html
  • “Hands-On Machine Learning” — Aurélien Géron (3-е издание) — MUST READ книга
  • Andrew Ng — Machine Learning Specialization(Coursera) — бесплатный auditing
  • StatQuest — лучший YouTube для объяснения ML-алгоритмов
  • Kaggle Learn — Intro to Machine Learning (бесплатный мини-курс)

🏋️ Упражнения

🟢 Easy

  1. Загрузите sklearn.datasets.load_wine(), выполните classify через LogisticRegression, выведите accuracy.
  2. Измените random_state в train_test_split несколько раз, посмотрите разницу.
  3. Сравните 3-fold и 10-fold CV через cross_val_score.

🟡 Medium

  1. Пример Pipeline: создайте Pipeline для Titanic dataset — SimpleImputer + OneHotEncoder + StandardScaler + LogisticRegression.
  2. Stratification: посмотрите разницу с stratify=y и без него на imbalanced dataset.
  3. Overfitting demo: добавьте PolynomialFeatures(degree=20) к одному признаку и визуально покажите overfitting.

🔴 Hard

  1. FastAPI ML-сервис: containerize Iris classifier в Docker, добавьте CI/CD через GitHub Actions, создайте healthcheck endpoint. Эта работа станет основой для MLOps-проекта в 6-м месяце.
  2. Custom Estimator: создайте custom transformer, наследуясь от BaseEstimator и TransformerMixin — чтобы можно было использовать внутри Pipeline.

Capstone

notebooks/month-02/00_ml_intro.ipynb:

  • Загрузите California Housing dataset (sklearn.datasets.fetch_california_housing)
  • Train/test split, train LinearRegression
  • Оцените с cross-validation (RMSE)
  • Запишите в виде Pipeline (StandardScaler + LinearRegression)
  • Создайте FastAPI endpoint и протестируйте с curl

✅ Чек-лист

  • Знаю разницу между Supervised и Unsupervised
  • Могу отличить задачи Regression и Classification
  • Понимаю, зачем нужно разделение Train/Validation/Test
  • Распознаю Overfitting и Underfitting при их появлении
  • Пишу cross-validation в коде
  • Использую Scikit-learn Pipeline и ColumnTransformer
  • Умею сохранять модель и serve в FastAPI
  • Понимаю важность random_state=42

Переходим к Regression.