在 scikit-learn 中使用 OneHotEncoder 为分类准备序数和标称特征
Preparing Ordinal and Nominal Features for classification using OneHotEncoder in scikit-learn
我想为 classification 准备一个包含连续、名义和有序特征的数据集。我在下面有一些解决方法,但我想知道是否有更好的方法使用 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
现在,class 标签可以通过标签编码器简单地转换(classifier 忽略 class 标签中的顺序)。
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
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]])
您可以将 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()
returns:
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']
我想为 classification 准备一个包含连续、名义和有序特征的数据集。我在下面有一些解决方法,但我想知道是否有更好的方法使用 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
现在,class 标签可以通过标签编码器简单地转换(classifier 忽略 class 标签中的顺序)。
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
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]])
您可以将 DictVectorizer 用于标称编码,从而使过程更清洁。您也可以直接使用 .map()
.
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()
returns:
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']