某アーティストグループは何を僕らに伝えたかったのか？？？ (WordCloudで歌詞化してみた)

こちらは<a href="https://adventar.org/calendars/5535">ITRC Advent Calendar 2020の7日目の記事です。</a>
前の記事: @hima_zin331さんの`超解像技術-SRGAN-実装してみた(Tensorflow 2.0) 推論フェーズ編`
次の記事: Comming Soon...

### はじめに
今年で某アーティストグループが活動休止する中で、当グループは結成１５年約１７０曲ほどの曲を出してきました。そこで今回は約１７０曲の歌詞を解析し、どんな単語をたくさん使い何をファンに伝えたかったのかをWordCloudで可視化してみました。

### 1. BeautifulSoup、pandasを使い歌詞をスクレイピングし、ファイルに格納する。
```:scraping.py

 import requests #URLを開くことができるライブラリ
from bs4 import BeautifulSoup #HTML, XMLから狙ったデータを抽出するためのライブラリ
import pandas as pd #データ分析を容易に行うことができる（今回は表作成のために使用)
import time

#スクレイピングしたデータを格納する表を作成(columns: 列名一列目に`歌詞`というラベル（名前)をつける。)
lyricsTable = pd.DataFrame(columns=['歌詞']) 

#テーブルの最初の５行を表示
lyricsTable.head() 

#曲ページ先頭アドレス
base_url = 'https://www.uta-net.com'

#歌詞一覧ページ
url = 'https://www.uta-net.com/artist/****/'
    
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml') #第一引数・・・取得した文字列はtext属性(response.text)で取得できる
                                            #第二引数・・・解析に利用するパーサー。'lxml'は高速に処理できる。
links = soup.find_all('td', class_='side td1') #tdタグ & クラス名が'side td1'な要素を全て取得する。リストで格納される。

for link in links:
    a = base_url + (link.a.get('href')) #aタグの属性を取得する。
    
    #歌詞詳細ページ
    response = requests.get(a)
    soup = BeautifulSoup(response.text, 'lxml')
    
    song_lyrics = soup.find('div', id="kashi_area", itemprop='text')
    
    #要素に含まれるテキストを取得(strip・・・Trueにすることにより改行や空白文字を除去してくれる)
    song_lyrics = song_lyrics.get_text(strip=True) 
    
    '''
     ---------------歌詞抽出完了--------------
    '''
    #取得した歌詞を表に追加
    tmp_seed = pd.DataFrame([song_lyrics], index=lyricsTable.columns).T
    lyricsTable = lyricsTable.append(tmp_seed)
    
    #CSVファイルに格納(mode・・・指定したパスが存在しない場合は新規作成、存在する場合は上書きする)
    lyricsTable.to_csv('lyricsTable_AAA.csv', mode='w', encoding='utf-8')
```

### 2. janomeを使用し、形態素解析を行う。
```:analytics.py
from janome.tokenizer import Tokenizer
import pandas as pd
import re

#CSVファイルを読み込み
lyrics_file = pd.read_csv('lyricsTable.csv', encoding='utf-8')

song_lyrics = lyrics_file['歌詞'].tolist() #リストに変換

t = Tokenizer()
results = []

for s in song_lyrics:
    tokens = t.tokenize(s)
    
    result = []
    
    for tok in tokens:
        if tok.base_form == '*':
            word = tok.surface
        else:
            word = tok.base_form
            
        #1単語の品詞の抽出 
        ps = tok.part_of_speech 
        hinshi = ps.split(',')[0] 
        
        if hinshi in ['名詞', '形容詞', '動詞', '副詞']:
            result.append(word)
    rl = (' '.join(result)).strip()
    results.append(rl)
    
    
    consequence = [i.replace('\u3000','')for i in results]
with open('word_lyrics.txt', 'w', encoding='utf-8') as fp: # `with`ブロックを使うことでブロックの終了時に自動的にCloseされる
    fp.write("\n".join(consequence))

```

### 3.WordCloudの作成
```:wordcloud.py
from wordcloud import WordCloud
with open('word_lyrics.txt', encoding='utf8') as text_file:
    text = text_file.read()

#日本語のフォントパス
fpath = '../ヒラギノ角ゴシック W9.ttc'

#表示対象にしたくない単語の除去
stop_words = ['そう', 'ない', 'いる', 'する', 'まま', 'よう', 'てる', 'なる', 'こと', 'もう', 'いい', 'ある',
                 'ゆく', 'れる', 'の', 'ん','せる', 'さ', 'く', '中']

wordcloud = WordCloud(background_color='white',
                     font_path = fpath, width=700, height=500, stopwords=set(stop_words)).generate(text)

wordcloud.to_file('./wordcloud.png')
```


### 4.完成
![wordcloud_AAA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541740/0c258bea-29bc-a7e6-e0b4-3a239bd4873b.png)

- 夢だったり世界、明日、笑顔などの前向きな言葉が多いですね！ 

### 参考資料
><a href="https://www.uta-net.com">歌ネット</a>
><a href="https://qiita.com/ysdyt/items/9ccca82fc5b504e7913a">https://qiita.com/ysdyt/items/9ccca82fc5b504e7913a</a>
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwj96_6b8rrtAhXIZt4KHapnDf4QFjACegQIBhAC&url=https%3A%2F%2Fnote.nkmk.me%2Fpython-janome-tutorial%2F&usg=AOvVaw32rxuE65WNlS2E4Ku7lvos
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwj6z6im8rrtAhVXfXAKHbZ7AmgQFjADegQIAhAC&url=https%3A%2F%2Fqiita.com%2Fyuuuusuke1997%2Fitems%2F122ca7597c909e73aad5&usg=AOvVaw1mWeXJY-GCeexfmd9ODOHs