Пересекающиеся списки строк в Tensorflow tf.feature_column.crossed_column

У меня есть две особенности post_tags а также user_tags, Это дополненные строки из N и M слов соответственно.

Так, например, мы могли бы иметь post_tag являющийся "the-oscars brad-pitt xyzpadxyz xyzpadxyz xyzpadxyz", Так что этот пост был помечен как Оскар и Брэд Питт.

Тогда для user_tag мы могли бы иметь "brad-pitt universal sag the-academy-awards xyzpadxyz xyzpadxyz xyzpadxyz xyzpadxyz xyzpadxyz xyzpadxyz"

user_tag Вот образец тегов из последних 20 сообщений, использованных пользователем.

Так post_tag всегда 5 меток и user_tag всегда 10 меток

Я разделяю каждую строку на тензор как часть обработки API набора данных следующим образом:

features['post_tag'] = tf.string_split([features['post_tag']])
features['post_tag'] = tf.sparse_tensor_to_dense(features['post_tag'], default_value=PADWORD)
features['user_tag'] = tf.string_split([features['post_tag']])
features['user_tag'] = tf.sparse_tensor_to_dense(features['post_tag'], default_value=PADWORD)

У меня есть Vocab-файл для тегов, и я добавляю каждую функцию в глубокие функции широкого и глубокого консервативного оценщика.

user_tag = tf.feature_column.categorical_column_with_vocabulary_file(
            key='user_tag',
            vocabulary_file='{}/tagvocab.csv'.format(INPUT_DIR)
            )
user_tag_embed = tf.feature_column.embedding_column(
        categorical_column = user_tag ,
        dimension = USER_TAG_EMBEDDING_SIZE
        )
deep.append(user_tag_embed)

post_tag = tf.feature_column.categorical_column_with_vocabulary_file(
                key='post_tag',
                vocabulary_file='{}/tagvocab.csv'.format(INPUT_DIR)
                )
    post_tag _embed = tf.feature_column.embedding_column(
            categorical_column = post_tag ,
            dimension = POST_TAG_EMBEDDING_SIZE
            )
    deep.append(post_tag_embed)

Это работает, однако, что я действительно хочу сделать, это сделать крест post_tag а также user_tag, Но если я сделаю что-то вроде этого:

user_post_tag_cross = tf.feature_column.crossed_column(
        keys = [user_tag, post_tag],
        hash_bucket_size = 25
        )
wide.append(user_post_tag_cross)

Я получаю эту ошибку:

InvalidArgumentError (see above for traceback): Expected D2 of index to be 2 got 3 at position 0

Я вижу, что это идет от этой строки в коде TF

У меня такое чувство, что скрещивание тензоров может оказаться невозможным, или оно ожидает только две строки. У меня есть связанные функции, которые post_tag_first а также user_tag_first которые являются только одним случайным тегом и просто передаются в виде строк. Тогда, если я сделаю:

user_post_first_tag_cross = tf.feature_column.crossed_column(
            keys = ['user_tag_first', 'post_tag_first'],
            hash_bucket_size = 25
            )
wide.append(user_post_first_tag_cross)

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

У кого-нибудь есть идеи - я бы подумал, что это что-то, с чем кто-то мог иметь дело раньше, так как данные тегов вроде этого довольно распространены, или это могут быть поисковые термины и условия документа, ключевые слова и т. Д.

Обновление - небольшой воспроизводимый пример

Вот небольшой исполняемый пример, который устанавливает, что я хочу сделать.

import tensorflow as tf
import numpy as np

# set up tag vocab
tag_vocab = ['brad-pitt','usa','donald-trump','tpb','tensorflow','xyzpadxyz','UNK']

# make data

# train data
user_tag_train = np.random.choice(tag_vocab,50).reshape((5, 10)) # 5 example rows with 10 tags per user
post_tag_train = np.random.choice(tag_vocab,25).reshape((5, 5)) # 5 example rows with 5 tags per post
x_train = np.array([1., 2., 3., 4., 5.]) # just another example numeric feature
y_train = np.array([0., -1., -2., -3., -4]) # outcome

