Python入門トップページ


目次

  1. 準備
  2. MeCab の第一歩
  3. 簡単な形態素解析
  4. TF-IDF を計算してみよう
  5. ワードクラウドを作成してみよう

Python で自然言語処理をしてみよう - MeCab 編

ワードクラウドを作成してみよう

ここでは,文書で使われている重要な単語を並べるワードクラウドを作成してみよう.

準備

Python では WordCloud ライブラリを使って簡単にワードクラウドを作成できます.WordCloud のオリジナルサイトはこちらです.これを利用するためには pip を使って wordcloud をインストールします.Windows 環境では Anaconda Prompt でインストール可能です.なお,Windows,Mac 環境ともに仮想環境を構築せずに base 環境に WordCloud ライブラリをインストールした場合に,ワードクラウドの作成で失敗する可能性があります.その際は,ここを参考に仮想環境を構築してから実行してください.

(base) C:\Users\lecture>pip install wordcloud
Collecting wordcloud
  Downloading wordcloud-1.8.1-cp37-cp37m-win_amd64.whl (154 kB)
     |████████████████████████████████| 154 kB 2.2 MB/s
Requirement already satisfied: matplotlib in c:\users\lecture\anaconda3\lib\site-packages (from wordcloud) (3.4.2)
Requirement already satisfied: pillow in c:\users\lecture\anaconda3\lib\site-packages (from wordcloud) (8.3.1)
Requirement already satisfied: numpy>=1.6.1 in c:\users\lecture\anaconda3\lib\site-packages (from wordcloud) (1.20.3)
Requirement already satisfied: cycler>=0.10 in c:\users\lecture\anaconda3\lib\site-packages (from matplotlib->wordcloud) (0.10.0)
Requirement already satisfied: python-dateutil>=2.7 in c:\users\lecture\anaconda3\lib\site-packages (from matplotlib->wordcloud) (2.8.2)
Requirement already satisfied: kiwisolver>=1.0.1 in c:\users\lecture\anaconda3\lib\site-packages (from matplotlib->wordcloud) (1.3.1)
Requirement already satisfied: pyparsing>=2.2.1 in c:\users\lecture\anaconda3\lib\site-packages (from matplotlib->wordcloud) (2.4.7)
Requirement already satisfied: six in c:\users\lecture\anaconda3\lib\site-packages (from cycler>=0.10->matplotlib->wordcloud) (1.16.0)
Installing collected packages: wordcloud
Successfully installed wordcloud-1.8.1

(base) C:\Users\lecture>pip list | find "wordcloud"
wordcloud                          1.8.1

(base) C:\Users\lecture>

Mac でも同様にターミナルでインストール可能です.

(base) rinsaka@Macmini2020 semi % pip install wordcloud
Collecting wordcloud
  Downloading wordcloud-1.8.1.tar.gz (220 kB)
     |████████████████████████████████| 220 kB 2.4 MB/s
  Preparing metadata (setup.py) ... done
Requirement already satisfied: numpy>=1.6.1 in /Users/rinsaka/opt/anaconda3/lib/python3.7/site-packages (from wordcloud) (1.19.5)
Requirement already satisfied: pillow in /Users/rinsaka/opt/anaconda3/lib/python3.7/site-packages (from wordcloud) (8.3.1)
Requirement already satisfied: matplotlib in /Users/rinsaka/opt/anaconda3/lib/python3.7/site-packages (from wordcloud) (3.4.2)
Requirement already satisfied: kiwisolver>=1.0.1 in /Users/rinsaka/opt/anaconda3/lib/python3.7/site-packages (from matplotlib->wordcloud) (1.3.1)
Requirement already satisfied: python-dateutil>=2.7 in /Users/rinsaka/opt/anaconda3/lib/python3.7/site-packages (from matplotlib->wordcloud) (2.8.2)
Requirement already satisfied: pyparsing>=2.2.1 in /Users/rinsaka/opt/anaconda3/lib/python3.7/site-packages (from matplotlib->wordcloud) (2.4.7)
Requirement already satisfied: cycler>=0.10 in /Users/rinsaka/opt/anaconda3/lib/python3.7/site-packages (from matplotlib->wordcloud) (0.10.0)
Requirement already satisfied: six in /Users/rinsaka/opt/anaconda3/lib/python3.7/site-packages (from cycler>=0.10->matplotlib->wordcloud) (1.15.0)
Building wheels for collected packages: wordcloud
  Building wheel for wordcloud (setup.py) ... done
  Created wheel for wordcloud: filename=wordcloud-1.8.1-cp37-cp37m-macosx_10_9_x86_64.whl size=160364 sha256=35f1b6b0d7eeae68a2eb087fd70fe26d996f045ebce5f0ce87b374584332c4f2
  Stored in directory: /Users/rinsaka/Library/Caches/pip/wheels/f8/f6/55/6bd394c32a844a621ca0fe5dbf563c8d71d71edaf095656991
