Python で LDAトピック分析手習い 〜 参考ウェブサイトのコード を 写経して、gensimモジュールを使うやり方を1ステップごと、確認してみた

  • 26
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Pythonでトピック分析を行う手習いまで、以下の記事所収コードを写経して、手元で実行してみた際の記録。

【 教科書ウェブサイト 】

以下、写経して、1ステップごと、内容確認しながら手元で動かしてみます。


Python3
pwd
# '/Users/hirofumi.yashima/Desktop/corpus'

ls
# Untitled.ipynb  corpus.txt      sample.txt

( コーパス・ファイルの中身 )

  • NHK NEWS WEB 掲載のニュース記事 より 一部抜粋 して使用
corpus.txt
4 sample.txt\n'
プロ 野球 ・ 巨人 は 、 去年 10月 に 発覚 し た 選手 3 人 が 関わっ た 野球 賭博 問題 で 、 8 日 、 新た に プロ 5 年 目 の 高木 京介 投手 も 賭博 に 関わっ た 疑い が 強まっ た こと の 責任 を 取っ て 、 球団 の 渡辺 恒雄 最高 顧問 、 白石 興 二 郎 オーナー 、 そして 桃井 恒和 球団 会長 が 辞任 する 意向 を 明らか に し まし た 。 
プロ 野球 、 巨人 は 選手 3 人 が 関わっ た 野球 賭博 問題 で 、 新た に プロ 5 年 目 の 高木 京介 投手 も 賭博 に 関わっ た 疑い が 強まっ た として NPB = 日本 野球 機構 の 熊崎 勝彦 コミッショナー に 告発 する こと を 明らか に し まし た 。 巨人 は この 問題 の 責任 を 取っ て 、 渡辺 恒雄 最高 顧問 、 白石 興 二 郎 オーナー 、 桃井 恒和 球団 会長 の 3 人 が 辞任 する 意向 で ある こと を 発表 し まし た 。 
巨人 は 8 日 夜 、 緊急 の 記者 会見 を 開き 、 久保 博 球団 社長 が 新た に プロ 5 年 目 の 高木 京介 投手 も 賭博 に 関わっ て い た 疑い が 強まっ た こと を 明らか に し まし た 。 巨人 に より ます と 、 先月 2 9 日 、 高木 投手 の 野球 賭博 へ の 関与 について 週刊 誌 の 取材 が あっ た こと から 調査 を 始め まし た 。 調査 に対して 、 高木 投手 は 当初 、 野球 賭博 を 行っ て 無期 失格 の 処分 を 受け た 笠原 将 生 投手 に 名前 を 貸し た だけ と 関与 を 否定 し まし た 。 
安倍 総理 大臣 は 、 総理 大臣 官邸 で 非 正規 雇用 で 働く 人 たち と 面談 し 、 「 働き 方 を 選択 できる 社会 を 作り 、 選択 によって 不利 に なら ない よう に し なけれ ば なら ない 」 と 述べ 、 同 一 労働 同 一 賃金 の 実現 に 意欲 を 示し まし た 。 安倍 総理 大臣 は 、 8 日 午後 総理 大臣 官邸 で 、 パート や 契約 社員 など として 働い て いる 9 人 と 意見 を 交わし まし た 。 この 中 で 、 安倍 総理 大臣 は 「 働き 方 を 選択 できる 社会 を 作り 、 選択 によって 不利 に なら ない よう に し なけれ ば なら ない 。 非 正規 と 正規 の 壁 を 見直し 、 同 一 労働 同 一 賃金 に 踏み込み たい と 考え て おり 、 必要 で あれ ば ちゅうちょ なく 法 改正 を し たい 」 と 述べ 、 同 一 労働 同 一 賃金 の 実現 に 意欲 を 示し まし た 。 

gensimモジュール の LowCorpusメソッド で、テキストファイルを読み込む

( 上記メソッドについては、教科書ウェブサイトに、以下のように説明されています。 )

