Edited at

doc2vecをしてみた(機械学習名古屋第13回勉強会)

More than 1 year has passed since last update.


自己紹介・近況

名前: 中西克典

所属: 有限会社 来栖川電算(バイト)

twitter: @n_kats_

昔は数学をしていた。

数週間前、全脳アーキテクチャ若手の会 関西異分野交流会なるものに参加するも、学生さんばかりで浮いていた気がする。



内容


  • 経緯

  • pythonでdoc2vecをする方法

  • 実際に使った話



経緯


先輩「好みの小説を探したいから小説をベクトル化してくれ」



最初の案


  • word2vecで単語をベクトルにして平均を取る?


  • タグやジャンルを推測する?



最初の案はダメ


  • 単純な平均じゃ意味のあるベクトルが取れる気がしない

  • 先輩「タグやジャンルよりもっと細かい検索がしたい」



doc2vecがあるやん!



doc2vecとは

文章をベクトルに変換する機械学習アルゴリズム

word2vecの進化形



不安要素


  • 小説みたいな長い文章も大丈夫?

  • doc2vecって技術的な評価はどうなっているの?強いの?

とりあえず、やってみよう

(この疑問は解決していません)



doc2vecの話



調べたこと


  • doc2vecのアルゴリズム

  • pythonでお手軽にdoc2vecが試せるパッケージ「gensim」



doc2vecの前にword2vecについて

word2vecは、単語をベクトルに変換。

文章の中でその単語の近くに出る単語の確率を学習するモデル。(雑)


\text{単語} \rightarrow \text{ベクトル} \rightarrow \text{近くの単語の確率}

左の矢印の部分が単語のベクトル化



doc2vecでは

\begin{align}

\text{単語} \rightarrow \text{ベクトル} \rightarrow &
\text{足したベクトル} &
\leftarrow \text{ベクトル} \leftarrow \text{文章} \\
& \downarrow & \\
& \text{近くの単語の確率} &
\end{align}

単語だけでなく、文章をベクトル化して、その単語の近くの単語を予想



未知の文章には?

word2vecでは、頻度の高いものだけベクトル化できればOK。未知の単語は重要ではない。(雑)

通常、ベクトル化したい文章は学習データの文章と一致しない。

最適化で実現



最適化で未知の文章をベクトル化


f(\text{単語のベクトル}, \text{文章のベクトル}) = \text{近くの単語の確率}

単語のベクトルは固定したまま、文章のベクトルだけ学習(最適化)

以上がdoc2vecのアルゴリズム



pythonでdoc2vec



gensim

https://radimrehurek.com/gensim/

(GNU LGPLv2.1 license)

自然言語に関する機械学習ライブラリ



学習の流れ


  1. 文章を用意する

  2. 単語に分解

  3. 単語を登録

  4. 学習



文章を用意する

gensimはしてくれないので、自分で頑張る。

学習用データとなる文章を十分に多く用意する。

素朴に、一行に一つの文章を書いたテキストファイルで十分。



単語に分解

文章を単語のリストにする。


  • 短い・長すぎる単語、頻度の低い・高すぎる単語、を削除

  • mecabなどで分かち書きへ変換

  • 扱う文章データ固有の前処理

gensimではsimple_preprocessという関数がある。

import gensim

gensim.utils.simple_preprocess("This is a document.")
# ['this', 'is', 'document']



学習データの入力

文章のID(何個目の文章かなど)と、単語に分割された文章をTaggedDocumentという形式で入力する。

from gensim.models.doc2vec import TaggedDocument

TaggedDocument(単語に分解された文章, [文章のID])



doc2vecのモデルを作成

from gensim.models import Doc2Vec

model = Doc2Vec(size=ベクトルの次元)

