在scikit-learn中使用OneHotEncoder对序数和名义特征进行分类准备

3

我想准备一个包含连续、名义和序数特征的数据集以进行分类。我有一些解决方法,但我想知道是否有更好的方法可以使用scikit-learn的编码器?

让我们考虑以下示例数据集:

import pandas as pd
df = pd.DataFrame([['green', 'M', 10.1, 'class1'], ['red', 'L', 13.5, 'class2'], ['blue', 'XL', 15.3, 'class1']])
df.columns = ['color', 'size', 'prize', 'class label']
df

enter image description here

现在,类别标签可以通过标签编码器简单地转换(分类器忽略类别标签中的顺序)。

from sklearn.preprocessing import LabelEncoder
class_le = LabelEncoder()
df['class label'] = class_le.fit_transform(df['class label'].values)

我会将序数特征列 size 转换如下:

size_mapping = {
           'XL': 3,
           'L': 2,
           'M': 1}

df['size'] = df['size'].apply(lambda x: size_mapping[x])
df

这里输入图片描述

最后是序数color特性:

color_mapping = {
           'green': [0,0,1],
           'red': [0,1,0],
           'blue': [1,0,0]}

df['color'] = df['color'].apply(lambda x: color_mapping[x])
df

enter image description here

y = df['class label'].values
X = df.iloc[:, :-1].values
X = np.apply_along_axis(func1d= lambda x: np.array(x[0] + list(x[1:])), axis=1, arr=X)
X

array([[  0. ,   0. ,   1. ,   1. ,  10.1],
       [  0. ,   1. ,   0. ,   2. ,  13.5],
       [  1. ,   0. ,   0. ,   3. ,  15.3]])
1个回答

4

你可以使用DictVectorizer进行名义编码,使得处理过程更加简洁。此外,你还可以直接使用.map()应用'size_maping'。

import pandas as pd
df = pd.DataFrame([['green', 'M', 10.1, 'class1'], ['red', 'L', 13.5, 'class2'], ['blue', 'XL', 15.3, 'class1']])
df.columns = ['color', 'size', 'prize', 'class label']

from sklearn.preprocessing import LabelEncoder
class_le = LabelEncoder()
df['class label'] = class_le.fit_transform(df['class label'].values)

size_mapping = {
       'XL': 3,
       'L': 2,
       'M': 1}

df['size'] = df['size'].map(size_mapping)

feats =df.transpose().to_dict().values()

from sklearn.feature_extraction import DictVectorizer
Dvec = DictVectorizer()

Dvec.fit_transform(feats).toarray()

返回:

array([[  0. ,   0. ,   1. ,   0. ,  10.1,   1. ],
       [  1. ,   0. ,   0. ,   1. ,  13.5,   2. ],
       [  0. ,   1. ,   0. ,   0. ,  15.3,   3. ]])

获取特征名称:

 Dvec.get_feature_names()

 ['class label', 'color=blue', 'color=green', 'color=red', 'prize', 'size']

谢谢,看起来干净多了! - user2489252
这是微妙的欺骗,展示了scikits的巨大限制。并非所有名义特征都可以像您展示的那样进行向量化,但这正是scikits所要求的。在这里,大小可以起作用,但是如果特征是“头发颜色”呢?你必须使用scikits来提取头发颜色1与3之间的线性关系。显然,这毫无意义,并将导致scikit的分类器和回归器产生同样荒谬的结果。 - Cerin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接