辞書とコーパスの構築をまとめて行う

上の例では辞書とコーパスの構築を個別に行なっていました

辞書とコーパスの構築をまとめてやるための便利なクラスとしていくつかのクラスが用意されています
簡単に使えそうなものを2つ紹介します

以下のような形式で分割された単語が得られていればgensim.corpora.lowcorpus.LowCorpusを使って読み込めます

gensim: corpora.lowcorpus – Corpus in List-of-Words format
文数
文1の単語1 文1の単語2 文1の単語3
文2の単語1 文2の単語2

複雑な処理をする場合にはgensim.corpora.textcorpus.TextCorpusが用意されています。

LowCorpusメソッド で、テキストファイルを読み込み実行

Python3
import gensim
corpus = gensim.corpora.lowcorpus.LowCorpus('corpus.txt')
  • ( 実行結果 )
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-148ff036de15> in <module>()
----> 1 corpus = gensim.corpora.lowcorpus.LowCorpus('corpus.txt')

/Users/hirofumi.yashima/anaconda/lib/python3.5/site-packages/gensim/corpora/lowcorpus.py in __init__(self, fname, id2word, line2words)
     68         self.fname = fname # input file, see class doc for format
     69         self.line2words = line2words # how to translate lines into words (simply split on space by default)
---> 70         self.num_docs = self._calculate_num_docs()
     71 
     72         if not id2word:

/Users/hirofumi.yashima/anaconda/lib/python3.5/site-packages/gensim/corpora/lowcorpus.py in _calculate_num_docs(self)
     92         with utils.smart_open(self.fname) as fin:
     93             try:
---> 94                 result = int(next(fin))
     95             except StopIteration:
     96                 result = 0

ValueError: invalid literal for int() with base 10: b'       4 sample.txt\n'

テキストエディタで開いて、1行目に記述された文字列「sample.txt」 を 消した

( 修正後のコーパス・ファイル中身 )

corpus.txt
4
プロ 野球 ・ 巨人 は 、 去年 10月 に 発覚 し た 選手 3 人 が 関わっ た 野球 賭博 問題 で 、 8 日 、 新た に プロ 5 年 目 の 高木 京介 投手 も 賭博 に 関わっ た 疑い が 強まっ た こと の 責任 を 取っ て 、 球団 の 渡辺 恒雄 最高 顧問 、 白石 興 二 郎 オーナー 、 そして 桃井 恒和 球団 会長 が 辞任 する 意向 を 明らか に し まし た 。 
プロ 野球 、 巨人 は 選手 3 人 が 関わっ た 野球 賭博 問題 で 、 新た に プロ 5 年 目 の 高木 京介 投手 も 賭博 に 関わっ た 疑い が 強まっ た として NPB = 日本 野球 機構 の 熊崎 勝彦 コミッショナー に 告発 する こと を 明らか に し まし た 。 巨人 は この 問題 の 責任 を 取っ て 、 渡辺 恒雄 最高 顧問 、 白石 興 二 郎 オーナー 、 桃井 恒和 球団 会長 の 3 人 が 辞任 する 意向 で ある こと を 発表 し まし た 。 
巨人 は 8 日 夜 、 緊急 の 記者 会見 を 開き 、 久保 博 球団 社長 が 新た に プロ 5 年 目 の 高木 京介 投手 も 賭博 に 関わっ て い た 疑い が 強まっ た こと を 明らか に し まし た 。 巨人 に より ます と 、 先月 2 9 日 、 高木 投手 の 野球 賭博 へ の 関与 について 週刊 誌 の 取材 が あっ た こと から 調査 を 始め まし た 。 調査 に対して 、 高木 投手 は 当初 、 野球 賭博 を 行っ て 無期 失格 の 処分 を 受け た 笠原 将 生 投手 に 名前 を 貸し た だけ と 関与 を 否定 し まし た 。 
安倍 総理 大臣 は 、 総理 大臣 官邸 で 非 正規 雇用 で 働く 人 たち と 面談 し 、 「 働き 方 を 選択 できる 社会 を 作り 、 選択 によって 不利 に なら ない よう に し なけれ ば なら ない 」 と 述べ 、 同 一 労働 同 一 賃金 の 実現 に 意欲 を 示し まし た 。 安倍 総理 大臣 は 、 8 日 午後 総理 大臣 官邸 で 、 パート や 契約 社員 など として 働い て いる 9 人 と 意見 を 交わし まし た 。 この 中 で 、 安倍 総理 大臣 は 「 働き 方 を 選択 できる 社会 を 作り 、 選択 によって 不利 に なら ない よう に し なけれ ば なら ない 。 非 正規 と 正規 の 壁 を 見直し 、 同 一 労働 同 一 賃金 に 踏み込み たい と 考え て おり 、 必要 で あれ ば ちゅうちょ なく 法 改正 を し たい 」 と 述べ 、 同 一 労働 同 一 賃金 の 実現 に 意欲 を 示し まし た 。 

