TensorFlow 2.0 : Beginner Tutorials : データのロードと前処理 :- TF.Text (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 10/08/2019
* 本ページは、TensorFlow org サイトの TF 2.0 – Beginner Tutorials – Load and preprocess data の以下のページを
翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ |
Facebook: https://www.facebook.com/ClassCatJP/ |
データのロードと前処理 :- TF.Text
イントロダクション
TensorFlow Text は TensorFlow 2.0 ですぐに使えるテキスト関連クラスと ops のコレクションを提供します。ライブラリはテキスト・ベースのモデルにより通常必要な前処理を遂行できてそしてコア TensorFlow で提供されないシークエンス・モデリングに有用な他の特徴を含みます。
貴方のテキスト前処理でこれらの ops を使用することの優位点はそれらは TensorFlow グラフで行なわれることです。推論時のトークン化とは異なる訓練のトークン化、あるいは前処理スクリプトの管理について心配する必要はありません、
Eager Execution
TensorFlow Text は TensorFlow 2.0 を必要とし、そして eager モードと graph モードと完全に互換です。
Note: 稀なケースとして、このインポートは TF ライブラリを探して失敗するかもしれません。ランタイムをリセットして上の (訳注: 原文ママ) pip install -q を再実行してください。
!pip install -q tensorflow-text
DEPRECATION: Python 3.4 support has been deprecated. pip 19.1 will be the last one supporting it. Please upgrade your Python as Python 3.4 won't be maintained after March 2019 (cf PEP 429).
import tensorflow as tf import tensorflow_text as text
Unicode
殆どの ops は文字列が UTF-8 にあることを想定しています。異なるエンコーディングを使用している場合、UTF-8 にコード変換するためにコア tensorflow transcode op を使用できます。もし貴方の入力が妥当でないかもしれない場合には、文字列を構造的に妥当な UTF-8 に強制するために同じ op を使用することもできます。
docs = tf.constant([u'Everything not saved will be lost.'.encode('UTF-16-BE'), u'Sad☹'.encode('UTF-16-BE')]) utf8_docs = tf.strings.unicode_transcode(docs, input_encoding='UTF-16-BE', output_encoding='UTF-8')
トークン化
トークン化は文字列をトークンに分解するプロセスです。一般には、これらのトークンは単語、数字、and/or 句読点です。
主要なインターフェイスは Tokenizer と TokenizerWithOffsets です、これらはそれぞれ単一のメソッド tokenize と tokenize_with_offsets を持ちます。現在利用可能な複数の tokenizer があります。これらの各々は TokenizerWithOffsets (これは Tokenizer を拡張します) を実装します、これは元の文字列へのバイトオフセットを得るためのオプションを含みます。これは呼び出し側にトークンがそれから作成された元の文字列でのバイトを知ることを可能にします。
tokenizer の総ては元の個々の文字列へマッピングするトークンの最奥の次元を持つ RaggedTensor を返します。その結果、結果としての shape の rank は一つ増やされます。ragged tensor ガイドをレビューしてください、それらに馴染みがないのであれば。https://www.tensorflow.org/guide/ragged_tensors
WhitespaceTokenizer
これは ICU 定義された空白文字 (eg. スペース、タブ、改行) 上で UTF-8 文字列を分割する基本的な tokenizer です。
tokenizer = text.WhitespaceTokenizer() tokens = tokenizer.tokenize(['everything not saved will be lost.', u'Sad☹'.encode('UTF-8')]) print(tokens.to_list())
WARNING: Logging before flag parsing goes to stderr. W0701 13:16:14.667488 140633166759744 deprecation.py:323] From /tmpfs/src/tf_docs_env/lib/python3.4/site-packages/tensorflow/python/util/dispatch.py:180: batch_gather (from tensorflow.python.ops.array_ops) is deprecated and will be removed after 2017-10-25. Instructions for updating: `tf.batch_gather` is deprecated, please use `tf.gather` with `batch_dims` instead. W0701 13:16:14.671800 140633166759744 deprecation.py:323] From /tmpfs/src/tf_docs_env/lib/python3.4/site-packages/tensorflow/python/ops/array_ops.py:1340: add_dispatch_support.<locals>.wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version. Instructions for updating: Use tf.where in 2.0, which has the same broadcast rule as np.where [[b'everything', b'not', b'saved', b'will', b'be', b'lost.'], [b'Sad\xe2\x98\xb9']]
UnicodeScriptTokenizer
tokenizer は Unicode スクリプト境界に基づいて UTF-8 文字列を分割します。使用されるスクリプトコードは International Components for Unicode (ICU) UScriptCode 値に対応します。参照: http://icu-project.org/apiref/icu4c/uscript_8h.html
実際には、これは WhitespaceTokenizer に類似しています、最も明白な差異はそれは言語テキスト (eg. USCRIPT_LATIN, USCRIPT_CYRILLIC, etc) から句読点 (USCRIPT_COMMON) を分割することです、互いに言語テキストもまた分ける一方で。
tokenizer = text.UnicodeScriptTokenizer() tokens = tokenizer.tokenize(['everything not saved will be lost.', u'Sad☹'.encode('UTF-8')]) print(tokens.to_list())
[[b'everything', b'not', b'saved', b'will', b'be', b'lost', b'.'], [b'Sad', b'\xe2\x98\xb9']]
Unicode 分割 (= split)
単語をセグメントするための空白なしで言語をトークン化するとき、文字で単に分割することは一般的です、これはコアで見つかる unicode_split op を使用して成されます。
tokens = tf.strings.unicode_split([u"仅今年前".encode('UTF-8')], 'UTF-8') print(tokens.to_list())
[[b'\xe4\xbb\x85', b'\xe4\xbb\x8a', b'\xe5\xb9\xb4', b'\xe5\x89\x8d']]
オフセット
文字列をトークン化するとき、トークンが元の文字列のどこに由来するかを知ることはしばしば望まれます。このため、TokenizerWithOffsets を実装する各 tokenizer は tokenize_with_offsets メソッドを持ちます、これはトークンと一緒にバイトオフセットを返します。offset_starts は元の文字列で各トークンが始まるバイトをリストして、offset_limits は各トークンが終わるバイトをリストします。
tokenizer = text.UnicodeScriptTokenizer() (tokens, offset_starts, offset_limits) = tokenizer.tokenize_with_offsets(['everything not saved will be lost.', u'Sad☹'.encode('UTF-8')]) print(tokens.to_list()) print(offset_starts.to_list()) print(offset_limits.to_list())
[[b'everything', b'not', b'saved', b'will', b'be', b'lost', b'.'], [b'Sad', b'\xe2\x98\xb9']] [[0, 11, 15, 21, 26, 29, 33], [0, 3]] [[10, 14, 20, 25, 28, 33, 34], [3, 6]]
TF.Data サンプル
tokenizer は tf.data API と共に期待どおりに動作します。下で単純な例が提供されます。
docs = tf.data.Dataset.from_tensor_slices([['Never tell me the odds.'], ["It's a trap!"]]) tokenizer = text.WhitespaceTokenizer() tokenized_docs = docs.map(lambda x: tokenizer.tokenize(x)) iterator = iter(tokenized_docs) print(next(iterator).to_list()) print(next(iterator).to_list())
[[b'Never', b'tell', b'me', b'the', b'odds.']] [[b"It's", b'a', b'trap!']]
他の Text ops
TF.Text は他の有用な前処理 ops をパッケージ化しています。下で 2, 3 をレビューします。
Wordshape
幾つかの自然言語理解モデルで使用される一般的な特徴はテキスト文字列が特定のプロパティを持つかを見ることです。例えば、センテンス分解モデルは単語の大文字化 (= capitalization) や句読点文字が文字列の最後にあるかを確認する特徴を含むかもしれません。
Wordshape は貴方の入力テキストの様々な関連パターンのための様々な有用な正規表現ベースのヘルパー関数を定義します。ここに 2, 3 のサンプルがあります。
tokenizer = text.WhitespaceTokenizer() tokens = tokenizer.tokenize(['Everything not saved will be lost.', u'Sad☹'.encode('UTF-8')]) # Is capitalized? f1 = text.wordshape(tokens, text.WordShape.HAS_TITLE_CASE) # Are all letters uppercased? f2 = text.wordshape(tokens, text.WordShape.IS_UPPERCASE) # Does the token contain punctuation? f3 = text.wordshape(tokens, text.WordShape.HAS_SOME_PUNCT_OR_SYMBOL) # Is the token a number? f4 = text.wordshape(tokens, text.WordShape.IS_NUMERIC_VALUE) print(f1.to_list()) print(f2.to_list()) print(f3.to_list()) print(f4.to_list())
[[True, False, False, False, False, False], [True]] [[False, False, False, False, False, False], [False]] [[False, False, False, False, False, True], [True]] [[False, False, False, False, False, False], [False]]
N-gram & スライディング・ウィンドウ
N-gram はスライディング・ウィンドウのサイズ n が与えられたときのシーケンシャルな単語です。トークンを結合するとき、サポートされる 3 つのリダクション・メカニズムがあります。テキストのためには、Reduction.STRING_JOIN を使用することを望むでしょう、これは文字列を互いに付加します。デフォルトのセパレータ文字はスペースですが、これは string_separater 引数で変更できます。
他の 2 つのリダクション・メソッドは殆どの場合数値とともに使用されます、そしてこれらは Reduction.SUM と Reduction.MEAN です。
tokenizer = text.WhitespaceTokenizer() tokens = tokenizer.tokenize(['Everything not saved will be lost.', u'Sad☹'.encode('UTF-8')]) # Ngrams, in this case bi-gram (n = 2) bigrams = text.ngrams(tokens, 2, reduction_type=text.Reduction.STRING_JOIN) print(bigrams.to_list())
[[b'Everything not', b'not saved', b'saved will', b'will be', b'be lost.'], []]
以上