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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用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)似乎都不起作用。除了手工编写之外,必须有一种方法可以做到这一点。

答案

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

method = data[feature].values

要么

for feature in label_encode:
    data[feature] = le.fit_transform(data[feature].values)
另一答案

我只修复你的代码添加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))
另一答案

编码器对象的工作方式是,当你使用fit时,它会在对象的属性中存储一些元数据。当您想要转换数据时,将使用这些属性。 fit_transformfittransform的便捷方法。

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

Setup

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

Answer to your question

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

How I'd Do It

每个单独的编码器都在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

如果您只想要代码,可以使用Pandas的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's 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
另一答案

这有点尴尬,但你可以访问系列中的值然后调用fit变换,同时选择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()

以上是关于如何使用SciKit Learn转换一次编码多个功能的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn 中跨多个列的标签编码

在 scikit-learn 中进行一种热编码的可能方法?

使用 scikit learn 进行标签编码时如何保持自然顺序

Scikit-Learn-对熊猫数据帧的某些列进行一次热编码

如何在 scikit-learn 中有效地编码数字目标变量?

使用 Scikit-learn 和 Pandas 将编码列连接到原始数据帧