Как извлечь векторные представления категориальных переменных

Вопрос или проблема

Я немного запутался с кодированием категориальных переменных. Есть другие посты/блог-посты по этой теме, но ни один из них не обсуждает проблему, с которой я сталкиваюсь.

У меня есть набор данных со смешанными переменными (то есть числовыми и категориальными). Некоторые из категориальных переменных имеют много категорий (почти 100). Поэтому вместо использования One Hot encoders, я ищу возможность использовать эмбеддинги.

Моя цель: использовать эмбеддинги категориальных переменных, извлечь их и объединить с моими числовыми переменными, чтобы сформировать матрицу дизайна/обучения, а затем запустить автокодировщик на этом (причина запуска автокодировщика – обнаружение аномальных данных).

Я собрал небольшой фрагмент кода (см. ниже), но что меня путает, так это как извлечь эмбеддинги, чтобы объединить их с моими числовыми переменными. Мне нужно знать это, потому что когда появляются новые данные, мне нужны эмбеддинги, чтобы запустить их через предсказание для изоляции любых “странных” точек данных от ошибки реконструкции.

from keras.models import Model
from keras.layers import Input, Dense, Concatenate, Reshape, Dropout
from keras.layers.embeddings import Embedding

inputs = []
embeddings = []

# для категориальных переменных
for cat in cat_model_vars:
    inp = Input(shape=(1,))
    inputs.append(inp)
    emb = Embedding(cat_sizes[cat]+1,cat_embedding_size[cat], input_length=1,name=f"{cat}_embedding")(inp)
    emb = Reshape(target_shape=(cat_embedding_size[cat],))(emb)
    embeddings.append(emb)

# для непрерывных/числовых переменных

inp_num = Input(shape=(len(num_model_vars),),name="cont_vars")
emb_num = Dense(10)(inp_num)
inputs.append(inp_num)
embeddings.append(emb_num)

# объединить эмбеддинги, это будет входом в нашу модель автокодировщика
output = Concatenate()(embeddings)

#%%

# построить стековый автокодировщик ниже и передать выход как его вход и выход

en_x = Dense(50, activation = 'relu')(output)
en_x = Dense(32, activation = 'relu')(en_x)
en_x = Dense(16, activation = 'relu')(en_x)
en_x = Dense(4, activation = 'relu')(en_x)

de_x = Dense(16, activation = 'relu')(en_x)
de_x = Dense(32, activation = 'relu')(de_x)
de_x = Dense(50, activation = 'relu')(de_x)

output = Dense(25, activation = 'relu')(de_x)

stacked_ae_model = Model(inputs, output)
stacked_ae_model.compile(loss="mean_squared_error",optimizer="Adam",
                         metrics=['mse','mape'])

"""НЕОБХОДИМО ИЗВЛЕЧЬ ЭМБЕДДИНГИ, КОТОРЫЕ ИСПОЛЬЗУЮТСЯ В КАЧЕСТВЕ ВХОДА ДЛЯ СТЕКОВОГО АВТОКОДИРОВЩИКА (НЕ СДЕЛАНО ЕЩЕ)"""

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

Любая помощь будет весьма признательна.

Спасибо и всего доброго.

Если у вас есть модель с несколькими входами, вы должны передать dataframe в модель в виде словаря строк. Разделите dataframe на 2 dataframe – категориальные и числовые.
Категориальный dataframe преобразуйте в словарь с помощью train_df.to_dict('list') и объедините в нем числовой dataframe как 1 многомерную переменную с именем “cont_vars”.
Также вы должны дать имена всем входным колонкам:

for cat in cat_model_vars:
   inp = Input(shape=(1,), name=cat)

inp_num = Input(shape=(len(num_model_vars),),name="cont_vars")

Обновите dataframe (не тестировалось):

train_df2 = train_df[cat_model_vars]
train_df2['cont_vars'] = train_df[cont_model_vars].values.tolist()
train_df = train_df2

