← Назад к вопросам

Какие деревья предпочтительнее для Random Forest?

2.0 Middle🔥 202 комментариев
#Машинное обучение

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Какие деревья предпочтительнее для Random Forest

Random Forest использует множество деревьев решений для создания мощного ensemble модели. Вопрос о том, какие деревья лучше всего работают в контексте Random Forest, имеет четкий ответ.

Основной принцип Random Forest

Random Forest базируется на двух ключевых идеях:

  1. Разнообразие (Diversity) — каждое дерево должно быть разным
  2. Относительная слабость отдельных деревьев — это превращается в силу ensemble

Предпочтительные деревья: ГЛУБОКИЕ и БЕЗ РЕГУЛЯРИЗАЦИИ

Почему именно глубокие деревья?

from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
import numpy as np

X, y = make_classification(n_samples=1000, n_features=20, random_state=42)

# Random Forest с глубокими деревьями (по умолчанию)
rf_deep = RandomForestClassifier(
    n_estimators=100,
    max_depth=None,  # Без ограничения глубины
    min_samples_split=2,  # Минимум 2 образца
    min_samples_leaf=1,   # По одному в листе
    random_state=42
)

# Random Forest с мелкими деревьями
rf_shallow = RandomForestClassifier(
    n_estimators=100,
    max_depth=5,  # Ограничиваем глубину
    min_samples_split=20,
    min_samples_leaf=10,
    random_state=42
)

# Сравнение
print(f"Deep trees CV score: {cross_val_score(rf_deep, X, y, cv=5).mean():.3f}")
print(f"Shallow trees CV score: {cross_val_score(rf_shallow, X, y, cv=5).mean():.3f}")

# Deep trees обычно дают лучший результат

Почему глубокие деревья работают лучше в Random Forest

1. Разнообразие через случайность

Каждое дерево в Random Forest обучается:

  • На случайной подвыборке данных (bootstrap)
  • С использованием случайного подмножества признаков

Глубокие деревья усиливают этот эффект:

from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt

# Деревья получают разные выборки и признаки
rf = RandomForestClassifier(
    n_estimators=100,
    max_features='sqrt',  # sqrt(n_features) при каждом разделении
    bootstrap=True,       # Случайная выборка с повторениями
    random_state=42
)

# Каждое дерево переобучается на своей подвыборке
# Но разнообразие + усреднение исправляют переобучение

2. Комплементарность деревьев

# Если деревья идентичны (мелкие):
# Они делают одинаковые ошибки
# Усреднение не помогает

# Если деревья разные (глубокие):
# Они делают разные ошибки
# Усреднение сильно помогает

Практический пример: влияние глубины на точность

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import numpy as np

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.2, random_state=42)

depths = [2, 5, 10, 20, None]  # None = без ограничения
train_scores = []
test_scores = []

for depth in depths:
    rf = RandomForestClassifier(
        n_estimators=100,
        max_depth=depth,
        random_state=42
    )
    rf.fit(X_train, y_train)
    train_scores.append(rf.score(X_train, y_train))
    test_scores.append(rf.score(X_test, y_test))

# Результаты показывают, что без ограничения (None) дает лучший результат
for d, train, test in zip(depths, train_scores, test_scores):
    print(f"Depth={d}: Train={train:.3f}, Test={test:.3f}")

Гиперпараметры Random Forest

1. max_depth: лучше None (без ограничения)

# Плохо — ограничиваем глубину
rf = RandomForestClassifier(max_depth=5)

# Хорошо — даем деревьям расти глубоко
rf = RandomForestClassifier(max_depth=None)  # По умолчанию

2. min_samples_split: лучше низкое значение

# Плохо — требуем больше образцов для разделения
rf = RandomForestClassifier(min_samples_split=50)

# Хорошо — позволяем деревьям глубже разделяться
rf = RandomForestClassifier(min_samples_split=2)  # По умолчанию

3. min_samples_leaf: лучше низкое значение

# Плохо
rf = RandomForestClassifier(min_samples_leaf=20)

# Хорошо
rf = RandomForestClassifier(min_samples_leaf=1)  # По умолчанию

Анализ ошибок деревьев

rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)

# Получаем ошибки отдельных деревьев
predictions = np.array([
    tree.predict(X_test) for tree in rf.estimators_
])

print(f"Shape: {predictions.shape}")  # (100, samples)

# Дисперсия предсказаний разных деревьев
variance = predictions.var(axis=0).mean()
print(f"Average variance: {variance:.3f}")

# Глубокие деревья имеют ВЫСОКУЮ дисперсию (разные ошибки)
# Усреднение эту дисперсию снижает

Регуляризация в Random Forest

Вместо ограничения глубины деревьев, Random Forest управляет переобучением через:

rf = RandomForestClassifier(
    n_estimators=100,        # Больше деревьев = лучше
    max_features='sqrt',     # Случайность в признаках
    bootstrap=True,          # Случайные подвыборки
    oob_score=True,          # Out-of-bag оценка
    random_state=42
)

rf.fit(X_train, y_train)
print(f"OOB Score: {rf.oob_score_:.3f}")  # Оценка на неиспользованных данных

Когда ограничивать глубину в Random Forest?

# Если очень мало памяти:
rf_small = RandomForestClassifier(
    n_estimators=50,
    max_depth=20,  # Ограничиваем немного
    random_state=42
)

# Если нужна интерпретируемость:
rf_interpretable = RandomForestClassifier(
    n_estimators=100,
    max_depth=10,  # Мелкие деревья понятнее
    random_state=42
)

# Но для максимальной точности:
rf_optimal = RandomForestClassifier(
    n_estimators=200,
    max_depth=None,  # Деревья растут свободно
    random_state=42
)

Сравнение с отдельным деревом

from sklearn.tree import DecisionTreeClassifier

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.2, random_state=42)

# Одно глубокое дерево
tree = DecisionTreeClassifier(max_depth=None, random_state=42)
tree.fit(X_train, y_train)
print(f"Tree: Train={tree.score(X_train, y_train):.3f}, Test={tree.score(X_test, y_test):.3f}")
# Output: Train=0.99, Test=0.75  (переобучение)

# Random Forest из глубоких деревьев
rf = RandomForestClassifier(n_estimators=100, max_depth=None, random_state=42)
rf.fit(X_train, y_train)
print(f"RF: Train={rf.score(X_train, y_train):.3f}, Test={rf.score(X_test, y_test):.3f}")
# Output: Train=0.95, Test=0.83  (лучше баланс)

Главный вывод

Для Random Forest лучше всего подходят ГЛУБОКИЕ, СЛАБО РЕГУЛЯРИЗОВАННЫЕ деревья

Это потому что:

  1. Разнообразие — каждое дерево разное благодаря bootstrap и случайным признакам
  2. Комплементарность — разные деревья делают разные ошибки
  3. Усреднение — комбинирование множества слегка переобученных моделей дает отличный результат
  4. Слабые ученики — философия ensemble: много слабых + комбинирование = сильный

Параметры по умолчанию в scikit-learn оптимальны именно поэтому.

Какие деревья предпочтительнее для Random Forest? | PrepBro