【发布时间】:2018-12-28 18:18:37
【问题描述】:
问题
似乎没有简单的方法来对没有顺序的数据进行一次热编码。我的问题是,单热编码没有特定顺序的值的最佳方法是什么?如果没有标准化的方法来做到这一点,为什么要订购 one-hot-encoded 功能?
示例
我正在尝试对一组特性进行单热编码,其中值是自定义对象。我的对象如下所示:
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
但是,我尝试过的所有解决方案都需要对数据进行一次热编码以具有某种顺序,而在我的情况下这是未定义的。我认为,如果订单未定义,则应该仍然可以使用 one-hot-encoding,因为在这种情况下,哪个 one-hot-encoded 功能在另一个之前并不重要。
尝试的解决方案
熊猫数据框
我第一次尝试的解决方案是使用 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-learn 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])
问题
重申一下:我的问题是,对没有特定顺序的值进行一次热编码的最佳方法是什么?如果没有标准化的方法来做到这一点,为什么要订购 one-hot-encoded 功能?
【问题讨论】:
标签: python pandas one-hot-encoding