使用树集成进行特征转换

Beginner

This tutorial is from open-source community. Access the source code

简介

在本实验中,我们将学习如何使用树集成将特征转换到更高维的稀疏空间。然后,我们将在这些特征上训练一个线性模型。我们将使用不同类型的集成方法,包括随机森林(Random Forest)和梯度提升(Gradient Boosting),并比较它们的性能。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”(Notebook)标签页,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。

数据准备

首先,我们将创建一个包含 80,000 个样本的大型数据集,并将其分为三组:

  • 一组用于训练集成方法,这些方法稍后将用作特征工程变换器
  • 一组用于训练线性模型
  • 一组用于测试线性模型。
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 层。

from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier

n_estimators = 10
max_depth = 3

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)

训练嵌入变换器

“随机树嵌入”(RandomTreesEmbedding)是一种无监督方法,不需要单独训练。

from sklearn.ensemble import RandomTreesEmbedding

random_tree_embedding = RandomTreesEmbedding(
    n_estimators=n_estimators, max_depth=max_depth, random_state=0
)

rt_model = make_pipeline(random_tree_embedding, LogisticRegression(max_iter=1000))
rt_model.fit(X_train_linear, y_train_linear)

使用随机森林和梯度提升进行特征转换

现在,我们将创建两个管道,它们将使用上述嵌入作为预处理阶段。特征转换将通过调用apply方法来实现。然后,我们将随机森林或梯度提升与逻辑回归进行管道连接。然而,scikit-learn 中的管道期望调用transform。因此,我们将对apply的调用包装在一个FunctionTransformer中。

from sklearn.preprocessing import FunctionTransformer
from sklearn.preprocessing import 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)

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)

评估模型

我们最终可以展示所有模型的不同 ROC 曲线。

import matplotlib.pyplot as plt
from sklearn.metrics import RocCurveDisplay

fig, 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")

总结

在本实验中,我们学习了如何使用树集成将特征转换到更高维的稀疏空间。我们使用了不同类型的集成方法,包括随机森林和梯度提升,并比较了它们的性能。“随机树嵌入”(RandomTreesEmbedding)是一种无监督方法,不需要单独训练。我们还学习了如何使用FunctionTransformer将随机森林或梯度提升与逻辑回归进行管道连接。最后,我们使用 ROC 曲线评估了所有模型的性能。