LowCorpusメソッド で、テキストファイル読み込み(再試行)

Python3
corpus = gensim.corpora.lowcorpus.LowCorpus('corpus.txt')
print(corpus)
  • ( 実行結果 )
<gensim.corpora.lowcorpus.LowCorpus object at 0x105f23d30>

gensim の LdaModelメソッド に 生成したcorpus を 渡して、LDAモデルを生成

Python3
lda = gensim.models.ldamodel.LdaModel(corpus=corpus, num_topics=20, id2word=corpus.id2word)
  • ( 実行結果 )
WARNING:gensim.models.ldamodel:too few updates, training might not converge; consider increasing the number of passes or iterations to improve accuracy
Python3
print(lda)
  • Ldamodelインスタンス が 生成されている
LdaModel(num_terms=165, num_topics=20, decay=0.5, chunksize=2000)

どのような内容をもつトピック群が生成されたか、トピックごとに、各トピックを構成するトークン集合をみてみる

  • LdaModelクラス の show_topics インスタンス・メソッドを用いる
  • 各トピック における 各トークン の出現確率が係数として表示される
Python3
for topic in lda.show_topics(-1):
    print(topic)

( 出力結果 )

(0, '0.042*、 + 0.036*を + 0.029*一 + 0.029*と + 0.028*同 + 0.024*に + 0.023*大臣 + 0.021*なら + 0.021*総理 + 0.020*し')
(1, '0.047*、 + 0.045*を + 0.043*に + 0.040*た + 0.035*の + 0.025*まし + 0.024*投手 + 0.023*。 + 0.021*し + 0.020*と')
(2, '0.006*、 + 0.006*に + 0.006*た + 0.006*を + 0.006*の + 0.006*し + 0.006*が + 0.006*。 + 0.006*野球 + 0.006*まし')
(3, '0.006*に + 0.006*、 + 0.006*た + 0.006*の + 0.006*を + 0.006*が + 0.006*し + 0.006*野球 + 0.006*プロ + 0.006*賭博')
(4, '0.048*、 + 0.041*を + 0.027*と + 0.026*同 + 0.026*総理 + 0.026*に + 0.024*で + 0.023*大臣 + 0.023*一 + 0.021*ない')
(5, '0.006*た + 0.006*、 + 0.006*に + 0.006*が + 0.006*の + 0.006*し + 0.006*賭博 + 0.006*プロ + 0.006*球団 + 0.006*関わっ')
(6, '0.056*た + 0.054*、 + 0.045*に + 0.034*の + 0.034*が + 0.029*を + 0.024*し + 0.022*野球 + 0.020*関わっ + 0.019*賭博')
(7, '0.056*、 + 0.043*を + 0.032*に + 0.032*一 + 0.029*同 + 0.026*で + 0.025*と + 0.025*大臣 + 0.024*総理 + 0.024*。')
(8, '0.034*、 + 0.021*を + 0.019*同 + 0.019*総理 + 0.018*一 + 0.018*に + 0.017*と + 0.015*で + 0.015*大臣 + 0.015*。')
(9, '0.059*た + 0.049*を + 0.049*、 + 0.045*の + 0.033*に + 0.027*が + 0.026*賭博 + 0.021*投手 + 0.020*。 + 0.019*こと')
(10, '0.056*、 + 0.045*た + 0.045*を + 0.041*に + 0.029*の + 0.019*。 + 0.018*し + 0.017*野球 + 0.016*と + 0.016*賭博')
(11, '0.006*、 + 0.006*た + 0.006*を + 0.006*の + 0.006*に + 0.006*が + 0.006*し + 0.006*は + 0.006*。 + 0.006*プロ')
(12, '0.006*、 + 0.006*に + 0.006*を + 0.006*た + 0.006*が + 0.006*の + 0.006*し + 0.006*まし + 0.006*。 + 0.006*で')
(13, '0.006*、 + 0.006*に + 0.006*た + 0.006*を + 0.006*の + 0.006*。 + 0.006*が + 0.006*し + 0.006*まし + 0.006*野球')
(14, '0.006*、 + 0.006*に + 0.006*た + 0.006*を + 0.006*の + 0.006*が + 0.006*。 + 0.006*賭博 + 0.006*し + 0.006*野球')
(15, '0.033*、 + 0.026*を + 0.026*に + 0.019*と + 0.018*同 + 0.018*ない + 0.016*で + 0.016*大臣 + 0.015*総理 + 0.015*一')
(16, '0.014*を + 0.014*た + 0.014*に + 0.014*、 + 0.012*の + 0.011*賭博 + 0.010*投手 + 0.009*。 + 0.009*関与 + 0.009*まし')
(17, '0.057*、 + 0.042*た + 0.038*の + 0.031*に + 0.027*が + 0.026*野球 + 0.022*プロ + 0.021*を + 0.020*こと + 0.019*問題')
(18, '0.037*に + 0.035*を + 0.035*、 + 0.032*と + 0.026*一 + 0.022*で + 0.019*同 + 0.019*総理 + 0.019*選択 + 0.019*大臣')
(19, '0.006*、 + 0.006*を + 0.006*た + 0.006*の + 0.006*に + 0.006*。 + 0.006*が + 0.006*野球 + 0.006*で + 0.006*は')

