テキストマイニングをしてみたいです。
このような要望にお応えします。
今回は、LDAを使いたいと思います。
LDA(Latent Dirichlet Allocation)は、日本語では潜在的ディリクレ配分法とも呼ばれます。
LDAベクトル空間モデルを利用した自然言語処理の技法の一つで、文書群とそこに含まれる単語について、 それらに関連した概念の集合を生成することで、その関係を分析する技術である。(wikipediaより抜粋)
LDAは、データが潜在的意味のカテゴリから生成されると仮定したモデルのことです。
この潜在的意味のカテゴリをトピックを呼んだりします。潜在的意味というのは、複数の単語の共起性により発生する情報のことを示しています。
また、LDAでは、文書に実際に記載された顕在的な共起性だけではなく、文書上には現れない潜在的共起性(暗黙的な共起性)も同時に考慮することができます。
それでは、実際に使用してみます。
gensimにLDAのライブラリがありますので、これを使えば手軽に課題に対して適応可能です。
適用データとしては、特定のキーワードを含むニュース記事をスクレイピングして利用することを考えます。キーワードは、”買い占め”、”暴落”を設定し、ニュース記事を収集しました。pythonによるスクレイピング時に使われているツールなどは、下記記事で紹介しています。
収集したデータは、下記のようにcsv形式で保存しています。
キーワード”買い占め”で収集したニュース記事一覧
キーワード”暴落”で収集したニュース記事一覧
対象データにLDAを適用するソースコードは以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# coding: utf-8 from janome.tokenizer import Tokenizer import gensim import pandas as pd import numpy as np from wordcloud import WordCloud from PIL import Image import matplotlib.pyplot as plt def fn_extact_words(text): t = Tokenizer() tokens = t.tokenize(text) return [token.base_form for token in tokens \ if token.part_of_speech.split(',')[0] in ['名詞', '動詞']] def fn_start_lda(): keyword = input("filename input-> ") filename = keyword + ".csv" df = pd.read_csv(filename) df.isnull().values.any() df.shape word_list = [fn_extact_words(sentence) for sentence in df['summary']] dictionary = gensim.corpora.Dictionary(word_list) dictionary.filter_extremes(no_below=3, no_above=0.8) corpus = [dictionary.doc2bow(t) for t in word_list] num_topics = input("Input Number of Topic") lda_model = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=num_topics, random_state=0) print(lda_model.print_topics()) for i, topic in enumerate(range(lda_model.num_topics)): res = dict(lda_model.show_topic(topic, 50)) img = WordCloud( background_color="black", width=800, height=600, font_path='NotoSansCJKjp-Regular.otf', collocations=False ).generate_from_frequencies(res) plt.figure(figsize=(3, 3), dpi=200) plt.imshow(img) plt.axis("off") plt.show() if __name__ == '__main__': fn_start_lda() |
各キーワードの適用結果をwordcloudで出力してみます。
キーワード”買い占め”
キーワード”暴落”
上記の各出力は、キーワード”買い占め”, “暴落”に対する関連度が高い単語同士で集まっているように思います。このように、LDAを使えば、潜在的に関連する単語の関係(類義語など)を見つけることもできます。今回は、動詞”する”等の多くの文書で共通して使用されるような単語を除去していません。このような単語を除去することで、より関連の高い単語の集合を得られるかもしれません。是非活用してみてください。