Ragged Tensorsについて

[RaggedTensors](https://www.tensorflow.org/beta/guide/ragged_tensors)について調べたけど、pandas使えば同じ事ができそうで、使う場面がちょっと想定出来なかった。pandasに慣れてるひいき目か？

形の不定形なデータ（数値でも文字列でも）を入れて置けるそうで（下記は説明サイトから）。

    digits = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
    words = tf.ragged.constant([["So", "long"], ["thanks", "for", "all", "the", "fish"]])

特にありがたみがあるのが数値データに色々適用する場面の様子。


自分としては、1-gramと2-gramをまとめあげて1つにまとめられるのが良さげと思いました。

    queries = tf.ragged.constant([['Who', 'is', 'Dan', 'Smith'],
                              ['Pause'],
                              ['Will', 'it', 'rain', 'later', 'today']])

    # Create an embedding table.
    num_buckets = 1024
    embedding_size = 4
    embedding_table = tf.Variable(
        tf.random.truncated_normal([num_buckets, embedding_size],
                       stddev=1.0 / math.sqrt(embedding_size)))

    # Look up the embedding for each word.
    word_buckets = tf.strings.to_hash_bucket_fast(queries, num_buckets)
    word_embeddings = tf.ragged.map_flat_values(
        tf.nn.embedding_lookup, embedding_table, word_buckets)                  # ①

    # Add markers to the beginning and end of each sentence.
    marker = tf.fill([queries.nrows(), 1], '#')
    padded = tf.concat([marker, queries, marker], axis=1)                       # ②

    # Build word bigrams & look up embeddings.
    bigrams = tf.strings.join([padded[:, :-1],
                               padded[:, 1:]],
                              separator='+')                                # ③

    bigram_buckets = tf.strings.to_hash_bucket_fast(bigrams, num_buckets)
    bigram_embeddings = tf.ragged.map_flat_values(
        tf.nn.embedding_lookup, embedding_table, bigram_buckets)                # ④

    # Find the average embedding for each sentence
    all_embeddings = tf.concat([word_embeddings, bigram_embeddings], axis=1)    # ⑤
    avg_embedding = tf.reduce_mean(all_embeddings, axis=1)                      # ⑥
    print(avg_embedding)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/d1e98e3b-35e5-d8f2-69b1-2cde5305c7eb.png)





特に、最近公開された？[tf.Text](https://www.tensorflow.org/beta/tutorials/tensorflow_text/intro)を使えば
日本語であっても、[ここ](https://medium.com/tensorflow/introducing-tf-text-438c8552bd5e)のようにtensorflow_text.WordpieceTokenizerを使って処理可能そう。

    def _CreateTable(vocab, num_oov=1):init = tf.lookup.KeyValueTensorInitializer(
          vocab,
          tf.range(tf.size(vocab, out_type=tf.int64), dtype=tf.int64),
          key_dtype=tf.string,
          value_dtype=tf.int64)
      return tf.lookup.StaticVocabularyTable(
          init, num_oov, lookup_key_dtype=tf.string)

    vocab_table = _CreateTable(["すもも", "も", "もも","の", "うち"])

    tokens = ["すもも",も","もも","も","もも","の","うち"]
    tokenizer = tensorflow_text.WordpieceTokenizer(
        vocab_table, token_out_type=tf.string)
    result = tokenizer.tokenize(tokens)
    print(result.to_list())
    wp = result.to_list()



    [[b'\xe3\x81\x99\xe3\x82\x82\xe3\x82\x82'], [b'\xe3\x82\x82'], [b'\xe3\x82\x82\xe3\x82\x82'], [b'\xe3\x82\x82'], [b'\xe3\x82\x82\xe3\x82\x82'], [b'\xe3\x81\xae'], [b'\xe3\x81\x86\xe3\x81\xa1']]


これをそのまま、

    queries = tf.ragged.constant(wp)

とすれば、日本語も1-gramとbygramを結合して分散表現を得られそう。

tensorflowに投入するまではpandasでいろいろ処理しているけど、RaggedTensorを使えば
もっと早い段階からtensorflowで完結できるのかも。要検討。
Mecabやsentencepieceとシームレスに連携できると使いやすさが向上すると思うのでやりたいと
思います。
この辺もよく理解しておきたい。[Ragged vs sparse tensors](https://www.tensorflow.org/beta/guide/ragged_tensors#ragged_vs_sparse_tensors)
特にtf.Textと組み合わせれば強力なツールになるかもと期待してます。