# eval data
user_tag_eval = np.random.choice(tag_vocab,50).reshape((5, 10)) # 5 example rows with 10 tags per user
post_tag_eval = np.random.choice(tag_vocab,25).reshape((5, 5)) # 5 example rows with 5 tags per post
x_eval = np.array([2., 5., 8., 1., 5.])
y_eval = np.array([-1.01, -4.1, -7, 0., 9.])

# define feature cols

x_num = tf.feature_column.numeric_column("x", shape=[1])

user_tag_cat = tf.feature_column.categorical_column_with_vocabulary_list(
    key = 'user_tag',
    vocabulary_list = tag_vocab)

user_tag_embed = tf.feature_column.embedding_column(
    categorical_column = user_tag_cat,
    dimension = 3
)

post_tag_cat = tf.feature_column.categorical_column_with_vocabulary_list(
    key = 'post_tag',
    vocabulary_list = tag_vocab)

post_tag_embed = tf.feature_column.embedding_column(
    categorical_column = post_tag_cat,
    dimension = 2
)

user_post_tag_cross = tf.feature_column.crossed_column(
    keys = [ user_tag_cat, post_tag_cat ],
    hash_bucket_size = 5
)

#user_post_tag_embed_cross = tf.feature_column.crossed_column(
#    keys = [ user_tag_embed, post_tag_embed ],
#    hash_bucket_size = 5
#)

feature_columns = [
  x_num,
  user_tag_cat,
  post_tag_cat,
  user_tag_embed,
  post_tag_embed,
  user_post_tag_cross,
  #user_post_tag_embed_cross,
  ]

estimator = tf.estimator.LinearRegressor(feature_columns=feature_columns)

input_fn = tf.estimator.inputs.numpy_input_fn(
    {
      "x": x_train,
      "user_tag": user_tag_train,
      "post_tag": post_tag_train,
    }, 
    y_train, 
    batch_size=5, 
    num_epochs=None, 
    shuffle=True
    )

train_input_fn = tf.estimator.inputs.numpy_input_fn(
    {
      "x": x_train,
      "user_tag": user_tag_train,
      "post_tag": post_tag_train,
      }, 
    y_train, 
    batch_size=5, 
    num_epochs=1000, 
    shuffle=False
    )

eval_input_fn = tf.estimator.inputs.numpy_input_fn(
    {
      "x": x_eval,
      "user_tag": user_tag_eval,
      "post_tag": post_tag_eval
      }, 
    y_eval, 
    batch_size=5, 
    num_epochs=1000, 
    shuffle=False
    )

estimator.train(input_fn=input_fn, steps=1000)

train_metrics = estimator.evaluate(input_fn=train_input_fn)

eval_metrics = estimator.evaluate(input_fn=eval_input_fn)

print("\n\ntrain metrics: %r"% train_metrics)
print("eval metrics: %r"% eval_metrics)

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

ValueError: Unsupported key type. All keys must be either string, or categorical column except _HashedCategoricalColumn. Given: _EmbeddingColumn(categorical_column=_VocabularyListCategoricalColumn(key='user_tag', vocabulary_list=('brad-pitt', 'usa', 'donald-trump', 'tpb', 'tensorflow', 'xyzpadxyz', 'UNK'), dtype=tf.string, default_value=-1, num_oov_buckets=0), dimension=3, combiner='mean', initializer=<tensorflow.python.ops.init_ops.TruncatedNormal object at 0x0000021C9AA14860>, ckpt_to_load_from=None, tensor_name_in_ckpt=None, max_norm=None, trainable=True)

На самом деле я не думаю, что смогу сделать user_post_tag_cross так как тэг vocab составляет ~40k (я был удивлен, что это сработало здесь, так как я думаю, что именно это привело к ошибке, с которой я связан выше - возможно, это связано с тем, когда вы пытаетесь скрестить двух кошек с большими вокабами).

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

0 ответов

Другие вопросы по тегам