如何使用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_transform
是fit
和transform
的便捷方法。
当您决定使用同一个对象执行另一个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
update
和apply
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-对熊猫数据帧的某些列进行一次热编码