はじめに
Genismで言葉のベクトル化を試してみようと思いました。
適当に使ってたらびっくりするほど動作が遅い(10分くらいかかったイメージ)という問題があり、ちょっと調べたら.txtのテキストデータとしてそのまま使っているのが問題でした。バイナリファイルに変換したらすっげぇ早くなったので共有します。
おそらくQiita見てる人にはあたりまえのことなんでしょうけど、、。備忘録代わりに。
そもそもでGenism入れるのも厄介でしたが、一先ずなんとかできました。
PCの性能
ご参考までにPCの性能を。
win10
i7 6700
gtx1080ti
ddr4 2133 32gb
厄介だったこと
まず、ja.binという学習データをダウンロードしたんですが、これが古いGenism(v3.??)でしか使うことができませんでした。
で、その古いGenismにダウングレードしようとしたら、Pythonのバージョンの関係で不可能でした。
そこで、とりあえず別の有名そうなデータを使おうと、jawiki.all_vectors.100d.txt.bz2というものを使うことにしました。
DL元: https://github.com/singletongue/WikiEntVec/releases
で、インストールして使おうとしました。
サンプルコードは以下の通り。
from gensim.models import KeyedVectors
# テキスト形式のベクトルを読み込む
model_path = 'jawiki.all_vectors.100d.txt'
wv = KeyedVectors.load_word2vec_format(model_path, binary=False)
# 確認
print(wv.vector_size)
# 次元数(100)
print(wv.most_similar('森林')) # 類似語の例
これがやっかいで、10分くらいかかりました。
そこそこ性能の良いPCを使っているのでびっくりしたわけですが、タスクマネージャー見てもあまりメモリもCPUも使用していないのでおかしいなと思いました。
で、GPT君に聞いたら、バイナリ化すれば早いよとのことでした。
以下に変換コードを。
from gensim.models import KeyedVectors
# 初回のみ:テキスト形式を読み込み
wv = KeyedVectors.load_word2vec_format('jawiki.all_vectors.100d.txt', binary=False)
# バイナリ形式で保存(次回から高速読み込み)
wv.save('jawiki_100d.kv')
この後に、以下のように参照元のデータを書き換えればすっごい早くなりました(数秒)。
うれしいです。
from gensim.models import KeyedVectors
# テキスト形式のベクトルを読み込む
wv = KeyedVectors.load('jawiki_100d.kv')
# 確認
print(wv.vector_size) # 次元数(100)
print(wv.most_similar('森林')) # 類似語の例
なお、参考までに出力結果を以下の通りに。
100
[('##森林##', 0.8718230724334717),
('自然環境', 0.8439704179763794),
('植生', 0.8354340195655823),
('林業', 0.825136125087738),
('山林', 0.7933074831962585),
('草地', 0.7923843860626221),
('林地', 0.7900059223175049),
('湿地', 0.7892200946807861),
('##原生林##', 0.782494068145752),
('自然保護', 0.780893862247467)]
まとめ
冷静に考えると.txtファイルから情報を読み込むのが早いわけなかったです。
バイナリってすごい。
あんまよくわかってないんですけどバイナリ状態で配ってはいけないんですかね?まじで無知なんでよくわからないんですが、、。
.kzち.binの違いもわからないですし、学びが足りませんね、、。