大切なものは、見えるところに。

乳がんかな?と疑い始めてからの日々を、振り返りながら、ゆるやかに綴ります。

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ともう少し密になってほしかったです。


全体的にみるとメインは「乳がんの自覚症状」ですね。それに付随して「乳がん検診」があるように見て取れます。
実際、乳がんの自覚症状を自分で見つけで乳がん検診に行きました。その時、もう少し早く見つけることができていたら・・と後悔した気持ちもほんの少し表れています。


個人的にグループ分けが上手く行ったのではないかと思います。