LoginSignup
15
17

More than 3 years have passed since last update.

【Python】WordCloudで日本語をMecabを使用せずに形態素解析チックな表示を実現する

Last updated at Posted at 2019-07-30

☁ WordCloudとは

文章中で出現頻度の高い単語を複数選び出し、その頻度に応じた大きさで図示する手法。

上記は実際に『レディー・ガガ』の『Born This Way』の歌詞で作成してみました。
この様にテキスト内の出現頻度の高い単語が大きく表示されビジュアル化出来ます。
そして比較的に簡単なコードで実践出来ます!
 

📖 今回やりたいこと

1、WordCloudを作成してみる。
2、猫の形などユニークなWordCloudに挑戦
3、日本語文章でMecab(形態素解析エンジン)を使用せずに実現する(思い付き)
 

・準備

・Python3
・WordCloud

Macはpipでインストール出来ます。

pip install wordcloud

オープンソースなので本家GitHubのURL載せておきます。
【GitHub】word_cloud - amueller
 

☁️ WordCloudの実践

1、同じフォルダに、analyze.txt を作成して分析したい文章を入れて保存する。
2、Pythonコードを書きます。

visualwords.py
# coding: utf-8
from wordcloud import WordCloud

# 作成したテキストの読み込み
with open('analyze.txt', 'r') as f:
    text = f.read()

# 除外したい単語
stop_text = ["ぴよぴよ", "ぽよぽよ"]

# wordcloudの設定
wordcloud = WordCloud(background_color="white",
            font_path="/system/Library/Fonts/ヒラギノ角ゴシック W4.ttc",
            collocations = False,
            stopwords = stop_text,
            width=800,height=600).generate(text)

# worcloudの作成
wordcloud.to_file("./wordcloud.png")

・設定の補足
font_path="" にはPCのフォントパスを指定します。(上記はMac)
collocations = False 同じ単語が2つ表示されるのを防ぐ
 

無事、レディー・ガガの『Born This Way』の歌詞で作成出来ました。
手軽に使ってみるだけならとても簡単ですね!
 

 

🇯🇵 日本語でWordCloud

では次に私のTwitter(@aocattleya)の過去全ツイートで作成してみます。
Twitterにて、[設定とプライバシー] → [Twitterデータ] → [データをリクエスト]
自分の全てのツイートがDL出来ます。(分析するテキストは何でもOK)

上手く出来ませんね...。
スペースで区切られてる英語文章と違い日本語はWordCloudに対応していません。
なので、Mecabという形態素解析エンジンを使うのが一般的です。
※今回は使いません。

・Mecabとは

オープンソースの形態素解析エンジン。
現GoogleソフトウェアエンジニアでGoogle 日本語入力開発者の一人である工藤拓によって開発されている。

簡単に説明すると、名詞や助詞などを判別してくれます。

Mecabの名称は開発者の好物メカブ
       ↓
Mecab の 名称 は 開発者 の 好物 メカブ


今回、簡単にWordCloudを試すのにインストールの面倒なMecabを入れるほどかな...。
と考えていると、自分でスペース区切りにすれば?と思いついたのでやってみました。

試行錯誤の結果、見栄えを良くする為に以下を削除します。(自由に変更可)
・a〜Z   全て
・カタカナ 3文字以下
・ひらがな 4文字以下
・漢字   2文字以下

a〜Zを削除

'''---------
a-Zを全て削除
---------'''
romaji = re.compile("[a-zA-Z]+")
text = romaji.sub("", text)

re.compile("[a-zA-Z]+")
正規表現でa〜z、A〜Zを指定します。

そして分析するテキスト内から見つけ出し → 空文字へ置換
(正規表現の置換の場合は、replaceではなくsub)

テキスト内からa-z,A-Zが削除されました。

3文字以下のカタカナを削除

'''---------------------
3文字以下の カタカナ を削除
---------------------'''
found_katanaka_list = []
four_text_list = []
pos = 0
katanaka_pattern = re.compile('[ァ-ヴ]+')

while True:

    match1 = katanaka_pattern.search( text, pos )

    if match1 == None:
        break

    # 見つかったカタカナの後からループ開始
    pos = match1.end( 0 )

    found_katanaka_list.append(match1[0])

for katakana_words in found_katanaka_list:

    # 文字数指定
    if len(katakana_words) >= 4:
        four_text_list.append(katakana_words)

text = katanaka_pattern.sub(" ", text)

for katakana in four_text_list:
    text += " " + katakana + " "

内容は、
1、正規表現でテキスト内からカタカナを見つけ出しリスト1へ追加(While文1つ目)
2、リスト1内から4文字以上のカタカナを見つけ出しリスト2へ追加(for文1つ目)
3、テキスト内のカタカナ全てを削除(下から4行目)
4、テキスト内にリスト2を前後にスペースを付けて追加(for文2つ目)

