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

Python 机器学习中如何处理分类数据进行预处理,python,pandas,dataframe,machine-learning,feature-selection,Python,Pandas,Dataframe,Machine Learning,Feature Selection,这可能是一个基本问题,我有一个分类数据,我想把它输入到我的机器学习模型中。我的ML模型只接受数值数据。将分类数据转换为数字数据的正确方法是什么 我的示例DF: 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

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

我的示例DF:

  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
我知道下面的代码将我的分类数据转换为数字

第一类:

df['T-size'] = df['T-size'].cat.codes
上面的行只是将类别从0转换为N-1。他们之间没有任何关系

对于这个例子,我知道S 第2类:

在这种类型中,我认为M和F之间没有关系,但我可以看出,当M的概率大于F时,即样本数为样本总数的1/1

对于男性来说

4/5

对于女性来说

2/4

WKT

4/5>2/4

我应该如何替换这种列

对于这个问题,我可以用4/5替换M,用2/4替换F吗

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


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

对于第一个问题,如果你有少量的类别,你可以用字典映射该列。通过这种方式,您可以设置订单:

d = {'L':2, 'M':1, 'S':0}
df['T-size'] = df['T-size'].map(d)
df['T-size'].astype(pd.api.types.CategoricalDtype(['S','M','L'],ordered=True)).
输出:

   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

对于第二个问题,您可以使用相同的方法,但我会将男性和女性的2个值保留为0和1。如果您只需要类别,并且不必对值进行操作,那么一个值等于另一个值。

对于第一个问题,如果您有少量类别,可以使用字典映射列。通过这种方式,您可以设置订单:

d = {'L':2, 'M':1, 'S':0}
df['T-size'] = df['T-size'].map(d)
df['T-size'].astype(pd.api.types.CategoricalDtype(['S','M','L'],ordered=True)).
输出:

   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

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

< P>如果您希望在大小参数中具有层次结构,则可以考虑使用线性映射。这将是:

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})

<>为了更详细的解释和覆盖比你的问题更多的特殊性,我建议阅读

如果你想在你的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})

要获得比你的问题更详细的解释和更具体的内容,我建议阅读

对分类数据进行编码的方法有很多,其中一些方法完全取决于你打算如何处理它。例如,如果您计划使用决策树/随机林/GBM,则最流行的一种热编码是

关于上述t恤,您可以向熊猫分类类型订购:

d = {'L':2, 'M':1, 'S':0}
df['T-size'] = df['T-size'].map(d)
df['T-size'].astype(pd.api.types.CategoricalDtype(['S','M','L'],ordered=True)).
如果您将tshirt设置为那样的分类,那么.cat.codes方法将非常有效。这也意味着您可以轻松地使用scikit learn的LabelEconder,它可以整齐地安装到管道中


关于性别编码,在使用目标变量和标签时需要非常小心。您不希望在列车测试拆分之前执行此编码,否则您将使用未看到数据的知识,使其不真正未看到。如果您使用交叉验证,这会变得更加复杂,因为您需要在每个CV迭代中进行编码,即每折叠一次新编码。如果您想这样做,我建议您从skcontribs类别编码器中进行检查,但同样,请确保在sklearn管道中使用此功能,否则您将弄乱列车测试拆分,并将测试集中的信息泄漏到您的培训集中。

对类别数据进行编码的方法有很多,其中一些完全取决于你打算用它做什么。例如,如果您计划使用决策树/随机林/GBM,则最流行的一种热编码是

关于上述t恤,您可以向熊猫分类类型订购:

d = {'L':2, 'M':1, 'S':0}
df['T-size'] = df['T-size'].map(d)
df['T-size'].astype(pd.api.types.CategoricalDtype(['S','M','L'],ordered=True)).
如果您将tshirt设置为那样的分类,那么.cat.codes方法将非常有效。这也意味着你可以很容易地使用 scikit learn的LabelEconder,可整齐地安装在管道中


关于性别编码,在使用目标变量和标签时需要非常小心。您不希望在列车测试拆分之前执行此编码,否则您将使用未看到数据的知识,使其不真正未看到。如果您使用交叉验证,这会变得更加复杂,因为您需要在每个CV迭代中进行编码,即每折叠一次新编码。如果您想这样做,我建议您从skcontribs类别编码器中进行检查,但请再次确保在sklearn管道中使用此功能,否则您将弄乱列车测试拆分,并将测试集中的信息泄漏到您的培训集中。

对于M/F示例来说,这可能有些过分,因为它是二进制的,但是如果你一直担心把一个分类映射成一个数字形式,那么就考虑一下。它基本上将包含n个类别的单个列扩展为n个二进制列

因此,数据集包括:

Gender
M
F
M
M
F
将成为

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

这就消除了一件事比另一件事更积极的任何概念——对于具有两个以上选项的分类数据来说,这是绝对必须的,其中不存在可传递的A>B>C关系,并且您不希望通过将一个结果强制加入编码方案来玷污您的结果 因此,数据集包括:

Gender
M
F
M
M
F
将成为

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


这就消除了一件事比另一件事更积极的任何概念——对于具有两个以上选项的分类数据来说,这是绝对必须的,其中不存在可传递的A>B>C关系,并且您不希望通过将一个结果强制加入编码方案来玷污您的结果

