Python-louvain法|自分が書いた記事を可視化〜乳がん検診に行くまで|ネットワーク分析
可視化を考える中で見つけたキーワードがネットワーク分析です。その中でもコミュニティ抽出と呼ばれるアプローチに興味を持ちました。文全体の構造を把握したり、グループに分けたり、密接に繋がっている部分を抽出してくれたりします。
参考にさせていただいたのはこちらです。この記事を見ていなかったらネットワーク分析をしたいとは思わなかったと思います。
ainow.ai
ネットワーク分析をするにあたり、louvain法を用いました。
アルゴリズムとか難しい話はよくわからず、ただグループ分けをしたいと思い使用しました。
詳しい説明はこちらでされています。難しい内容をシンプルに記述されていてすごいなと思いました。
analytics-note.xyz
環境
python3 -V Python 3.9.2 pip3 show python-louvain Name: python-louvain Version: 0.16 pip3 show networkx Name: networkx Version: 2.8.5 pip3 show numpy Name: numpy Version: 1.23.1
テキストの形態素分析にはjanomeを使用しました。
yoihinomemo.hateblo.jp
以前、そのテキストをwordcloudで可視化しました。
yoihinomemo.hateblo.jp
今回は、ネットワーク分析です。
louvain法を使用したコード
from janome.tokenizer import Tokenizer from janome.analyzer import Analyzer from janome.tokenfilter import * from janome.charfilter import * import numpy as np import collections import codecs import itertools from itertools import chain, combinations from collections import Counter import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.colors as mcolors import networkx as nx from networkx.drawing import nx_agraph import japanize_matplotlib from community import community_louvain import csv import pprint my=open("ファイルがある場所とファイル名.txt").read() my_split=my.split("\n") #word=my.replace("_","") tokenizer = Tokenizer("janomeの簡易辞書.csv", udic_type="simpledic", udic_enc="utf8") corpus=[] for my_list in my_split: tokens = tokenizer.tokenize(my_list) corpus.append([token.base_form for token in tokens if token.part_of_speech.split(',')[0]=="名詞" or token.part_of_speech.split(',')[0]=="動詞" or token.part_of_speech.split(',')[0]=="形容詞" or token.part_of_speech.split(',')[0]=="感動詞"]) print(corpus) #counterで上位のいらないものを消す remove_words = ["、","。","の","に","ます","た","て","が","は","を","です","する","と","も","いる","ない","で","しれる","ある","なる"] #for文で一文字ずつ削除 for remove_words in remove_words: corpus = [corpus for corpus in corpus if remove_words not in corpus] print(corpus,file=codecs.open('ファイルの作成.txt', 'w', 'utf-8')) pair_list = [ list(itertools.combinations(n, 2)) for n in corpus if len(corpus) >=2 ] print(pair_list) print(pair_list,file=codecs.open('ファイルの作成.txt', 'w', 'utf-8')) # 名詞ペアリストの平坦化 all_pairs = [] for u in pair_list: all_pairs.extend(u) print(all_pairs,file=codecs.open('ファイルの作成.txt', 'w', 'utf-8')) G = nx.Graph(all_pairs) #ノード固定seed seed = 0 np.random.seed(seed) plt.figure(figsize=(20, 20)) pos = nx.spring_layout(G,k=0.2,iterations=30,seed=seed)# k = node間反発係数1~0通常k=0.2_iteration18 #コミュニティに分ける #partition=community.best_partition(G) partition = community_louvain.best_partition(G) print(partition) print(partition,file=codecs.open('ファイルの作成.txt', 'w', 'utf-8')) #以下並べ替え part=sorted(partition.items(), key = lambda x:x[1]) print(part) pprint.pprint(part) print(part,file=codecs.open('ファイルの作成.txt', 'w', 'utf-8')) nx.draw_networkx(G, pos, node_color=list(partition.values()), alpha=0.5,edge_color='gray', node_size=500,font_family='IPAexGothic') plt.savefig('グラフの保存.png') plt.show()
louvain法により記事がグループ分けされた図。
図が小さくて分かりづらいですが、色でグループが見分けられるようになっています。
9つのグループに分けられていて、図の中心にあるのが「凹む」です。
乳がん自覚症状の一つエクボ症状のことです。
私にとって乳がん検診に行くきっかけになった症状なので、重要な単語だと思います。
「凹む」の近くにあるのが、紫グループと群青グループと緑グループです。
各グループを丸で囲んでみました。
中央部分にある「0」と「2」と「4」のグループは密接に繋がっているように見えます。「凹む」を中心に枝が出ています。
0〜8に分けられたグルーブの内容について
グループ0
私の乳がん自覚症状を皆さんに伝える内容です。
('乳がん', 0), ('自覚症状', 0), ('皆さん', 0), ('いくつご存知', 0), ('乳房', 0), ('私', 0), ('場合', 0), ('しこり', 0), ('引っ張る', 0), ('もの', 0), ('何', 0), ('安心', 0), ('他', 0), ('ご存知', 0), ('知る', 0), ('ため', 0), ('自分', 0), ('老化', 0), ('捉える', 0), ('られる', 0), ('気', 0), ('付ける', 0), ('過去', 0), ('アドバイス', 0), ('2020年', 0), ('2021年', 0),
グループ2
一般的な乳がん自覚症状についてです。
('くい', 2), ('ぼる', 2), ('症状', 2), ('ひきつれる', 2), ('赤い', 2), ('腫れる', 2), ('乳首', 2), ('陥没', 2), ('ただれる', 2), ('赤茶色', 2), ('透明', 2), ('分泌物', 2), ('左右差', 2), ('目', 2), ('見る', 2), ('気付く', 2), ('事', 2), ('できる', 2), ('変化', 2), ('周囲', 2), ('シワ', 2),
グループ4
私自身の乳がん自覚症状についてです。
('凹む', 4), ('左乳房', 4), ('一瞬', 4), ('激痛', 4), ('石', 4), ('よう', 4), ('硬い', 4), ('塊', 4), ('それ', 4), ('皮膚', 4), ('引く', 4), ('つれる', 4), ('エクボ', 4), ('最初', 4), ('気づく', 4), ('異変', 4), ('風邪', 4)
この3つのグループは、「乳がん自覚症状」でまとめられたものだと言えそうです
グループ2の隣にあるグループ6は、私がしていたセルフチェックです。
('身体', 6), ('素手', 6), ('洗う', 6),
グループ0の隣りにあるグループ3は、私がもう一つの乳がん自覚症状ではないかと疑っている「痛み」について触れています。
('痛み', 3), ('一般的', 3), ('伴う', 3), ('みたい', 3),
右上には「7」と「8」のグループが重なっているように見えます。
グループ7
乳がん検診受診に向けての内容になっています。
('2年', 7), ('1回', 7), ('乳がん検診', 7), ('受ける', 7), ('こと', 7), ('ブレスト・アウェアネス', 7), ('一環', 7), ('行く', 7), ('無駄', 7), ('日', 7), ('翌日', 7), ('予約', 7), ('取る', 7), ('2週間後', 7),
グループ8
乳がんの早期発見について言及しています。
('今', 8), ('時期', 8), ('見つける', 8), ('もらう', 8)
この2つのグループは「乳がん検診に行くことの大切さ」でまとめられています。
その他のグループ
グループ1
私が毎年うけている健康診断の結果です。
('健康診断', 1), ('A', 1)
グループ5
これは「痛み」が起きる間隔についての内容です。
('半年', 5), ('一回', 5), ('間隔', 5)
これはグループ3ともう少し密になってほしかったです。
全体的にみるとメインは「乳がんの自覚症状」ですね。それに付随して「乳がん検診」があるように見て取れます。
実際、乳がんの自覚症状を自分で見つけで乳がん検診に行きました。その時、もう少し早く見つけることができていたら・・と後悔した気持ちもほんの少し表れています。
個人的にグループ分けが上手く行ったのではないかと思います。