各文書ごと の 推定トピック を 出力

  • 読み込んだコーパス・ファイル の 各行 を 各文書 と 認識される
Python3
for topics_per_document in lda[corpus]:
    print(topics_per_document)

( 出力結果 )

  • 読み込んだコーパス・ファイル に 格納されていた4件の文書について、生成したLDAモデルから推定されるトピック番号 が、確信度の確率値 を付けて出力される
[(6, 0.9884146340982356)] # 1件目の文書の推定トピック番号 , 推定の確信度
[(6, 0.99030612219142911)] # 2件目の文書の推定トピック番号 , 推定の確信度
[(9, 0.99214876014564679)] # 3件目の文書の推定トピック番号 , 推定の確信度
[(7, 0.99469273739485931)] # 4件目の文書の推定トピック番号 , 推定の確信度

取り扱った 4件の文書(1行が1文書)

スクリーンショット 2016-03-08 23.15.07.png


( 参考 )

コーパス・ファイル の 作成過程

スクリーンショット 2016-03-08 23.15.07.png

スクリーンショット 2016-03-08 23.08.54.png

スクリーンショット 2016-03-08 23.09.15.png

スクリーンショット 2016-03-08 23.09.21.png

スクリーンショット 2016-03-08 23.09.27.png

スクリーンショット 2016-03-08 23.09.38.png

スクリーンショット 2016-03-08 23.09.46.png

スクリーンショット 2016-03-08 23.09.53.png

スクリーンショット 2016-03-08 23.10.09.png


【 その他、参考になる記事 】