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

Как Decision Tree в Random Forest дают один голос?

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

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

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

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

Механизм голосования деревьев в Random Forest

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

Базовая архитектура Random Forest

Random Forest состоит из множества независимых Decision Trees, каждое из которых обучено на случайной выборке исходных данных (bootstrap sample) и использует случайное подмножество признаков при каждом расщеплении узла.

Механизм голосования для классификации

Для задач классификации используется majority voting (голосование большинством):

from sklearn.ensemble import RandomForestClassifier
import numpy as np

# Создаём Random Forest с 100 деревьями
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)

# Для одного образца:
# Дерево 1: предсказывает класс 0
# Дерево 2: предсказывает класс 1
# Дерево 3: предсказывает класс 0
# ...
# Дерево 100: предсказывает класс 0

# Итоговое предсказание: класс 0 (так как 65 деревьев проголосовали за него)
y_pred = rf.predict(X_test)  # Класс с большинством голосов

Как именно работает голосование

Шаг 1: Получение предсказаний от каждого дерева

Для каждого образца X каждое дерево в Random Forest выполняет прямой проход и выдаёт предсказание. В классификации это класс, который дерево считает правильным ответом.

# Внутри Random Forest
predictions = []
for tree in rf.estimators_:  # Каждое дерево в лесу
    prediction = tree.predict(X)[0]  # Предсказание одного дерева
    predictions.append(prediction)

# predictions = [0, 1, 0, 0, 1, 0, 1, 0, 0, 0, ...]
# (для 100 деревьев)

Шаг 2: Подсчёт голосов

# Подсчитываем, сколько деревьев проголосовало за каждый класс
from collections import Counter
vote_counts = Counter(predictions)
# Counter({0: 65, 1: 35})

# Выбираем класс с большинством голосов
final_prediction = vote_counts.most_common(1)[0][0]  # 0

Шаг 3: Выборочное возвращение вероятностей

Для получения вероятностей (confidence), Random Forest использует долю голосов:

probabilities = {
    'class_0': 65 / 100,  # 65%
    'class_1': 35 / 100   # 35%
}

y_pred_proba = rf.predict_proba(X_test)
# [[0.65, 0.35], [0.72, 0.28], ...]

Механизм голосования для регрессии

Для задач регрессии используется усреднение (averaging) вместо голосования:

from sklearn.ensemble import RandomForestRegressor

rf_reg = RandomForestRegressor(n_estimators=100)
rf_reg.fit(X_train, y_train)

# Для одного образца:
# Дерево 1: предсказывает 45.2
# Дерево 2: предсказывает 47.1
# Дерево 3: предсказывает 44.8
# ...
# Дерево 100: предсказывает 46.5

# Итоговое предсказание: среднее значение
final_prediction = np.mean([45.2, 47.1, 44.8, ..., 46.5])  # 45.92

Практическая реализация

import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification

# Создаём данные
X, y = make_classification(n_samples=100, n_features=10, n_informative=5, 
                           n_classes=3, random_state=42)

# Обучаем Random Forest
rf = RandomForestClassifier(n_estimators=5, random_state=42)  # 5 деревьев для примера
rf.fit(X, y)

# Получаем голоса от каждого дерева
X_test = X[:1]  # Один образец
individual_predictions = [tree.predict(X_test)[0] for tree in rf.estimators_]
print(f"Голоса деревьев: {individual_predictions}")
# Голоса деревьев: [0, 1, 1, 0, 0]

# Финальное предсказание Random Forest
final_pred = rf.predict(X_test)[0]
print(f"Финальное предсказание: {final_pred}")  # 0 (3 голоса против 2)

# Вероятности
proba = rf.predict_proba(X_test)[0]
print(f"Вероятности: {proba}")
# Вероятности: [0.6  0.4  0.0]  (для 3 классов)

Почему голосование работает лучше

Мудрость толпы (Wisdom of Crowds): Если индивидуальные деревья допускают независимые ошибки, голосование большинством уменьшает влияние этих ошибок.

Ошибка 1 дерева: ~30%
Ошибка 10 деревьев (голосование): ~15%
Ошибка 100 деревьев (голосование): ~5%

Разнообразие: Random Forest обеспечивает разнообразие через:

  • Bootstrap sampling (разные подмножества данных)
  • Random feature selection (случайный выбор признаков)
  • Random splits (случайность в выборе расщеплений)

Это разнообразие критично для эффективности голосования.

Взвешенное голосование

В некоторых случаях деревья могут иметь разные веса на основе их производительности. Scikit-learn использует единые веса по умолчанию, но можно настроить:

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

# Внутри каждое дерево имеет вес 1.0 (одинаковый)
# Но можно использовать другие подходы для взвешивания

Когда голосование работает хорошо

  1. Деревья независимы — обучены на разных данных и признаках
  2. Деревья лучше случайной гадки — каждое дерево должно быть лучше, чем 50% для бинарной классификации
  3. Ошибки некоррелированы — деревья ошибаются в разных местах

Влияние количества деревьев

for n_trees in [1, 5, 10, 50, 100]:
    rf = RandomForestClassifier(n_estimators=n_trees)
    rf.fit(X_train, y_train)
    accuracy = rf.score(X_test, y_test)
    print(f"{n_trees} деревьев: {accuracy:.4f} точность")

# 1 деревьев: 0.8200 точность
# 5 деревьев: 0.8950 точность
# 10 деревьев: 0.9100 точность
# 50 деревьев: 0.9200 точность
# 100 деревьев: 0.9220 точность (улучшение замедляется)

Итоговое объяснение

Каждое дерево в Random Forest выполняет свой прямой проход и выдаёт предсказание. Затем Random Forest агрегирует эти предсказания через голосование (для классификации) или усреднение (для регрессии). Это позволяет снизить влияние переобучения отдельного дерева и повысить обобщающую способность модели. Сила Random Forest в том, что это простой, но очень эффективный способ объединения множества слабых учеников в один сильный предсказатель.