Word Cloudでツイートを可視化してみた(python)

# はじめに
現場でデータサイエンスチームが文章を形態素解析して、ビジュアル化しているのを見て自分でもやってみたいと思いました。
そのため、今回はtwitterのツイート情報取得して、Word Cloudで可視化をしてみました。
言語はpythonを使用しました。

ソースコードはこちらに上げております。
https://github.com/nsuzuki7713/twitter-analysis

## 用語
### 形態素解析
文章・フレーズを「意味を持つ最小限の単位」に分解すること。
例えば、
「私は会社でプログラミングをします」 という文章を形態素解析を行うと、
「私 / は / 会社 / で / プログラミング / を / し / ます」　のように最小限の単位に分割できます。

### Word Cloud
文章中で出現頻度が高い単語を複数選び出し、その頻度に応じた大きさで図示する手法。  文字の大きさだけでなく、色、字体、向きに変化をつけることで、文章の内容をひと目で印象づけることができます。

Pythonでもこのライブラリが実装されています。
http://amueller.github.io/word_cloud/index.html

## Twitter APIの取得
[Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ](https://qiita.com/kngsym2018/items/2524d21455aac111cdee)
https://www.torikun.com/entry/twitter-developer-api
僕は上記2つの記事を参考にしました。英語はGoogle翻訳を使用して入力しました。

## pythonやライブラリをインストール
python等はanacondaを使って構築しています。
[MacでJupyter Notebook(Anaconda)を利用する手順](https://qiita.com/turmericN/items/37ea643439c40c556aa4)

また、ライブラリも必要になるのでインストールします。

```
# Python 用の OAuth 認証ライブラリ
pip install requests-oauthlib

# Pythonの形態素解析エンジン
pip install janome

# Word Cloudのライブラリ
pip install wordcloud

#  絵文字を扱うためのライブラリ
pip install emoji --upgrade
```

## ツイートデータの取得
```python:getTimeLines2.py
import json
import config
from requests_oauthlib import OAuth1Session
from time import sleep
import emoji

# 絵文字を除去する
def remove_emoji(src_str):
    return ''.join(c for c in src_str if c not in emoji.UNICODE_EMOJI)

# APIキー設定(別ファイルのconfig.pyで定義しています)
CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET

# 認証処理
twitter = OAuth1Session(CK, CS, AT, ATS)  

# タイムライン取得エンドポイント
url = "https://api.twitter.com/1.1/statuses/user_timeline.json"  

# パラメータの定義
params = {'screen_name': '@以降のアカウント名を記載',
          'exclude_replies': True,
          'include_rts': False,
          'count': 200}

# 出力先ファイル
f_out = open('./output/tweet_data', 'w')

for j in range(100):
    res = twitter.get(url, params=params)
    if res.status_code == 200:
        # API残り回数
        limit = res.headers['x-rate-limit-remaining']
        print("API remain: " + limit)
        if limit == 1:
            sleep(60*15)

        n = 0
        timeline = json.loads(res.text)
        # 各ツイートの本文を表示
        for i in range(len(timeline)):
            if i != len(timeline)-1:
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　# 絵文字があると、wordcloudが使用できないため、削除する
                f_out.write(remove_emoji(timeline[i]['text']) + '\n')
            else:
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　# 絵文字があると、wordcloudが使用できないため、削除する
                f_out.write(remove_emoji(timeline[i]['text']) + '\n')
                # 一番最後のツイートIDをパラメータmax_idに追加
                params['max_id'] = timeline[i]['id']-1

f_out.close()
```

APIのリクエスト制限上、ループを回してツイート情報を取得しています。
`python getTimeLines2.py`　で実行すると、出力先ファイルにツイート情報が保存されると思います。

## Word Cloudの生成
```python:wordcloud.py
# coding:utf-8
import csv
from janome.tokenizer import Tokenizer
import matplotlib.pyplot as plt
from wordcloud import WordCloud
from bs4 import BeautifulSoup
from collections import Counter, defaultdict

# 名詞だけ抽出、単語をカウント
def counter(texts):
    t = Tokenizer()
    words_count = defaultdict(int)
    words = []
    for text in texts:
        tokens = t.tokenize(text)
        for token in tokens:
            # 品詞から名詞だけ抽出
            pos = token.part_of_speech.split(',')[0]
            if pos in ['名詞']:
                # 必要ない単語を省く(実際の結果を見てから不必要そうな単語を記載しました)
                if token.base_form not in ["こと", "よう", "そう", "これ", "それ"]:
                    words_count[token.base_form] += 1
                    words.append(token.base_form)
    return words_count, words

with open('./output/tweet_data', 'r') as f:
    reader = csv.reader(f, delimiter='\t')
    texts = []
    for row in reader:
        if(len(row) > 0):
            text = row[0].split('http')
            texts.append(text[0])

words_count, words = counter(texts)
text = ' '.join(words)

# fontは自分の端末にあるものを使用する
fpath = "~/Library/Fonts/RictyDiminished-Bold.ttf"
wordcloud = WordCloud(background_color="white",
                      font_path=fpath, width=900, height=500).generate(text)

wordcloud.to_file("./wordcloud_sample.png")
```

`python wordcloud.py` を実行すると、Word Cloud の画像を出力されると思います。

## 結果
自分のツイートだとこんな結果になりました。

**特徴**

- 「自分」：一人称でよく使っているから
- 「おしごと」：おしごとamというpodcastを聴いて、感想を書いていたから
- 技術、コード、エンジニア、勉強とかが大きいので、エンジニア向けのツイートが多い
- 趣味のツイートは少なそう

![wordcloud_sample.png](https://qiita-image-store.s3.amazonaws.com/0/226008/5f6a9b89-21b7-91ed-90bf-ad26aed6d687.png)

## おわりに
すでに多くの方がコードを残しているので、苦労せずに進めることができました。
勉強会などのツイートを可視化することで、どういった内容が反響があったのかが分かりそうです。
汎用性は高いと思うので、色々試してみたいと思います。

## 参考サイト
[Python で Twitter API を利用していろいろ遊んでみる](https://qiita.com/bakira/items/00743d10ec42993f85eb)
[【Python でテキストマイニング】Twitter データを WordCloud で可視化してみる](http://www.randpy.tokyo/entry/python_wordcloud)
[python で絵文字を駆逐する](https://qiita.com/yoshimo123/items/85331d881aed9ad41020)