【问题标题】:LabelEncoder vs. onehot encoding in random forest regressor随机森林回归器中的 LabelEncoder 与 onehot 编码
【发布时间】:2021-04-21 06:17:43
【问题描述】:

我正在尝试使用 python 来使用 RandomForestRegressor。我知道对于数字列,不需要缩放,因为只有一列会导致大多数信息增益用于拆分数据。然而,我们似乎仍然需要将分类值转换为数字,以便我们的机器能够理解。

我想在 labelEncoder 和 onehot 编码之间进行比较,并想了解为什么首选其中一个。

我正在使用来自Beijing Multi-Site Air-Quality Data Data Set | Machine Learning Repository, Center for Machine Learning and IntelligentSystems 的数据集并尝试预测 PM2.5 值

我的数据框看起来像这样

        year  month day    hour   PM2.5    PM10  SO2 NO2      CO      O3    TEMP    PRES    DEWP    RAIN    wd  WSPM    station
0       2013    3   1         0     4.0     4.0 4.0  7.0    300.0   77.0    -0.7    1023.0  -18.8   0.0     NNW 4.4    Aotizhongxin
1       2013    3   1         1     8.0     8.0 4.0  7.0    300.0   77.0    -1.1    1023.2  -18.2   0.0     N   4.7    Aotizhongxin
2       2013    3   1         2     7.0     7.0 5.0  10.0   300.0   73.0    -1.1    1023.5  -18.2   0.0     NNW 5.6    Aotizhongxin
3       2013    3   1         3     6.0     6.0 11.0 11.0   300.0   72.0    -1.4    1024.5  -19.4   0.0     NW  3.1    Aotizhongxin
4       2013    3   1         4     3.0     3.0 12.0 12.0   300.0   72.0    -2.0    1025.2  -19.5   0.0     N   2.0     Aotizhongxin

首先我使用 one-hot 编码

ohe_df = pd.get_dummies(data=df, columns=["wd", "station"])

y = ohe_df["PM2.5"].values
X = ohe_df.drop(columns=["PM2.5"]).values

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

rf_reg = RandomForestRegressor(n_estimators=100,
                               criterion="mse",
                               n_jobs=-1,
                               random_state=42)

rf_reg.fit(X_train, y_train)

train_pred_y = rf_reg.predict(X_train)
test_pred_y = rf_reg.predict(X_test)

print(f"train_MAE = {mean_absolute_error(y_train, train_pred_y)}")
print(f"test_MAE = {mean_absolute_error(y_test, test_pred_y)}")

>>>train_MAE = 3.7268903322031877
>>>test_MAE = 10.108332295400825

然后在使用标签编码器后使用相同的 rf_reg 进行训练和预测

le = LabelEncoder()

le_df = df.copy()
le_df["wd"] = le.fit_transform(df["wd"])
le_df["station"] = le.fit_transform(df["station"])

y = le_df["PM2.5"].values
X = le_df.drop(columns=["PM2.5"]).values

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

rf_reg.fit(X_train, y_train)
train_pred_y = rf_reg.predict(X_train)
test_pred_y = rf_reg.predict(X_test)
print(f"train_MAE = {mean_absolute_error(y_train, train_pred_y)}")
print(f"test_MAE = {mean_absolute_error(y_test, test_pred_y)}")

>>>train_MAE = 3.765413599883373
>>>test_MAE = 10.189870188659498

从这个比较来看,one-hot 编码似乎表现更好,但我的问题是,比较不同的编码方法是否正确?如果是,为什么 labelEncoding 的性能比一种热编码更差(即使是一点点)?

【问题讨论】:

    标签: python machine-learning scikit-learn random-forest categorical-data


    【解决方案1】:

    LabelEncoderOneHotEncoder 这两个函数有不同的目标,不能互换。

    来自OneHotEncoder docs(强调我的):

    将分类特征编码为一次性数值数组。

    来自LabelEncoder docs(强调我的):

    使用 0 到 n_classes-1 之间的值编码 目标标签

    这个转换器应该用于编码目标值y不是输入X

    因此,此处对功能进行编码的正确方法是使用OneHotEncoder。使用LabelEncoder 将另外在分类特征之间施加一个顺序,因为0 小于1 等,这对于分类特征正确(这是对于分类问题中的标签来说不是问题,LabelEncoder 就是这样)。

    如果您的功能是有序的(wdstation 似乎不是这种情况),您应该考虑使用 OrdinalEncoder 而不是 one-hot

    【讨论】:

    • 那么对于 X 变量中的分类值,唯一的方法是 OneHotEncoding?
    • @Ambleu 不,在适当的时候还有OrdinalEncoder。检查提供的文档链接(这些链接又提供了用户指南相应部分的链接),它们是您最好的朋友。
    • 谢谢。那么说我将 LabelEncoder 与 Ordinal Encoder 一起使用,我比较两种(Ordinal 与一种热门)可接受的做法的方式是什么?
    • @Ambleu 不清楚您所说的“可接受的做法”是什么意思;这一切都取决于具体的案例数据:据我所知,您的 wdstation 功能不是序数,因此在这里使用 OrdinalEncoder 是不正确的(并且会使任何比较实际上无效),您应该坚持默认为 OHE。
    • 为什么使用 LabelEncoder(Ordinal 编码器的工作)输出相似的性能?
    猜你喜欢
    • 1970-01-01
    • 2019-12-06
    • 2023-03-14
    • 1970-01-01
    • 2019-10-23
    • 2018-06-24
    • 2016-04-24
    • 2018-06-17
    • 2019-08-08
    相关资源
    最近更新 更多