[自然言語処理/NLP] pyvisライブラリを使って共起ネットワークを簡単に描画してみる(SageMaker使用)
こんにちは、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")
見事、共起ネットワークが可視化がされましたね!
まとめ
テキストマイニングなどでは共起関係の分析を行うことが多いと思いますので、その際に共起ネットワークを簡単に描画できるのは分析が捗りそうですね!