Kaggle知识点:类别变量处理与精度对比

a285c94af9abfc135746140f24d46e09.png

来源:Coggle数据科学
本文约1200字,建议阅读4分钟
本文将使用埃姆斯爱荷华州房屋数据集进行房价分析。

在这个例子中,我们将比较使用不同的编码策略来处理分类特征时,HistGradientBoostingRegressor 的训练时间和预测性能。具体来说,我们将评估以下几种方法:

  • 删除分类特征;

  • 使用 OneHotEncoder;

  • 使用 OrdinalEncoder,将分类特征视为有序、等距的量;

  • 使用 OrdinalEncoder,并依赖于 HistGradientBoostingRegressor 估计器的原生类别支持。

我们将使用埃姆斯爱荷华州房屋数据集进行工作,该数据集包含数值和分类特征,其中房屋销售价格是目标变量。

步骤1:加载数据集

 
 
from sklearn.datasets import fetch_openml


X, y = fetch_openml(data_id=42165, as_frame=True, return_X_y=True)


# Select only a subset of features of X to make the example faster to run
categorical_columns_subset = [
    "BldgType",
    "GarageFinish",
    "LotConfig",
    "Functional",
    "MasVnrType",
    "HouseStyle",
    "FireplaceQu",
    "ExterCond",
    "ExterQual",
    "PoolQC",
]


numerical_columns_subset = [
    "3SsnPorch",
    "Fireplaces",
    "BsmtHalfBath",
    "HalfBath",
    "GarageCars",
    "TotRmsAbvGrd",
    "BsmtFinSF1",
    "BsmtFinSF2",
    "GrLivArea",
    "ScreenPorch",
]


X = X[categorical_columns_subset + numerical_columns_subset]
X[categorical_columns_subset] = X[categorical_columns_subset].astype("category")


categorical_columns = X.select_dtypes(include="category").columns
n_categorical_features = len(categorical_columns)
n_numerical_features = X.select_dtypes(include="number").shape[1]


print(f"Number of samples: {X.shape[0]}")
print(f"Number of features: {X.shape[1]}")
print(f"Number of categorical features: {n_categorical_features}")
print(f"Number of numerical features: {n_numerical_features}")

步骤2:基准模型(删除类别变量)

 
 
from sklearn.compose import make_column_selector, make_column_transformer
from sklearn.ensemble import HistGradientBoostingRegressor
from sklearn.pipeline import make_pipeline


dropper = make_column_transformer(
    ("drop", make_column_selector(dtype_include="category")), remainder="passthrough"
)
hist_dropped = make_pipeline(dropper, HistGradientBoostingRegressor(random_state=42))

步骤3:OneHot类别变量

from sklearn.preprocessing import OneHotEncoder


one_hot_encoder = make_column_transformer(
    (
        OneHotEncoder(sparse_output=False, handle_unknown="ignore"),
        make_column_selector(dtype_include="category"),
    ),
    remainder="passthrough",
)


hist_one_hot = make_pipeline(
    one_hot_encoder, HistGradientBoostingRegressor(random_state=42)
)

步骤4:Ordinal类别变量

 
 
import numpy as np


from sklearn.preprocessing import OrdinalEncoder


ordinal_encoder = make_column_transformer(
    (
        OrdinalEncoder(handle_unknown="use_encoded_value", unknown_value=np.nan),
        make_column_selector(dtype_include="category"),
    ),
    remainder="passthrough",
    # Use short feature names to make it easier to specify the categorical
    # variables in the HistGradientBoostingRegressor in the next step
    # of the pipeline.
    verbose_feature_names_out=False,
)


hist_ordinal = make_pipeline(
    ordinal_encoder, HistGradientBoostingRegressor(random_state=42)
)

步骤5:原生类别支持

 
 
hist_native = HistGradientBoostingRegressor(
    random_state=42, categorical_features="from_dtype"
)

步骤6:对比模型速度和精度

 
 
from sklearn.model_selection import cross_validate


scoring = "neg_mean_absolute_percentage_error"
n_cv_folds = 3


dropped_result = cross_validate(hist_dropped, X, y, cv=n_cv_folds, scoring=scoring)
one_hot_result = cross_validate(hist_one_hot, X, y, cv=n_cv_folds, scoring=scoring)
ordinal_result = cross_validate(hist_ordinal, X, y, cv=n_cv_folds, scoring=scoring)
native_result = cross_validate(hist_native, X, y, cv=n_cv_folds, scoring=scoring)

我们可以观察到,使用独热编码的模型明显最慢。这是可以预期的,因为独热编码为每个类别值(对于每个分类特征)创建了一个额外的特征,因此在拟合过程中需要考虑更多的分裂点。

理论上,我们预期原生处理分类特征的速度会略慢于将类别视为有序量('Ordinal'),因为原生处理需要对类别进行排序。

d860ae986329341029ba8244377b510d.png

通常情况下,可以预期使用独热编码的数据会导致更差的预测结果,特别是当树的深度或节点数量受限时:使用独热编码的数据,需要更多的分裂点,即更深的树,才能恢复相当于原生处理中的一个单一分裂点所能获得的等效分裂。

a7b49b038eec733e679f8db188bf9b84.png

当类别被视为有序量时,这一点同样适用:如果类别为A..F,最佳分裂是ACF - BDE,则独热编码模型将需要3个分裂点(左节点中的每个类别一个),而非原生模型将需要4个分裂:1个分裂来隔离A,1个分裂来隔离F,以及2个分裂来从BCDE中隔离C。

代码链接:https://scikit-learn.org/stable/auto_examples/ensemble/plot_gradient_boosting_categorical.html

编辑:黄继彦

c6ce40f17d1c9c500d5b862fecb9a1ce.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值