Successfully built wordcloud
Installing collected packages: wordcloud
Successfully installed wordcloud-1.8.1
(base) rinsaka@Macmini2020 semi % pip list | grep wordcloud
wordcloud                          1.8.1
(base) rinsaka@Macmini2020 semi %

目次に戻る

英文のワードクラウドを作成する

英語の文章は単語ごとに区切られた体裁になっているため,ワードクラウドの作成は簡単です.まず,ライブラリをインポートしたあと,ファイルを読み込みます.

ファイルの読み込み
from wordcloud import WordCloud
import os
# テキストファイル読み込み
f = open(os.path.sep.join(['corpora', 'en_abs_1.txt']), encoding='utf-8')
raw = f.read()
f.close()
print(raw)
In this paper, we consider a nonparametric adaptive
software rejuvenation schedule under a random censored data.
For u failure time data and v random censored data, we
formulate upper and lower bounds of the predictive system
availability based on a nonparametric predictive inference (NPI).
Then, we derive adaptive rejuvenation policies which maximizes
the upper or lower bound. In simulation experiments, we show
that estimates of the software rejuvenation schedule are updated
by acquisition of new failure data, and converge to the theoretical
optimal solution.

ファイルの読み込みが終われば,WordCloud().generate( ) でワードクラウドを作成して,wc.to_file( ) によって指定したファイル名で書き出すことができます.もちろん,ソースコードと同じフォルダに PNG ファイルが書き出されていることに注意してください.なお,PDF ファイルとして書き出すことも可能です.ただし,PDF ファイルの場合も PNG ファイルと同じようにラスターデータ(ビットマップデータ)になることに注意してください.

英文のワードクラウド作成
wc = WordCloud().generate(raw)
wc.to_file("wc-1.png")
wc-1

なお,ワードクラウドの作成時に,最大のフォントサイズを指定することも可能です.

最大フォントサイズの変更
wc = WordCloud(max_font_size=36).generate(raw)
wc.to_file("wc-2.png")
wc-2

目次に戻る

日本語のワードクラウドを作成する(失敗例1)

次に,日本語の文章についても英文と同じ方法でワードクラウドを作成してみよう.まずは,ここと同じように,不要な改行文字やタブ文字を削除してからワードクラウドを作成します.しかしながら,日本語フォントが指定されていないために失敗しました.

失敗例1
from wordcloud import WordCloud
import os
import re

def strip_CRLF_from_Text(text):
    """
    テキストファイルの改行,タブを削除する.
    改行文字やタブ文字の前後が日本語文字の場合はそれを削除する.
    それ以外はスペースに置換する.
    """
    # 改行前後の文字が日本語文字の場合は改行を削除する
    plaintext = re.sub('([ぁ-んー]+|[ァ-ンー]+|[\\u4e00-\\u9FFF]+|[ぁ-んァ-ンー\\u4e00-\\u9FFF]+)(\n)([ぁ-んー]+|[ァ-ンー]+|[\\u4e00-\\u9FFF]+|[ぁ-んァ-ンー\\u4e00-\\u9FFF]+)',
                       r'\1\3',
                       text)
    # 残った改行とタブ記号はスペースに置換する
    plaintext = plaintext.replace('\n', ' ').replace('\t', ' ')
    return plaintext

# テキストファイル読み込み
# ファイルを開く
f = open(os.path.sep.join(['corpora', 'ja_abs_1.txt']), encoding='utf-8')
raw = f.read()
f.close()
print(raw)
text = strip_CRLF_from_Text(raw)
print(text)

# WordCloud画像を生成する
wc = WordCloud(max_font_size=36).generate(text)
wc.to_file("wc-3.png")
研究者が自身で収集した学術論文の文献 PDF ファイルを効率的に管理し,研究活動に
有効活用することを目的として,文献 PDF データベースシステムを開発した.利用者は
PDF ファイルを Web ブラウザからサーバにアップロードすることで,PDF ファイルを
一元的に管理できるようになるとともに,全文検索,ジャーナル検索,著者検索,タグ
(キーワード)検索が利用できるようになる.また,論文情報の登録などに BIBTEX 情報を
活用することも本システムの特徴のひとつである.本論文では文献 PDF データベースシ
ステムの詳細について議論するとともに,性能評価実験の結果を考察する.

