Основные типы моделей для детекции
В машинном обучении существуют различные архитектуры для задач детекции объектов, каждая со своими преимуществами и недостатками.
CNN-based подходы (Convolutional Neural Networks)
YOLO (You Only Look Once) — самая популярная одностадийная архитектура. Модель делит изображение на сетку и предсказывает ограничивающие рамки непосредственно для всего изображения за один проход. Это обеспечивает высокую скорость (реал-тайм), но может теряться на малых объектах.
R-CNN семейство (R-CNN, Fast R-CNN, Faster R-CNN) — двухстадийные модели. Сначала выделяют кандидаты регионов, затем классифицируют каждый. Более медленнее, чем YOLO, но обычно точнее.
SSD (Single Shot MultiBox Detector) — одностадийный детектор, находится между YOLO и R-CNN по скорости/точности.
Трансформер-based подходы
Задача классификации в машинном обучении
Классификация — это задача supervised learning, где требуется предсказать дискретный класс (категорию) для объекта на основе его признаков (features). Модель обучается на размеченных примерах и затем делает предсказания для новых данных.
Основные типы
Бинарная классификация (Binary Classification) Делим объекты на два класса:
Многоклассовая классификация (Multiclass) Один объект принадлежит одному из N классов (N > 2):
Многолейбловая классификация (Multilabel) Один объект может принадлежать нескольким классам одновременно:
Основные этапы решения
Что нравилось на прошлой работе: создаём позитивный нарратив
Этот вопрос часто идёт после «что не нравилось». Это возможность показать, что вы цените позитивное, и переходить на эту работу не из бегства, а из стремления.
Пример 1: Команда и сотрудничество
"Больше всего я ценил людей и командный дух.
Конкретно:
Текущие проекты и направления разработки
Основные активности в последнее время
1. Optimizing Large Language Models (LLM) для production
На последних проектах фокусируюсь на эффективности больших языковых моделей:
# Пример: квантизация модели через transformers
from transformers import AutoModelForSequenceClassification
from optimum.onnxruntime import ORTQuantizer
model = AutoModelForSequenceClassification.from_pretrained("bert-base")
quantizer = ORTQuantizer.from_pretrained(model)
quantized_model = quantizer.quantize(
save_dir="./quantized_bert",
quantization_config=QuantizationConfig(is_static=False)
)
# Модель становится в 4 раза меньше, в 2-3 раза быстрее!
2. Реанализ убыточных проектов ML
Какие задачи выполняет Data Scientist?
Data Scientist — это роль на пересечении статистики, программирования и бизнес-аналитики. Профессионал работает со всеми этапами жизненного цикла данных и моделей.
1. Подготовка и анализ данных (EDA)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Исследовательский анализ данных (Exploratory Data Analysis)
df = pd.read_csv('data.csv')
# Базовая информация
print(df.info())
print(df.describe())
# Проверка пропусков
print(df.isnull().sum())
# Распределение целевой переменной
df['target'].value_counts()
# Визуализация
df.hist(figsize=(10, 8))
plt.show()
# Корреляционный анализ
import seaborn as sns
corr_matrix = df.corr()
sns.heatmap(corr_matrix)
plt.show()
Задачи:
2. Очистка и обработка данных (Data Cleaning)
О чем говорит высокий variance в bias-variance tradeoff
Высокий variance — это критический сигнал о переобучении модели. Объясню, почему это важно и как это диагностировать.
Что такое variance в контексте bias-variance tradeoff
Variance характеризует, насколько сильно модель меняет свои предсказания при небольших изменениях тренировочных данных.
Можно представить это так: если мы обучим модель на 100 разных случайных подвыборках одного датасета, высокий variance означает, что полученные модели будут сильно отличаться друг от друга.
Высокий bias (недообучение):
- Модель слишком простая
- Предсказания практически идентичны для всех датасетов
- Но все они ошибочны
Высокий variance (переобучение):
- Модель слишком сложная
- Предсказания сильно отличаются для разных датасетов
- Модель "запомнила" шум в тренировочных данных
Как диагностировать высокий variance
Главный признак: большой разрыв между train и test метриками.
Улучшения бинарной кросс-энтропии в современном ML
Бинарная кросс-энтропия (Binary Cross-Entropy, BCE) — это одна из самых распространённых функций потерь для задач бинарной классификации. Однако за годы развития ML появилось множество улучшений и альтернатив, которые решают её ограничения и улучшают обучение моделей.
Классическая бинарная кросс-энтропия
Формула:
BCE = -1/n * Σ[y*log(p) + (1-y)*log(1-p)]
где:
- y — истинная метка (0 или 1)
- p — вероятность положительного класса
- n — количество образцов
Реализация:
import torch
import torch.nn as nn
criterion = nn.BCELoss() # Классическая BCE
loss = criterion(y_pred, y_true)
1. Focal Loss (потеря для несбалансированных данных)
Проблема, которую решает: BCE обрабатывает легкие примеры одинаково с трудными. Если класс 0 встречается в 99% случаев, модель может достичь 99% accuracy, просто предсказывая все 0.
Решение — Focal Loss:
FL(p_t) = -α_t * (1 - p_t)^γ * log(p_t)
Градиентный взрыв: проблема и решения
Градиентный взрыв (Gradient Explosion) — это проблема при обучении глубоких нейронных сетей, когда градиенты становятся экспоненциально большими, приводя к расхождению обучения и NaN значениям весов.
1. Что такое градиентный взрыв
При обратном распространении ошибки (backpropagation) через много слоёв, градиенты умножаются на частные производные каждого слоя:
Входной слой → [W1 * σ'1] → [W2 * σ'2] → [W3 * σ'3] → ... → Выходной слой
Полный градиент = δL/δW = δL/δOut * dOut/dW3 * dW3/dW2 * dW2/dW1 * dW1/dInput
Если каждое умножение > 1, градиент экспоненциально растёт:
1 → 1.1 → 1.21 → 1.33 → 1.46 → ... → бесконечность (NaN)
2. Визуализация проблемы
import numpy as np
import matplotlib.pyplot as plt
Стратификация в машинном обучении
Стратификация — это техника разделения данных на тренировочное и тестовое подмножества таким образом, чтобы распределение целевой переменной (класса) было одинаковым в обоих наборах. Она особенно важна при работе с несбалансированными классами.
Проблема без стратификации
from sklearn.model_selection import train_test_split
import numpy as np
# Несбалансированный датасет
y = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) # 90% класс 0, 10% класс 1
# Обычное разделение (БЕЗ стратификации)
from sklearn.model_selection import train_test_split
X_dummy = np.arange(10).reshape(-1, 1)
X_train, X_test, y_train, y_test = train_test_split(
X_dummy, y, test_size=0.3, random_state=42
)
Стек (Stack) в Python: Полное объяснение
Стек (Stack) — это абстрактная структура данных, которая работает по принципу LIFO (Last In, First Out — последним вошёл, первым вышел). Это означает, что элемент, добавленный последним, удаляется первым. Стек широко используется в программировании для управления памятью, синтаксического анализа и алгоритмов обхода.
Концепция и аналогия
Представь стопку тарелок:
Это основной принцип работы стека.
Основные операции стека
Push — добавление элемента в стек Pop — удаление и возврат верхнего элемента Peek — просмотр верхнего элемента без удаления IsEmpty — проверка, пуст ли стек Size — получение количества элементов
Реализация стека в Python
Базовая реализация на списке
Самый простой способ — использовать список:
Что такое filter в Python?
filter() — это встроенная функция Python, которая создаёт итератор, содержащий только те элементы из последовательности, которые удовлетворяют определённому условию (предикату). Это инструмент функционального программирования для фильтрации данных.
Основной синтаксис
filtered_data = filter(function, iterable)
где:
Практические примеры
Пример 1: Фильтрация чисел
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # [2, 4, 6, 8, 10]
Пример 2: Фильтрация со своей функцией
def is_positive(x):
return x > 0
data = [-5, -2, 0, 3, 7, -1]
positives = list(filter(is_positive, data))
print(positives) # [3, 7]
Что не нравилось на прошлой работе?
На моей прошлой работе были в целом позитивные впечатления, но было несколько аспектов, которые я хотел бы улучшить.
1. Технический долг
Один из основных вызовов был связан с техническим долгом в legacy codebase. Часть проектов была разработана 5+ лет назад без современных практик. Это замедляло разработку новых фич на 20-30%.
Я частично решал это через:
Но понимал, что нужна стратегическая переписка некоторых систем. Это требует больше time investment, чем часто было доступно.
2. Скорость принятия решений
На больших организациях процесс принятия решений медленный. Простое изменение в архитектуре требовало согласования с 5+ stakeholders. Это замедляло темп разработки.
Мне нравятся более agile команды, где можно быстро экспериментировать и итерировать.
Направления развития в Data Science
Мой путь развития сосредоточен на углублении экспертизы в ключевых направлениях, которые становятся всё более актуальными в индустрии.
1. LLM и Generative AI
Почему это важно:
Мои интересы:
2. Production ML и MLOps
Когда начал программировать?
Путь в Data Science
Мой путь в программирование начался в 2009 году, когда я учился в третьем курсе университета. Это был естественный переход: увлечение математикой и информатикой привело меня к первому языку программирования — C++.
Первые шаги: C++ и алгоритмы
В 2009-2010 годах я занимался программированием на C++, участвовал в олимпиадах по информатике и решал задачи на algorithmic problem-solving. Это была отличная основа для понимания:
Разработка на C++ требует глубокого понимания памяти, типов данных и эффективности — навыки, которые остаются полезны в любой области программирования.
Переход к Python: 2011-2013
Использование моделей бустинга при дисбалансе классов
Дисбаланс классов — частая проблема в реальных проектах. Модели бустинга обладают встроенными механизмами для работы с этим.
1. Встроенные механизмы бустинга
XGBoost с взвешиванием
XGBoost предоставляет несколько параметров для обработки дисбаланса:
from xgboost import XGBClassifier
n_negative = (y_train == 0).sum()
n_positive = (y_train == 1).sum()
scale_pos_weight = n_negative / n_positive
model = XGBClassifier(
scale_pos_weight=scale_pos_weight,
max_depth=5,
learning_rate=0.1,
n_estimators=100,
random_state=42
)
model.fit(X_train, y_train)
# Способ 2: sample_weight
weights = np.where(y_train == 0, 1, n_negative / n_positive)
model.fit(X_train, y_train, sample_weight=weights)
LightGBM с балансировкой
from lightgbm import LGBMClassifier
Как долго работал на удалёнке?
Как опытный Data Scientist с 10+ годами в индустрии, я имею значительный опыт работы в удалённом формате.
Мой опыт удалённой работы
Продолжительность: около 6-7 лет в удалённом/гибридном формате (последний период особенно интенсивно).
Периоды работы:
Что я получил из удалённой работы
Разделение датасета на обучающую и тестовую части — критический этап, определяющий валидность оценки модели. Существует несколько подходов в зависимости от природы данных.
Стандартная случайная разбивка
Самый распространённый подход — случайное разделение на train/test с помощью train_test_split:
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
)
test_size=0.2 означает 80/20 разбивку. Для больших датасетов часто используют 70/30. random_state=42 обеспечивает воспроизводимость.
Стратифицированная разбивка
Для дисбалансированных классов критична стратификация — она гарантирует одинаковое распределение классов в train и test:
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
Это обязательно при работе с классификацией с дисбалансом.
Кросс-валидация
Переобучение (Overfitting): диагностика и методы борьбы
Переобучение — это ситуация, когда модель слишком хорошо подгоняется к тренировочным данным и теряет способность обобщаться на новые данные. Модель запоминает частности тренировочного набора вместо того, чтобы изучать общие закономерности.
Признаки переобучения
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.model_selection import train_test_split
# Создание данных с истинной зависимостью + шум
np.random.seed(42)
X = np.linspace(0, 10, 50).reshape(-1, 1)
y_true = np.sin(X.ravel())
y = y_true + np.random.normal(0, 0.3, len(y_true)) # добавляем шум
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
Set (множество) в Python
Set — это встроенный тип данных в Python, который представляет неупорядоченную коллекцию уникальных элементов. Это одна из четырёх основных встроенных коллекций в Python наряду с list, tuple и dict.
Основные характеристики
Уникальность: каждый элемент в множестве может присутствовать только один раз. Если попытаться добавить дубликат, он просто проигнорируется.
Неупорядоченность: элементы в множестве не имеют индексов, порядок их хранения не определён и может изменяться. Вы не можете обратиться к элементу по индексу.
Изменяемость: множество изменяемо (mutable) — вы можете добавлять и удалять элементы после создания.
Хеширование: элементы в set должны быть хешируемы (hashable) — это означает, что они должны иметь постоянный хеш-код. Поэтому list и dict нельзя добавить в множество, но tuple можно.
Создание множеств
# Создание пустого множества
my_set = set()
Байесовский оптимизатор в Python
Байесовская оптимизация — это вероятностный метод для поиска оптимальных значений гиперпараметров модели. Вместо того, чтобы случайно или перебирать все комбинации (grid search, random search), она использует информацию о предыдущих испытаниях для интеллектуального выбора следующих кандидатов.
Основная идея
Байесовская оптимизация основана на двух концепциях:
Как это работает
Какой у тебя уровень знаний SQL?
Уровень владения SQL
Я обладаю экспертным уровнем SQL с 10+ лет опыта в практическом применении при разработке систем машинного обучения и аналитики данных.
Основные навыки
DDL (Data Definition Language)
DML (Data Manipulation Language)
SELECT
user_id,
order_date,
amount,
SUM(amount) OVER (PARTITION BY user_id ORDER BY order_date ROWS BETWEEN 30 PRECEDING AND CURRENT ROW) as rolling_30d_sum,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_date DESC) as recency_rank
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '1 year'
F-мера при precision и recall равных 1
F-мера равна 1 когда precision и recall оба равны 1.
Формула F-меры
F-мера (F1-score) — это гармоническое среднее precision и recall:
$$F_1 = 2 \cdot \frac{precision \cdot recall}{precision + recall}$$
Или в более общем виде:
$$F_\beta = (1 + \beta^2) \cdot \frac{precision \cdot recall}{\beta^2 \cdot precision + recall}$$
где β = 1 для стандартной F1-меры.
Расчёт при precision = 1 и recall = 1
precision = 1
recall = 1
# Подстановка в формулу
F1 = 2 * (precision * recall) / (precision + recall)
F1 = 2 * (1 * 1) / (1 + 1)
F1 = 2 * 1 / 2
F1 = 1
Ответ: F1 = 1
Что это означает
Если precision = 1 и recall = 1, это значит:
Это идеальная ситуация — модель работает на 100% правильно:
Словари в работе Data Scientist
Словарь — одна из фундаментальных структур данных в Python и data science. Это неупорядоченная коллекция пар ключ-значение, которая используется повсеместно в аналитике данных.
1. Основное назначение словарей
Словари позволяют:
# Основное использование
user = {
"name": "Иван",
"age": 28,
"city": "Москва",
"skills": ["Python", "SQL", "ML"]
}
print(user["name"]) # O(1) доступ
user["experience_years"] = 5 # Добавление
2. Словари в обработке данных
В data science словари используются для преобразования и маппинга данных:
import pandas as pd
import numpy as np
KNN: K-Nearest Neighbors
KNN (K-Nearest Neighbors) — это один из самых простых и интуитивных алгоритмов машинного обучения, основанный на принципе близости. Несмотря на простоту, он остаётся полезным инструментом в практике Data Science.
Основной принцип
Алгоритм работает на простой идее: объект похож на объекты, находящиеся рядом с ним в пространстве признаков.
Для предсказания значения для нового объекта:
Пример реализации
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
AUC: Area Under the ROC Curve
Определение
AUC (Area Under the Curve) — это площадь под ROC кривой (Receiver Operating Characteristic). Это метрика для оценки качества бинарной классификации, которая показывает способность модели различать два класса при различных порогах классификации.
ROC кривая
ROC кривая строится с помощью:
Кривая получается путём изменения порога вероятности классификации от 0 до 1.
Пример построения ROC кривой
from sklearn.metrics import roc_curve, auc
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
model = LogisticRegression()
model.fit(X_train, y_train)
Получение эмбеддингов из текстов для трансформера
Эмбеддинги — это численные векторные представления текста, которые захватывают семантическое значение и структуру языка. Трансформеры позволяют получить высококачественные эмбеддинги, которые используются в различных задачах NLP.
Методы получения эмбеддингов
Самый популярный и рекомендуемый подход — использование готовых предобученных моделей.
from transformers import AutoTokenizer, AutoModel
import torch
import numpy as np
# Загрузка модели и токенизатора
model_name = "sentence-transformers/all-MiniLM-L6-v2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name)
Gradient Boosting Trees: Мощный алгоритм ансамбля
Определение
Gradient Boosting - это ансамбль-метод машинного обучения, который последовательно строит деревья решений, где каждое новое дерево исправляет ошибки предыдущих.
Основная идея:
Дерево 1: делает предсказание
Дерево 2: исправляет ошибки дерева 1
Дерево 3: исправляет ошибки деревьев 1 и 2
...
Итоговый результат = Дерево 1 + Дерево 2 + Дерево 3 + ...
История
1997: Фридман предложил Gradient Boosting в статье
2001: XGBoost (начальная версия)
2014: LightGBM от Microsoft
2017: CatBoost от Яндекса
2024: Стандарт для табличных данных в ML соревнованиях
Сравнение с другими методами
Random Forest (параллельный ансамбль):
- Деревья строятся независимо
- Ошибки разных деревьев некоррелированы
- Менее точный, но более устойчивый
Gradient Boosting (последовательный ансамбль):
- Деревья строятся по одному
- Каждое исправляет ошибки предыдущих
- Более точный, но может переобучиться
Перечислите этапы построения дерева решений
Введение
Дерево решений (Decision Tree) — это одна из самых интерпретируемых и популярных моделей машинного обучения. Процесс его построения состоит из чётко определённых этапов, каждый из которых критически важен для получения качественной и эффективной модели.
Этап 1: Подготовка и очистка данных
Первый этап — это всегда подготовка данных к работе. Необходимо:
from sklearn.preprocessing import LabelEncoder
# Кодирование категориальных признаков
le = LabelEncoder()
X['category'] = le.fit_transform(X['category'])
Валидация моделей машинного обучения
Правильная валидация критична для оценки реальной производительности модели. Существуют различные стратегии в зависимости от типа данных и задачи.
1. Базовое разбиение: Train-Validation-Test Split
from sklearn.model_selection import train_test_split
# Базовое разбиение 60-20-20
X_train, X_temp, y_train, y_temp = train_test_split(
X, y,
test_size=0.4,
random_state=42
)
X_val, X_test, y_val, y_test = train_test_split(
X_temp, y_temp,
test_size=0.5,
random_state=42
)
# Для классификации со стратификацией
X_train, X_temp, y_train, y_temp = train_test_split(
X, y,
test_size=0.4,
random_state=42,
stratify=y
)
X_val, X_test, y_val, y_test = train_test_split(
X_temp, y_temp,
test_size=0.5,
random_state=42,
stratify=y_temp
)
2. Кроссвалидация (K-Fold Cross-Validation)
Самый надёжный метод для оценки качества:
Подсчёт размера группы в SQL
При группировке в SQL размер каждой группы подсчитывается с помощью агрегирующей функции COUNT(), которая считает количество строк в каждой группе.
Основной синтаксис
Самый простой способ — использовать COUNT(*) или COUNT(column):
SELECT column1, COUNT(*) as group_size
FROM table_name
GROUP BY column1;
Здесь COUNT(*) подсчитывает все строки в каждой группе, включая строки с NULL значениями.
Примеры использования
Пример 1: Количество заказов по клиентам
SELECT
customer_id,
COUNT(*) as number_of_orders
FROM orders
GROUP BY customer_id
ORDER BY number_of_orders DESC;
Пример 2: Группировка по нескольким столбцам
SELECT
department,
job_title,
COUNT(*) as employees_count
FROM employees
GROUP BY department, job_title;
Различия между COUNT() вариантами
Оценка качества модели — многоуровневый процесс, который зависит от типа задачи, характера данных и требований бизнеса. Я использую системный подход, сочетающий различные метрики и методы валидации.
1. Выбор метрик в зависимости от задачи
Классификация
Для бинарной классификации:
from sklearn.metrics import (
accuracy_score, precision_score, recall_score, f1_score,
roc_auc_score, confusion_matrix, roc_curve, auc
)
import matplotlib.pyplot as plt
y_test = [0, 1, 1, 0, 1, 1, 0, 0, 1]
y_pred = [0, 1, 1, 0, 0, 1, 0, 1, 1]
y_proba = [0.1, 0.95, 0.92, 0.15, 0.4, 0.88, 0.2, 0.6, 0.85]
# Базовые метрики
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
roc_auc = roc_auc_score(y_test, y_proba)
print(f"Accuracy: {accuracy:.4f}")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1-score: {f1:.4f}")
print(f"ROC-AUC: {roc_auc:.4f}")
System Design для веб-краулера
Веб-краулер — сложная распределённая система для сбора данных в масштабе. Рассмотрим архитектуру для обработки миллионов страниц эффективно.
1. Высокоуровневая архитектура
Система состоит из нескольких ключевых компонентов:
2. URL Frontier (управление очередью)
import redis
from urllib.parse import urlparse
import hashlib
Портфель моих Data Science проектов
Имею опыт работы на полном цикле от постановки задачи до мониторинга в production.
1. Рекомендательная система для стриминг-платформы
Масштаб: 2M+ активных пользователей, 100K+ контента
Проблема: Стандартный контент показывал низкий engagement
Решение:
2. Система прогнозирования спроса (Demand Forecasting)
Контекст: Сеть розничных магазинов, 500+ точек продаж
Задача: Точно предсказать спрос SKU на 7-14 дней
Подход:
Когда медиана описывает данные лучше, чем среднее?
Среднее (mean) и медиана (median) — это две основные меры центральной тенденции в статистике. Выбор между ними критичен для правильного анализа данных, особенно когда речь идёт о распределениях с выбросами и асимметрией.
Основное различие
Среднее (mean):
mean = (x₁ + x₂ + ... + xₙ) / n
Чувствительно к каждому значению в наборе данных.
Медиана (median):
Значение, которое делит отсортированный набор данных пополам.
Для нечётного количества: среднее значение
Для чётного количества: среднее двух центральных значений
Устойчива к экстремальным значениям.
Когда медиана лучше среднего
import numpy as np
# Данные о зарплате в команде (в тысячах)
salaries = [30, 35, 40, 42, 38, 45, 40000] # последнее значение — CEO
mean_salary = np.mean(salaries) # 5761 (искажено выбросом)
median_salary = np.median(salaries) # 40 (более репрезентативно)
Обработка пропущенных значений (Missing Data)
Пропущенное значение — это отсутствие данных в какой-то ячейке таблицы. В Python/Pandas обозначается как NaN, None или NA. Это одна из самых частых задач при подготовке данных.
Виды пропусков (MCAR, MAR, MNAR)
1. MCAR (Missing Completely At Random)
Определение: вероятность пропуска не зависит ни от наблюдаемых, ни от ненаблюдаемых переменных. Полностью случайно.
Пример: из-за сбоя датчика потеряны некоторые измерения
Как обработать: любой метод работает хорошо (удаление, импутация, модели).
2. MAR (Missing At Random)
Определение: вероятность пропуска зависит от наблюдаемых переменных, но не от самого пропущенного значения.
Пример: люди с высокой зарплатой менее охотно её указывают.
Пропуск зарплаты зависит от: был ли вопрос, откуда человек узнал об опросе,
но не от самой зарплаты напрямую.
Как обработать: метод на основе всех доступных переменных (например, multiple imputation).
Что такое ансамбль методов?
Ансамбль методов (Ensemble Methods) — это техника машинного обучения, которая объединяет предсказания нескольких базовых моделей для получения лучшего финального результата. Основная идея: группа слабых или средних моделей вместе может дать более сильное и надёжное предсказание, чем любая отдельная модель.
Основной принцип
Мудрость толпы (Wisdom of Crowds):
Если модели делают ошибки независимо друг от друга, то их объединение уменьшит общую ошибку. Это работает, когда модели:
# Пример: бросание монеты 100 раз
# Одна монета может дать неправильный результат
# Но сотня монет даст результат, близкий к 50/50
import numpy as np
# Одна модель
model1_accuracy = 0.6 # 60% точность
В чём разница между контролируемым и неконтролируемым машинным обучением?
Это две фундаментальные парадигмы машинного обучения, которые отличаются наличием или отсутствием помеченных целевых переменных в обучающих данных.
Контролируемое обучение (Supervised Learning)
Определение: модель обучается на размеченном датасете, где каждый пример имеет входные признаки (X) и соответствующую целевую переменную (y).
Примеры задач:
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestClassifier
# Контролируемое обучение: регрессия
# X — входные признаки, y — целевая переменная (есть ответы!)
X = np.array([[2104, 5], [1600, 3], [2400, 5], [1416, 2]]) # площадь, комнаты
y = np.array([399, 321, 424, 250]) # цена дома
# Обучение
model = LinearRegression()
model.fit(X, y)
Random Forest (Метод случайного леса)
Random Forest — это ансамблевый алгоритм машинного обучения, который строит множество решающих деревьев на случайных подвыборках данных и объединяет их предсказания для получения более точного и стабильного результата.
Основной принцип
Random Forest использует бэггинг (bootstrap aggregating) и случайность признаков:
Создание подвыборок (Bootstrap): Из исходного датасета размером N случайно с возвратом выбираются B подвыборок размером N. В среднем каждый пример участвует в ~63% подвыборок.
Построение деревьев: На каждой подвыборке строится полное решающее дерево без ограничения глубины.
Случайность признаков: На каждом узле дерева рассматривается не все признаки, а только случайная подвыборка (обычно √m или log₂m, где m — число признаков).
Агрегация: Результаты всех деревьев объединяются через голосование (классификация) или усреднение (регрессия).
Что такое pandas?
Pandas — это фундаментальная Python-библиотека для работы с данными, которая предоставляет высокоуровневые структуры данных и инструменты для анализа и манипуляции табличными данными. Это стандартный инструмент в арсенале любого Data Scientist.
Основные структуры данных
Series — одномерный массив с метками (индексами), похожий на столбец в таблице:
import pandas as pd
s = pd.Series([10, 20, 30, 40], index=["a", "b", "c", "d"])
print(s["a"]) # 10
DataFrame — двумерная таблица с метками строк и столбцов. Это основная структура, с которой работает большинство аналитиков:
df = pd.DataFrame({
"name": ["Alice", "Bob", "Charlie"],
"age": [25, 30, 35],
"salary": [50000, 60000, 75000]
})
Ключевые преимущества
F1-мера: зачем нужна и когда её использовать
F1-мера — это гармоническое среднее precision и recall, один из самых важных метрик оценки качества классификационных моделей. Она решает критическую проблему: как оценить модель, когда важны оба типа ошибок.
1. Проблема: Accuracy недостаточна
Основная метрика accuracy часто обманчива при дисбалансе классов:
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
import numpy as np
# Дисбалансированный датасет: 99% одного класса
y_true = [0] * 990 + [1] * 10 # 990 негативов, 10 позитивов
y_pred_lazy = [0] * 1000 # Модель просто всегда предсказывает 0
acc = accuracy_score(y_true, y_pred_lazy)
print(f"Accuracy: {acc:.1%}") # 99.0% — звучит отлично!
# Но на самом деле модель бесполезна:
precision = precision_score(y_true, y_pred_lazy, zero_division=0)
recall = recall_score(y_true, y_pred_lazy, zero_division=0)
f1 = f1_score(y_true, y_pred_lazy, zero_division=0)
Проекты в области Data Science
Большинство моего опыта я получил на реальных production-проектах с высокими требованиями к качеству и производительности.
Проект 1: Система рекомендаций для e-commerce
Задача: Рекомендовать товары пользователям в реальном времени
Решение:
Результат:
Проект 2: Прогнозирование оттока клиентов (Churn Prediction)
Контекст: SaaS платформа с подписочной моделью
Почему меняешь работу?
Что проверяет интервьюер?
Этот вопрос выясняет:
Структура правильного ответа
1. Благодарность за опыт (не критика)
2. Позитивная причина ухода (рост, новые задачи)
3. Конкретное направление развития
4. Связь с вашей компанией (почему именно вы?)
Примеры хороших ответов
"Я 3 года работал в компании X и многому научился. Но я достиг того
уровня, где основные задачи я решаю на автомате. Хочу работать с
проблемами масштаба — рекомендательные системы, петабайты данных.
Ваша компания обрабатывает 100M+ событий в день, и это ровно то, что
мне интересно. Я видел ваш доклад на конференции о том, как вы решали
проблему X, и хочу быть частью этого."
Что такое Accuracy?
Определение
Accuracy (Точность) — это самая простая метрика для оценки классификационных моделей:
Accuracy = (TP + TN) / (TP + FP + FN + TN)
Где:
Простыми словами
Accuracy = доля правильных предсказаний из всех предсказаний
Пример: если модель правильно предсказала 85 случаев из 100, то Accuracy = 85%
Пример
Предположим:
- У нас 10 примеров: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
- Модель предсказала: [0, 0, 0, 1, 0, 1, 1, 1, 0, 1]
Правильные:
- TP (истинные единицы): 3 (индексы 5, 6, 7)
- TN (истинные нули): 4 (индексы 0, 1, 2, 4)
Ошибочные:
- FP (ложные единицы): 1 (индекс 3)
- FN (ложные нули): 1 (индекс 8)
Accuracy = (3 + 4) / 10 = 70%
Разница между MAE, MSE и RMSE
Введение
MAE (Mean Absolute Error), MSE (Mean Squared Error) и RMSE (Root Mean Squared Error) — это три наиболее распространённые метрики для оценки качества моделей регрессии. Они измеряют ошибку предсказания, но по-разному штрафуют за большие ошибки.
1. MAE (Mean Absolute Error) — Средняя абсолютная ошибка
MAE вычисляет среднее абсолютное отклонение предсказаний от реальных значений.
Формула:
MAE = (1/n) * sum(|y_actual - y_pred|)
import numpy as np
from sklearn.metrics import mean_absolute_error
# Пример
y_actual = np.array([3, -0.5, 2, 7])
y_pred = np.array([2.5, 0.0, 2, 8])
# Ручной расчёт
errors = np.abs(y_actual - y_pred)
print(f"Ошибки: {errors}") # [0.5, 0.5, 0.0, 1.0]
mae = np.mean(errors)
print(f"MAE: {mae:.3f}") # 0.5
# Через sklearn
mae_sklearn = mean_absolute_error(y_actual, y_pred)
print(f"MAE (sklearn): {mae_sklearn:.3f}") # 0.5
Развёртывание ML модели в production
Развёртывание (deployment) модели в production — это процесс переноса обученной модели из экспериментальной среды на боевой сервер, где она будет обслуживать реальные запросы. Это намного сложнее, чем просто сохранить модель в файл. Нужно обеспечить масштабируемость, надёжность, мониторинг и актуальность модели.
Основные этапы
1. Сохранение модели
Первый шаг — правильно сохранить обученную модель:
import pickle
import joblib
import json
from sklearn.ensemble import RandomForestClassifier
# Обучить модель
model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)
# Вариант 1: pickle (простой, но может быть несовместим между версиями)
with open('model.pkl', 'wb') as f:
pickle.dump(model, f)
# Вариант 2: joblib (рекомендуется для sklearn моделей)
joblib.dump(model, 'model.joblib')
Как определить необходимый размер выборки для эксперимента?
Определение размера выборки (sample size) это критический шаг в дизайне A/B тестов и других экспериментов. Недостаточный размер выборки приводит к низкой мощности теста и ошибкам типа II (пропускаем реальный эффект). Слишком большой размер это пустая трата ресурсов и времени.
Основные параметры для расчета
Размер выборки зависит от четырёх ключевых параметров:
1. Уровень значимости (alpha)
Вероятность ошибки типа I (ложноположительный результат). Стандартное значение alpha = 0.05 (5%).
2. Статистическая мощность (power)
Вероятность обнаружить реальный эффект. Стандартное значение power = 0.8 (80%). Это означает, что если эффект действительно существует, тест обнаружит его в 80% случаев.
3. Величина эффекта (effect size)
Наименьший практически значимый эффект, который нам нужно обнаружить. Это зависит от бизнес-контекста.
4. Базовая конверсия (baseline conversion)
Центральная предельная теорема (Central Limit Theorem, CLT)
Центральная предельная теорема — это одна из самых фундаментальных теорем в статистике и теории вероятностей. Она объясняет, почему нормальное распределение так часто встречается в природе и почему оно столь важно в анализе данных.
Формальное определение
Центральная предельная теорема гласит: если мы возьмём выборку размером n из любого распределения вероятностей с конечным математическим ожиданием μ и конечной дисперсией σ², то при достаточно большом n распределение выборочного среднего будет приблизительно нормальным (гауссовым) распределением с параметрами:
Математическое ожидание: μ_mean = μ Дисперсия: σ²_mean = σ² / n
Символьно: (X̄ - μ) / (σ / √n) → N(0, 1) при n → ∞
Ключевые моменты
Исходное распределение может быть ЛЮБЫМ
Ответ: В чём разница между INNER JOIN и LEFT/RIGHT JOIN?
Основное различие
JOIN в SQL — это операция объединения двух таблиц по условию совпадения значений в указанных столбцах. Ключевое различие между типами JOIN заключается в том, какие строки будут включены в результат.
INNER JOIN
INNER JOIN возвращает только строки, у которых есть совпадение в обеих таблицах.
SELECT
customers.customer_id,
customers.name,
orders.order_id,
orders.amount
FROM customers
INNER JOIN orders ON customers.customer_id = orders.customer_id;
Результат:
customer_id | name | order_id | amount
1 | Alice | 101 | 500
1 | Alice | 102 | 750
3 | Charlie | 103 | 200
Если у клиента нет заказов или есть заказ без клиента — такие строки не попадут в результат.
LEFT JOIN (LEFT OUTER JOIN)
Что делает оператор UNION в SQL?
UNION — это оператор SQL, который объединяет результаты двух или более SELECT запросов в один результирующий набор. UNION удаляет дубликаты по умолчанию, в отличие от UNION ALL, который сохраняет все строки.
Базовый синтаксис UNION
SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;
Требования к UNION:
UNION vs UNION ALL
SELECT id, name FROM employees
WHERE department = 'Sales'
UNION
SELECT id, name FROM employees
WHERE department = 'Marketing';
Результат: если один сотрудник работает в обоих отделах, он появится один раз.
id | name
---|-------
1 | Alice
2 | Bob
3 | Charlie
Виды нормализации в машинном обучении
Нормализация — это критический шаг предобработки данных и один из ключевых компонентов при обучении глубоких нейросетей. Существует множество подходов, каждый с собственным назначением и эффектом. Разберёмся подробно.
1. Нормализация признаков (Feature Normalization)
Min-Max Scaling (Нормализация на диапазон [0,1])
Формула: x_norm = (x - x_min) / (x_max - x_min)
Преимущества: интуитивна, результаты в фиксированном диапазоне Недостатки: чувствительна к выбросам
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_scaled = scaler.fit_transform(X)
Standardization (Z-score нормализация)
Формула: x_std = (x - mean) / std
Преимущества: учитывает распределение, лучше для алгоритмов, чувствительных к масштабу Недостатки: значения могут быть вне [0,1]
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
Robust Scaling