Пример преобразования pandas dataframes в тензоры:

test_data = tf.data.Dataset.from_tensor_slices(test_df.to_dict('list')).batch(BATCH_SIZE).cache()
train_data = tf.data.Dataset.from_tensor_slices((train_df.to_dict('list'), labels)).shuffle(10000).batch(BATCH_SIZE, drop_remainder=True).cache()

Наконец, обучите и предскажите модель:

model.fit(train_data, epochs=100)
y_pred_test = model.predict(test_data, batch_size=BATCH_SIZE)

Ответ или решение

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

Шаг 1: Подготовка данных

В первую очередь, вам нужно разбить ваш набор данных на категориальные и числовые переменные. Убедитесь, что вы правильно определили все необходимые переменные.

# Разделите данные на категориальные и числовые переменные
cat_df = train_df[cat_model_vars]
num_df = train_df[num_model_vars]

Шаг 2: Создание словаря из данных

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

cat_dict = cat_df.to_dict('list')
num_array = num_df.values.tolist()
cat_dict['cont_vars'] = num_array

Шаг 3: Определение модели

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

# Определение входных слоев для категориальных переменных
inputs = []
embeddings = []

for cat in cat_model_vars:
    inp = Input(shape=(1,), name=cat)
    inputs.append(inp)
    emb = Embedding(cat_sizes[cat]+1, cat_embedding_size[cat], input_length=1, name=f"{cat}_embedding")(inp)
    emb = Reshape(target_shape=(cat_embedding_size[cat],))(emb)
    embeddings.append(emb)

# Входной слой для числовых переменных
inp_num = Input(shape=(len(num_model_vars),), name="cont_vars")
emb_num = Dense(10)(inp_num)
inputs.append(inp_num)
embeddings.append(emb_num)

# Конкатенация эмбеддингов
output = Concatenate()(embeddings)

# Строительство стека автоэнкодера
en_x = Dense(50, activation='relu')(output)
en_x = Dense(32, activation='relu')(en_x)
en_x = Dense(16, activation='relu')(en_x)
de_x = Dense(32, activation='relu')(en_x)
de_x = Dense(50, activation='relu')(de_x)
output = Dense(len(cat_model_vars) * max(cat_embedding_size.values()) + 10, activation='relu')(de_x)

stacked_ae_model = Model(inputs, output)
stacked_ae_model.compile(loss="mean_squared_error", optimizer="Adam", metrics=['mse', 'mape'])

Шаг 4: Подготовка данных для обучения и прогноза

Теперь важно превратить ваши данные в формат, который может быть использован моделью. Для этого вы можете установить TensorFlow Dataset:

import tensorflow as tf

train_data = tf.data.Dataset.from_tensor_slices(cat_dict).batch(BATCH_SIZE).cache()

Шаг 5: Обучение модели

Обучите вашу модель с использованием подготовленных данных:

stacked_ae_model.fit(train_data, epochs=100)

Шаг 6: Извлечение эмбеддингов

Чтобы извлечь эмбеддинги, вам нужно создать вспомогательную модель, которая будет использовать эмбеддинговые слои как выходы. Вы можете сделать это следующим образом:

# Создание модели для извлечения эмбеддингов
embedding_model = Model(inputs, embeddings)

# Извлечение эмбеддингов из обучающего набора
train_embeddings = embedding_model.predict(train_data)

# Для новой информации используйте модель для предсказания
new_data_embeds = embedding_model.predict(new_data)

Заключение

Теперь вы имеете все необходимые инструменты для извлечения эмбеддингов категориальных переменных и их использования вместе с числовыми переменными для анализа данных с помощью автоэнкодера. Обязательно следите за тем, чтобы все новые данные также преобразовывались в тот же формат перед обработкой. Успехов в ваших экспериментах!

Оцените материал
Добавить комментарий

Капча загружается...