テキストマイニングをしてみたいです。
このような要望にお応えします。
今回は、GloVeを使いたいと思います。
GloVeは、単語をベクトル化する手法のことです。このベクトル化したものを単語の分散表現と呼びます。GloVeは単語の意味は周囲の単語により形成されるという考えに基づいています。
これを分布仮説と呼びます。類似する意味や使われ方をする単語は類似する文脈の中に登場するという考えのもと、単語をベクトル化しています。このため、上記のような類似単語同士はベクトル空間上で近い場所に存在し、コサイン類似度が高くなります。
データ収集
データとしては、特定のキーワードを含むニュース記事をスクレイピングして利用することを考えます。キーワードは、”買い占め”、”暴落”、”安部”、”花見”、”緊急事態宣言”を設定し、ニュース記事を収集しました。pythonによるスクレイピング時に使われているツールなどは、下記記事で紹介しています。
収集したデータは、下記のようにcsv形式で保存しています。
キーワード”暴落”
キーワード”買い占め”
キーワード”安部首相”
キーワード”花見”
キーワード”緊急事態宣言”
コーパスの作成
テキストマイニングを行うために、テキストを分かち書きします。このとき、文書において語の区切りに空白を挟んで記述する必要があります。これをjanomeで解析処理します。
データ加工/学習
pythonのGloVeのライブラリは、以下のリンク先を利用します。
https://github.com/hans/glove.py
GloVeの学習で必要となる単語辞書、共起行列の作成を行います。作成したコーパス、単語辞書、共起行列を用いて、学習を行います。
ソースコード
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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# coding: utf-8 from janome.tokenizer import Tokenizer from gensim.models import word2vec import pandas as pd import numpy as np import glove import evaluate import gensim 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_GloVe(): keyword = input("filename input-> ") filename = keyword + ".csv" df = pd.read_csv(filename) df.isnull().values.any() df.shape window_size = 5 min_count = 5 embedding_size = 50 iterations = 100 # コーパスの作成 ex [['python', '応用', 'データ', '解析'], ['python', '画像', '認識'], ['機械', '学習', 'python']] word_list = [fn_extact_words(sentence) for sentence in df['summary']] # 単語辞書の作成 vocab = glove.build_vocab(word_list) # 共起行列の作成 cooccur_matrix = glove.build_cooccur( vocab, word_list, window_size=window_size, min_count=min_count ) id2word = evaluate.make_id2word(vocab) #学習 glove_model = glove.train_glove( vocab, cooccur_matrix, vector_size=embedding_size, iterations=iterations ) glove_model = evaluate.merge_main_context(glove_model) # モデル保存 glove.save_model(glove_model, "glove.pkl") # 関連語抽出 n = 15 word_id = vocab[keyword][0] dists = np.dot(glove_model, glove_model[word_id]) top_ids = np.argsort(dists)[::-1][:n + 1] for id in top_ids: print(id2word[id], dists[id]) result = [(id2word[id], dists[id]) for id in top_ids if id != word_id][:n] res = dict(result) 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_GloVe() |
マイニング結果(関連語抽出)
学習したモデルに対して、キーワードを入力し、関連語を抽出します。また、各キーワードの学習結果をwordcloudで出力してみます。
キーワード”暴落”
キーワード”買い占め”
キーワード”安部首相”
キーワード”花見”
キーワード”緊急事態宣言”
これらの出力は、各キーワードに対して関連度の高い単語で構成されています。
このように、GloVeを使えば、単語間の関連度が高いもの(類義語など)を見つけることもできます。
是非活用してみてください。