研究者が自身で収集した学術論文の文献 PDF ファイルを効率的に管理し,研究活動に有効活用することを目的として,文献 PDF データベースシステムを開発した.利用者は PDF ファイルを Web ブラウザからサーバにアップロードすることで,PDF ファイルを一元的に管理できるようになるとともに,全文検索,ジャーナル検索,著者検索,タグ (キーワード)検索が利用できるようになる.また,論文情報の登録などに BIBTEX 情報を活用することも本システムの特徴のひとつである.本論文では文献 PDF データベースシステムの詳細について議論するとともに,性能評価実験の結果を考察する.
wc-3

目次に戻る

日本語のワードクラウドを作成する(失敗例2)

上の例では,日本語フォントを指定していないために日本語文字が正しく表示されませんでした.ここでは,フォントのファイルを指定してワードクラウドを作成します.なお,OS や環境によってフォントの場所等が異なるので注意してください.


from wordcloud import WordCloud
import os
import re

def strip_CRLF_from_Text(text):
    """テキストファイルの改行,タブを削除し,形態素解析を実行する.
    改行前後が日本語文字の場合は改行を削除する.
    それ以外はスペースに置換する.
    """
    # 改行前後の文字が日本語文字の場合は改行を削除する
    plaintext = re.sub('([ぁ-んー]+|[ァ-ンー]+|[\\u4e00-\\u9FFF]+|[ぁ-んァ-ンー\\u4e00-\\u9FFF]+)(\n)([ぁ-んー]+|[ァ-ンー]+|[\\u4e00-\\u9FFF]+|[ぁ-んァ-ンー\\u4e00-\\u9FFF]+)',
                       r'\1\3',
                       text)
    # 残った改行とタブ記号はスペースに置換する
    plaintext = plaintext.replace('\n', ' ').replace('\t', ' ')
    return plaintext

# テキストファイル読み込み
# ファイルを開く
f = open(os.path.sep.join(['corpora', 'ja_abs_1.txt']), encoding='utf-8')
raw = f.read()
print(raw)
text = strip_CRLF_from_Text(raw)
print(text)

# フォントの保存先を指定する(環境によって書き換えてください)
# font_path = "C:\\WINDOWS\\FONTS\\MEIRYO.TTC"    ## Windows 版はこちら
font_path = "/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc"  ## Mac 版はこちら

# WordCloud画像を生成する
wc = WordCloud(max_font_size=36, font_path=font_path).generate(text)
wc.to_file("wc-4.png")
研究者が自身で収集した学術論文の文献 PDF ファイルを効率的に管理し,研究活動に
有効活用することを目的として,文献 PDF データベースシステムを開発した.利用者は
PDF ファイルを Web ブラウザからサーバにアップロードすることで,PDF ファイルを
一元的に管理できるようになるとともに,全文検索,ジャーナル検索,著者検索,タグ
(キーワード)検索が利用できるようになる.また,論文情報の登録などに BIBTEX 情報を
活用することも本システムの特徴のひとつである.本論文では文献 PDF データベースシ
ステムの詳細について議論するとともに,性能評価実験の結果を考察する.

研究者が自身で収集した学術論文の文献 PDF ファイルを効率的に管理し,研究活動に有効活用することを目的として,文献 PDF データベースシステムを開発した.利用者は PDF ファイルを Web ブラウザからサーバにアップロードすることで,PDF ファイルを一元的に管理できるようになるとともに,全文検索,ジャーナル検索,著者検索,タグ (キーワード)検索が利用できるようになる.また,論文情報の登録などに BIBTEX 情報を活用することも本システムの特徴のひとつである.本論文では文献 PDF データベースシステムの詳細について議論するとともに,性能評価実験の結果を考察する.
wc-4

これで日本語文字が正しくワードクラウドに埋め込まれました.しかし,英文と違って日本語は単語がスペースで区切られていないので,想像した結果にはなりませんでした.

目次に戻る

日本語のワードクラウドを作成する(成功例)

最後にここと同じ方法によって,日本語文章を分かち書きし,さらに名詞だけを抽出することで,理想通りのワードクラウドを作成できました.


