如何在pandas中将变量指定为序数/分类?

时间:2015-04-09 02:18:05

标签: python pandas scikit-learn

我正在尝试使用scikit-learn在数据集上运行一些机器学习算法。我的数据集有一些类似于类别的功能。就像一个特征是A,其值1,2,3指定了某些东西的质量。 1:Upper, 2: Second, 3: Third class。所以它就像一个序数变量。

类似地,我重新编码了一个变量City,将('London', Zurich', 'New York'三个值1,2,3转换为{{1}},但没有特定的值。所以现在这是一个名义上的分类变量。

如何在pandas中指定算法将其视为分类和序数等?与R一样,分类变量由因子(a)指定,因此不被视为连续值。在pandas / python中有类似的东西吗?

最好的方法是什么?

由于

3 个答案:

答案 0 :(得分:21)

几年后......(因为我认为这个问题的一个很好的解释不仅需要这个问题,还需要在将来提醒自己)

Ordinal vs. Nominal

通常,人们会将分类变量转换为虚拟变量(或host of other methodologies),因为它们是名义上的,例如他们有{strong>没有感觉a > b > c。在OP原始问题中,这将在城市上进行,如伦敦,苏黎世,纽约。

标称

的虚拟变量

对于此类问题,pandas提供了 - 到目前为止 - 使用pandas.get_dummies进行的最简单的转换。所以:

# create a sample of OPs unique values
series = pandas.Series(
           numpy.random.randint(low=0, high=3, size=100))
mapper = {0: 'New York', 1: 'London', 2: 'Zurich'}
nomvar = series.replace(mapper)

# now let's use pandas.get_dummies
print(
    pandas.get_dummies(series.replace(mpr))

Out[57]:
    London  New York  Zurich
0        0         0       1
1        0         1       0
2        0         1       0
3        1         0       0

分类变量的序数编码

但是在序数变量的情况下,用户必须谨慎使用pandas.factorize。原因是工程师想要保留映射中的关系a > b > c

因此,如果我想在large > medium > small中使用一组分类变量并保留它,我需要确保pandas.factorize保留该关系。

# leveraging the variables already created above
mapper = {0: 'small', 1: 'medium', 2: 'large'}
ordvar = series.replace(mapper)

print(pandas.factorize(ordvar))

Out[58]:
(array([0, 1, 1, 2, 1,...  0, 0]),
Index(['large', 'small', 'medium'], dtype='object'))

事实上,使用pandas.factorize已经失去了需要保留以保持序数概念的关系。在这样的实例中,我使用自己的映射来确保保留序数属性。

preserved_mapper = {'large':2 , 'medium': 1, 'small': 0}
ordvar.replace(preserved_mapper)
print(ordvar.replace(preserved_mapper))

Out[78]:
0     2
1     0
...
99    2
dtype: int64

事实上,通过创建自己的dict来映射值,不仅可以保留所需的序数关系,还可以用作“保持预测算法的内容和映射有序”,以确保您不仅没有在过程中丢失任何序数信息,而且还存储了每个变量的每个映射的记录。

int进入sklearn

最后,OP谈到将信息传递到scikit-lean分类器,这意味着需要int。对于这种情况,如果您的数据中包含NaN,请确保您了解详细astype(int) gotchahere

答案 1 :(得分:2)

您应该将OneHotEncoder变换器与分类变量一起使用,并保持序数变量不变:

>>> import pandas as pd
>>> from sklearn.preprocessing import OneHotEncoder
>>> df = pd.DataFrame({'quality': [1, 2, 3], 'city': [3, 2, 1], columns=['quality', 'city']}
>>> enc = OneHotEncoder(categorical_features=[False, True])
>>> X = df.values
>>> enc.fit(X)
>>> enc.transform(X).todense()
matrix([[ 0.,  0.,  1.,  1.],
        [ 0.,  1.,  0.,  2.],
        [ 1.,  0.,  0.,  3.]])

答案 2 :(得分:1)