简介
在本实验中,我们将学习如何使用树集成将特征转换到更高维的稀疏空间。然后,我们将在这些特征上训练一个线性模型。我们将使用不同类型的集成方法,包括随机森林(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 曲线评估了所有模型的性能。