これで、分析するテキストファイルから3文字以下のカタカナが消え、
4文字以上のカタカナの前後に、スペースが付いた状態で追加出来ました。

4文字以下の ひらがな を削除

'''---------------------
4文字以下の ひらがな を削除
---------------------'''
found_hiragana_list = []
five_text_list = []
pos = 0
hiragana_pattern = re.compile('[ぁ-ん]+')

while True:

    match2 = hiragana_pattern.search( text, pos )

    if match2 == None:
        break

    pos = match2.end( 0 )

    found_hiragana_list.append(match2[0])

for hiragana_words in found_hiragana_list:

    # 文字数指定
    if len(hiragana_words) >= 5:
        five_text_list.append(hiragana_words)

text = hiragana_pattern.sub(" ", text)

for hiragana in five_text_list:
    text += " " + hiragana + " "

2文字以下の漢字を削除

visualwords.py
'''----------------
2文字以下の 漢字 を削除
----------------'''
found_kanzi_list = []
three_text_list = []
pos = 0
kanzi_pattern = re.compile('[一-龥]+')

while True:

    match3 = kanzi_pattern.search( text, pos )

    if match3 == None:
        break

    pos = match3.end( 0 )
    found_kanzi_list.append(match3[0])

for kanzi_words in found_kanzi_list:

    # 文字数指定
    if len(kanzi_words) >= 3:
        three_text_list.append(kanzi_words)

text = kanzi_pattern.sub(" ", text)

for kanzi in three_text_list:
    text += " " + kanzi + " "

処理はほぼ同じ
完成した繋がったコードはこちら → default_visualwords.py(GitHub)

実行してみます↓↓↓

いい感じになりました。
これだけではありきたりな見た目なので猫の形で作成してみましょう。

🐱 WordCloud 猫ver.

背景透過した猫のpng画像を用意してmaskとして設定します。
猫以外も、もちろん可能で画像は黒でなくても大丈夫です。

from PIL import Image
import numpy as np

mask = np.array(Image.open('cat.png'))
mask = np.where(mask == 0, 0, 255)

'''-----------
WordCloudの設定
-----------'''
wordcloud = WordCloud(mask = mask,
                      stopwords = stop,
                      font_path="/system/Library/Fonts/ヒラギノ角ゴシック W4.ttc",
                      colormap = 'copper_r',
                      width=800, height=600).generate(text)

画像を読み込んで、WordCloudの設定でmaskの指定と文字色をオレンジに変更。

完成したコード → visualwords.py(GitHub)

実行してみます↓↓↓

なかなかいい感じではないでしょうか!
ひとまず満足です。


似た方法で、分析するワードを絞り作成してみるのも良いかもと思いました。

テキスト内から指定したプログラミング言語だけを見つけて他は全て削除
プログラミング言語だけの人気順WordCloud

テキスト内から指定したポケモンの名前だけを見つけて他は全て削除
ポケモンの名前だけの人気順WordCloud

今回は、カタカナや漢字などを指定しましたが面白そうです。
 

 

コードはリポジトリにまとめています。
【GitHub】WordCloud-Japanese - aocattleya

苦戦したこと

例えばテキスト内から、ひらがな4文字以下を削除しようとした場合に、
初めは4文字以下の単語を単純に見つけ出して削除していたのですが、
ひらがな全てが消えてしまう現象が起きました。

ありがとうならば,,,,で分解されて消えていた模様
なので上記のコードの、
1、テキスト内から5文字以上の、ひらがなを見つけてリストに追加
2、テキスト内からひらがな全て削除
3、後からテキスト内にリストを追加
というように修正した。
 

・問題点

君の名は。のような混ざった単語が出ない、個別に取得すれば可能だけど想定し辛い..。
・ カタカナ,ひらがな,漢字の処理が似てるので関数に出来そう?あと変数名見ずらい気がする。
  ..もうちっと力を付けるまで待っておくれ(๑•́‧̫•̀๑)
 

・終わりに

最初は簡単に実践できれば良いと思っていたのですが、
思い付きから色々やってみて、自己流ながら納得出来るように作れて楽しく嬉しかった。
正規表現は全く使ったことが無かったので使えたのも良かったです。

WordCloud自体は結構有名な物なので、ぜひ色々試してみて下さい!
 

・参考

Pythonでテキストマイニング ②Word Cloudで可視化
Word Cloudで同じ単語が2回出てきて困る
 

~ リンク ~

🐦 Twitter
 https://twitter.com/aocattleya
:octocat: GitHub
 https://github.com/aocattleya
📗 Qiita
 https://qiita.com/aocattleya

15
17
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
17