Как кодировать несколько функций одновременно с SciKit Learn transform - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь закодировать некоторые категориальные функции, чтобы иметь возможность использовать их как функции в модели машинного обучения, на данный момент у меня есть следующий код:

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 голосов
/ 26 ноября 2018

Способ работы объекта кодировщика заключается в том, что при fit он сохраняет некоторые метаданные в атрибутах объекта.Эти атрибуты используются, когда вы хотите преобразовать данные.fit_transform - это удобный метод для fit и transform за один шаг.

Когда вы решите использовать тот же объект для выполнения другого fit_transform, вы перезаписываете сохраненные метаданные.Это хорошо, если вы не хотите использовать объекты inverse_transform.

Настройка

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

Ответ на свой вопрос

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

Как я это сделаю

Каждый отдельный кодировщик заносится в словарь 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
0 голосов
/ 26 ноября 2018

Это немного неловко, но вы получаете доступ к значениям из ряда, а затем вызываете для этого подходящее преобразование, выбирая ряд внутри цикла 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()
0 голосов
/ 26 ноября 2018

Я просто исправляю твой код, добавляя 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))
0 голосов
/ 26 ноября 2018

Конечно, method = 'data.' + feature + '.values' не будет работать - это сама строка!Попробуйте вместо

method = data[feature].values

или

for feature in label_encode:
    data[feature] = le.fit_transform(data[feature].values)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...