Как обучается модель случайного леса?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как обучается модель случайного леса?
Random Forest — ансамблевый метод машинного обучения, основанный на построении множества решающих деревьев и усреднении их предсказаний. Это один из самых популярных и мощных алгоритмов благодаря универсальности и высокому качеству.
Основная идея
Вместо одного большого дерева, которое может переобучиться, Random Forest строит несколько деревьев на случайных подвыборках данных. Каждое дерево делает своё предсказание, и финальный результат — среднее (регрессия) или голос большинства (классификация).
Процесс обучения Random Forest пошагово
Шаг 1: Bootstrap (Bootstrap Aggregating / Bagging)
Для каждого из N деревьев (обычно 100-1000):
- Случайно выбираем n образцов из тренировочного набора с возвращением (допускаются дубликаты)
- Получается подвыборка примерно такого же размера как исходный набор
- ~37% данных (1 - (1-1/n)^n) не попадают в выборку (OOB — Out-of-Bag данные)
from sklearn.ensemble import RandomForestClassifier
import numpy as np
# Симуляция bootstrap
data = np.arange(10) # [0, 1, 2, ..., 9]
bootstrap_sample = np.random.choice(data, size=len(data), replace=True)
print(f"Исходные данные: {data}")
print(f"Bootstrap выборка: {bootstrap_sample}")
# Пример выхода: [2, 7, 5, 5, 9, 1, 2, 7, 3, 6]
# Видим, что 5 и 7 повторяются, а 0, 4, 8 не попали
Шаг 2: Построение дерева решений
Для каждой bootstrap выборки строим полное дерево решений без pruning:
from sklearn.tree import DecisionTreeClassifier
def build_tree_on_bootstrap_sample(X, y, n_features=None):
# Индексы для bootstrap
bootstrap_indices = np.random.choice(len(X), size=len(X), replace=True)
X_boot = X[bootstrap_indices]
y_boot = y[bootstrap_indices]
# Случайное подмножество признаков для каждого расщепления
# Обычно sqrt(n_features) для классификации, n_features/3 для регрессии
tree = DecisionTreeClassifier(
max_features=n_features,
max_depth=None, # дерево растёт до полной глубины
min_samples_split=1
)
tree.fit(X_boot, y_boot)
return tree
Шаг 3: Случайное выбор признаков на каждом расщеплении
Ключевая идея: при поиске лучшего расщепления в каждом узле дерева используем только случайное подмножество признаков:
# Вместо того, чтобы проверить все признаки
if use_all_features: # ❌ Плохо - соседние деревья будут очень похожи
best_split_features = range(n_features)
# Используем только sqrt(n_features) признаков
if use_random_features: # ✅ Хорошо - декорелирует деревья
best_split_features = np.random.choice(
n_features,
size=int(np.sqrt(n_features)), # для классификации
replace=False
)
Это очень важно для уменьшения корреляции между деревьями!
Математическое описание алгоритма
Алгоритм Random Forest
─────────────────────────────────────────
По i от 1 до n_trees:
1. Создать bootstrap выборку B_i из обучающего набора
2. Построить дерево T_i на B_i:
- На каждом узле:
a) Выбрать случайное подмножество m признаков
b) Найти лучший признак и threshold из m признаков
c) Расщепить узел
- Растить дерево до максимальной глубины (без pruning)
Для предсказания нового образца x:
Классификация: класс = argmax (количество голосов за класс k)
Регрессия: значение = среднее из всех T_i(x)
Пример обучения на Python
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# Создаём данные
X, y = make_classification(n_samples=1000, n_features=20, n_informative=10)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# Создаём и обучаем модель
rf = RandomForestClassifier(
n_estimators=100, # количество деревьев
max_features='sqrt', # sqrt(n_features) для классификации
max_depth=None, # дерево растёт без ограничений
min_samples_split=2, # минимум образцов для расщепления узла
min_samples_leaf=1, # минимум в листе
bootstrap=True, # использовать bootstrap
random_state=42,
n_jobs=-1, # использовать все CPU cores
oob_score=True # вычислить score на OOB данных
)
rf.fit(X_train, y_train)
# Оценка качества
from sklearn.metrics import accuracy_score, classification_report
y_pred = rf.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.3f}")
print(f"OOB Score: {rf.oob_score_:.3f}") # Estimate качества без тестового сета
Важные параметры
RandomForestClassifier(
n_estimators=100, # больше деревьев = лучше (но медленнее)
# обычно 100-1000
max_features='sqrt', # количество признаков для расщепления
# 'sqrt' для классификации
# 'log2' для регрессии
max_depth=None, # глубина дерева (None = без ограничений)
# для борьбы с переобучением уменьшить
min_samples_split=2, # мин. образцов для расщепления узла
# увеличить чтобы упростить дерево
min_samples_leaf=1, # мин. образцов в листе
# увеличить чтобы упростить дерево
random_state=42, # reproducibility
n_jobs=-1, # распараллеливание (-1 = все ядра)
class_weight='balanced', # для дисбалансированных классов
)
Преимущества Random Forest
- Высокое качество — часто лучше одного дерева
- Устойчивость к переобучению — bootstrap и случайные признаки
- Параллелизация — деревья строятся независимо
- Handling missing data — может работать с пропусками
- Feature importance — можно оценить важность каждого признака
- Не требует нормализации — работает с сырыми признаками
- OOB estimate — оценка качества без отдельного тестового сета
Feature Importance в Random Forest
# Посмотреть важность признаков
importances = rf.feature_importances_
feature_names = [f"Feature {i}" for i in range(X.shape[1])]
for name, importance in sorted(zip(feature_names, importances),
key=lambda x: x[1], reverse=True)[:10]:
print(f"{name}: {importance:.4f}")
# Визуализировать
import matplotlib.pyplot as plt
plt.barh(feature_names, importances)
plt.xlabel('Importance')
plt.show()
Out-of-Bag (OOB) оценка
Красивое свойство Random Forest:
# Примерно 37% данных не попали в каждую bootstrap выборку
# Можем использовать их как тестовый сет без отдельного split!
rf = RandomForestClassifier(oob_score=True)
rf.fit(X_train, y_train)
print(f"OOB Score: {rf.oob_score_:.3f}") # Качество на OOB данных
# Обычно близко к тестовому качеству
Когда использовать Random Forest?
- Классификация и регрессия — универсален
- Много признаков — работает хорошо
- Нелинейные зависимости — ловит сложные паттерны
- Дисбалансированные классы — параметр class_weight
- Быстрое решение — быстрее настройки Deep Learning
Когда использовать другие методы?
- Очень большой набор данных — XGBoost часто быстрее
- Нужна максимальная точность — Gradient Boosting (XGBoost, LightGBM)
- Нужна интерпретируемость — одно дерево вместо леса
- Много категориальных признаков — обработать кодированием лучше
Итог
Random Forest обучается построением множества независимых деревьев решений на bootstrap выборках с использованием случайных подмножеств признаков. Это простой, быстрый и эффективный алгоритм, часто дающий отличные результаты без специальной настройки параметров.