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

自己紹介・近況

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

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


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


『 機械学習 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。