from wordcloud import WordCloud
import os
import re
import MeCab as mc

def strip_CRLF_from_Text(text):
    """テキストファイルの改行,タブを削除し,形態素解析を実行する.
    改行前後が日本語文字の場合は改行を削除する.
    それ以外はスペースに置換する.
    """
    # 改行前後の文字が日本語文字の場合は改行を削除する
    plaintext = re.sub('([ぁ-んー]+|[ァ-ンー]+|[\\u4e00-\\u9FFF]+|[ぁ-んァ-ンー\\u4e00-\\u9FFF]+)(\n)([ぁ-んー]+|[ァ-ンー]+|[\\u4e00-\\u9FFF]+|[ぁ-んァ-ンー\\u4e00-\\u9FFF]+)',
                       r'\1\3',
                       text)
    # 残った改行とタブ記号はスペースに置換する
    plaintext = plaintext.replace('\n', ' ').replace('\t', ' ')
    return plaintext

def mecab_wakati(text):
    """
    MeCabで分かち書き.
    ただし品詞は名詞だけに限定.
    """
    t = mc.Tagger()  # for Windows
    # t = mc.Tagger('-r /dev/null -d /opt/homebrew/lib/mecab/dic/ipadic')  # for macOS
    # t = mc.Tagger('-r /dev/null -d /opt/homebrew/lib/mecab/dic/mecab-ipadic-neologd')

    node = t.parseToNode(text)
#     print(node)
    sent = ""
    while(node):
#         print(node.surface, node.feature)
        if node.surface != "":  # ヘッダとフッタを除外
            word_type = node.feature.split(",")[0]
            # 名詞だけをリストに追加する
            if word_type in ["名詞"]:
                 sent += node.surface + " "  # node.surface は「表層形」
            # 動詞(の原型),形容詞,副詞もリストに加えたい場合は次の2行を有効にする
            if word_type in [ "動詞", "形容詞","副詞"]:
                sent += node.feature.split(",")[6] + " " # node.feature.split(",")[6] は形態素解析結果の「原型」
        node = node.next
        if node is None:
            break
    return sent

# テキストファイル読み込み
f = open(os.path.sep.join(['corpora', 'ja_abs_1.txt']), encoding='utf-8')
raw = f.read()
f.close()
print(raw)
text = strip_CRLF_from_Text(raw)
print(text)
sent = mecab_wakati(text)
print(sent)

# フォントの保存先を指定する(環境によって書き換えてください)
# font_path = "C:\\WINDOWS\\FONTS\\MEIRYO.TTC"    ## Windows 版はこちら
font_path = "/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc"  ## Mac 版はこちら

# WordCloud画像を生成する
wc = WordCloud(max_font_size=36, font_path=font_path).generate(sent)
wc.to_file("wc-5.png")
研究者が自身で収集した学術論文の文献 PDF ファイルを効率的に管理し,研究活動に
有効活用することを目的として,文献 PDF データベースシステムを開発した.利用者は
PDF ファイルを Web ブラウザからサーバにアップロードすることで,PDF ファイルを
一元的に管理できるようになるとともに,全文検索,ジャーナル検索,著者検索,タグ
(キーワード)検索が利用できるようになる.また,論文情報の登録などに BIBTEX 情報を
活用することも本システムの特徴のひとつである.本論文では文献 PDF データベースシ
ステムの詳細について議論するとともに,性能評価実験の結果を考察する.

研究者が自身で収集した学術論文の文献 PDF ファイルを効率的に管理し,研究活動に有効活用することを目的として,文献 PDF データベースシステムを開発した.利用者は PDF ファイルを Web ブラウザからサーバにアップロードすることで,PDF ファイルを一元的に管理できるようになるとともに,全文検索,ジャーナル検索,著者検索,タグ (キーワード)検索が利用できるようになる.また,論文情報の登録などに BIBTEX 情報を活用することも本システムの特徴のひとつである.本論文では文献 PDF データベースシステムの詳細について議論するとともに,性能評価実験の結果を考察する.
研究 者 自身 収集 学術 論文 文献 PDF ファイル 効率 的 管理 研究 活動 有効 活用 こと 目的 文献 PDF データベースシステム 開発 利用 者 PDF ファイル Web ブラウザ サーバ アップ ロード こと PDF ファイル 一元 的 管理 よう 全文 検索 ジャーナル 検索 著者 検索 タグ キーワード 検索 利用 よう 論文 情報 登録 BIBTEX 情報 活用 こと システム 特徴 ひとつ 論文 文献 PDF データベースシステム 詳細 議論 性能 評価 実験 結果 考察
wc-5

