Подробное руководство по встраиванию категориальных признаков

Вступление :

Хорошо известно, что подготовка данных может составлять до 80% времени, необходимого для создания реального продукта машинного обучения. Кроме того, работа с категориальными функциями - одна из тех вещей, которые могут быть немного сложными и требующими много времени, особенно в случае больших кардинальных данных. Когда у вас есть функции с более чем 1000 категориями, и вам нужно построить на их основе модель, каждый специалист по данным должен выбрать лучший подход для представления этих категориальных функций модели. Назовем несколько распространенных:

  • Факторизация, где каждой уникальной категории присваивается уникальный ярлык.
  • Одно горячее кодирование, этот метод создает вектор с длиной, равной количеству категорий в наборе данных. Если точка данных принадлежит к категории i th, тогда вы найдете 1 в компоненте i th и 0 в другом месте (может поставить вас в ситуацию с данными большого размера)
  • Целевая кодировка (немного сложная, так как может вызвать чрезмерную подгонку), которая состоит из кодирования каждого значения со средним значением целевой переменной (должно выполняться в схеме перекрестной проверки)

В этом руководстве мы изучим еще один очень эффективный подход для работы с категориальными функциями (особенно в случае высокой мощности), и для этого мы будем использовать Tensorflow 2.0; так что обязательно обновите, чтобы следить.

Набор данных: мы будем работать над набором реальных данных о доходах переписи, также известным как набор данных для взрослых, доступным в репозитории UCI ML, где мы будем прогнозировать, будут ли потенциальный доход людей превышает 50 тысяч долларов в год или нет.

Встраивание категориальных признаков:

Если вы раньше работали над проектом НЛП, то, скорее всего, вы знакомы со словом «Встраивание». Если нет, позвольте мне объяснить это:

Встраивание означает представление чего-либо в виде вектора, проекции.

Это так просто, но вопрос в том, как нам получить этот вектор? Вот здесь и пригодятся глубокие нейронные сети.

Итак, хватит разговоров, давайте теперь поговорим о коде:

1 - Сначала мы загрузим данные (загружать их не нужно, просто установите пакет shap, и данные будут доступны из него):

import shap

data,labels = shap.datasets.adult(display=True)

2 - Затем давайте проверим наши категориальные особенности, запустив эту строку кода:

data.select_dtypes('category').columns

Итак, наши категориальные характеристики: «Рабочий класс», «Семейное положение», «Род занятий», «Отношения», «Раса», «Пол», «Страна».

2.1 - И просто из любопытства давайте также проверим наши числовые функции, запустив следующий код:

data.select_dtypes('number').columns

Результатом будет: «Возраст», «Образование», «Прирост капитала», «Убыток капитала»,
«Часы в неделю».

3 - Теперь давайте проверим количество элементов категориальных характеристик (сколько уникальных значений содержит каждая из них):

data[data.select_dtypes('category').columns].nunique().reset_index(n
ame='cardinality')

Таким образом, кажется, что у нас нет очень высоких основных характеристик (более 100 категорий), но у нас есть «Страна» с 42 категориями, а также «Профессия» с 15 категориями.

Однако это руководство применимо к любому номеру.

4 - Теперь давайте приступим к построению нашей модели: как было подчеркнуто ранее, проект предназначен для прогнозирования того, получит ли человек более или менее 50 тысяч долларов США на основе списка функций, и для этого мы будем создавать нейронную сеть в Tensorflow. 2.0, используя как категориальные, так и числовые функции.

Что мы будем делать :

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

То, что я сказал выше, означает следующее:

  • Сначала нам нужно встроить категориальные признаки (представить каждое из уникальных значений категориального признака вектором),
  • Для этого мы будем определять модель встраивания для каждой категориальной функции (которая является входным слоем плюс встраиваемым слоем),
  • Что касается других числовых функций, мы скормим их нашей модели, как мы обычно делаем для любой обычной сети глубокого обучения из этого последнего входного слоя.

Таким образом, в общей сложности будет иметься модели number_of_categorical_features +1 (модель внедрения number_of_categorical_feature + модель идентичности).

После того, как мы определим эти модели, и поскольку нам понадобится одна модель в конце, мы объединим их в один слой.

Итак, снова достаточно разговоров, и давайте поговорим о коде:

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

def prepar_data_set(data_df):
    categoy_features = data_df.select_dtypes('category').columns
    numerique_features = data_df.select_dtypes('number').columns
    for col in categoy_features:
        encoder = LabelEncoder()
        data_df[col] = encoder.fit_transform(data_df[col])
    return data_df,categoy_features,numerique_features