感谢您的回答,这里您使用了s->0,M->2,L->2的映射值。我想知道您为什么选择0,1,2。如果它代表重量,我可以分别使用10、20、30。它会对我的模型产生任何影响吗?我会从最小的值0开始,然后增加到最大值。我真的不知道该分配什么值。将标量值替换为类别是否足以处理类别数据?是的,很抱歉重复这个问题,我真的想知道,我不需要明确地给出权重吗?谢谢你的回答,这里你使用了s->0,m->2,L->2的映射值。我可以知道你为什么选择0,1,2吗。如果它代表重量,我可以分别使用10、20、30。它会对我的模型产生任何影响吗?我会从最小的值0开始,然后增加到最大值。我真的不知道该分配什么值。将标量值替换为类别是否足以处理类别数据?是的,很抱歉重复这个问题,我真的很想知道,我不需要明确地给出权重吗?谢谢你的回答,对于第一个问题,你分配1,2,3我可以知道这背后的原因吗?你的尺寸参数值之间的关系是未知的,所以我假设它是线性的。因为大小是正数,所以我把最小值设为大于0。它确保了M的大小是S的倍数,当然对于L的大小也是如此,对于S=0,M=1和L=3,它不是真的。我很好奇,我能用10,20,30或5,10,15来代替1,2,3吗?是的,你可以。最重要的部分是建模元素之间关系的方式。如果将其设置为c=3a和b=2a的线性关系,则无论使用1、2和3或任何其他保持相同线性关系的三元组,数据中的模式都将保持不变。感谢您的回答,对于第一个问题,您指定了1、2、,3我可以知道这背后的原因吗?你的尺寸参数值之间的关系是未知的,所以我假设它是线性的。因为大小是正数,所以我把最小值设为大于0。它确保了M的大小是S的倍数,当然对于L的大小也是如此,对于S=0,M=1和L=3,它不是真的。我很好奇,我能用10,20,30或5,10,15来代替1,2,3吗?是的,你可以。最重要的部分是建模元素之间关系的方式。如果将其设置为c=3a和b=2a的线性关系,则无论您使用1、2和3或任何其他保持相同线性关系的三元组,您在数据中发现的模式都将保持不变。感谢您的回答,我理解了第一部分,但我未能理解具有两个以上选项的分类数据的绝对必要性,其中不存在可传递的A>B>C关系,并且您不希望通过将结果强制到编码方案中来抹黑您的结果。这一点。你能说清楚吗,在你的例子中,你已经概括了两种类型的分类变量,{S,M,L}是可传递的,因为你可以给它们赋值一个顺序。{M,F}不是传递的,但是
是二进制的,所以编码到{0,1}可能是可以的。另一种类型的分类变量是有两个以上的选项,但不可排序,即不可传递-因此{香草、草莓、葡萄}可能是分类变量中的选项,但如果转换为{0,1,2},则会引入偏差,这表明草莓存在于香草和葡萄之间,而在任意编码之外不存在这种关系。很好的解释,非常感谢。对于这个{香草、草莓、葡萄}一个热编码解决了问题,对吗?是的,没错。没有什么能阻止你也把它用在{M,F}上。一个热编码的缺点是扩展数据的维度,当字段中的类别数量变大时,这可能会成为一个问题,但请记住,它通常是一个很好的通用选项。感谢您的回答,我理解了第一部分,但是我没有理解有两个以上选项的分类数据的绝对必要性,其中不存在可传递的A>B>C关系,并且您不希望通过将一个结果强制加入到编码方案中来玷污您的结果。这一点。你能说清楚吗,在你的例子中,你已经概括了两种类型的分类变量,{S,M,L}是可传递的,因为你可以给它们赋值一个顺序。{M,F}不是可传递的,但它是二进制的,所以编码到{0,1}可能是可以的。另一种类型的分类变量是有两个以上的选项,但不可排序,即不可传递-因此{香草、草莓、葡萄}可能是分类变量中的选项,但如果转换为{0,1,2},则会引入偏差,这表明草莓存在于香草和葡萄之间,而在任意编码之外不存在这种关系。很好的解释,非常感谢。对于这个{香草、草莓、葡萄}一个热编码解决了问题,对吗?是的,没错。没有什么能阻止你也把它用在{M,F}上。一个热编码的缺点是扩展数据的维度,当字段中的类别数量变大时,这可能会成为一个问题,但请记住,它通常是一个很好的通用选项。有序编码的重要性是什么。i、 例如,df['T-size'].astype'category'和df['T-size'].astypepd.api.types.categorialdType['S','M','L',ordered=TrueWell之间有什么区别?你说你想确保Syeah得到它-为了澄清这一点,您不希望在列车测试分离之前进行这种编码,否则您将使用未看到数据的知识,使其不是真正未看到的。此语句此编码表示哪种编码?你是说我的假设对吗?或者你是指其他什么?@MohamedThasinah从技术上讲,任何编码,尤其是任何使用目标变量或被编码变量分布的编码。有序的重要性是什么。i、 例如,df['T-size'].astype'category'和df['T-size'].astypepd.api.types.categorialdType['S','M','L',ordered=TrueWell之间有什么区别?你说你想确保Syeah得到它-为了澄清这一点,您不希望在列车测试分离之前进行这种编码,否则您将使用未看到数据的知识,使其不是真正未看到的。此语句此编码表示哪种编码?你是说我的假设对吗?或者你是指其他什么?@MohamedThasinah从技术上讲,任何编码,尤其是使用目标变量或被编码变量分布的任何编码。