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

В чем разница между Decision Tree и Random Forest?

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

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

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

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

Decision Tree vs Random Forest: полное сравнение

Decision Tree (Дерево решений)

Структура и принцип: Дерево решений — это иерархическая структура, где каждый узел представляет тест на значение признака, ветви — исходы теста, а листья — предсказания.

Как работает:

  1. На каждом узле выбирается признак и порог (threshold), которые лучше всего разделяют данные
  2. Критерий выбора: максимизация информационного прироста (Information Gain) или минимизация примесей (Gini, Entropy)
  3. Процесс повторяется рекурсивно для каждого подмножества
  4. Останавливается, когда узел «чист» (все примеры одного класса) или выполнены критерии остановки
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt

# Простое дерево
dt = DecisionTreeClassifier(
    max_depth=3,
    min_samples_split=2,
    min_samples_leaf=1,
    criterion='gini'
)
dt.fit(X_train, y_train)

# Визуализация
plt.figure(figsize=(20,10))
plot_tree(dt, filled=True, feature_names=feature_names, class_names=class_names)
plt.show()

Характеристики:

  • Одно дерево: одна модель
  • Глубина: часто растет очень глубоким
  • Интерпретируемость: очень высокая — можно проследить каждое решение
  • Склонность к переобучению: ВЫСОКАЯ (deep trees memorize)

Random Forest (Случайный лес)

Структура и принцип: Random Forest — это ансамбль (ensemble) множества независимых деревьев решений. Каждое дерево обучается на случайной подвыборке данных и случайном подмножестве признаков.

Как работает:

  1. Повторить N раз (обычно 100-1000):
    • Взять bootstrap sample (случайная выборка с повторением)
    • На каждом узле случайно выбрать sqrt(n_features) или log(n_features) признаков
    • Построить полное дерево без ограничения глубины
  2. Для предсказания:
    • Классификация: голосование большинства (majority voting)
    • Регрессия: среднее значение
from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(
    n_estimators=100,          # Количество деревьев
    max_depth=None,            # Полная глубина
    min_samples_split=2,
    min_samples_leaf=1,
    max_features='sqrt',       # sqrt(n_features) на каждом узле
    bootstrap=True,            # Bootstrap samples
    random_state=42
)
rf.fit(X_train, y_train)

Характеристики:

  • Множество деревьев: ансамбль (обычно 100-1000)
  • Независимость: деревья выращиваются независимо
  • Интерпретируемость: ниже, чем у одного дерева (нужно анализировать все деревья)
  • Склонность к переобучению: НИЗКАЯ (усреднение снижает variance)

Прямое сравнение

АспектDecision TreeRandom Forest
СтруктураОдно деревоАнсамбль деревьев
Количество моделей1100-1000
Данные для обученияВсе данныеBootstrap samples
Выбор признаковВсе признакиСлучайное подмножество
ГлубинаЧасто глубокоеОбычно полное (глубокое)
OverfittingВЫСОКИЙНИЗКИЙ
UnderfittingНИЗКИЙНИЗКИЙ
ИнтерпретируемостьВЫСОКАЯСРЕДНЯЯ-НИЗКАЯ
Computational CostНизкийВыше (много деревьев)
ТочностьМожет быть худшейОбычно лучше
ПараллелизмНе требуетсяЛегко параллелизируется

Bias-Variance Decomposition

Decision Tree:
- Bias: НИЗКИЙ (дерево может выучить любую функцию)
- Variance: ВЫСОКАЯ (чувствительно к шумам в данных)
- Общая ошибка: ВЫСОКАЯ из-за variance

Random Forest:
- Bias: НИЗКИЙ (каждое дерево низкого bias)
- Variance: ОЧЕНЬ НИЗКАЯ (усреднение независимых моделей)
- Общая ошибка: НИЗКАЯ благодаря variance reduction

Пример: данные с шумом

import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor

# Генерируем данные
X = np.linspace(0, 10, 100).reshape(-1, 1)
y = np.sin(X.squeeze()) + np.random.randn(100) * 0.3  # sin с шумом

