Вопрос или проблема
В случайном лесу Scikit-learn вы можете установить bootstrap=True, и каждое дерево выберет подмножество образцов для обучения. Есть ли способ увидеть, какие образцы используются в каждом дереве?
Я ознакомился с документацией о деревьях-оценках и всех атрибутах деревьев, которые предоставляет Scikit-learn, но ни один из них, похоже, не предоставляет искомую информацию.
Я не думаю, что это возможно получить напрямую, но мы можем использовать случайное значение.
random_stateint, экземпляр RandomState или None, по умолчанию=None
Контролирует как случайность бутстрэппинга образцов, используемых при построении деревьев (если bootstrap=True)
Это из кода RF на Github
def _generate_sample_indices(random_state, n_samples, n_samples_bootstrap):
"""
Приватная функция, используемая в функции _parallel_build_trees."""
random_instance = check_random_state(random_state)
sample_indices = random_instance.randint(0, n_samples, n_samples_bootstrap)
return sample_indices
Таким образом, мы можем получить эти данные с помощью пользовательского кода, если мы зафиксируем вышеуказанное значение, например, для 2 деревьев:
import pandas as pd, numpy as np
num = 20 # максимальный индекс
np.random.seed(0) # Фиксируем значение
sample_1 = np.random.randint(0,num,(1,num))
oob_1 = [elem for elem in np.arange(num) if elem not in sample_1 ]
sample_2 = np.random.randint(0,num,(1,num))
oob_2 = [elem for elem in np.arange(num) if elem not in sample_2 ]
Пожалуйста, проверьте это с помощью пользовательского кода. Я это не проверял.
На самом деле это возможно. Ответ не слишком отличается от данного @10xAI, но он не пытается использовать порядок случайных значений неявно, так как это нарушит работу при параллельном обучении. Поэтому приведенный выше ответ может работать только для деревьев, которые не обучаются параллельно. Но я не уверен.
Фактически работающий ответ прост, и он заключается в использовании генератора случайных чисел, сохраненного в каждом оценщике, и использовании его для повторного случайного выборки.
Таким образом, например, предположим, что rf
— это ваш обученный случайный лес, тогда легко получить как выбранные, так и неизбранные индексы, импортируя соответствующие функции и повторяя выборку с использованием значения в каждом rf.estimators[0].random_state
. Например, чтобы получить списки выбранных и неизбранных индексов:
import sklearn.ensemble._forest as forest_utils
n_samples = len(Y) # количество обучающих образцов
n_samples_bootstrap = forest_utils._get_n_samples_bootstrap(
n_samples, rf.max_samples
)
unsampled_indices_trees = []
sampled_indices_trees = []
for estimator in rf.estimators_:
unsampled_indices = forest_utils._generate_unsampled_indices(
estimator.random_state, n_samples, n_samples_bootstrap)
unsampled_indices_trees.append(unsampled_indices)
sampled_indices = forest_utils._generate_sample_indices(
estimator.random_state, n_samples, n_samples_bootstrap)
sampled_indices_trees.append(sampled_indices)
estimator
в данном случае является деревом решений, поэтому можно использовать все методы для вычисления пользовательских oob_scores
и тому подобного.
Надеюсь, это поможет!
Объект RandomForestRegressor имеет атрибут с образцами, использованными для каждого дерева.
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import load_iris
iris = load_iris()
X, y = iris.data, iris.target
rf = RandomForestRegressor()
rf.fit(X,y)
rf.estimators_samples_ # Это дает вам индексы строк, использованных в каждом дереве. (list[list[int]])
```
Ответ или решение
В библиотеке Scikit-learn, при использовании метода Random Forest, можно указать параметр bootstrap=True
, что позволяет каждому дереву выбирать подмножество образцов для обучения. Однако, если вы хотите увидеть, какие именно образцы использованы для тренировки каждого дерева, то это можно сделать несколькими способами.
Способ 1: Использование атрибута estimators_samples_
Scikit-learn предоставляет атрибут estimators_samples_
для объектов RandomForestRegressor и RandomForestClassifier. Этот атрибут содержит индексы образцов, которые были использованы для обучения каждого дерева. Вот пример, как это сделать:
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import load_iris
# Загружаем датасет
iris = load_iris()
X, y = iris.data, iris.target
# Создаем и обучаем модель Random Forest
rf = RandomForestRegressor()
rf.fit(X, y)
# Получаем индексы образцов для каждого дерева
samples_used = rf.estimators_samples_
# Выводим индексы для каждого дерева
for i, samples in enumerate(samples_used):
print(f"Дерево {i}: образцы {samples}")
Способ 2: Воспроизведение процедуры выборки с учетом генератора случайных чисел
Если вы не используете estimators_samples_
, и вам нужно вручную воспроизвести, какие образцы были выбраны для каждого дерева, вы можете воспользоваться генератором случайных чисел, который хранится в каждом дереве. Приведенный ниже код демонстрирует этот метод:
import numpy as np
import sklearn.ensemble._forest as forest_utils
# Общее количество образцов
n_samples = len(y)
# Список для хранения выбранных и невыбранных индексов
unsampled_indices_trees = []
sampled_indices_trees = []
# Итерация по каждому дереву в модели
for estimator in rf.estimators_:
# Получаем количество образцов для бутстрепинга
n_samples_bootstrap = forest_utils._get_n_samples_bootstrap(
n_samples, None
)
# Генерируем невыбранные индексы
unsampled_indices = forest_utils._generate_unsampled_indices(
estimator.random_state, n_samples, n_samples_bootstrap)
unsampled_indices_trees.append(unsampled_indices)
# Генерируем выбранные индексы
sampled_indices = forest_utils._generate_sample_indices(
estimator.random_state, n_samples, n_samples_bootstrap)
sampled_indices_trees.append(sampled_indices)
# Выводим индексы
for i, (sampled, unsampled) in enumerate(zip(sampled_indices_trees, unsampled_indices_trees)):
print(f"Дерево {i}: выбранные образцы {sampled}, невыбранные образцы {unsampled}")
Заключение
Оба метода позволяют вам получить доступ к информации о том, какие образцы использовались для обучения каждого дерева в вашем Random Forest. Вы можете использовать атрибут estimators_samples_
для быстрого доступа, или же повторять выборку с использованием генератора случайных чисел, чтобы лучше понять процесс бутстрепинга.
Таким образом, в зависимости от ваших требований к анализу, вы можете выбрать любой из подходов для получения интересующей информации.