【问题标题】:Using OrdinalEncoder to transform categorical values使用 OrdinalEncoder 转换分类值
【发布时间】:2021-04-12 19:41:59
【问题描述】:

我有一个包含许多列的数据集

No  Name  Sex  Blood  Grade  Height  Study
1   Tom   M    O      56     160     Math
2   Harry M    A      76     192     Math
3   John  M    A      45     178     English
4   Nancy F    B      78     157     Biology
5   Mike  M    O      79     167     Math
6   Kate  F    AB     66     156     English
7   Mary  F    O      99     166     Science

我想把它改成那样

No  Name  Sex  Blood  Grade  Height  Study
1   Tom   0    0      56     160     0
2   Harry 0    1      76     192     0
3   John  0    1      45     178     1
4   Nancy 1    2      78     157     2
5   Mike  0    0      79     167     0
6   Kate  1    3      66     156     1
7   Mary  0    0      99     166     3

我知道有一个图书馆可以做到这一点

from sklearn.preprocessing import OrdinalEncoder

我试过了,但是没用

enc = OrdinalEncoder()
enc.fit(df[["Sex","Blood", "Study"]])

谁能帮我找出我做错了什么以及怎么做?

谢谢

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    你就快到了!

    基本上是fit 方法,准备编码器(适合您的数据,即准备映射),但不要转换数据。

    您必须调用transform 来转换数据,或者使用适合和转换相同数据的fit_transform

    enc = OrdinalEncoder()
    enc.fit(df[["Sex","Blood", "Study"]])
    df[["Sex","Blood", "Study"]] = enc.transform(df[["Sex","Blood", "Study"]])
    

    或直接

    enc = OrdinalEncoder()
    df[["Sex","Blood", "Study"]] = enc.fit_transform(df[["Sex","Blood", "Study"]])
    

    注意:这些值不会是您提供的值,因为在内部 fit 方法使用 numpy.unique,它给出了按字母顺序而不是按出现顺序排序的结果。

    enc.categories_可以看到

    [array(['F', 'M'], dtype=object),
     array(['A', 'AB', 'B', 'O'], dtype=object),
     array(['Biology', 'English', 'Math', 'Science'], dtype=object)]```
    

    数组中的每个值都由它的位置编码。 (F 将被编码为 0 ,M 为 1)

    【讨论】:

    • 没用,跑完那条线后还是男/女不是0/1!!!
    • 这真的很奇怪,你可以看到它在我身边工作pasteboard.co/Iitfx2g.png
    • 你找到答案了吗?也许问题存在是因为您使用的数据帧不是原始数据帧而是切片?
    【解决方案2】:

    我认为重要的是要指出这不是变量序数编码的示例。 Sex, Blood 和 Study 都不应该有一个顺序量表(也没有由提出问题的人建议)。序数数据有排名(参见例如https://en.wikipedia.org/wiki/Ordinal_data)这里的示例没有排名。

    如果您的变量是目标变量,您可以使用 LabelEncoder。(https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html)

    然后你可以这样做:

    from sklearn.preprocessing import LabelEncoder
    
    for col in ["Sex","Blood", "Study"]:
        df[col] = LabelEncoder().fit_transform(df[col])
    

    如果您的变量是特征,您应该使用 Ordinalencoder 来完成此操作。 (请参阅我的回答 cmets)。

    Ordinalencoder 的命名非常不幸,因为从数学而非统计命名的角度来看“序数”。

    更多关于 sklearn 中序数编码器和标签编码器之间的区别:https://datascience.stackexchange.com/questions/39317/difference-between-ordinalencoder-and-labelencoder

    【讨论】:

    • 你说得有道理,但同样重要的是要注意,我认为 LabelEncoder 在 Pipelines 中工作得不是很好。根据我在网上收集的信息,它仅适用于您的目标或响应变量。所以,为了做 OP 想做的事情,他们实际上建议使用 OrdinalEncoder。
    • 感谢您的评论。你能用任何资源来支持你的论点吗?我也不明白你的意思。我很高兴学习:)
    • 当然,在用户指南的顶部,它非常明确地说这只是为了转换目标而不是编码功能:scikit-learn.org/stable/modules/… 您还可以在此 github 问题响应中看到这一点: github.com/scikit-learn/scikit-learn/issues/12720
    • 你是对的。我认为问题在于“序数”一词的使用,这不是从统计角度来看的,而是从数学角度来看的(en.wikipedia.org/wiki/Ordinal_number)。我将编辑我的答案。感谢您指出!
    猜你喜欢
    • 2020-02-24
    • 2021-07-08
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 1970-01-01
    • 2019-07-17
    • 2018-04-12
    • 2022-01-02
    相关资源
    最近更新 更多