Как лучше всего кодировать неиерархические категориальные функции в машинном обучении? - PullRequest
0 голосов
/ 10 февраля 2019

Для строковых функций, когда порядок не имеет значения, что лучше получить манекены или oneHotEncoder?

Например, на этом фрейме данных панд:

df_with_cat = pd.DataFrame({'A': ['ios', 'android', 'web', 'NaN', 'ios','ios', 'NaN', 'android'], 'B' : [4, 4, 'NaN', 2, 'NaN', 3, 3, 'NaN']})

df_with_cat.head()

    A        B
---------------
0   ios      4
1   android  4
2   web      NaN
3   NaN      2
4   ios      NaN
5   ios      3
6   NaN      3
7   android  NaN

Я знаю, что теперь, чтобы обработать их (вменять пропущенные значения и т. Д.), Я должен их кодировать, как-то так:

from sklearn.preprocessing import LabelEncoder

df_with_cat_orig = df_with_cat.copy()
la_encoder = LabelEncoder()
df_with_cat['A'] = la_encoder.fit_transform(df_with_cat.A)

Вывод:

df_with_cat.head(10)

    A   B
-----------
0   2   4
1   1   4
2   3   NaN
3   0   2
4   2   NaN
5   2   3
6   0   3
7   1   NaN

Но теперь кажется, что есть некоторый порядок 0-3, но это не тот случай ... 'ios' ->2 не обязательно больше, чем'android' ->1

Ответы [ 3 ]

0 голосов
/ 10 февраля 2019

Я только что получил ответ на мой вопрос выше (и связанный с желтым, отмеченным ниже):

Когда вы кодируете их в числа и оставляете их как одну особенность, модель предполагает, что порядокозначает что-то, в этом отношении, что «IOS» (который сопоставлен с 2) больше, чем «Android» (который равен 1)

Но теперь кажется, что есть некоторый порядок 0-3, но это не так ... 'ios' -> 2 не обязательно больше, чем 'android' -> 1

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

data_with_dummies = pd.get_dummies(df_with_cat, columns=['A'], drop_first=True)


        B A_1 A_2   A_3
------------------------
    0   4   0   1   0
    1   4   1   0   0
    2   NaN 0   0   1
    3   2   0   0   0
    4   NaN 0   1   0
    5   3   0   1   0
    6   3   0   0   0
    7   NaN 1   0   

Теперь мы избегаем проблемы, с которой я начинал, это должно значительно улучшить производительность модели

Или просто используйте OneHotEncoder - как @Primusa указано вответ выше

0 голосов
/ 10 февраля 2019

Все, что вам нужно - это OneHotEncoder

from sklearn.preprocessing import LabelEncoder

df_with_cat_orig = df_with_cat.copy()
la_encoder = LabelEncoder()
df_with_cat['A'] = la_encoder.fit_transform(df_with_cat.A)

from sklearn.preprocessing import OneHotEncoder

oh_enc = OneHotEncoder(categorical_features=[0])
df_with_cat = oh_enc.fit_transform(df_with_cat).toarray()

df_with_cat = df_with_cat[:, 1:]       # remove first column to avoid dummy variable trap
0 голосов
/ 10 февраля 2019

Категориальные признаки отличаются от числовых признаков тем, что категориальные признаки представляют собой набор дискретных значений, в то время как числовые признаки образуют непрерывную последовательность.Например, для функции «животное», если 1 -> кошка и 2 -> собака, у вас не может быть 1,5, вы либо 1, либо 2. И в этой настройке собака не обязательно больше, чем кошка - однаи два являются просто кодировками «реальной» особенности.

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

В терминахимея дело с категориальными функциями, вы на месте - мы их кодируем.Например, sklearn.preprocessing имеет OrdinalEncoder, который просто преобразует категориальные признаки (в основном строки типа «мужской», «женский» и т. Д.) В целые числа.

Теперь я неслишком хорошо знаком со sklearn и какими типами кодирования это требуется, но я чувствую, что должен обсудить некоторые более «продвинутые» способы кодирования категориальных функций.В зависимости от того, какие модели машинного обучения вы используете, они могут применяться или не применяться.Лично я в первую очередь использую их для нейронных сетей.

Более простой способ - это горячее кодирование, которое похоже на кодирование каждой категории в целое число по умолчанию.За исключением этого времени, чтобы избавиться от проблемы, когда модель рассматривает одну категорию как большую, чем другую, она использует массив единиц и нулей.то есть "кошка" -> 0 -> [1, 0, 0], "собака" -> 1-> [0, 1, 0], "птица" -> 2 -> [0, 0, 1].По сути, каждая категория кодируется в целочисленный индекс, а ваш результат - это массив всех нулей, кроме единицы с этим индексом.

Другой способ, которым мы кодируем, - это использование Embeddings.Это очень похоже на одноразовое кодирование в том смысле, что вы преобразуете целочисленный индекс (для категории) в n-мерный вектор.Однако это экономит место в том, что размер вектора может быть меньше, чем количество категорий.Это обычно используется в нейронных сетях, которые обрабатывают семантическую информацию.Каждое слово передается в модель как целочисленный индекс, но слой Embedded преобразует каждый индекс в n-мерный вектор.По мере обучения модели слой «Внедрение» будет лучше и лучше представлять каждую категорию.

...