使用 scikit-learn OneHotEncoder 时如何处理分类数据中的缺失值 (NaN)?

sum*_*s22 6 python machine-learning scikit-learn

我最近开始学习 Python,以使用机器学习方法为研究项目开发预测模型。我有一个包含数值和分类数据的大型数据集。数据集有很多缺失值。我目前正在尝试使用 OneHotEncoder 对分类特征进行编码。当我读到 OneHotEncoder 时,我的理解是,对于缺失值 (NaN),OneHotEncoder 会将 0 分配给所有特征的类别,如下所示:

0     Male 
1     Female
2     NaN
Run Code Online (Sandbox Code Playgroud)

应用 OneHotEncoder 后:

0     10 
1     01
2     00
Run Code Online (Sandbox Code Playgroud)

但是,当运行以下代码时:

0     Male 
1     Female
2     NaN
Run Code Online (Sandbox Code Playgroud)

我收到错误ValueError: Input contains NaN

所以我猜我之前对 OneHotEncoder 如何处理缺失值的理解是错误的。有没有办法让我获得上述功能?我知道在编码之前插补缺失值将解决这个问题,但我不愿意这样做,因为我正在处理医疗数据,并担心插补可能会降低我的模型的预测准确性。

我发现这个问题很相似,但答案没有提供关于如何处理 NaN 值的足够详细的解决方案。

让我知道你的想法,谢谢。

Ben*_*ger 8

从版本 0.24 开始,OneHotEncoder现在仅将缺失值视为其自己的类别。 什么是新条目


Om *_*ogi 5

  1. 使用 "Others"更改NaN 值。
  2. 然后继续one-hot编码
  3. 然后您可以删除“其他”列。


yat*_*atu 5

您需要先估算缺失值。例如,在 OneHot 编码之前,您可以Pipeline使用SimpleImputer设置most_frequent策略来定义一个插补步骤:

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
    ('encoder', OneHotEncoder(handle_unknown='ignore'))])

preprocessor = ColumnTransformer(
    transformers=[
        ('cat', categorical_transformer, [0])
    ])
Run Code Online (Sandbox Code Playgroud)
df = pd.DataFrame(['Male', 'Female', np.nan])
preprocessor.fit_transform(df)
array([[0., 1.],
       [1., 0.],
       [1., 0.]])
Run Code Online (Sandbox Code Playgroud)

  • 我建议使用“strategy='constant'”、“fill_value='missing'”来保留类别的结构,而不是使用最频繁的值进行插补。 (2认同)