doc2vecの結果をtensorboardで可視化


word2vecの結果をtensorboardで可視化する方法があったので、これはdoc2でもいけるんじゃないかと思いやってみた結果。

1.背景

上記のとおり、word2vecの結果をtensorboardで可視化すると、1個1個のプロットが
1ワードになっている。説明を読むと、「この可視化は単語の分散表現以外にも、ユニークなIDやラベルに対して固定長のベクトルが割り当てられていれば、一般的な特徴量やベクトル表現にも応用できます。」
とのことだったので、doc2vecも当てはまると思いやってみることに。

2.工夫した点

word2vecでは

weights = model.wv.vectors
labels = model.wv.index2word

とすればいい。
word2vecの1ワード毎の分散表現が wv.vectorsに、
word2vecの1ワード自体がwv.index2wordに
格納されている。

doc2vecでは

weights =[]
labels =[]
for i in range(0,len(model2.docvecs)):
    weights.append(model2.docvecs[i].tolist())
    labels.append(model2.docvecs.index_to_doctag(i)) #model2.docvecs

とする。

doc2vecでもwv.vectors,wv.index2wordが出力可能なので、ここでハマった。
(自分としてはtensorboardの可視化した1つの点が1つの文章として表示したかった)
そこでdoc2vecではdocvecsの中に
・1文章毎の分散表現が入っている
・見出し(tag)はindex_to_doctagに入っている
ことを発見したので、それらをそれぞれweights,labelsに入れるようにプログラムを作成した。
デフォルトではnumpy.arrayなのでtolistなどをする必要がある点も注意。

3.その他

出力してみた結果の図。イメージ通り。

tensorboardが可視化ツールとして面白そうと判明。

全体プログラム

import torch
import tensorboardX as tbx
from tensorboardX import SummaryWriter
writer = tbx.SummaryWriter()

#word2vecの場合
#weights = model2.wv.vectors
#labels = model2.wv.index2word

#doc2vecの場合
weights =[]
labels =[]
for i in range(0,len(model2.docvecs)):
    weights.append(model2.docvecs[i].tolist())
    labels.append(model2.docvecs.index_to_doctag(i)) #model2.docvecs

# DEBUG: visualize vectors up to 1000
weights = weights[:1000]
labels = labels[:1000]
writer.add_embedding(torch.FloatTensor(weights), metadata=labels)