gensimのLdaModel実行時に「too few updates ~」 と怒られた時
投稿の練習,昨日Qiitaで書いたやつ.
なんすかこれ...
passesかiterationsをいじればいいっぽいけど
数値計算のパラメタ調整とか中身知らないので本当に怖い.
model_lda = LdaModel(corpus=corpus, num_topics=30, id2word=corpus.id2word) WARNING:gensim.models.ldamodel:too few updates, training might not converge; consider increasing the number of passes or iterations to improve accuracy
ソースコードを見てみる
問題はinit最後に実行されるupdateメソッド616行付近
if updates_per_pass * passes < 10: logger.warning("too few updates, training might not converge; consider " "increasing the number of passes or iterations to improve accuracy")
passesは LdaModelのinitパラメタpassesをそのまま使ってる.
デフォルトで1が代入されている.
updates_per_pass... むむむ...
updateメソッド内_607行らへん
updates_per_pass = max(1, lencorpus / updateafter)
lencorpusはupdateメソッドの585行目付近で len(corpus)の値が代入されている.
要は文書数.この警告が出ている時の文章数は4019.
updateafter...
updateメソッド内_599行目あたり
if update_every: updatetype = "online" updateafter = min(lencorpus, update_every * self.numworkers * chunksize) else: updatetype = "batch" updateafter = lencorpus
updateメソッドの引数指定が無いなら,
update_everyには,initパラメタupdate_everyと同じものが代入される.初期値は1.
updatetypeはonlineになる.
self.numworkersには,initパラメタdistributedがFalseのままなら1が入っている.
chunksizeは...
updateメソッド内_たぶん595行
chunksize = min(lencorpus, self.chunksize)
self.chunksizeはinitパラメタchunksizeとおなじ.デフォルトは2000.
つまり...
updateafter = min(4019, 112000) = 2000
updates_per_pass = max(1, 4019 / 2000) ≒ 2
で,ifの左の評価式は 2*1 になる.アウト.
対策は
・passesを増やす.今回の場合ではpasses=5で怒られなくなる.
・updateafterを小さくする=update_everyかchunksizeを小さくする.
_今回の場合でchunksizeだけを変えるなら400ぐらいにしたら怒られなくなる.
このパラメタについては疲れたので別の日に調べます.