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

# ☁ WordCloudとは
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307359/1d02cedb-6a6b-0a10-b1b6-19922f4a1e72.png" width=70%>

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

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

# 📖 今回やりたいこと
１、WordCloudを作成してみる。
２、猫の形などユニークなWordCloudに挑戦
３、**日本語文章でMecab（形態素解析エンジン）を使用せずに実現する（思い付き）**
　  

## ・準備

・Python3
・WordCloud

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

```
pip install wordcloud
```


オープンソースなので本家GitHubのURL載せておきます。
【GitHub】[word_cloud - amueller](https://github.com/amueller/word_cloud)
　  

# ☁️ WordCloudの実践

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

```python3: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つ表示されるのを防ぐ
　  
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307359/1d02cedb-6a6b-0a10-b1b6-19922f4a1e72.png" width=70%>

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

# 🇯🇵 日本語でWordCloud
では次に私のTwitter([@aocattleya](https://twitter.com/aocattleya))の過去全ツイートで作成してみます。
Twitterにて、[設定とプライバシー] → [Twitterデータ] → [データをリクエスト]
自分の全てのツイートがDL出来ます。（分析するテキストは何でもOK）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307359/05034453-215b-57a3-2db1-88ad432ed171.png" width=70%>

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

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

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

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

----

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

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

### a〜Zを削除

```py
'''---------
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文字以下のカタカナを削除

```py
'''---------------------
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文字以下の ひらがな を削除

```py
'''---------------------
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文字以下の漢字を削除

```python3: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***](https://github.com/aocattleya/WordCloud-Japanese_Sample/blob/master/default_visualwords.py)（GitHub）

実行してみます↓↓↓
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307359/ae1a64b7-6552-f48b-3e9b-08e46017fb63.png" width=70%>

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

# 🐱 WordCloud　猫ver.

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307359/43a61f7e-94e9-dbe4-b353-bfe354770321.png" width=30%>

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

```py
from PIL import Image
import numpy as np

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

```py

'''-----------
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***](https://github.com/aocattleya/WordCloud-Japanese_Sample/blob/master/visualwords.py)（GitHub）

実行してみます↓↓↓

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307359/2c13c582-b283-68f9-fdb1-f67ef38b3c1b.png" width=70%>

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

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

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

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


今回は、カタカナや漢字などを指定しましたが面白そうです。
　  
　  
コードはリポジトリにまとめています。
【GitHub】[***WordCloud-Japanese - aocattleya***](https://github.com/aocattleya/WordCloud-Japanese_Sample)

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

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

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

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

WordCloud自体は結構有名な物なので、ぜひ色々試してみて下さい！
　  
## ・参考
・ [Pythonでテキストマイニング　②Word Cloudで可視化](https://qiita.com/furipon308/items/be97abf25cf4caa0574e)
・ [Word Cloudで同じ単語が2回出てきて困る](https://qiita.com/kbs/items/33b3dd6dae15f7b20b9e)
　  
# ～ リンク ～
🐦 Twitter
　https://twitter.com/aocattleya
:octocat: GitHub
　https://github.com/aocattleya
📗 Qiita 
　https://qiita.com/aocattleya