📄

GiNZA 5 (=SudachiPy >= 0.6)で49149 bytes以上のテキストをTokenizeする

2022/03/29に公開

1. GiNZA(というかSudachiPy)でデカ目のテキストファイルがTokenizeできなかった話

講談社サイエンティフィク 実践Data ScienceシリーズPythonではじめるテキストアナリティクス入門を勉強中。
(この本、雑に理解していたGiNZA、spaCy、Sudachiの処理が体系的に理解出来てとてもありがたい)。

サンプルコードは GiNZA==4.0.6SudachiPy==0.5.4 環境での利用が推奨されている。

GiNZAのバージョン上げたら、スピードアップするかしら? と思い試しに、サンプルコードをGiNZA 5.1環境で実行したところ、江戸川乱歩作「影男」のテキストをTokenizeするコードで下記のエラー。

Exception: Tokenization error: Input is too long, it can't be more than 49149 bytes, was 464332

2. 原因

SudachiのSlack検索させていただいたところ、内部のコスト計算でオーバフローが起こるため、入力サイズに制限を掛けているとの説明あり。
どのバージョンからの変更なのかは不明だが、 GiNZA==5.1 + SudachiPy==0.6.3 の環境では上記エラー発生。
GiNZA==4.0.6SudachiPy==0.5.4 環境の環境ではエラーおきず。

3. 一時的解決策

入力ファイルの分割が推奨とのことだったので、textを .readlines で一行ずつ読み込みlistに格納。適当な単位(今回は100要素)でテキストを塊(Chunk)に分割してlistに格納。chunkから要素を取り出して、tokenize処理してみた。

import spacy

input_fn = 'text/kageotoko.corpus.txt'

nlp = spacy.load("ja_ginza")

with open(input_fn) as f:
    lines = f.readlines()

chunks = [' '.join(lines[i:i+100]) for i in range(0, len(lines), 100)]

for chunk in chunks:
    doc = nlp(chunk)
    for ## 以下処理省略

4. 将来の課題

分割してtokenizeした後のDocオブジェクトをまとめておけるDocBinというオブジェクトもあるようなので、今後必要になったら、使ってみよう。

https://spacy.io/api/docbin#_title

Discussion

ログインするとコメントできます