【问题标题】:Missing categorical data should be encoded with an all-zero one-hot vector缺失的分类数据应使用全零的 one-hot 向量进行编码
【发布时间】:2022-02-10 02:43:43
【问题描述】:

我正在处理一个带有非常稀疏标记数据的机器学习项目。有几个分类特征,导致特征之间大约有一百个不同的类别。

例如:

0    red
1    blue
2    <missing>

color_cat = pd.DataFrame(['red', 'blue', np.NAN])
color_enc = OneHotEncoder(sparse=True, handle_unknown='ignore')
color_one_hot = color_enc.fit_transform(color_cat)

在我通过 scikit 的OneHotEncoder 输入这些数据后,我希望丢失的数据被编码为00,因为文档指出handle_unknown='ignore' 导致编码器返回一个全零数组。用 [SimpleImputer][1] 替换其他值对我来说不是一个选项。

我的期望:

0    10
1    01
2    00

相反,OneHotEncoder 将缺失值视为另一个类别。

我得到了什么:

0    100
1    010
2    001

我看过相关问题:How to handle missing values (NaN) in categorical data when using scikit-learn OneHotEncoder? 但是解决方案对我不起作用。我明确要求一个零向量。

【问题讨论】:

  • 只需将 nan 替换为 'unknown' 然后 labelencoder fit_transform 您的数据框类别列或使用 pd.get_dummies
  • 另请参阅OneHotEncodercategory_encoders 包版本,它可以选择handle_missing='value' 来做你想做的事。 contrib.scikit-learn.org/category_encoders/onehot.html
  • 也是一个有趣的解决方案,但我不想只为一个功能安装另一个库。但注意未来!谢谢你,本。

标签: python pandas machine-learning scikit-learn data-science


【解决方案1】:

从未真正使用过稀疏矩阵,但一种方法是删除与您的 nan 值对应的列。从您的模型中获取categories_ 并创建一个布尔掩码,它不是nan(我使用pd.Series.notna,但可能是其他方式)并创建一个新的(或重新分配)稀疏矩阵。基本上添加到您的代码中:

# currently you have
color_one_hot
# <3x3 sparse matrix of type '<class 'numpy.float64'>'
#   with 3 stored elements in Compressed Sparse Row format>

# line of code to add
new_color_one_hot = color_one_hot[:,pd.Series(color_enc.categories_[0]).notna().to_numpy()]

# and now you have
new_color_one_hot
# <3x2 sparse matrix of type '<class 'numpy.float64'>'
#   with 2 stored elements in Compressed Sparse Row format>

# and
new_color_one_hot.todense()
# matrix([[0., 1.],
#         [1., 0.],
#         [0., 0.]])

编辑:get_dummies 也给出了类似的结果pd.get_dummies(color_cat[0], sparse=True)

编辑:在查看更多内容后,您可以在 OneHotEncoder 中指定参数 categories,所以如果您这样做:

color_cat = pd.DataFrame(['red', 'blue', np.nan])
color_enc = OneHotEncoder(categories=[color_cat[0].dropna().unique()],  ## here
                          sparse=True, handle_unknown='ignore')
color_one_hot = color_enc.fit_transform(color_cat)
color_one_hot.todense()
# matrix([[1., 0.],
#         [0., 1.],
#         [0., 0.]])

【讨论】:

  • 确实,对我来说,未知类别是那些在合适的时候不存在,而在转换过程中存在的。 categories 的手动规范允许定义在拟合期间要考虑的类别。
  • 感谢您的回答!我已经用整数对标签进行了编码,这带来了额外的麻烦,即需要为类别提供 sorted 数组。
猜你喜欢
  • 2017-11-06
  • 1970-01-01
  • 1970-01-01
  • 2021-02-23
  • 2019-08-13
  • 2021-10-21
  • 2017-06-21
  • 2020-06-23
  • 2014-07-31
相关资源
最近更新 更多