PythonのWordCloudで「こころ」の頻出単語を可視化する【形態素解析, 自然言語処理】
- 作成日: 2020-11-09
- 更新日: 2023-12-26
- カテゴリ: 自然言語処理
Pythonによる頻出単語の可視化
「ワードクラウド」というのは文章の中の頻出単語を可視化した画像のことです。
自然言語処理の分野でよく使われます。
文章の中の名詞や動詞が、どれがよく使われているのかと言うのを視覚的に非常にわかりやすく表示することが可能です。
Pythonにはこのワードクラウドを簡単に表示するためのライブラリがあります。
その名も「WordCloud」です。
WordCloudに例えば名詞が羅列されたテキストを渡すと、WordCloudはそのテキストを解析してワードクラウドの画像を生成してくれます。
今回はこのWordCloudを使って、簡単なスクリプトを作成しました。
「show-wordcloud.py
」というスクリプトです。
この記事ではこのshow-wordcloud.py
の紹介と解説を行います。
具体的には↓の内容になります。
- show-wordcloud.pyの全コード
- Janomeによる形態素解析
- WordCloudによる画像の生成
- matplotlibで画像を表示
- show-wordcloud.pyで「こころ」を解析
show-wordcloud.pyの全コード
最初に作成した「show-wordcloud.py
」のコードの全文を紹介します。
"""
show-wordcloud.py
標準入力から文字列を読み込み、名詞のみを抽出してワードクラウドを表示する
Usage:
python show-wordcloud.py
or
curl https://xxx.xxx | python show-wordcloud.py
"""
from janome.analyzer import Analyzer
from janome.tokenfilter import POSKeepFilter
from wordcloud import WordCloud
import matplotlib.pyplot as plt
from bs4 import BeautifulSoup
import sys
import io
def analyze(src):
"""
srcを解析して名詞のみが羅列されたテキストに変換する
@param {str} src
@return {str}
"""
# HTMLからテキストのみを抽出
soup = BeautifulSoup(src, 'html.parser')
src = soup.get_text()
# janomeのフィルター
# 名詞のみを抽出するのでPOSKeepFilterに名詞を指定
token_filters = [POSKeepFilter(['名詞'])]
# token_filtersを指定してAnalyzerを生成
an = Analyzer(token_filters=token_filters)
# 解析してトークン列(名詞の列)に
toks = an.analyze(src)
# トークン列を半角スペース区切りのテキストに変換
text = ' '.join([tok.surface for tok in toks])
return text
def show_wordcloud(text):
"""
textからワードクラウドを表示する
@param {str} text
"""
# WordCloudで使うフォント。ここではWindowsのフォントを使用
font_path = 'C:\\Windows\\Fonts\\msgothic.ttc'
# WordCloudをオブジェクトに
wordcloud = WordCloud(
background_color='white', # 背景色
font_path=font_path, # フォントのパス
width=300, # 横幅
height=200, # 高さ
)
# textを元に画像を生成
wordcloud.generate(text)
# matplotlibで生成した画像を表示する
plt.figure(figsize=(8, 4)) # figsize=(横幅, 高さ)
plt.imshow(wordcloud)
plt.axis('off')
plt.show() # 表示
def main():
sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='cp932')
src = sys.stdin.read()
text = analyze(src)
show_wordcloud(text)
main()
スクリプトの使い方
↑のコードを「show-wordcloud.py
」などのファイルに保存します。
環境にpip
で↓のパッケージをインストールします。
pip install janome matplotlib wordcloud BeautifulSoup4
コマンドプロンプトなどのシェルからスクリプトを↓のように実行します。
python show-wordcloud.py
デフォルトでは標準入力から入力を読み取りますので何か入力し、Ctrl+Z
やCtrl+D
などを入力すると解析が始まります。
解析が完了すると画面にワードクラウドの画像を表示します。
また、Curlなどと組み合わせる場合は↓のようにパイプを使います。
curl https://xxx.xxx | python show-wordcloud.py
このスクリプトは標準入力がデフォルトでcp932
になっています(青空文庫がcp932
のため)。
そのためUTF-8
のコンテンツを読み込ませたい場合は、main
関数内の↓の部分、
sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='cp932')
encoding='cp932'
のところをencoding='utf-8'
などに変更してください。
(スクリプトの簡便さのためにオプションによる切り替えは省略しています)
Janomeによる形態素解析
まず、WordCloudに文字列を解析させたいわけですが、そのためには単語が羅列されたテキストを作る必要があります。
日本語の文章を単語のリストに変換するには形態素解析という技術を使います。
形態素解析を行えるライブラリはMecabなどが有名ですが、PythonにはJanomeというライブラリもあります。
Janomeはpip
で簡単にインストールできるので、このスクリプトではJanomeを使ってコードを書いています。
Janomeにはトーカナイザー(janome.tokenizer
)という字句解析を行うモジュールがあり、これが基本となるモジュールです。
今回はこれは使っていません。
トーカナイザーの使い方については↓の記事をご覧ください。
今回はJanomeのアナライザー(janome.analyzer
)という応用的な使い方をするモジュールを使います。
このアナライザーは品詞のフィルタリングなどを簡単に行えるモジュールです。
スクリプトでは名詞の単語を抽出したいわけなので、アナライザーはまさにうってつけという訳です。
スクリプトのコードを見てみましょう。
analyze()
と言う関数でJanomeを使った形態素解析を行っています。
この関数は引数として日本語の文章の文字列を取り、結果を名詞が羅列されたテキストとして返します。
def main():
...
text = analyze(src)
...
analyze()
関数内ではJanomeのアナライザーを使った形態素解析を行っています。
最初に引数src
がHTMLであった場合にそなえて、BeautifulSoup4というHTMLパーサーでsrc
をパースしています。
# HTMLからテキストのみを抽出
soup = BeautifulSoup(src, 'html.parser')
src = soup.get_text()
↑のようにBeautifulSoup
のオブジェクトのメソッドget_text()
を使うと、タグを取り除いたテキストを取得することが出来ます。
BeautifulSoup
を使うにはbs4
モジュールからBeautifulSoup
クラスをインポートする必要があります。
from bs4 import BeautifulSoup
JanomeのAnalyzerを使うにはjanome.analyzer
モジュールからAnalyzer
クラスをインポートします。
それからフィルターとしてjanome.tokenfilter
モジュールからPOSKeepFilter
クラスをインポートします。
POSKeepFilter
はアナライザーで解析するときに特定の品詞のみを抽出するフィルターです。
from janome.analyzer import Analyzer
from janome.tokenfilter import POSKeepFilter
↓のようにPOSKeepFilter
に抽出したい品詞のリストを渡してオブジェクトにし、token_filters
というリストにします。
token_filters = [POSKeepFilter(['名詞'])]
それからこのtoken_filters
をAnalyzer
のtoken_filters
に指定して、Analyzer
をオブジェクトにします。
an = Analyzer(token_filters=token_filters)
生成したアナライザー(an
)のメソッドanalyze()
に文字列を渡すと解析が実行され、形態素解析が行われます。
その結果はトークン列で返ってきます。これは名詞のみのリストです。
toks = an.analyze(src)
トークン列内のトークンはsurface
という単語の表層形を表す属性を持っています。
表層形とは単語の元の文章そのままの表記です。
このsurface
を参照し、↓のようにリスト内包表記と文字列のjoin()
を使って、名詞が羅列されたテキストに変換します。
text = ' '.join([tok.surface for tok in toks])
変換したテキストを、analyze()
の最後でreturn
してanalyze()
関数の仕事は終わりです。
WordCloudによる画像の生成
analyze()
で日本語の文章を解析したら次はWordCloudによる画像の表示です。
これはshow_wordcloud()
関数で行います。
def main():
...
show_wordcloud(text)
show_wordcloud()
関数はテキストを引数に取ります。
この引数にはanalyze()
の結果のテキストを渡します。
WordCloudは画像で文字列を生成していますが、この画像による文字列にはフォントが必要です。
そのため外部からフォントを仕入れてそのパスを指定する必要があります。
font_path = 'C:\\Windows\\Fonts\\msgothic.ttc'
今回はWindows10に最初から入っているmsgothic.ttc
フォントを使っています。
次にWordCloudをオブジェクトにします。これはWordCloud
クラスを使います。
WrodCloud
クラスを使うにはwordcloud
モジュールからWordCloud
クラスをインポートする必要があります。
from wordcloud import WordCloud
WordCloud
をオブジェクトにする時にさきほどのフォントのパス、それから背景色なども指定します。
# WordCloudをオブジェクトに
wordcloud = WordCloud(
background_color='white', # 背景色
font_path=font_path, # フォントのパス
width=300, # 横幅
height=200, # 高さ
)
WordCloud
をオブジェクトにしたら、そのメソッドであるgenerate()
にテキストを渡して画像を生成します。
wordcloud.generate(text)
これでワードクラウドの画像が生成されました。
matplotlibで画像を表示
次にこの画像を表示しますが、これにはmatplotlib
というライブラリを使います。
matplotlib
を使うには↓のようにplt
をインポートする必要があります。
import matplotlib.pyplot as plt
matplotlib
にさきほど生成したwordcloud
オブジェクトを指定して画面に画像を表示します。
# matplotlibで生成した画像を表示する
plt.figure(figsize=(8, 4)) # figsize=(横幅, 高さ)
plt.imshow(wordcloud)
plt.axis('off')
plt.show() # 表示
show-wordcloud.pyで「こころ」を解析
ではこのスクリプトを使って青空文庫に掲載されている夏目漱石の「こころ」を解析してみましょう。
↓のようにコマンドを打って実行します。
curl 青空文庫のURLをここに書く | python show-wordcloud.py
しばらくすると↓のような画像が表示されます。
画像を見ると、やはり主人公だけあって「先生」というワードが多いのが視覚的にわかります。
それから「よう」、「もの」、「それ」も多いですね。
おわりに
PythonのWordCloudを使うと簡単に頻出単語を視覚化することが出来ました。
このスクリプトをあなたのツールに加えてみてはいかがでしょうか?
ライセンスはMITです。改造もご自由にどうぞ。
🦝 < 雲のような人間になりたい