Примечание
Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.
Преобразования признаков с помощью ансамблей деревьев
Преобразуйте признаки в разреженное пространство большей размерности. Затем обучите линейную модель на этих признаках.
Сначала обучите ансамбль деревьев (полностью случайные деревья, случайный лес или деревья с градиентным бустингом) на обучающей выборке. Затем каждому листу каждого дерева ансамбля присваивается фиксированный произвольный индекс признака в новом пространстве признаков. После этого индексы листьев кодируются в формате one-hot.
Каждый образец проходит через узлы каждого дерева ансамбля и оказывается в одном листе каждого дерева. Образец кодируется присвоением значения 1 признакам, соответствующим этим листьям, и значения 0 — остальным признакам.
Полученный преобразователь обучается создавать для данных разреженное категориальное вложение высокой размерности с учётом целевых значений.
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause
Сначала создадим большой набор данных и разделим его на три выборки:
- выборку для обучения ансамблевых методов, которые затем будут использоваться как преобразователь для создания признаков;
- выборку для обучения линейной модели;
- выборку для тестирования линейной модели.
Важно разделить данные таким образом, чтобы избежать переобучения из-за утечки данных.
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
X, y = make_classification(n_samples=80_000, random_state=10)
X_full_train, X_test, y_full_train, y_test = train_test_split(
X, y, test_size=0.5, random_state=10
)
X_train_ensemble, X_train_linear, y_train_ensemble, y_train_linear = train_test_split(
X_full_train, y_full_train, test_size=0.5, random_state=10
)
Для каждого из ансамблевых методов будем использовать 10 оценщиков и максимальную глубину 3 уровня.
n_estimators = 10 max_depth = 3
Сначала обучим случайный лес и градиентный бустинг на отдельной обучающей выборке.
from sklearn.ensemble import GradientBoostingClassifier, RandomForestClassifier
random_forest = RandomForestClassifier(
n_estimators=n_estimators, max_depth=max_depth, random_state=10
)
random_forest.fit(X_train_ensemble, y_train_ensemble)
gradient_boosting = GradientBoostingClassifier(
n_estimators=n_estimators, max_depth=max_depth, random_state=10
)
_ = gradient_boosting.fit(X_train_ensemble, y_train_ensemble)
Обратите внимание, что HistGradientBoostingClassifier работает гораздо быстрее, чем GradientBoostingClassifier, начиная с наборов данных среднего размера (n_samples >= 10_000), чего нельзя сказать о данном примере.
RandomTreesEmbedding — это метод без учителя, поэтому его не нужно обучать отдельно.
from sklearn.ensemble import RandomTreesEmbedding
random_tree_embedding = RandomTreesEmbedding(
n_estimators=n_estimators, max_depth=max_depth, random_state=0
)
Теперь создадим три конвейера, которые будут использовать приведённое выше вложение на этапе предварительной обработки.
Вложение случайных деревьев можно напрямую объединить в конвейер с логистической регрессией, поскольку это стандартный преобразователь scikit-learn.
from sklearn.linear_model import LogisticRegression from sklearn.pipeline import make_pipeline rt_model = make_pipeline(random_tree_embedding, LogisticRegression(max_iter=1000)) rt_model.fit(X_train_linear, y_train_linear)
Pipeline(steps=[('randomtreesembedding',
RandomTreesEmbedding(max_depth=3, n_estimators=10,
random_state=0)),
('logisticregression', LogisticRegression(max_iter=1000))])
В среде Jupyter повторно запустите эту ячейку, чтобы отобразить HTML-представление, или доверьте этому ноутбуку. На GitHub HTML-представление не отображается; попробуйте открыть эту страницу на nbviewer.org.
Параметры
Обученные атрибуты
Параметры
Обученные атрибуты
75 признаков
| randomtreesembedding_0_3 |
| randomtreesembedding_0_4 |
| randomtreesembedding_0_6 |
| randomtreesembedding_0_7 |
| randomtreesembedding_0_10 |
| randomtreesembedding_0_11 |
| randomtreesembedding_0_13 |
| randomtreesembedding_0_14 |
| randomtreesembedding_1_3 |
| randomtreesembedding_1_4 |
| randomtreesembedding_1_6 |
| randomtreesembedding_1_7 |
| randomtreesembedding_1_10 |
| randomtreesembedding_1_11 |
| randomtreesembedding_1_13 |
| randomtreesembedding_1_14 |
| randomtreesembedding_2_3 |
| randomtreesembedding_2_4 |
| randomtreesembedding_2_6 |
| randomtreesembedding_2_7 |
| randomtreesembedding_2_10 |
| randomtreesembedding_2_11 |
| randomtreesembedding_2_13 |
| randomtreesembedding_2_14 |
| randomtreesembedding_3_3 |
| randomtreesembedding_3_4 |
| randomtreesembedding_3_6 |
| randomtreesembedding_3_7 |
| randomtreesembedding_3_10 |
| randomtreesembedding_3_11 |
| randomtreesembedding_3_13 |
| randomtreesembedding_3_14 |
| randomtreesembedding_4_3 |
| randomtreesembedding_4_4 |
| randomtreesembedding_4_6 |
| randomtreesembedding_4_7 |
| randomtreesembedding_4_10 |
| randomtreesembedding_4_11 |
| randomtreesembedding_4_13 |
| randomtreesembedding_4_14 |
| randomtreesembedding_5_3 |
| randomtreesembedding_5_4 |
| randomtreesembedding_5_6 |
| randomtreesembedding_5_7 |
| randomtreesembedding_5_10 |
| randomtreesembedding_5_11 |
| randomtreesembedding_5_12 |
| randomtreesembedding_6_3 |
| randomtreesembedding_6_4 |
| randomtreesembedding_6_6 |
| randomtreesembedding_6_7 |
| randomtreesembedding_6_9 |
| randomtreesembedding_6_11 |
| randomtreesembedding_6_12 |
| randomtreesembedding_7_3 |
| randomtreesembedding_7_4 |
| randomtreesembedding_7_6 |
| randomtreesembedding_7_7 |
| randomtreesembedding_7_10 |
| randomtreesembedding_7_11 |
| randomtreesembedding_7_13 |
| randomtreesembedding_7_14 |
| randomtreesembedding_8_1 |
| randomtreesembedding_8_4 |
| randomtreesembedding_8_5 |
| randomtreesembedding_8_7 |
| randomtreesembedding_8_8 |
| randomtreesembedding_9_3 |
| randomtreesembedding_9_4 |
| randomtreesembedding_9_6 |
| randomtreesembedding_9_7 |
| randomtreesembedding_9_10 |
| randomtreesembedding_9_11 |
| randomtreesembedding_9_13 |
| randomtreesembedding_9_14 |
Параметры
Атрибуты обученной модели
Затем можно объединить случайный лес или градиентный бустинг с логистической регрессией в конвейер. Однако преобразование признаков будет выполняться вызовом метода apply. Конвейер в scikit-learn предполагает вызов transform. Поэтому мы обернули вызов apply в FunctionTransformer.
from sklearn.preprocessing import FunctionTransformer, OneHotEncoder
def rf_apply(X, model):
return model.apply(X)
rf_leaves_yielder = FunctionTransformer(rf_apply, kw_args={"model": random_forest})
rf_model = make_pipeline(
rf_leaves_yielder,
OneHotEncoder(handle_unknown="ignore"),
LogisticRegression(max_iter=1000),
)
rf_model.fit(X_train_linear, y_train_linear)
Pipeline(steps=[('functiontransformer',
FunctionTransformer(func=<function rf_apply at 0x78414c6c97a0>,
kw_args={'model': RandomForestClassifier(max_depth=3,
n_estimators=10,
random_state=10)})),
('onehotencoder', OneHotEncoder(handle_unknown='ignore')),
('logisticregression', LogisticRegression(max_iter=1000))])
В среде Jupyter повторно выполните эту ячейку, чтобы отобразить HTML-представление, или доверьте блокноту. На GitHub HTML-представление отобразить не удаётся. Попробуйте открыть эту страницу с помощью nbviewer.org.
Параметры
Обученные атрибуты
Параметры
Обученные атрибуты
| Имя | Тип | Значение |
|---|---|---|
| n_features_in_ n_features_in_: int Количество признаков, обнаруженных во время :term:`fit`. .. добавлено в версии:: 0.24 | int | 20 |
Параметры
Обученные атрибуты
79 признаков
| x0_3 |
| x0_4 |
| x0_6 |
| x0_7 |
| x0_10 |
| x0_11 |
| x0_13 |
| x0_14 |
| x1_3 |
| x1_4 |
| x1_6 |
| x1_7 |
| x1_10 |
| x1_11 |
| x1_13 |
| x1_14 |
| x2_3 |
| x2_4 |
| x2_6 |
| x2_7 |
| x2_10 |
| x2_11 |
| x2_13 |
| x2_14 |
| x3_3 |
| x3_4 |
| x3_6 |
| x3_7 |
| x3_10 |
| x3_11 |
| x3_13 |
| x3_14 |
| x4_3 |
| x4_4 |
| x4_6 |
| x4_7 |
| x4_10 |
| x4_11 |
| x4_13 |
| x4_14 |
| x5_3 |
| x5_4 |
| x5_6 |
| x5_7 |
| x5_10 |
| x5_11 |
| x5_13 |
| x5_14 |
| x6_3 |
| x6_4 |
| x6_6 |
| x6_7 |
| x6_10 |
| x6_11 |
| x6_13 |
| x6_14 |
| x7_3 |
| x7_4 |
| x7_6 |
| x7_7 |
| x7_10 |
| x7_11 |
| x7_13 |
| x7_14 |
| x8_3 |
| x8_4 |
| x8_6 |
| x8_7 |
| x8_10 |
| x8_11 |
| x8_13 |
| x8_14 |
| x9_3 |
| x9_4 |
| x9_7 |
| x9_10 |
| x9_11 |
| x9_13 |
| x9_14 |
Параметры
Обученные атрибуты
def gbdt_apply(X, model):
return model.apply(X)[:, :, 0]
gbdt_leaves_yielder = FunctionTransformer(
gbdt_apply, kw_args={"model": gradient_boosting}
)
gbdt_model = make_pipeline(
gbdt_leaves_yielder,
OneHotEncoder(handle_unknown="ignore"),
LogisticRegression(max_iter=1000),
)
gbdt_model.fit(X_train_linear, y_train_linear)
Pipeline(steps=[('functiontransformer',
FunctionTransformer(func=<function gbdt_apply at 0x78414c6c9e80>,
kw_args={'model': GradientBoostingClassifier(n_estimators=10,
random_state=10)})),
('onehotencoder', OneHotEncoder(handle_unknown='ignore')),
('logisticregression', LogisticRegression(max_iter=1000))])
В среде Jupyter выполните эту ячейку повторно, чтобы отобразить HTML-представление, или доверьте выполнение блокноту. На GitHub HTML-представление не отображается; попробуйте открыть эту страницу с помощью nbviewer.org.
Параметры
Атрибуты обученной модели
Параметры
Атрибуты обученной модели
| Имя | Тип | Значение |
|---|---|---|
| n_features_in_ n_features_in_: int Количество признаков, обнаруженных во время :term:`fit`. .. добавлено в версии:: 0.24 | int | 20 |
Параметры
Атрибуты обученной модели
76 признаков
| x0_4.0 |
| x0_6.0 |
| x0_7.0 |
| x0_10.0 |
| x0_11.0 |
| x0_13.0 |
| x0_14.0 |
| x1_4.0 |
| x1_6.0 |
| x1_7.0 |
| x1_10.0 |
| x1_11.0 |
| x1_13.0 |
| x1_14.0 |
| x2_4.0 |
| x2_6.0 |
| x2_7.0 |
| x2_10.0 |
| x2_11.0 |
| x2_13.0 |
| x2_14.0 |
| x3_4.0 |
| x3_6.0 |
| x3_7.0 |
| x3_10.0 |
| x3_11.0 |
| x3_13.0 |
| x3_14.0 |
| x4_3.0 |
| x4_4.0 |
| x4_6.0 |
| x4_7.0 |
| x4_10.0 |
| x4_11.0 |
| x4_13.0 |
| x4_14.0 |
| x5_3.0 |
| x5_4.0 |
| x5_6.0 |
| x5_7.0 |
| x5_10.0 |
| x5_11.0 |
| x5_13.0 |
| x5_14.0 |
| x6_3.0 |
| x6_4.0 |
| x6_6.0 |
| x6_7.0 |
| x6_10.0 |
| x6_11.0 |
| x6_13.0 |
| x6_14.0 |
| x7_3.0 |
| x7_4.0 |
| x7_6.0 |
| x7_7.0 |
| x7_10.0 |
| x7_11.0 |
| x7_13.0 |
| x7_14.0 |
| x8_3.0 |
| x8_4.0 |
| x8_6.0 |
| x8_7.0 |
| x8_10.0 |
| x8_11.0 |
| x8_13.0 |
| x8_14.0 |
| x9_3.0 |
| x9_4.0 |
| x9_6.0 |
| x9_7.0 |
| x9_10.0 |
| x9_11.0 |
| x9_13.0 |
| x9_14.0 |
Параметры
Атрибуты обученной модели
Наконец, можно показать различные ROC-кривые для всех моделей.
import matplotlib.pyplot as plt
from sklearn.metrics import RocCurveDisplay
_, ax = plt.subplots()
models = [
("RT embedding -> LR", rt_model),
("RF", random_forest),
("RF embedding -> LR", rf_model),
("GBDT", gradient_boosting),
("GBDT embedding -> LR", gbdt_model),
]
model_displays = {}
for name, pipeline in models:
model_displays[name] = RocCurveDisplay.from_estimator(
pipeline, X_test, y_test, ax=ax, name=name
)
_ = ax.set_title("ROC curve")

_, ax = plt.subplots()
for name, pipeline in models:
model_displays[name].plot(ax=ax)
ax.set_xlim(0, 0.2)
ax.set_ylim(0.8, 1)
_ = ax.set_title("ROC curve (zoomed in at top left)")

Общее время выполнения скрипта: (0 минут 2.366 секунды)
Связанные примеры
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/ensemble/plot_feature_transformation.html