【问题标题】:How to handle missing values (NaN) in categorical data when using scikit-learn OneHotEncoder?使用 scikit-learn OneHotEncoder 时如何处理分类数据中的缺失值 (NaN)?
【发布时间】:2020-10-06 02:37:33
【问题描述】:

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

0     Male 
1     Female
2     NaN

应用 OneHotEncoder 后:

0     10 
1     01
2     00

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

    # Encoding categorical data
    from sklearn.compose import ColumnTransformer
    from sklearn.preprocessing import OneHotEncoder


    ct = ColumnTransformer([('encoder', OneHotEncoder(handle_unknown='ignore'), [1])],
                           remainder='passthrough')
    obj_df = np.array(ct.fit_transform(obj_df))
    print(obj_df)

我收到错误 ValueError: Input contains NaN

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

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

请告诉我你的想法,谢谢。

【问题讨论】:

标签: python machine-learning scikit-learn


【解决方案1】:
  1. NaN 值更改为“其他”
  2. 然后进行 one-hot 编码
  3. 然后您可以删除“其他”列。

【讨论】:

  • 你的意思是用pandas.DataFrame.fillna把NaN替换成字符串“Others”吗?
  • 是的,使用fillna
  • 我不会使用“其他”,因为这是性,在医学背景下,它很可能应该是“男性”或“女性”。其他没有多大意义,除非我们知道,例如,nans 是变性人,等等。
  • “其他”最终会被删除。如果您担心命名法,可以使用“未提及”标签。
【解决方案2】:

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

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])
    ])

df = pd.DataFrame(['Male', 'Female', np.nan])
preprocessor.fit_transform(df)
array([[0., 1.],
       [1., 0.],
       [1., 0.]])

【讨论】:

  • 感谢您的回答和有用的代码。您认为使用列中最频繁的值进行插补不会影响模型的预测准确性吗?
  • 这是一种非常常见的分类数据策略。它并不理想,但毕竟您确实丢失了数据。尽管在没有太多缺失数据的情况下,这是一种合理的方法@sums
  • 是的,我一直在寻找替代方案,以查看是否可以避免过多地操纵数据。不幸的是,我有很多缺失的数据。不过,我可能不得不求助于他的方法。感谢您的意见。
  • 如果你将 Onehot 编码,这些值无论如何都会被分配给相同的值,所以它只是真正使 OneHotEncoder 能够处理它们@sums 不要忘记你可以投票并接受答案,如果它有帮助:) 见What should I do when someone answers my question?,谢谢!
  • 我建议使用strategy='constant'fill_value='missing' 来保留类别的结构,而不是使用最频繁的归类。
【解决方案3】:

这个问题已经解决了,但是 pd.get_dummies 也会创建一个允许你缺失值的 nan 列

【讨论】:

    猜你喜欢
    • 2015-07-30
    • 2016-02-02
    • 1970-01-01
    • 2020-02-01
    • 2016-01-11
    • 2014-10-04
    • 2012-07-11
    • 2014-02-17
    相关资源
    最近更新 更多