【Python】WordCloudでリアルタイムに話題を可視化

WordCloudという文章に使われている単語の傾向を可視化するpythonのツールがあります。

これをニュースサイトの記事に使えば以下のような図が得られます。2022/12/10現在の社会ニュースでよく取り上げられている単語が強調されて表示されています。

このように入力された文章の頻出単語を調べ、頻度が多い順から強調して表示することで、文章の傾向を把握することができるツールです。
![2023_03_22_22WordCloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/c2abac0c-2d0b-b210-4ffd-fda3555493e4.png)

WordCloudの用途は様々です。Twitterで個人のつぶやきの傾向を調べてみたり、国会文章からある時期の国政の関心を調べてみたり。

https://ikesala.com/wordcloud-2/

https://www.mediatechnology.jp/entry/parliamentary-bills-database

今回は、ニュースサイトのRSS機能を使って、リアルタイムの社会の話題を可視化してみます。

# 概要
手順は以下の通りです。

・RSSからニュース記事の文章を取得する

・ニュース記事の形態素解析を行い単語に分類する

・単語の出現回数をカウントし出現回数に応じたワードクラウド画像を作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/abb82616-86d6-6363-5703-2a126609a69e.png)

## 形態素解析
形態素解析とは、文章を単語（形態素）のレベルまで分割し、その品詞（名詞、動詞、助詞など）を判定することです。例えば「吾輩は猫である」を形態素解析すると

吾輩 / は / 猫 / で / ある

のようになります。

今回はワードクラウドを作りたいので、janome.tokenizerを使って名詞のみを抽出します。

# 準備
以下の準備が必要です。

・作業用フォルダの作成
・RSSのURL指定ファイルの作成
・パッケージのインストール
・フォントの準備

## 作業用フォルダの作成
適当な場所に作業用フォルダを準備してください。
必要なファイルやソースコードはここに置きます。

## RSS のURL指定ファイルの作成
ワードクラウドの作成に使いたいニュースサイトのRSSを指定します。
使いたいRSSのURLをピックアップし、以下のようなCSVファイルを作成して作業フォルダにおいてください。
ソースは多いほうがいいです。
|  提供者  |  RSS  |
| ---- | ---- |
|  ニュースサイトA  |  https://********  |
|  ニュースサイトB  |  https://********  |

使用するRSSのジャンルによって、ワードクラウドの結果が変わります。
社会ニュースで作りたければ社会ニュースのRSSを、スポーツで作りたければスポーツニュースのRSSを指定してください。
ニュース系のRSSであれば一覧がYahooから提供されています。

https://news.yahoo.co.jp/rss

## パッケージのインストール
以下の4つのパッケージが必要ですのでインストールされていなければインストールしてください。
```python
pip install feedparser
pip intasll janome
pip install wordcloud
pip install pandas
```

## フォントの準備
WordCloudは日本語に対応していないので、そのまま使うと文字化けしてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/ca54cb58-37cb-2b1b-66d8-095e426aef81.png)
そのため、日本語対応したフォントを指定する必要があります。

PC 内のフォントは”C:\Windows\Fonts”に保管されていますので、ここから使いたいフォントを探し作業用フォルダにコピーします。私は”meiryo.ttc”を使用しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/71e7e3ab-d56b-37d3-74f7-4073cfc40d49.png)

# 実装
準備が整ったら実装していきましょう。

## パッケージのインポート
必要なパッケージをインポートします。
```python
import feedparser
import pandas as pd
from janome.tokenizer import Tokenizer
from wordcloud import WordCloud
import re
```

## ファイルの指定
用意したフォントファイルのパスとRSSを指定したcsvファイルを読み込みます。

フォントファイルをソースコードと同じフォルダに置いている場合は以下のコピペでよいですが、別の場所に置いている場合、パスを指定してください。
```python
FONT_PATH = "meiryo.ttc"
URLs = pd.read_csv('RSS.csv', encoding="shift-jis")
```

##形態素解析
janome.tokenizerを使って、与えられたテキストの形態素解析を行い、テキスト中の名詞のリストを返す関数を作ります。
```python
def get_word_str(text):
    
    t = Tokenizer()
    token = t.tokenize(text)
    word_list = []
 
    for line in token:
        tmp = re.split('\t|,', str(line))
        if tmp[1] in ["名詞"]:
            if tmp[2] in ["一般", "固有名詞"]:
                word_list.append(tmp[0])
 
    return " " . join(word_list)
```

## WordCloud画像の作成
RSSから記事のテキストを取得し、形態素解析関数に投げ、得た名詞のリストをWordCloudにかけることで画像を作成します。
```python
word_str = ""

for i in URLs.index:
    RSS_URL = URLs['RSS'][i]

    d = feedparser.parse(RSS_URL)
    for entry in d.entries:
      if hasattr(entry, 'title'):
        word_str = word_str + " " + get_word_str(entry.description)
word_str_c = word_str.split(' ')

# 画像作成
wc = WordCloud(background_color='white',font_path=FONT_PATH, max_font_size=75, width=960,height=640, max_words=80).generate(word_str)

# 画像保存
wc.to_file("WordCloud.png")
```

実行すると作業用フォルダにワードクラウド画像が生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2605106/92097f72-022f-5962-4f80-dd872bc44089.png)

# コード全文
```python
import feedparser
import pandas as pd
from janome.tokenizer import Tokenizer
from wordcloud import WordCloud
import re

FONT_PATH = "meiryo.ttc"
URLs = pd.read_csv('RSS.csv', encoding="shift-jis")

def get_word_str(text):
    t = Tokenizer()
    token = t.tokenize(text)
    word_list = []
 
    for line in token:
        tmp = re.split('\t|,', str(line))
        # 名詞のみ対象
        if tmp[1] in ["名詞"]:
            # さらに絞り込み
            if tmp[2] in ["一般", "固有名詞"]:
                word_list.append(tmp[0])
 
    return " " . join(word_list)

word_str = ""

for i in URLs.index:
    RSS_URL = URLs['RSS'][i]
    d = feedparser.parse(RSS_URL)
    for entry in d.entries:
      if hasattr(entry, 'title'):
        word_str = word_str + " " + get_word_str(entry.description)
word_str_c = word_str.split(' ')

# 画像作成
wc = WordCloud(background_color='white',font_path=FONT_PATH, max_font_size=75, width=960,height=640, max_words=80).generate(word_str)

# 画像保存
wc.to_file("WordCloud.png")
```

コードはgithubにも置いています。

https://github.com/BB-engineer/sandbox/tree/main/WordCloud

# まとめ
今回はPythonのワードクラウドを用いてリアルタイムに社会の話題を可視化する方法について説明しました。

今回は社会ニュースで行いましたが、スポーツやガジェット系のニュースサイトを使っても面白いかと思います。

また、今回は今現在取得できる記事のみでワードクラウド作成を行いましたが、ある程度の期間内で出た記事を貯めておき、そこからワードクラウドを作成し前後の時期で比較してみる、というのも面白そうです。

以上、ご覧いただきましてありがとうございました。