Gensimを用いたトピックモデルの学習
夏目漱石の"坊ちゃん"を題材に、トピックモデルの学習に挑戦してみます。
参考URL
難しいトピックモデルを簡単に!PythonライブラリGensimの使い方
https://www.sejuku.net/blog/67863
準備
実装概要は、下記の通りです。
1.文章の分かち書き
2.単語リストの作成
3.コーパス作成
4.トピックモデルの学習・可視化
実装
実装準備
まず、gensimをインストールしておきます。
!pip install gensim
1.文章の分かち書き
ローカルに保存してあった坊ちゃんのデータを分かち書きします。
分かち書きにはjanomeを利用しました。
import janome
import numpy as np
FILE_PATH = "./bocchan.txt"
text=""
a = Tokenizer(wakati=True)
with open(FILE_PATH, 'r',encoding="Shift-JIS") as f:
for line in f:
lines = a.tokenize(line)
text += " ".join(lines)
text[0:500]
'坊っちゃん夏目 漱石+ 目次一親 譲 お やゆ ずり の 無鉄砲 むてっぽうで 小 供 の 時 から 損 ばかり し て いる 。 小学校 に 居る 時分 学校 の 二 階 から 飛び降り て 一 週間 ほど 腰 こし を 抜 ぬかし た 事 が ある 。 なぜ そんな 無闇 むやみ を し た と 聞く 人 が ある かも 知れ ぬ 。 別段 深い 理由 で も ない 。 新築 の 二 階 から 首 を 出し て い たら 、 同級生 の 一 人 が 冗談 じ ょうだんに 、 いくら 威張 いばっ て も 、 そこ から 飛び降りる 事 は 出来 まい 。 弱虫 や ー い 。 と 囃 は やし た から で ある 。 小使 こづかい に 負ぶさっ て 帰っ て 来 た 時 、 おやじ が 大きな 眼 め を し て 二 階 ぐらい から 飛び降り て 腰 を 抜かす 奴 やつ が ある か と 云い っ た から 、 この 次 は 抜かさ ず に 飛ん で 見せ ます と 答え た 。親類 の もの から 西洋 製 の ナイフ を 貰 もらっ て 奇麗 きれい な 刃 は を 日 '
2.単語リストの作成
"。"を区切り文字として小説を区切り、一文にします。
一文をさらに半角で区切り単語を配列に格納していきます。
なお、不要な単語を取り除くため、ストップワードを適当に選択しています。
#リスト = str.split(‘区切り文字’)
text_list = text.split("。")
stop_words = set('た する ない を に の ん は で が てる と ぜ だ て いる から 「 」'.split())
#ストップワードの除去
texts = [[word for word in document.split(" ") if word not in stop_words ] for document in text_list]
3.コーパス作成
辞書とコーパスを作成していきます。
前処理として、filter_extremesメソッドを用いて、
頻度が多すぎる・少なすぎる単語は辞書から削除してしまいます。
なお、コーパスとは、文章毎に「単語ID,単語IDの文章内の出現頻度」のタプルを持つデータのことです。
from gensim import models
from gensim import corpora
dictionary = corpora.Dictionary(texts)
# no_below:頻度がno_below回以下の単語は無視
# no_above: 頻出単語も無視
# keep_n : 使用単語数に上限設定
dictionary.filter_extremes(no_below=100, no_above=0.5, keep_n=100000)
corpus = [dictionary.doc2bow(text) for text in texts]
corpus
文章毎に、[(単語ID,単語IDの文章内の出現頻度)]の下記情報が手に入ります。
これがコーパスです。
[[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1)],
[(5, 1),
(6, 1),
(7, 1),
(8, 1),
(9, 1),
(10, 1),
(11, 1),
(12, 1),
(13, 1),
(14, 1),
(15, 1),
(16, 1)],
...(中略)
4.トピックモデルの学習・可視化
トピックモデルを学習します。
トピック数は所与として与え、トピック毎に特徴的な文言を表示してみます。
num_topics = 6
lda = models.ldamodel.LdaModel(
corpus=corpus,
num_topics=num_topics,
id2word=dictionary
)
トピックを可視化してみます。
import matplotlib.pyplot as plt
plt.figure(figsize=(30,30))
for t in range(lda.num_topics):
plt.subplot(3,2,t+1)
x = dict(lda.show_topic(t,200))
im = WordCloud(background_color="white",font_path='C:\Windows\Fonts\meiryo.ttc').generate_from_frequencies(x)
plt.imshow(im)
plt.axis("off")
plt.title("Topic #" + str(t))
今回は、チューニングもしていないですが、
色々触ってみると面白そうです。
次回は、坊ちゃんの文章要約に取り組みます。