Функция получит категориальные характеристики и закодирует их одну за другой в целые числа и вернет 3 вещи: (i) закодированные данные, (ii) список категориальных характеристик и (iii) список числовых характеристик.

2 - Поскольку теперь у нас есть данные о наших поездах, а также метки, давайте построим архитектуру нашей модели:

Давайте нарушим этот кусок кода, приведенный выше:

2.1 - Как вы можете видеть, для каждой категории в наших категориальных функциях мы определяем входной слой, который принимает входные данные формы 1 (так как нашим входом будет значение категории, которое просто число),

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

2.3 - Затем мы определяем наш слой встраивания, который в основном представляет собой матрицу с несколькими строками и столбцами.

2.3.1 - Количество строк будет мощностью категориальных признаков (сколько уникальных значений),

2.3.2 - Количество столбцов будет предоставлено вектору, который будет представлять эти уникальные значения (которые являются параметрами, которые необходимо настроить). Для этого урока мы выбираем 200 (очень распространенное число для начала).

2.3.2 - Обратите внимание, что мы устанавливаем слой на Trainable. Поскольку мы инициализировали его только случайными числами, которые не представляют для нас никакой ценности, нам нужно, чтобы он продолжал обновляться во время обучения (обратное распространение).

2.3.3 - Наконец, мы должны преобразовать вывод в единый одномерный массив, который в основном будет иметь форму предоставленного вектора встраивания.

Итак, вот как мы определим наши модели встраивания number_of_categorical_feature (в данном случае 7 категориальных характеристик, которые означают 7 моделей встраивания).

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

num_input = tf.keras.layers.Input(shape=(len(num_features)),\
                                  name='input_number_features')
# append this model to the list of models
models.append(num_input)
# keep track of the input, we are going to feed them later to the #final model
inputs.append(num_input)

2.5 - Теперь, когда у нас есть 8 моделей (7 моделей внедрения и 1 модель идентичности), и мы все добавили их в список под названием модели, давайте объединим их в один слой:

merge_models= tf.keras.layers.concatenate(models)

2.6 - Теперь у нас есть один слой, который мы можем сложить поверх него - список полностью связанных слоев:

Как видите, мы построили 2 полностью связанных слоя по 1000 единиц в каждом поверх объединенных моделей. После этого мы добавили слои прогнозирования, которые будут возвращать вероятности того, что человек имеет более или менее 50 тысяч долларов США, и, наконец, мы скомпилировали нашу модель, чтобы минимизировать перекрестную энтропию с помощью оптимизатора adam, и точность как оценочная функция.

2.7 - Теперь последнее, что нужно передать в нашу модель.

Поскольку мы использовали нейронную сеть с несколькими входами, лучше всего использовать данные поезда в виде словаря, где ваши ключи - это имя входного слоя, а значения - это то, что ожидается на каждом слое. Итак, позвольте нам сделать это, чтобы вы могли понять, что я имею в виду:

input_dict= {
    'input_Workclass':train["Workclass"],
    "input_Marital_Status":train["Marital Status"],
    "input_Occupation":train["Occupation"],
    "input_Relationship":train["Relationship"],
    "input_Race":train["Race"],
    "input_Sex":train["Sex"],
    "input_Country":train["Country"],
    "input_number_features": train[num_featture]
}

Как видите, мы на 100% уверены, что отправляем правильные данные в правильную модель.

2.8 - И все, подойдем к нашей модели:

model.fit(input_dict,labels,epochs=50,batch_size=64)

И Вуаля, мы подошли к концу этого урока, надеюсь, он был достаточно ясным и практичным.

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

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
train[num_featture] = scaler.fit_transform(train[num_featture])

Надеюсь, вам понравился этот урок, скоро будет больше, так что следите за обновлениями.

ссылка на полный репозиторий кода: https://github.com/oussamaErra/tf-2-tutorial-categorical-features-embedding

Если вы нашли это руководство хорошим и практичным, не забудьте подписаться на меня на Medium, чтобы получить еще много хороших материалов по практическим наукам о данных и искусственному интеллекту.

А если у вас возникнут ко мне вопросы, вы можете связаться со мной напрямую через Linkedin или gmail (перечисленные ниже).

Обо мне

Я главный специалист по данным в Clever Ecommerce Inc, мы помогаем компаниям создавать и управлять кампаниями Google Рекламы с помощью мощной технологии, основанной на искусственном интеллекте.

Вы можете связаться со мной через Linkedin или gmail: [email protected].