2

我有一個像post標籤的功能。因此,對於每個觀察,post_tag功能可能是諸如「oscars,brad-pitt,awards」等標籤的選擇。我希望能夠通過運行在谷歌雲機器學習上的估算器API(根據this example,但適用於我自己的問題)將此作爲特徵傳遞給張量流模型構建。tensoflow中的多重編碼(谷歌雲機器學習,tf estimator api)

我只是不確定如何將其轉換爲張量流中的多熱點編碼特徵。我試圖在sklearn中獲得類似於MultiLabelBinarizer的東西。

我認爲this是有點關係,但不是我所需要的。

所以說,我有這樣的數據:

id,post_tag 
1,[oscars,brad-pitt,awards] 
2,[oscars,film,reviews] 
3,[matt-damon,bourne] 

我想特徵化它,因爲tensorflow內預處理的一部分,如:

id,post_tag_oscars,post_tag_brad_pitt,post_tag_awards,post_tag_film,post_tag_reviews,post_tag_matt_damon,post_tag_bourne 
1,1,1,1,0,0,0,0 
2,1,0,0,1,1,0,0 
3,0,0,0,0,0,1,1 

更新

如果我有post_tag_list在輸入csv中是一個類似「oscars,brad-pitt,awards」的字符串。如果我嘗試那麼做:

INPUT_COLUMNS = [ 
... 
tf.contrib.lookup.HashTable(tf.contrib.lookup.KeyValueTensorInitializer('post_tag_list', 
              tf.range(0, 10, dtype=tf.int64), 
              tf.string, tf.int64), 
          default_value=10, name='post_tag_list'), 
...] 

我得到這個錯誤:

Traceback (most recent call last): 
    File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main 
    "__main__", fname, loader, pkg_name) 
    File "/usr/lib/python2.7/runpy.py", line 72, in _run_code 
    exec code in run_globals 
    File "/home/andrew_maguire/localDev/codeBase/pmc-analytical-data-mart/clickmodel/trainer/task.py", line 4, in <module> 
    import model 
    File "trainer/model.py", line 49, in <module> 
    default_value=10, name='post_tag_list'), 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/lookup_ops.py", line 276, in __init__ 
    super(HashTable, self).__init__(table_ref, default_value, initializer) 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/lookup_ops.py", line 162, in __init__ 
    self._init = initializer.initialize(self) 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/lookup_ops.py", line 348, in initialize 
    table.table_ref, self._keys, self._values, name=scope) 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/gen_lookup_ops.py", line 205, in _initialize_table_v2 
    values=values, name=name) 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/op_def_library.py", line 767, in apply_op 
    op_def=op_def) 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 2632, in create_op 
    set_shapes_for_outputs(ret) 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 1911, in set_shapes_for_outputs 
    shapes = shape_func(op) 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", line 1861, in call_with_requiring 
    return call_cpp_shape_fn(op, require_shape_fn=True) 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/common_shapes.py", line 595, in call_cpp_shape_fn 
    require_shape_fn) 
    File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/common_shapes.py", line 659, in _call_cpp_shape_fn_impl 
    raise ValueError(err.message) 
ValueError: Shape must be rank 1 but is rank 0 for 'key_value_init' (op: 'InitializeTableV2') with input shapes: [], [], [10]. 

如果我是來填充每個post_tag_list要像「奧斯卡,布拉德 - 皮特,獎勵,其他,其他,其他,其他,其他,其他,其他「,所以它總是10個長。這是否是一個可能的解決方案?

或者我需要以某種方式知道我可能會在這裏傳遞的所有帖子標籤的大小(有點不適合定義爲新創建的所有時間)。

+0

所有標籤的集合的基數是多少? – rhaertel80

+1

它實際上是開放式的。當有人創建帖子時,如果他們找不到現有的帖子,他們也可以創建新的標籤。到目前爲止,它大約有7k,我們試圖鼓勵它們不要製作新標籤,但是它們是開放式的,意味着新的新聞故事是否會突破新的標籤,從而獲得新的標籤。所以可能實際上將標籤視爲與帖子標題類似的詞並將其放入嵌入空間可能更合適。我正在對標籤和帖子進行doc2vec培訓,並將這些向量作爲密集特徵傳遞。希望有標籤假人用於廣泛的山谷。 – andrewm4894

+1

以前看不見的標籤將被映射到一個或多個「看不見」的權重向量。所以7K就是我所需要的 - 主要是數量級。 – rhaertel80

回答

1

您是否試過tf.contrib.lookup.Hashtable?

這裏是我自己用的一個實例:https://github.com/TensorLab/tensorfx/blob/master/src/data/_transforms.py#L160和由例如片段基礎上認爲:

import tensorflow as tf 
session = tf.InteractiveSession() 

entries = ['red', 'blue', 'green'] 
table = tf.contrib.lookup.HashTable(
    tf.contrib.lookup.KeyValueTensorInitializer(entries, 
               tf.range(0, len(entries), dtype=tf.int64), 
               tf.string, tf.int64), 
    default_value=len(entries), name='entries') 
tf.tables_initializer().run() 

value = tf.constant([['blue', 'red'], ['green', 'red']]) 
print(table.lookup(value).eval()) 

我相信查找同時適用於常規張量和SparseTensors(你可能最終與後者給出你的可變長度值列表)。

+0

太棒了 - 看起來完全像我所需要的,謝謝。我只是需要玩弄一下,弄清楚我怎樣才能將csv中的字符串變成像你的例子中那樣的「red | blue | green」。所以我想''post_tags = post_tag_list.split(「|」)''然後像'INPUT_COLUMNS = [ ... tf.contrib.lookup.KeyValueTensorInitializer('post_tags', tf.range(0,len (post_tags),dtype = tf.int64), tf.string,tf.int64), ... ]' – andrewm4894

+0

ugh ..'Traceback(最近調用最後一個): 文件「/ usr/lib/python2 0.7/runpy.py」,線174,在_run_module_as_main 「__main__」,FNAME,裝載機,程序包名稱) 文件 「/usr/lib/python2.7/runpy.py」,線路72,在_run_code EXEC代碼在run_globals 文件「/home/andrew_maguire/localDev/codeBase/pmc-analytical-data-mart/clickmodel/trainer/task.py」,第4行,在 導入模型 文件 「教練/ model.py」 32行,在 post_tags = post_tag_list.split( 「|」) NameError:名字 'post_tag_list' 不是defined' – andrewm4894

+0

我不知道如果我能做到的.split(「|」)定義INPUT_COLUMNS。但不太清楚讀取[post_tag_list]字段的類型(看起來像「red | green | blue」),因此它最終會像列表中的實體一樣列表,然後可以傳遞給hashtable() – andrewm4894

1

這裏有幾個問題需要解決。首先,關於一個不斷增長的標籤集的問題。您還想知道如何解析CSV中的可變長度數據。

要處理不斷增長的標記集,您需要使用OOV或函數散列。 Nikhil展示了後者,所以我會展示前者。

如何從CSV

解析可變長度數據

讓我們假設列可變長度的數據使用|作爲分隔符,例如

csv = [ 
    "1,oscars|brad-pitt|awards", 
    "2,oscars|film|reviews", 
    "3,matt-damon|bourne", 
] 

您可以使用類似代碼將其轉換爲SparseTensor

import tensorflow as tf 

# Purposefully omitting "bourne" to demonstrate OOV mappings. 
TAG_SET = ["oscars", "brad-pitt", "awards", "film", "reviews", "matt-damon"] 
NUM_OOV = 1 

def sparse_from_csv(csv): 
    ids, post_tags_str = tf.decode_csv(csv, [[-1], [""]]) 
    table = tf.contrib.lookup.index_table_from_tensor(
     mapping=TAG_SET, num_oov_buckets=NUM_OOV, default_value=-1) 
    split_tags = tf.string_split(post_tags_str, "|") 
    return ids, tf.SparseTensor(
     indices=split_tags.indices, 
     values=table.lookup(split_tags.values), 
     dense_shape=split_tags.dense_shape) 

# Optionally create an embedding for this. 
TAG_EMBEDDING_DIM = 3 

ids, tags = sparse_from_csv(csv) 

embedding_params = tf.Variable(tf.truncated_normal([len(TAG_SET) + NUM_OOV, TAG_EMBEDDING_DIM])) 
embedded_tags = tf.nn.embedding_lookup_sparse(embedding_params, sp_ids=tags, sp_weights=None) 

# Test it out 
with tf.Session() as s: 
    s.run([tf.global_variables_initializer(), tf.tables_initializer()]) 
    print(s.run([ids, embedded_tags])) 

你會看到像這樣的輸出(因爲嵌入是隨機的,確切的數字會發生變化):

[array([1, 2, 3], dtype=int32), array([[ 0.16852427, 0.26074541, -0.4237918 ], 
     [-0.38550434, 0.32314634, 0.858069 ], 
     [ 0.19339906, -0.24429649, -0.08393878]], dtype=float32)] 

你可以看到,在CSV每一列表示爲ndarray,其中標籤現在是三維嵌入。

+0

非常感謝你 - 這是非常有用的。將嘗試並納入,讓你知道我如何得到。 – andrewm4894