簡単!日本語でWordCloud(任意の単語の除外も)

知り合いから相談されて、WordCloudがpythonで実装できないか、調べてやってみた。
思ったよりも、簡単にできた。
「必要ない単語を除外」というのが一工夫だったが、これもリストの操作で簡単にできた。

調べてみたところ、英語のWordCloudについてはいろいろ解説があったが、日本語については少なかったので、自分の整理のために備忘録として残しておく。

アーニャ・フォージャーについてのpixivの紹介文のWordCloud
  • Jupyter lab Desktop Version 3.2.9-1
  • wordcloud 1.8.1
  • matplotlib 3.5.1
  • numpy 1.22.2
  • pandas 1.4.1
  • Janome 0.4.2
スポンサーリンク

WordCloudにした「テキストファイル」を読み込もう

まず、以下のライブラリーを読み込み。そんなの無いよと言われたら、
>pip install <ライブラリー名>
しておく。

%matplotlib inline
import os
import wordcloud
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from janome.tokenizer import Tokenizer
from PIL import Image

そして、WordCloudにしたいテキストの読み込みです。
やや、複雑になっていますが、
C:\Users\Username\Jupyter\data\wc\text1.txt
を読み込むように指示しています。

単純にpathを
path = …
と書き込んでもOKです。

ただ、こうしておけば、
C:\Users\Username\Jupyter\data\wc\
の中にtext2.txt,text3.txt,…と様々なファイルをいれて、titleを変えるだけでどんどん、wordcloudを作成することができます。
(さらに、outputを画像で保存するとき、titleによってファイル名を変えて変更されます。)

#ファイルの指定->title,dir_nameに該当ファイル名,フォルダ名を入力。
title = 'text1'
dir_name1 = 'data'
dir_name2 = 'wc'
keishiki = '.txt'
path1 = r'C:\Users\Username\Jupyter'

#テキストの読み込み 
path = os.path.join(path1, dir_name1, dir_name2, title) + keishiki
print(path)
f = open(path, 'r', encoding = 'UTF-8')
text = f.read()

ちなみに今回はテストで、アーニャ・フォージャーのpixivの紹介文をtext1.txtとして読み込んでみます。

スポンサーリンク

テキストを自動で種類別に分ける

次に、janomeというライブラリーを使って、対象のファイルを単語や動詞などキーワードに区別していきます(※1)。すごい!便利~。

tk = Tokenizer()
words_list = []

#動詞、形容詞、形容動詞、名詞、副詞、連体詞、接続詞、感動詞、助動詞、助詞のどれを抽出するか。

hinshi = ['動詞','形容詞','形容動詞','名詞','副詞','感動詞']

for i in hinshi:
    for token in tk.tokenize(text):
        if token.part_of_speech.split(",")[0] == i:
            words_list.append(token.surface)
          
#1文字の単語を出現させるにはregexpの設定が必要
wc = wordcloud.WordCloud(width=2000, height=1200, 
                         background_color="white", font_path=r"C:\Windows\Fonts\UDDigiKyokashoN-B.ttc",
                         regexp="[\w']+")

hinshi = [‘動詞’,’形容詞’,’形容動詞’,’名詞’,’副詞’,’感動詞’]

の中に、好きな品詞の種類を入れればOKです。

空のwords_listというリストを作って、そこに、文節ごとに分類した単語を、hinshiリストに入っているものと照合し、会うモノだけこのリストに入れる…という操作です。

日本語については、一文字の単語にも意味があるものが多いので、regexpの設定で残しています。(英単語だと一文字は意味ないのでデフォルトでは消去される。)

C:\Windows\Fonts\の中の、好きなフォントも選んで描画できます。

さ、で、実はこれでもう描画できます。下記のコード(※2)を実行してみてください。

#画像の大きさを設定
figsize_px = np.array([1280, 720])
dpi = 100
figsize_inch = figsize_px / dpi
print("figsize", figsize_inch)  # figsize (6.4, 3.6)
fig, ax = plt.subplots(figsize=figsize_inch, dpi=dpi)

#描画する
wc.generate(" ".join(words_list))
plt.imshow(wc)
plt.axis("off")
#保存先の指定
dir_name1 = 'out'
keishiki = '.png'
path = os.path.join(path1, dir_name1, dir_name2, title) + keishiki
print(path)

#画像の保存
plt.savefig(path)

C:\Users\Username\Jupyter\out\wc\text1.png
に画像が保存されるようにしてあります。

おお~。っぽい。
のですが、「する」とか「よう」とか「ため」とか、あまり意味ない単語もまじってしまっております。これを除去するにはどうしたら良いのでしょうか?

スポンサーリンク

必要ない単語を除去する

描画する前、janomeで言葉を品詞別に区別した※1のコードのあとに、こんなコードを入れてみました。
▽区分けされた単語の上位50位ランキングを確認する
というコードです。

import collections
c = collections.Counter(words_list)
print(c.most_common(50))

結果はこちら。

[('アーニャ', 51), ('し', 38), ('いる', 38), ('%', 32), ('こと', 21), ('ロイド', 18), ('れ', 17), ('能力', 15), ('さ', 14), ('3', 13), ('する', 12), ('E', 11), ('的', 11), ('い', 10), ('おり', 10), ('心', 9), ('ヨル', 9), ('家族', 9), ('ため', 9), ('83', 8), ('よう', 8), ('ち', 7), ('なっ', 7), ('フォージャー', 7), ('家', 7), ('任務', 7), ('ダミアン', 7), ('読む', 6), ('なる', 6), ('ある', 6), ('人物', 6), ('被験', 6), ('体', 6), ('隠し', 5), ('呼ば', 5), ('正体', 5), ('彼', 5), ('イーデン', 5), ('校', 5), ('協力', 5), ('ボンド', 5), ('せ', 4), ('.', 4), ('A', 4), ('登場', 4), ('者', 4), ('犬', 4), ('歳', 4), ('一', 4), ('自身', 4)]

おお~。区分けされたリストの内容が、回数の多い順に並んでいます。
これをみて、除外する単語を選んでいきます。

#jogaiに消去したい単語を登録)
jogai = ['し','いる','%','こと','れ','さ','する','的','い','おり','ため','よう','ち','なっ','なる','ある','せ']

#jogaiに登録した単語【以外】のwords_listを作り直す≓リストからjogaiの要素を全削除
for i in jogai:
    words_list = [a for a in words_list if a != i]

これまで、
▽text.1を読み込み
 →品詞ごとに区別
 →words_listというリストに格納
ということをやってきました。

さらに除外したい単語を格納したjogaiというリストをつくってやります。
で、「そのjogaiに入っている【以外】の要素だけ残した新しいwords_listを作れ」という命令です。

これで、再度、描画してみます。

#画像の大きさを設定
figsize_px = np.array([1280, 720])
dpi = 100
figsize_inch = figsize_px / dpi
print("figsize", figsize_inch)  # figsize (6.4, 3.6)
fig, ax = plt.subplots(figsize=figsize_inch, dpi=dpi)

#描画する
wc.generate(" ".join(words_list))
plt.imshow(wc)
plt.axis("off")
#保存先の指定
dir_name1 = 'out'
keishiki = '.png'
path = os.path.join(path1, dir_name1, dir_name2, title) + keishiki
print(path)

#画像の保存
plt.savefig(path)

だいぶ様子が変わって、「意味のありそうな単語」が前面に出てくるようになりました。

code初心者のつぶやき
スポンサーリンク
スポンサーリンク
シェアする
ton2net.com

コメント