如何在机器学习中处理分类数据以进行预处理

时间:2018-11-26 09:26:06

标签: python pandas dataframe machine-learning feature-selection

这可能是一个基本问题,我有一个分类数据,我想将其输入到我的机器学习模型中。我的ML模型仅接受数值数据。将这种分类数据转换为数值数据的正确方法是什么?

我的样本DF:

proof : p ≡ refl
proof = begin
  (λ i → p i)             ≡⟨⟩
  (λ i → f (loop i))      ≡⟨ (λ i j → proofAt j i) ⟩
  (λ i → f base)          ≡⟨⟩
  (λ i → refl {x = x} i)  ∎

我知道以下代码将我的分类数据转换为数字

类型1:

  T-size Gender  Label
0      L      M      1
1      L      M      1
2      M      F      1
3      S      F      0
4      M      M      1
5      L      M      0
6      S      F      1
7      S      F      0
8      M      M      1

上一行仅将类别从0转换为N-1。它们之间没有任何关系。

在此示例中,我知道S

类型2:

在这种情况下,我M和F之间没有关系。但是我可以判断出df['T-size'] = df['T-size'].cat.codes 的概率大于M。也就是说,样品应为1 /样品总数

对于男性

(4/5)

对于女性

(2/4)

WKT,

(4/5)>(2/4)

我应该如何替换此类列?

我可以针对此问题将M替换为(4/5),将F替换为(2/4)吗?

处理专栏的正确方法是什么?

帮助我更好地理解这一点。

4 个答案:

答案 0 :(得分:2)

对于第一个问题,如果类别数量很少,则可以map带有字典的列。这样,您可以设置订单:

d = {'L':2, 'M':1, 'S':0}
df['T-size'] = df['T-size'].map(d)

输出:

   T-size Gender  Label
0       2      M      1
1       2      M      1
2       1      F      1
3       0      F      0 
4       1      M      1
5       2      M      0
6       0      F      1
7       0      F      0
8       1      M      1

对于第二个问题,您可以使用相同的方法,但是我将保留男性和女性01的2个值。如果只需要类别,而不必使用值进行运算,则一个值等于另一个。

答案 1 :(得分:2)

有很多编码分类数据的方法,其中一些取决于您打算如何处理。例如,如果您打算使用决策树/随机森林/ GBM,那么一种最容易使用的单编码方式就是extremely poor choice

关于上面的T恤,您可以给熊猫分类键入订单:

df['T-size'].astype(pd.api.types.CategoricalDtype(['S','M','L'],ordered=True)).

如果您以这种方式设置了T恤,那么您的.cat.codes方法就可以完美地工作。这也意味着您可以轻松地使用scikit-learn的LabelEconder,它非常适合管道。

关于性别编码,在使用目标变量(Label)时需要格外小心。您不希望在火车测试拆分之前进行这种编码,否则您将使用对看不见的数据的了解,从而使它不是真正看不见的。如果您使用交叉验证,这将变得更加复杂,因为您需要在每次CV迭代中进行编码(即每折新编码)。如果要执行此操作,建议您从skcontribs类别编码器中检出TargetEncoder,但再次确保在sklearn Pipeline中使用此方法,否则您会弄乱训练测试的拆分和泄漏信息从测试集中到训练集中。

答案 2 :(得分:1)

如果要在size参数中具有层次结构,则可以考虑对其使用线性映射。这将是:

size_mapping = {"S": 1, "M":2 , "L":3}

#mapping to the DataFrame
df['T-size_num'] = df['T-size'].map(size_mapping)

这可让您在保留层次结构的同时将输入视为数字数据

关于性别,您误解了重新分配和程序。如果已经将重新分区作为输入,则会在数据中引入偏差。您必须将“男性”和“女性”视为两个不同的类别,而不管其现有分区如何。您应该用两个不同的数字映射它,但不要引入比例。

df['Gender_num'] = df['Gender'].map({'M':0 , 'F':1})

要获得比您的问题更详细的解释和更多细节,我建议阅读this article regarding categorical data in Machine Learning

答案 3 :(得分:1)

由于M / F示例是二进制的,因此对于M / F示例而言可能是过大的了-但是如果您曾经担心将分类映射为数字形式,请考虑使用one hot encoding。基本上,它将包含 n 个类别的单个列扩展为 n 个二进制列。

因此,一个数据集:

Gender
M
F
M
M
F

将成为

Gender_M    Gender_F
1           0
0           1
1           0
1           0
0           1

这消除了任何事物比另一事物更“积极”的概念-具有超过2个选项的分类数据的绝对必须,其中没有传递A> B> C的关系,并且您不想涂抹您的通过将其中一项强加到您的编码方案中来获得结果。