この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、Mr.Moです。
共起ネットワークを描画するのにpyvisライブラリを使うと簡単にできたので下記にまとめていきます。
共起ネットワークについて
- 共起とは?
> 共起(きょうき,英:Co-occurrence)は、ある単語がある文章(または文)中に出たとき、その文章(文)中に別の限られた単語が頻繁に出現すること。
https://ja.wikipedia.org/wiki/%E5%85%B1%E8%B5%B7
共起ネットワークは共起する単語の関係をネットワーク図で表したものです。
https://en.wikipedia.org/wiki/Co-occurrence_network
pyvisライブラリについて
ネットワーク図の視覚化に特化したライブラリのようです。
チュートリアル がありデータも用意されているのですがそちらは英語のデータになるので、本記事では日本語のデータを別途用意した上で共起ネットワークを描画したいと思います。
データの準備
下記の記事を参考にデータを作っていきます。
事前準備
前提としてSageMaker上で作業をしていきます。
SageMakerでノートブックインスタンスの作成
まずはじめにSageMakerの画面を開きます。
次にノートプックインスタンスを作成します。 下記の要領で赤枠の部分を対応して後はデフォルトのままで大丈夫です。
ノートブックはconda_python3の環境で実行します。
MeCabのインストール
MeCabを使うのでインストールをしていきます。ノートブックのセルに下記のコードをコピペしておもむろに実行してください。完了まで少し時間がかかります。
参考:https://qiita.com/YuukiMiyoshi/items/00b9878a1fa32b859a43
%%bash
sudo yum install -y bzip2 bzip2-devel gcc gcc-c++ git make wget curl openssl-devel readline-devel zlib-devel patch file
# 作業フォルダを作成して移動
mkdir -p ~/source/mecab
cd ~/source/mecab
# ソースをダウンロードして解凍して移動
wget 'https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE' -O mecab-0.996.tar.gz
tar zxvf mecab-0.996.tar.gz
cd mecab-0.996
# インストール先フォルダを作成
sudo mkdir -p /opt/mecab
# configure(コンパイルのための設定)を実行し、コンパイルしてインストール
./configure --prefix=/opt/mecab --with-charset=utf8 --enable-utf8-only
make
sudo make install
# bashの場合
echo "export PATH=/opt/mecab/bin:\$PATH" >> ~/.bashrc
source ~/.bashrc
sudo bash -c "echo \"/opt/mecab/lib\" > /etc/ld.so.conf.d/libmecab.conf"
sudo ldconfig
# 作業フォルダを作成して移動
mkdir ~/source/mecab-ipadic
cd ~/source/mecab-ipadic
# 辞書ファイルを取得して解凍して移動
wget 'https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM' -O mecab-ipadic-2.7.0-20070801.tar.gz
tar zxvf mecab-ipadic-2.7.0-20070801.tar.gz
cd mecab-ipadic-2.7.0-20070801
# 設定してmakeしてインストール
./configure --with-mecab-config=/opt/mecab/bin/mecab-config --with-charset=utf8
make
sudo make install
# 作業フォルダに移動してファイルを取得
cd ~/source
git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
# 設定とともにインストールを実行
./mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n -y -p /opt/mecab/lib/mecab/dic/neologd
MeCabをPythonで使うのに下記モジュールが必要なのでインストールしましょう。
!pip install --upgrade pip
!pip install mecab-python3
データ準備
青空文庫からテキストデータをダウンロード
今回扱うテキストデータは青空文庫にある福沢諭吉の『学問のすすめ』を使わせていただきましょう。
<br />!wget https://www.aozora.gr.jp/cards/000296/files/47061_ruby_28378.zip
!mkdir data
!unzip 47061_ruby_28378.zip -d data
ダウンロードしたデータを少し加工します。先に加工に必要な関数などを定義しておきます。下記のコードをノートブック上で実行していっってください。
参考:https://newtechnologylifestyle.net/711-2/
import re
# テキストファイルのルビや注釈などを削除して本文のみを取得する
def convert(download_text):
binarydata = open(download_text, 'rb').read()
text = binarydata.decode('shift_jis')
# ルビ、注釈などの除去
text = re.split(r'\-{5,}', text)[2]
text = re.split(r'底本:', text)[0]
text = re.sub(r'《.+?》', '', text)
text = re.sub(r'[#.+?]', '', text)
text = re.sub(r'\r\n', '', text)
text = re.sub(r'\u3000', '', text)
text = text.strip()
return text
# ストップワードをダウンロード
import urllib.request
url = 'http://svn.sourceforge.jp/svnroot/slothlib/CSharp/Version1/SlothLib/NLP/Filter/StopWord/word/Japanese.txt'
urllib.request.urlretrieve(url, 'stop_word.txt')
with open('stop_word.txt', 'r', encoding='utf-8') as file:
stopwords = [word.replace('\n', '') for word in file.readlines()]
import MeCab
mecab = MeCab.Tagger("-Owakati -d /opt/mecab/lib/mecab/dic/neologd")
# 文章から名刺のみを抽出する
def get_meishi(sentence):
keywords = []
node = mecab.parseToNode(sentence)
while node:
word = node.surface
feature = node.feature.split(',')
if feature[0] == '名詞' and node.surface not in stopwords:
keywords.append(word)
node = node.next
return keywords
下記のコードから実際のデータ加工を実行していきます。
download_file = './data/gakumonno_susume.txt'
text = convert(download_file)
import itertools
sentences = [get_meishi(w) for w in text.split("。")]
sentence_combinations = [list(itertools.combinations(sentence, 2)) for sentence in sentences]
sentence_combinations = [[tuple(sorted(words)) for words in sentence] for sentence in sentence_combinations]
target_combinations = []
for sentence in sentence_combinations:
target_combinations.extend(sentence)
import collections
ct = collections.Counter(target_combinations)
ct.most_common()[:10]
準備が整いましたので、さっそく共起ネットワークを可視化してみましょう。
共起ネットワークの描画
下記のコードを実行していってください。
!pip install pyvis
# ネットワーク描画のメイン処理定義
def kyoki_word_network():
from pyvis.network import Network
import pandas as pd
#got_net = Network(height="500px", width="100%", bgcolor="#222222", font_color="white", notebook=True)
got_net = Network(height="1000px", width="95%", bgcolor="#FFFFFF", font_color="black", notebook=True)
# set the physics layout of the network
#got_net.barnes_hut()
got_net.force_atlas_2based()
got_data = pd.read_csv("kyoki.csv")[:150]
sources = got_data['first']#count
targets = got_data['second']#first
weights = got_data['count']#second
edge_data = zip(sources, targets, weights)
for e in edge_data:
src = e[0]
dst = e[1]
w = e[2]
got_net.add_node(src, src, title=src)
got_net.add_node(dst, dst, title=dst)
got_net.add_edge(src, dst, value=w)
neighbor_map = got_net.get_adj_list()
# add neighbor data to node hover data
for node in got_net.nodes:
node["title"] += " Neighbors:<br>" + "<br>".join(neighbor_map[node["id"]])
node["value"] = len(neighbor_map[node["id"]])
got_net.show_buttons(filter_=['physics'])
return got_net
#got_net.show("gameofthrones.html")
# 所定の構造でCSVファイルに出力
import pandas as pd
pd.DataFrame([{'first' : i[0][0], 'second' : i[0][1], 'count' : i[1]} for i in ct.most_common()]).to_csv('kyoki.csv', index=False)
# 処理の実行
got_net = kyoki_word_network()
got_net.show("kyoki.html")
見事、共起ネットワークが可視化がされましたね!
まとめ
テキストマイニングなどでは共起関係の分析を行うことが多いと思いますので、その際に共起ネットワークを簡単に描画できるのは分析が捗りそうですね!