引数は色々指定できる(公式ドキュメント



単語の登録

build_vocabメソッドを使う。

model.build_vocab(train_corpus)

# train_corpusは、TaggedDocumentのリスト



学習

学習はtrainメソッドを呼ぶだけ。

model.train(

train_corpus,
total_examples=model.corpus_count,
epochs=50)



文章のベクトル化

infer_vectorメソッドを使う

model.infer_vector(preprocess(document))

# preprocessは前処理を行う関数



まとめると

from gensim.models.doc2vec import TaggedDocument

from gensim.utils import simple_preprocess as preprocess
from gensim.models import Doc2Vec

# 学習データ読み込み
train_data = ... # 学習文章データのパスに置き換えてください
assert train_data != ...

train_corpus = [
TaggedDocument(preprocess(doc), [i])
for i, doc in enumerate(open(train_data))]

# モデル作成
model = Doc2Vec(size=50)
model.build_vocab(train_corpus)
# 学習
model.train(train_corpus, total_examples=model.corpus_count, epochs=10)

print(model.infer_vector(preprocess("This is a document.")))



使用例


文章ベクトルで近傍探索

ベクトルが近い文章を探す

result = model.docvecs.most_similar([vec])

# modelは上で学習したmodel
# vecは入力の文章のベクトル
# resultは文章のIDとスコア(どれだけ近いか)の対のリスト



使ってみた



目標

doc2vecで論文のabstractをベクトル化してそ、論文の近傍探索したい


  • この論文に近い論文はこれだ、読んでみよう

  • 最近投稿された論文で、よく参照するような論文と近いのはこれだ

  • 別ジャンルだけど、似たようなことを扱っているものを見つける

みたいな使い方をしたい



現状

まだまだ開発中

https://github.com/n-kats/arxiv2vec


  • ベクトル化や近傍探索は試せる

  • いい感じに近い論文が出てきているかは怪しい



日本語の小説は・・・


  • 分かち書きが必要

  • 頼まれたけど自分が小説を読まない

という理由で不採用



文章を用意する

arXivにある論文のabstractを利用

APIを叩いて適当な分野の論文の情報を取得

一行に一つの論文のabstract文章が書かれたテキストファイルを用意



課題

abstractは数式混じりの文章

For an oriented link $L \subset S^3 = \Bd\!D^4$, let $\chi_s(L)$ be the greatest 

Euler characteristic $\chi(F)$ of an oriented 2-manifold $F$ (without closed components)
smoothly embedded in $D^4$ with boundary $L$.

等式も\$で囲われるし、一文字のものも\$で囲われる

例は、https://arxiv.org/abs/math/9307233から。いい加減に選んだだけです。



単語に分解


数式部分を隔離する

$\TeX$では、例えば、\$記号で囲った部分を数式部分と解釈される

空白が無しで、foo$y=f(x)$barのように単語と数式がくっついていることがあるのをfoo + $y=f(x)$ + barのように数式部分の前後を単語の切り目として切る



後は適当に学習



ベクトルの近傍探索の例

入力: Resnetの論文のアブストラクト

結果:

1位 0.7645617723464966

Deep Residual Learning for Image Recognition
http://arxiv.org/abs/1512.03385v1

2位 0.6277217268943787
DiracNets: Training Very Deep Neural Networks Without Skip-Connections
http://arxiv.org/abs/1706.00388v1

3位 0.614996075630188
The Reversible Residual Network: Backpropagation Without Storing Activations
http://arxiv.org/abs/1707.04585v1



4位 0.6054012775421143
Truncating Wide Networks using Binary Tree Architectures
http://arxiv.org/abs/1704.00509v1

5位 0.602472186088562
Places205-VGGNet Models for Scene Recognition
http://arxiv.org/abs/1508.01667v1

6位 0.5984947085380554
Densely Connected Convolutional Networks
http://arxiv.org/abs/1608.06993v4

7位 0.5884192585945129
Face Detection with the Faster R-CNN
http://arxiv.org/abs/1606.03473v1


8位 0.5854528546333313

Deep Residual Networks with Exponential Linear Unit
http://arxiv.org/abs/1604.04112v4

9位 0.581209123134613
Wide Residual Networks
http://arxiv.org/abs/1605.07146v4

10位 0.5765923857688904
Inception-v4, Inception-ResNet and the Impact of Residual onnections on Learning
http://arxiv.org/abs/1602.07261v2

画像分類系の論文が見つかりました!



ご清聴ありがとうございました