如何使用SciKit Learn一次编码多个功能

时间:2018-11-26 15:23:51

标签: python pandas machine-learning encoding scikit-learn

我正在尝试对一些分类特征进行编码,以便能够将它们用作机器学习模型中的特征,目前我具有以下代码:

data_path = '/Users/novikov/Assignment2/epl-training.csv'
data = pd.read_csv(data_path)
data['Date'] = pd.to_datetime(data['Date'])

le = preprocessing.LabelEncoder()


data['HomeTeam'] = le.fit_transform(data.HomeTeam.values)
data['AwayTeam'] = le.fit_transform(data.AwayTeam.values)
data['FTR'] = le.fit_transform(data.FTR.values)
data['HTR'] = le.fit_transform(data.HTR.values)
data['Referee'] = le.fit_transform(data.Referee.values)

这可以很好地工作,但是这不是理想的,因为如果要编码100个功能,那么手工处理将花费很长时间。如何自动执行该过程?我尝试实现一个循环:

label_encode = ['HomeTeam', 'AwayTeam', 'FTR', 'HTR', 'Referee']

for feature in label_encode:
    method = 'data.' + feature + '.values'
    data[feature] = le.fit_transform(method)

但是我得到ValueError: bad input shape ()

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-11-1b8fb6164d2d> in <module>()
     11     method = 'data.' + feature + '.values'
     12     print(method)
---> 13     data[feature] = le.fit_transform(method)

/anaconda3/lib/python3.6/site-packages/sklearn/preprocessing/label.py in fit_transform(self, y)
    109         y : array-like of shape [n_samples]
    110         """
--> 111         y = column_or_1d(y, warn=True)
    112         self.classes_, y = np.unique(y, return_inverse=True)
    113         return y

/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in column_or_1d(y, warn)
    612         return np.ravel(y)
    613 
--> 614     raise ValueError("bad input shape {0}".format(shape))
    615 
    616 

ValueError: bad input shape ()

此代码的所有变体(例如仅放置data.feature.values)似乎都无效。除了手工编写,还必须有其他方法。

4 个答案:

答案 0 :(得分:3)

当然,method = 'data.' + feature + '.values'不起作用-它本身就是一个字符串!试试吧

method = data[feature].values

for feature in label_encode:
    data[feature] = le.fit_transform(data[feature].values)

答案 1 :(得分:2)

我正在修复您添加pd.eval的代码

label_encode = ['HomeTeam', 'AwayTeam', 'FTR', 'HTR', 'Referee']

for feature in label_encode:
    method = 'data.' + feature + '.values'
    data[feature] = le.fit_transform(pd.eval(method))

答案 2 :(得分:2)

编码器对象的工作方式是,当您fit时,它将在对象的属性中存储一些元数据。当您要转换数据时,将使用这些属性。 fit_transform是一步实现fittransform的一种便捷方法。

当您决定使用同一对象执行另一个fit_transform时,将覆盖存储的元数据。如果您不想使用对象inverse_transform,那就很好。

设置

df = pd.DataFrame({
    'HomeTeam':[1, 3, 27],
    'AwayTeam':[9, 8, 100],
    'FTR':['dog', 'cat', 'dog'],
    'HTR': [*'XYY'],
    'Referee': [*'JJB']
})

回答您的问题

updateapply

le = preprocessing.LabelEncoder()
label_encode = ['HomeTeam', 'AwayTeam', 'FTR', 'HTR', 'Referee']

df.update(df[label_encode].apply(le.fit_transform))
df

   AwayTeam FTR HTR  HomeTeam Referee
0         1   1   0         0       1
1         0   0   1         1       1
2         2   1   1         2       0

我该怎么做

每个单独的编码器都被捕获在le字典中,以备将来使用

from collections import defaultdict
le = defaultdict(preprocessing.LabelEncoder)
label_encode = ['HomeTeam', 'AwayTeam', 'FTR', 'HTR', 'Referee']

df = df.assign(**{k: le[k].fit_transform(df[k]) for k in label_encode})
df

   AwayTeam FTR HTR  HomeTeam Referee
0         1   1   0         0       1
1         0   0   1         1       1
2         2   1   1         2       0

pandas.factorize

如果您只想要代码,则可以使用熊猫的factorize。请注意,这不会对最终值进行排序,也不会按照它们初次显示的顺序对其进行标记。

df.update(df[label_encode].apply(lambda x: x.factorize()[0]))
df

   AwayTeam FTR HTR  HomeTeam Referee
0         0   0   0         0       0
1         1   1   1         1       0
2         2   0   1         2       1

Numpy的unique

这确实对最终值进行了排序,看起来像LabelEncoder

df.update(df[label_encode].apply(lambda x: np.unique(x, return_inverse=True)[1]))

   AwayTeam FTR HTR  HomeTeam Referee
0         1   1   0         0       1
1         0   0   1         1       1
2         2   1   1         2       0

答案 3 :(得分:0)

这有点尴尬,但是您可以访问序列中的值,然后对其进行调用fit transform,同时在for循环“ X [c] =”中选择序列以指示您希望将值分配回DF。

X = pd.DataFrame({
    'A':[1, 3, 27],
    'B':[9, 8, 100],
    'C':['dog', 'cat', 'dog']})
print(X.head())

le = LabelEncoder()

for c in X.columns:

    X[c] = le.fit_transform(X[c].values)

X.head()