[Python][自然言語処理] gensimのトピックモデルの使い方まとめ

 今回はトピックモデルの説明ではなく、トピックモデルをgensimでどうやって扱うかについて書いていきます。

トピックモデルについてざっくり説明


 ドキュメントはそれぞれ複数の潜在的なトピックから確率的に生成されると仮定したモデルのこと。

 ドキュメントがどのトピックに属しているかの確率、トピックごとに出現しやすい単語などを算出することができます。

 詳しい説明は他のページがやっているのでここでは書きません。というか数学的に色々大変なので収まらない…。

gensimセットアップ


 pipでgensim入れるだけ。

pip install gensim

gensimでトピックモデルを扱う


 トピックモデルの学習・生成は以下の流れだ。

  1. ドキュメントごとの単語リストを用意(訓練データ)
  2. 1.のデータから単語辞書を作る
  3. 単語辞書を使って1.のデータをBoW表現にする
  4. 3.のデータを使ってトピックモデルオブジェクトを生成

 推論の場合はこんな感じ。

  1. 推論対象のドキュメントを単語リストにする
  2. 学習時に生成した単語辞書を使って、1.のデータをBoW表現にする
  3. 2.のデータをトピックモデルオブジェクトで推論、トピック確率を算出
import gensim

# TODO ここは本来ドキュメントを形態素解析した単語リストにする
words_list = [
    ["単語", "英語", "英単語", "学習"], ["野球", "スポーツ", "投手", "打者"],
    ["ニュース", "英語", "文法", "学習"], ["サッカー", "スポーツ", "シュート"],
]  # ドキュメントごとの単語リスト
max_document_frequency, min_document_frequency = 1.0, 0.0  # 単語の出現頻度の上限下限

words_dictionary = gensim.corpora.Dictionary(words_list)  # 単語辞書を生成
words_dictionary.filter_extremes(no_above=max_document_frequency, no_below=min_document_frequency)  # 出現頻度でフィルタリングする

num_topics = 2  # トピック数
corpus = [words_dictionary.doc2bow(words) for words in words_list]  # 単語辞書を使って単語リストをBoW表現にする
# BoWコーパス、単語辞書からモデル生成
lda_model = gensim.models.ldamodel.LdaModel(
    corpus=corpus,
    num_topics=num_topics,
    id2word=words_dictionary,
    random_state=99
)

num_words = 5
print("Topic words\n----------------------------------------------------")
# トピックごとの単語上位をnum_words個表示
for topic_num in range(lda_model.num_topics):
    word_weight_dict_by_topic = lda_model.show_topic(topic_num, num_words)  # トピックごとの単語と重みのリスト
    print(f"Topic {topic_num}:  {word_weight_dict_by_topic}")  # トピックごとの上位単語・重みを表示

# ドキュメントの推論
target_document_words = [
    "スポーツ"
]  # 推論したいドキュメントの単語リスト
target_document_corpus = words_dictionary.doc2bow(target_document_words)  # 既存単語辞書を使ってBoW表現にする

print("\n\n\n")

print("Topic probability of target document\n----------------------------------------------------")
# ドキュメントのトピック確率(形式はList[topic_num, probability])
topic_probabilities = lda_model[target_document_corpus]
for topic_prob in topic_probabilities:
    print(f"Topic {topic_prob[0]}:   Prob {topic_prob[1]}")  # トピックごとに該当確率を表示

コメントを残す

メールアドレスが公開されることはありません。