X_test = np.linspace(0, 10, 300).reshape(-1, 1)
y_test = np.sin(X_test.squeeze())

# Decision Tree
dt = DecisionTreeRegressor(max_depth=15)
dt.fit(X, y)
y_pred_dt = dt.predict(X_test)

# Random Forest
rf = RandomForestRegressor(n_estimators=100, max_depth=15, random_state=42)
rf.fit(X, y)
y_pred_rf = rf.predict(X_test)

# Визуализация
plt.figure(figsize=(12, 6))
plt.plot(X_test, y_test, 'b-', label='True function', linewidth=2)
plt.scatter(X, y, alpha=0.3, label='Training data')
plt.plot(X_test, y_pred_dt, 'r-', label='Decision Tree', linewidth=2)
plt.plot(X_test, y_pred_rf, 'g-', label='Random Forest', linewidth=2)
plt.legend()
plt.title('Decision Tree vs Random Forest: шумные данные')
plt.show()

# Decision Tree переобучается и колеблется
# Random Forest дает более гладкую кривую ближе к истине

Как Random Forest решает проблемы Decision Tree

1. Переобучение

Problem: Одно дерево может глубоко переобучиться, запоминая шум.

Solution: RF использует множество независимых деревьев. Если одно дерево запомнило выброс, остальные 99 деревьев проголосуют иначе.

2. Нестабильность

Problem: Небольшое изменение в данных может полностью изменить структуру дерева.

Solution: Bootstrap sampling + множество деревьев обеспечивают стабильность.

3. Высокая variance

Problem: Decision Tree имеет высокую variance из-за чувствительности к данным.

Solution: Усреднение независимых моделей математически снижает variance:

Var(среднее(Y1, Y2, ..., Yn)) = Var(Y) / n (если независимы)

Практический пример: выбор между ними

from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score

# Пример 1: Маленький датасет
X_small, y_small = X[:50], y[:50]
dt_small = DecisionTreeClassifier(max_depth=3)
rf_small = RandomForestClassifier(n_estimators=50, max_depth=3)

dt_score_small = cross_val_score(dt_small, X_small, y_small, cv=5).mean()
rf_score_small = cross_val_score(rf_small, X_small, y_small, cv=5).mean()

print(f"Small dataset: DT={dt_score_small:.3f}, RF={rf_score_small:.3f}")
# RF часто лучше даже на маленьких данных

# Пример 2: Большой датасет
dt_large = DecisionTreeClassifier(max_depth=15)
rf_large = RandomForestClassifier(n_estimators=100, max_depth=15)

dt_score_large = cross_val_score(dt_large, X, y, cv=5).mean()
rf_score_large = cross_val_score(rf_large, X, y, cv=5).mean()

print(f"Large dataset: DT={dt_score_large:.3f}, RF={rf_score_large:.3f}")
# RF обычно значительно лучше

Важность признаков

# Decision Tree: используется информация об одном пути
importances_dt = dt.feature_importances_

# Random Forest: усредняется важность по всем деревьям
importances_rf = rf.feature_importances_

plt.bar(range(X.shape[1]), importances_rf)
plt.xlabel('Feature')
plt.ylabel('Importance')
plt.title('Feature Importance (Random Forest)')
plt.show()

Когда использовать каждый

Decision Tree:

  • Когда нужна максимальная интерпретируемость
  • Когда данные очень маленькие
  • Когда нужна быстрая модель на предсказание
  • Как base learner для бустинга

Random Forest:

  • В большинстве практических случаев
  • Когда важна точность
  • Когда есть много признаков
  • Когда данные содержат выбросы и шум
  • Как baseline для сравнения других моделей

Заключение

Random Forest — это эволюция Decision Tree, которая решает его основные проблемы через ансамблирование. Хотя Random Forest менее интерпретируем, он обычно дает лучшие результаты и более робастен к переобучению. Это делает его одним из самых популярных и практичных алгоритмов в машинном обучении.