なお,上のコードの 24-25 行目をコメントアウトし,26 行目を有効にして,高機能な mecab-ipadic-NEologd 辞書 を使うと,次のような結果になります.上の結果と比較すると,「全文検索」「効率的」「有効活用」「研究者」「利用者」「一元的」「アップロード」などがそれぞれ一つの単語として認識されていることがわかります.

wc-5-neo

目次に戻る

様々なオプションを試す

ここまでは,max_font_sizefont_path というオプションを使用してきましたが,他にも様々なオプションを指定できます.一旦 font_path だけを指定した結果を示します.


wc = WordCloud(
        font_path=font_path
    ).generate(sent)
wc.to_file("wc-6.png")
wc-6

WordCloud のソースコード (wordcloud/wordcloud.py) を参照すると,次のようなオプションが使用できるようです.font_path 以外はデフォルトの値を設定しています.具体的には,WordCloud のソースコード (wordcloud/wordcloud.py) において class WordCloud(object): でクラスの定義がありますが,この中の def __init__(): 関数の定義を見れば確認できます.2022年1月時点では 309 行目です.


wc = WordCloud(
        font_path=font_path, width=400, height=200, margin=2,
        ranks_only=None, prefer_horizontal=.9, mask=None, scale=1,
        color_func=None, max_words=200, min_font_size=4,
        stopwords=None, random_state=None, background_color='black',
        max_font_size=None, font_step=1, mode="RGB",
        relative_scaling='auto', regexp=None, collocations=True,
        colormap=None, normalize_plurals=True, contour_width=0,
        contour_color='black', repeat=False,
        include_numbers=False, min_word_length=0, collocation_threshold=30
    ).generate(sent)
wc.to_file("wc-7.png")
wc-7

background_color を変更してみます.


wc = WordCloud(
        font_path=font_path,
        background_color='white',
    ).generate(sent)
wc.to_file("wc-8.png")
wc-8

repeat = True を設定すると,同じ単語がいくつも表示されるようになります.


wc = WordCloud(
        font_path=font_path,
        repeat=True,
    ).generate(sent)
wc.to_file("wc-9.png")
wc-9

min_font_size = 20 を設定します.


wc = WordCloud(
        font_path=font_path,
        min_font_size=20,
    ).generate(sent)
wc.to_file("wc-10.png")
wc-10

目次に戻る

画像ファイルでマスクする

次は画像ファイルでマスクしたワードクラウドを作成してみましょう.まずは白黒(実際のデータは256階調のグレースケール)画像を準備します.サンプルのデータは GitHub に置いてあるので,ダウンロードしてソースと同じフォルダに設置してください.

画像データを読み込んで取り扱うために2つのライブラリをインポートします.


from PIL import Image
import numpy as np

画像データを Jupyter Notebook 内で表示するには,「セルの種別」を「マークダウン」に変更して,次のように入力します.なお,マークダウンの使い方はここを参照してください


![ink_bk](ink_bk.png)
ink_bk

画像データを開いて,NumPy 配列に格納します.256階調のグレースケールになっていることが確認できるはずです.


ink_mask = np.array(Image.open("ink_bk.png"))
ink_mask
array([[255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       ...,
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)

画像でマスクするにために,mask オプションを指定します.この結果,インクボトルの形にマスクされていることが(多少は)わかります.


wc = WordCloud(
        font_path=font_path,
        mask=ink_mask,
    ).generate(sent)
wc.to_file("wc-11.png")
wc-11

背景色を変更します.


wc = WordCloud(
        font_path=font_path,
        mask=ink_mask,
        background_color="white",
    ).generate(sent)
wc.to_file("wc-12.png")
wc-12

輪郭線の太さを設定することで,インクボトルの形状がはっきりと認識できるようになりました.


wc = WordCloud(
        font_path=font_path,
        mask=ink_mask,
        background_color="white",
        contour_width=3,
    ).generate(sent)
wc.to_file("wc-13.png")
wc-13

輪郭線の色を指定します.


wc = WordCloud(
        font_path=font_path,
        mask=ink_mask,
        background_color="white",
        contour_width=3,
        contour_color='blue',
    ).generate(sent)
wc.to_file("wc-14.png")
wc-14

目次に戻る