post Image
トピックモデルを操作 ~Interactive Topic Model~

Interactive Topic Modelの実装、及びその結果


はじめに

自然言語処理の技術で、文書集合から内容を抽出する方法としてトピックモデルという考え方がある。

その中でも、トピック内で出現する単語を意図的に操作する方法として、Interactive Topic Modelというものが存在する。

そこで、本記事ではInteractive Topic Modelの実装とその効果の検証を行う。


手法


トピックモデル

トピックモデルでは文書集合から、トピック(例えば、新聞記事には政治やスポーツなどのトピックが含まれていると推測される)が出現する確率、トピック分布$\theta$と、そのトピック内でどのような単語が出やすいか、単語分布$\phi$を推定する手法である。

トピックモデルの説明は、

http://qiita.com/GushiSnow/items/8156d440540b0a11dfe6

http://statmodeling.hatenablog.com/entry/topic-model-4

あたりの資料がわかりやすいので参照してください。


Latent Dirichlet Allocation(LDA)

様々あるトピックモデルの中でも、Latent Dirichlet Allocation(LDA)が一番有名である。

LDAでは、1つの文書(新聞記事)の中に、複数のトピックが存在(政治やニュースなど)し、それぞれのトピックが異なる単語分布を持つと考える。

グラフィカルモデルは下記の図の通り

LDA.png

ちなみに$\theta$はトピック分布、$\phi$は単語分布、$z$は文書内の単語に割り当てられるトピック、$v$は文書内の単語、$N$は文書内の単語数、$D$は文書数、$K$はトピック数、$\alpha$、$\beta$はハイパーパラメータです。

LDAの計算には、ギブスサンプリングや、変分ベイズが使えるが、崩壊型ギブスサンプリング(CGS)が一番有名?である。

崩壊型ギブスサンプリングでLDAを計算する際の疑似コードは下記の通り



N_dk = 0 # 文書d内でトピックkが割り当てられている単語の数
N_kv = 0 # トピックk内で単語vが出現した回数
N_k = 0 # トピックkが割り当てられた単語の数
d = 1, …, D # 文書番号
k = 1, …, K # トピック番号
v = 1, …, V # 語彙番号

initialize(z_dn) # 文書d内、n番目の単語のトピックをランダムに初期化

repeat
for d = 1, …, D do
for n = 1, …, N_d do # N_dは文書d内で使用されている単語数

N_d[k=z_dn] -= 1 # カウントから引く
N_[k=z_dn][v=w_n] -= 1
N_[k=z_dn] -= 1

for k = 1, …, K do
cal(p(z_dn = k)) # 文書d内のn番目の単語にトピックkが割り当てられる確率を計算
endfor

z_dn ~ Categorical(p(z_dn)) # z_dnのトピックをサンプリング

N_d[k=z_dn] += 1 # 新しく割り当てられたトピックをカウント
N_[k=z_dn][v=w_n] += 1
N_[k=z_dn] += 1

endfor
endfor
until 終了条件を満たすまで

疑似コード内の$p(z_{dn} = k)$になる確率を計算は、以下のようにする。

p(z_{dn}=k) \propto (N_{dk}+\alpha)\frac{N_{kw_{dn}}+\beta}{N_k+\beta V}

で計算できる。


Interactive Topic Model(ITM)

LDAでトピックの計算をすると、この単語とこの単語は一緒のトピックになって欲しいのに・・・ということがある。

この問題に対して、単語Aと単語Bは同じトピックから出るようにしてください、と制約をかけることで取り組むことができる。

それがInteractive Topic Model(ITM)

http://dl.acm.org/citation.cfm?id=2002505

感覚的な説明をすると、ITMでは、制約をかけた単語同士を1つの単語と考え、その単語の出現確率を等分配することで、制約をかけた単語同士を、同じトピックで出やすくする。

スクリーンショット 2017-02-16 16.12.51.png

※ Interactive Topic Modelの論文より

計算は簡単で、LDAの$p(z_{dn} = k)$を計算する式を以下のように書き換える。

p(z_{dn} = k) \propto \begin{cases}

(N_{dk}+\alpha)\frac{N_{kw_{dn}}+\beta}{N_k+\beta V} \;\;\;\;(w_{dn} \notin \Omega)\\
(N_{dk}+\alpha)\frac{N_{k\Omega}+|\Omega|\beta}{N_k+\beta V}\frac{W_{k\Omega w_{dn}}+\eta}{W_{k \Omega} + |\Omega|\eta} \;\;\;\;(w_{dn} \in \Omega)

\end{cases}

ただし、$\Omega$は制約であり、$|\Omega|$は制約内に含まれる単語数、$N_{k\Omega}$はトピック$k$で制約$\Omega$が出てきた回数、$W_{k\Omega w_{dn}}$はトピックkに割り当てられた制約$\Omega$の中で単語 $w_{dn}$が出てきた回数を表している。

つまり、単語 $w_{dn}$が制約$\Omega$に含まれていなければ、LDAと同じ式で、含まれていたら下の式でp(z_{dn} = k)を計算すれば良い。


実験

実験ではITMの精度検証を行う。


データセット

データセットには、livedoorコーパスを用いた。http://bookmarks2022.blogspot.jp/2015/06/livedoor.html


コード

ITMのコードはここに

https://github.com/kenchin110100/machine_learning/blob/master/sampleITM.py


実験結果

トピック数 $K = 10$、$\alpha = 0.1$、$\beta = 0.01$、$\eta = 100$に固定

まずは制約なしで50iteration分(つまり普通のLDAと同じ)

各トピック内での出現単語の上位は下記の表の通り

トピック1

トピック2

トピック3

トピック4

トピック5

機能

アプリ

女性

作品

日本

発売

搭載

ゴルフ

映画

更新

更新

画面

自分

153

関連

記事

smartphone

男性

181

世界

利用

発表

結婚

監督

人気

デジ

対応

多い

公開

映画

関連

マックス株式会社

相手

3

http://

smartphone

Android

仕事

96

自分

ソフトウェア

表示

クリスマス

13

話題

ユーザー

2012年

女子



すごい

これだけでもそれなりのトピックが見れます。

次に表内の青地の単語が同じトピックになるように制約をかけて

さらに50iteration回します。

トピック1

トピック2

トピック3

トピック4

トピック5

発売

アプリ

女性

153

映画

利用

搭載

自分

181

日本

機能

smartphone

ゴルフ

3

作品

更新

発表

男性

96

公開

記事

対応

結婚

13

世界

サービス



多い

552

監督

関連

マックス株式会社

相手

144

関連

デジ

Android

仕事

310

特集

ソフトウェア

表示

クリスマス

98

http://

情報

2012年

いい

ヒーロー

すごい

制約をかけた青文字の単語がトピック5に共通して出現していますね。


まとめ

Interactive Topic Model(ITM)により、単語に制約をかけてトピック分布の推定をしました。

載せた内容は一見良さそうに見えますが、実は何回のトライアンドエラーした結果・・・

ITMはジャーナルも出ているので、そっちの内容を実装すればもっと精度が良くなるかもしれませんね。


『 Python 』Article List