【发布时间】:2020-08-27 13:01:22
【问题描述】:
假设我有两个数据集,一个用于训练,一个用于预测。
在两个数据集中,我有相同的分类变量,我希望使用 sklearn 的 preprocessing.OneHotEncoder() 进行一次热编码。
接下来,让我们看看变量 X 可能的唯一值:['a', 'b', 'c', 'd', 'e']
因此,变量 X 存在于训练和测试数据集中。但是,只有值'a' 和'b' 出现在训练集中,而只有'c'、'd' 和'e' 出现在测试集中。
所以,如果我将以下代码应用于这两个数据集:
enc1 = pre.OneHotEncoder()
to_encode = train_df.select_dtypes(include='object')
encoded = enc1.fit_transform(to_encode).toarray()
dum_df = pd.DataFrame(encoded, columns=enc1.get_feature_names(to_encode.columns))
train_df = train_df.join(dum_df)
train_df.drop(to_encode.columns, axis=1, inplace=True)
# And repeat, just replace train_df with test_df
我得到两个单热编码数据帧。但是,它们的维度会有所不同,因为训练集中的一些值没有出现在测试集中(反之亦然)。
假设我已经在训练集上训练了一个算法:
- 当我将测试集中的数据输入机器学习算法时会发生什么,该算法在训练集上进行了训练 不同的维度?
-
算法是否会关心某些数据列是否丢失?具体来说,我使用的是
XGBoost.XGBRegressor(),但我也有兴趣知道是否有一个通用的答案。
【问题讨论】:
-
1.你不/不能。无论您用于训练的任何功能都需要用于测试。如果您的特征是 [a, b, c] 但您的测试数据只有 [d,e] 那么它不会为 d 和 e 获得 2 列,因为 [a, b, c] 它会获得全 0 的 3 列是您的功能,而您没有。您可以研究更复杂的数据拆分方法(分层随机拆分),以确保在必要时代表所有类别。
-
@ALollz 我在数据拆分方面受到限制,因为“测试”数据来自 kaggle 比赛并且是预先拆分的。他们对某些类别的测试数据没有全部可能的唯一值。我刚刚读到,如果我使用适合训练集的相同编码器,如果它没有这些值,它将插入所有 0 的列用于测试集编码。这似乎是一个合理的选择。你怎么看?
-
你不应该将 enc1.fit_transform() 应用于测试集,它应该只是 enc1.transform() 因为如果你再次适应,你正在从测试集中学习。然后,在 OneHotEncoder 中,您可以使用选项 handle_unknown="ignore" 来避免出现以前未见过的新类别时出现的错误。算法不管理缺失值,因为您必须先估算:scikit-learn.org/stable/modules/impute.html
-
@jjsantoso 但是,我将丢失那些未知类别的数据。也许最好的办法是加入测试和训练数据,以便对所有可能的类别进行编码。然后,我可以稍后将它们拆分出来进行训练和预测。
-
@rocksNwaves 可能是这样,但你永远不知道全新的看不见的数据会带来什么,你需要能够处理所有这些情况。您可以使用已知类别创建字典,以未知类别缺失值的方式映射到新列。然后使用插补来填补缺失的新类别。您将以一个收集所有未知类别的新类别结束。并不完美,但您不会丢失所有信息。
标签: python pandas scikit-learn xgboost one-hot-encoding