LoginSignup
1
0

More than 1 year has passed since last update.

TensorFlowでのtext.Tokenizerがうまく動かなかったのでtensorflow_textを使ってみた

Posted at

作業環境

Jupyter Notebook(6.1.4)を用いて作業を進めた。
各versionはpandas(1.1.3), tensorflow(2.5.0), tensorflow_datasets(4.3.0), tensorflow_text(2.5.0)である。

発生状況

TensorFlowについて学習中、文章データを読み込みそれをトークンに分割する場面が出てきた。調べたところtensorflow_datasetsパッケージの中にTokenizerクラスが含まれているようだったので以下を実行してみたところエラーになってしまった。

import tensorflow as tf
import tensorflow_datasets as tfds

tokenizer =tfds.features.text.Tokenizer()
#---> AttributeError: module 'tensorflow_datasets.core.features' has no attribute 'text'

どうやらもうこのクラスは利用できなくなっているようである。TensorFlowの公式ガイドを見てみると、text.Tokenizerがdeprecated(非推奨)のクラスの中に入っていることが確認できた。一応以下のようにすると(2021年8月17日現在では)まだ使えるようである。

tokenizer =tfds.deprecated.text.Tokenizer()
tokens = tokenizer.tokenize("What you know you can't explain, but you feel it.")
print(tokens)
#---> ['What', 'you', 'know', 'you', 'can', 't', 'explain', 'but', 'you', 'feel', 'it']

ただ非推奨なのでいつまで使えるのか不安ではある。そこで別の方法としてtensorflow_textを使用してみた。

tensorflow_textを使ってトークンに分割する

まずはプロンプトで以下のようにインストールを行った。

pip install tensorflow-text

GitHubで公開されているガイドから以下を実行して試してみた。

import tensorflow_text as tf_text

tokenizer = tf_text.WhitespaceTokenizer()
tokens = tokenizer.tokenize(["What you know you can't explain, but you feel it."])
print(tokens.to_list())
#---> [[b'What', b'you', b'know', b'you', b"can't", b'explain,', b'but', b'you', b'feel', b'it.']]

tokenizer = tf_text.UnicodeScriptTokenizer()
tokens = tokenizer.tokenize(["What you know you can't explain, but you feel it."])
print(tokens.to_list())
#---> [[b'What', b'you', b'know', b'you', b'can', b"'", b't', b'explain', b',', b'but', b'you', b'feel', b'it', b'.']]

1つ目のWhitespaceTokenizer()は単純にスペース区切りで一つの単語と認識し、2つ目のUnicodeScriptTokenizer()は記号も1つの単語として認識されている。

もともとやりたかったtext.Tokenizer()の結果と見比べてみると、

  • 区切り方はUnicodeScriptTokenizer()の方が近いが、記号もトークンとして認識されている
  • tensorflow_textでは一つ一つの単語がバイナリ表現で返ってきている
  • tensorflow_textではリストのリストとして返ってきている

といった違いがある。

そこでこれらを解消するために以下を実行してtext.Tokenizer()の結果に寄せてみた。

#「リストのリスト」状態を解消
l = tokens.to_list()[0]
#各要素をバイナリからstrへ変換
l = [s.decode('utf-8') for s in l]
#記号の削除
l = [i for i in l if not i in [',', '.', "'", '?', '!']]
l
#---> ['What', 'you', 'know', 'you', 'can', 't', 'explain', 'but', 'you', 'feel', 'it']

これで今回の文章については同じ結果を得ることができた。

課題

以下のような課題があげられる。

  • for文で実行しているのでかなり時間がかかる
  • 記号の削除の仕方が限定的

二番目については正規表現をうまく使えばもっと落とすべき表現を広範囲に指定できそうである。また、'is'などの頻出表現を消去するのもこのあたりでいじってもいいかもしれない。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0