1. Для формирования бутстреп-выборок используется случайный выбор с возвращением.

import numpy as np

 

data = np.array([5, 10, 15, 20, 25, 30])

 

rng = np.random.default_rng(42)

 

for i in range(3):

    sample = rng.choice(

        data,

        size=len(data),

        replace=True

    )

 

    missing = np.setdiff1d(data, sample)

 

    print(f"Выборка {i + 1}:", sample)

    print("Не вошли:", missing)

Полученные выборки могут содержать повторяющиеся наблюдения. Часть исходных объектов может отсутствовать.

Бэггинг использует разные бутстреп-выборки для обучения нескольких моделей. После обучения их ответы агрегируются, что позволяет уменьшать вариативность нестабильных алгоритмов.

2. Для каждого объекта определим класс, получивший большинство голосов.

import numpy as np

 

predictions = np.array([

    [1, 0, 1],

    [1, 1, 0],

    [0, 0, 1],

    [1, 0, 1],

    [0, 1, 1]

])

 

final_predictions = []

 

for column in predictions.T:

    classes, counts = np.unique(

        column,

        return_counts=True

    )

 

    final_class = classes[np.argmax(counts)]

    final_predictions.append(final_class)

 

print("Итоговые классы:", final_predictions)

Результат:

Итоговые классы: [1, 0, 1].

Для первого объекта класс 1 получил три голоса.

Для второго объекта класс 0 получил три голоса.

Для третьего объекта класс 1 получил четыре голоса.

Агрегирование объединяет результаты нескольких деревьев. Разнообразие деревьев важно, поскольку усреднение сильно коррелированных моделей даёт меньший выигрыш.

3. Обучим случайный лес с разным количеством деревьев.

from sklearn.datasets import make_classification

from sklearn.model_selection import train_test_split

from sklearn.ensemble import RandomForestClassifier

from sklearn.metrics import accuracy_score

 

X, y = make_classification(

    n_samples=300,

    n_features=6,

    n_informative=4,

    n_redundant=0,

    random_state=42

)

 

X_train, X_test, y_train, y_test = train_test_split(

    X, y,

    test_size=0.2,

    stratify=y,

    random_state=42

)

 

for n_trees in [50, 100]:

    model = RandomForestClassifier(

        n_estimators=n_trees,

        bootstrap=True,

        oob_score=True,

        random_state=42

    )

 

    model.fit(X_train, y_train)

 

    predictions = model.predict(X_test)

 

    print("Количество деревьев:", n_trees)

    print("OOB:", round(model.oob_score_, 3))

    print(

        "Test accuracy:",

        round(accuracy_score(y_test, predictions), 3)

    )

    print("Важность:", model.feature_importances_)

    print()

При увеличении количества деревьев результаты ансамбля могут изменяться. Это не гарантирует улучшения качества в каждом эксперименте.

OOB-оценка использует наблюдения, не попавшие в бутстреп-выборки отдельных деревьев. Она полезна для диагностики, но не заменяет независимый финальный тест, поскольку итоговую способность модели работать с новыми данными необходимо проверять отдельно.

При выборе количества деревьев и других гиперпараметров следует использовать валидацию. Тестовая выборка предназначена для итоговой оценки.