繁体   English   中英

如何在python中热编码无序离散数据?

[英]How to one hot encode unordered discrete data in python?

问题

似乎没有简单的方法可以对没有顺序的数据进行一次热编码。 我的问题是,对没有特定顺序的值进行一次热编码的最佳方法是什么? 而且,如果没有标准化的方法,为什么还要订购一种热编码功能?

我正在尝试对其中值为自定义对象的一组功能进行热编码。 我的对象看起来像这样:

class MyObject(object)
    def __init__(self, identity):
        self.identity = identity

    def __hash__(self):
        return self.identity

    def __eq__(self, other):
        return self.identity == other.identity

在此设置中,可以比较MyObject的每个实例是否相等。 假设我们具有以下对象列表:

objects = [MyObject(0), MyObject(1), MyObject(0)]

函数set(objects)产生一组2个对象,即MyObject(0)MyObject(1) 这确实是我所期望的行为。 因此,当我尝试对这些数据进行一次热编码时,我会期望以下形式:

index   MyObject_0, MyObject_1
    0            1           0
    1            0           1
    2            1           0

但是,我尝试过的所有解决方案都要求对数据进行单次热编码以使其具有某种顺序,而在我的情况下这是未定义的。 我认为,如果顺序未定义,则仍然可以进行单次热编码,因为在那种情况下,哪个单次热编码功能位于另一项之前并不重要。

尝试的解决方案

熊猫数据框

我第一次尝试的解决方案是使用pandas的get_dummies()函数。

import pandas as pd

objects   = [MyObject(0), MyObject(1), MyObject(0)]
dataframe = pd.DataFrame({'MyObjectFeature': objects})
dummies   = pd.get_dummies(dataframe)

但是,此示例给出TypeError:

TypeError: 'values' is not ordered, please explicitly specify the categories order by passing in a categories argument.

Scikit学习LabelEncoder和OneHotEncoder

我的第二次尝试是使用Scikit-learn的LabelEncoder对值进行编码,然后再将其放入OneHotEncoder对象。 但是,在LabelEncoder ,出现了与使用Pandas数据帧相同的问题。

from sklearn.preprocessing  import LabelEncoder, OneHotEncoder

objects = [MyObject(0), MyObject(1), MyObject(0)]
encoder = LabelEncoder()
dummies = encoder.fit_transform(objects)

此示例还给出了TypeError:

TypeError: '<' not supported between instances of 'MyObject' and 'MyObject'

定制解决方案

我还创建了自己的UnorderedLabelEncoder对象,无需顺序即可对标签进行编码。 这可以正常工作,但是我想知道是否存在针对我的问题的标准解决方案,即使用知名的库。 还是如果不是这种情况,我想知道是否有理由要求订购功能?

class UnorderedLabelEncoder(object):

    def __init__(self):
        """ CustomLabelEncoder is capable of handling any
            hashable object including None values.
            """
        self.classes_ = dict()

    def fit(self, y):
        """ Fit label encoder.

            Parameters
            ----------
            y : array-like of shape (n_samples,)
                Target values.

            Returns
            -------
            self : returns an instance of self.
            """
        self.classes_ = {o:i for i, o in enumerate(set(y))}
        return self

    def fit_transform(self, y):
        """ Fit label encoder and return encoded labels.

            Parameters
            ----------
            y : array-like of shape [n_samples]
                Target values.

            Returns
            -------
            y : array-like of shape [n_samples]
        """
        self.fit(y)
        return self.transform(y)

    def transform(self, y):
        """ Transform labels to normalized encoding.

            Parameters
            ----------
            y : array-like of shape [n_samples]
                Target values.

            Returns
            -------
            y : array-like of shape [n_samples]
        """
        return np.array([self.classes_.get(x, -1) for x in y])

重申一下:我的问题是,对没有特定顺序的值进行一次热编码的最佳方法是什么? 而且,如果没有标准化的方法,为什么还要订购一种热编码功能?

我要说的是,如果值不具有源自其类型的固有顺序(部分顺序),那么您可以人为地定义顺序(类似于数据库中的人为主键)。 然后,这就是您施加在数据上的顺序,然后您可以使用可用于有序数据的任何方法(就像首先出现了[部分]顺序一样)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM