通过feature_columns将自由文本功能引入具有数据集API的Tensorflow Canned Estimat



我正在尝试建立一个提供reddit_score = f('subreddit','comment')的模型

这主要是作为一个例子,然后我可以为一个工作项目进行构建。

我的代码在这里。

我的问题是我看到预设估计器(例如 DNNLinearCombinedRegressor)必须具有属于FeatureColumn类的feature_columns。

我有我的词汇文件,并且知道如果我只限制在评论的第一个单词,我可以做类似的事情

tf.feature_column.categorical_column_with_vocabulary_file(
key='comment',
vocabulary_file='{}/vocab.csv'.format(INPUT_DIR)
)

但是,如果我从注释中传入前 10 个单词,那么我不确定如何从像"this is a pre padded 10 word comment xyzpadxyz xyzpadxyz"这样的字符串转到feature_column,以便我可以构建一个嵌入以传递给deep特征在一个广泛而深入的模型中。

似乎它一定是非常明显或简单的东西,但我一生都找不到任何具有这种特定设置的现有示例(罐装广泛和深度、数据集 API 以及混合功能,例如 subreddit 和原始文本功能,如评论)。

我什至考虑自己进行词汇整数查找,以便我传入的comment特征类似于 [23,45,67,12,1,345,7,99,999,999,999],然后也许我可以通过带有形状的numeric_feature将其输入,然后从那里对其进行处理。但这感觉有点奇怪。

您可以使用 tf.string_split(),然后执行 tf.slice() 对其进行切片,首先注意 tf.pad() 带有零的字符串。查看以下位置的标题预处理操作: https://towardsdatascience.com/how-to-do-text-classification-using-tensorflow-word-embeddings-and-cnn-edae13b3e575

有了单词后,您可以创建十个特征列

根据帖子中的方法添加答案 @Lak 做了,但针对数据集 API 进行了一些调整。

# Create an input function reading a file using the Dataset API
# Then provide the results to the Estimator API
def read_dataset(prefix, mode, batch_size):
def _input_fn():
def decode_csv(value_column):
columns = tf.decode_csv(value_column, field_delim='|', record_defaults=DEFAULTS)
features = dict(zip(CSV_COLUMNS, columns))
features['comment_words'] = tf.string_split([features['comment']])
features['comment_words'] = tf.sparse_tensor_to_dense(features['comment_words'], default_value=PADWORD)
features['comment_padding'] = tf.constant([[0,0],[0,MAX_DOCUMENT_LENGTH]])
features['comment_padded'] = tf.pad(features['comment_words'], features['comment_padding'])
features['comment_sliced'] = tf.slice(features['comment_padded'], [0,0], [-1, MAX_DOCUMENT_LENGTH])
features['comment_words'] = tf.pad(features['comment_sliced'], features['comment_padding'])
features['comment_words'] = tf.slice(features['comment_words'],[0,0],[-1,MAX_DOCUMENT_LENGTH])
features.pop('comment_padding')
features.pop('comment_padded')
features.pop('comment_sliced')
label = features.pop(LABEL_COLUMN)
return features, label
# Use prefix to create file path
file_path = '{}/{}*{}*'.format(INPUT_DIR, prefix, PATTERN)
# Create list of files that match pattern
file_list = tf.gfile.Glob(file_path)
# Create dataset from file list
dataset = (tf.data.TextLineDataset(file_list)  # Read text file
.map(decode_csv))  # Transform each elem by applying decode_csv fn
tf.logging.info("...dataset.output_types={}".format(dataset.output_types))
tf.logging.info("...dataset.output_shapes={}".format(dataset.output_shapes))
if mode == tf.estimator.ModeKeys.TRAIN:
num_epochs = None # indefinitely
dataset = dataset.shuffle(buffer_size = 10 * batch_size)
else:
num_epochs = 1 # end-of-input after this
dataset = dataset.repeat(num_epochs).batch(batch_size)
return dataset.make_one_shot_iterator().get_next()
return _input_fn

然后在下面的函数中,我们可以引用我们作为decode_csv()的一部分创建的字段:

# Define feature columns
def get_wide_deep():
EMBEDDING_SIZE = 10
# Define column types
subreddit = tf.feature_column.categorical_column_with_vocabulary_list('subreddit', ['news', 'ireland', 'pics'])
comment_embeds = tf.feature_column.embedding_column(
categorical_column = tf.feature_column.categorical_column_with_vocabulary_file(
key='comment_words',
vocabulary_file='{}/vocab.csv-00000-of-00001'.format(INPUT_DIR),
vocabulary_size=100
),
dimension = EMBEDDING_SIZE
)
# Sparse columns are wide, have a linear relationship with the output
wide = [ subreddit ]
# Continuous columns are deep, have a complex relationship with the output
deep = [ comment_embeds ]
return wide, deep

最新更新