Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

by n_kats_
1 / 40

自己紹介・近況

名前: 中西克典
所属: 有限会社 来栖川電算(バイト)
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

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


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

n_kats_
kurusugawa
「いいソフトウェアを楽に作る」技術を追求する企業。今は、機械学習、画像認識中心。
http://kurusugawa.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away