きっかけ
えーみなさん、曲を聞いているときに歌詞を見たりしますか?
僕はよく見てます。でも歌詞って長くて読むの疲れちゃいますよね?
なので作詞家の言いたいことをスパッとまとめてみたいと思いました。
ズバリ「歌詞の可視化」です。
あ、いやまぁ研究をしているときに、聞いていた曲を一目で見てみたい!と思って、
「歌詞の可視化」に臨みました。はい、そうです。歌詞の可視化です。
2021/11/22追記
Google Colaboratoryで可視化をした記事を書きました。環境設定が段違いに簡単になってますので、興味があればご覧ください。
自己紹介
自己紹介ページ ->
環境情報
Python 3.6.5 |Anaconda, Inc.|
Windows10
本日のお品書き
今回はやることが多いですね。
・歌詞の収集(Webスクレイピング)
・歌詞を単語にする(形態素解析)
・可視化(WordCloud)
の3ステップです。
完成図
誰のなんの曲だかわかりますか?
注意
今回はJupyter Notebook上で実行しました。
Jupyter Notebookのインストールについては、Googleで調べてみてください。
文法などが一部、普通のPythonとは少し異なる部分もあるのでお気を付けください。
対象者
・Python3系を使っているユーザー(Anacondaでインストール)
・米津玄師のファン
・1を聞いて10を理解できるエンジニア
・Jupyter NoteBookを使ったことがある人
・Windowsの人
非対象者
・Python2系を使っているユーザー
・新米教師のファン
・説明下手な筆者を攻撃しようとするエンジニア
・Jupyter Notebookを使ったことがない人
・Macの人
Cf.)Python2系とかPython3系の意味が分からない人へ!
Pythonには2系と3系があって、最近始めた人ならほとんどPython3系だと思います。一応バージョンを確認する方法を記載しておきます。
コマンドプロンプトでPythonのインタラクティブ(対話)モードを起動すればバージョン情報が表示されます。
$ Python
>Python 3.6.5 |Anaconda, Inc.| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
インタラクティブモードを辞めるには*exit()*を入力しましょう!
Let's start
歌詞の収集
いちいちコピペするのは大変なので、一気にスクレイピングしましょう。
こちらのサイトを参考にいたしました。
import os
import re
import bs4
import time
import requests
import pprint
def load(url):
res = requests.get(url)
res.raise_for_status()
return res.text
def pickup_tag(html, find_tag):
soup = bs4.BeautifulSoup(str(html), 'html.parser')
paragraphs = soup.find_all(find_tag)
return paragraphs
def parse(html):
soup = bs4.BeautifulSoup(str(html), 'html.parser')
# htmlタグの排除
kashi_row = soup.getText()
kashi_row = kashi_row.replace('\n', '')
kashi_row = kashi_row.replace(' ', '')
# 英数字の排除
kashi_row = re.sub(r'[a-zA-Z0-9]', '', kashi_row)
# 記号の排除
kashi_row = re.sub(r'[ <>♪`‘’“”・…_!?!-/:-@[-`{-~]', '', kashi_row)
# 注意書きの排除
kashi = re.sub(r'注意:.+', '', kashi_row)
return kashi
def main():
with open('yonedu_kashi.txt', 'a') as f:
# アーティストページ(米津玄師)のアドレス
url = 'https://www.uta-net.com/artist/12795/'
# 曲ページの先頭アドレス
base_url = 'https://www.uta-net.com'
# ページの取得
html = load(url)
# 曲ごとのurlを格納
musics_url = []
# 歌詞を格納
kashis = ''
""" 曲のurlを取得 """
# td要素の取り出し
for td in pickup_tag(html, 'td'):
# a要素の取り出し
for a in pickup_tag(td, 'a'):
# href属性にsongを含むか
if 'song' in a.get('href'):
# urlを配列に追加
musics_url.append(base_url + a.get('href'))
""" 歌詞の取得 """
for i, page in enumerate(musics_url):
print('{}曲目:{}'.format(i + 1, page))
html = load(page)
for div in pickup_tag(html, 'div'):
# id検索がうまく行えなかった為、一度strにキャスト
div = str(div)
# 歌詞が格納されているdiv要素か
if r'itemprop="text"' in div:
# 不要なデータを取り除く
kashi = parse(div)
print(kashi, end = '\n\n')
# 歌詞を1つにまとめる
kashis += kashi + '\n'
# 1秒待機
time.sleep(1)
break
# 歌詞の書き込み
f.write(kashis)
if __name__ == '__main__':
main()
# 出力結果はURLがたくさん並びます。
> 1曲目:https://www.uta-net.com/song/162135/
2曲目:https://www.uta-net.com/song/195154/
3曲目:https://www.uta-net.com/song/195149/
4曲目:https://www.uta-net.com/song/135723/
5曲目:https://www.uta-net.com/song/215592/
6曲目:https://www.uta-net.com/song/238731/
・・・(省略)
参考サイトより
歌詞情報サイト歌ネット(utanet)から米津玄師さんの全73曲(2018.7.2現在)の歌詞を取得しました。
サーバに負荷を与えないため、1つの歌詞ごとに1秒待機するようにしています。今回は73曲なので1分ちょっとで終了しました。
※スクレイピングには注意が必要です。→過去記事
上記の方法ですべての歌詞を取得できます。
歌詞を単語にする(形態素解析)
形態素解析というものは、文章を切り分ける技術です。
ちなみに形態素というのは文章から、意味を持つように切り分けたときの最小単位です。
英語なら文章に空白が入っているので、形態素に切り分けやすいです。
I am Semple
ならI
とam
とSemple
に分けることができます。
しかし日本語は英語と異なり、形態素には切り分けられません。
わたしはSempleです
の場合はわたし
とは
とSemple
とです
に切り分ける必要があります。
そこでMeCabというツールを利用します。MeCabはいい感じに日本語を切り分けてくれます。
MeCabのインストールや形態素解析については今回は本筋から外れるので、詳細は面倒なので割愛いたします。まぁそういうものがあるんだなと思ってください。詳しく知りたい方がいたら、コメントください。要望があれば書きます。調べたほうが早いけどね…
MeCabの参考ページ
・インストール系
https://qiita.com/grachro/items/4fbc9bf8174c5abb7bdd
https://qiita.com/woody-kawagoe/items/09c0f89a55701bcf72eb#mecab
・使い方系
https://qiita.com/taroc/items/b9afd914432da08dafc8
様々な形態素解析器の紹介(Windows用ではないけど…。)
import MeCab
#スクレイピングした歌詞のデータを取得
bindata = open("yonedu_kashi.txt", 'rb').read()
kashi = bindata.decode('cp932')
# 曲ごとに区切る
lines = kashi.split('\n')
mecab = MeCab.Tagger('-Ochasen')
mecab.parse('')
#一曲目を取得
node = mecab.parseToNode(lines[0])
output = []
#意味をなさないような単語を除外する。
stoplist=['「', '」', 'じゅう', 'そこら', 'れる', 'くい','ん','よう','の']
# 品詞に分解して、助詞や接続詞などは除外している。
while node:
word_type = node.feature.split(",")[0]
if word_type in ["名詞","形容詞","副詞","動詞"]:
if not node.surface in stoplist and not node.surface.isdigit():
output.append(node.surface.upper())
node = node.next
print(output)
#出力結果 (ちなみになんの曲かわかる方いますかね…?いやまぁスクレイピングの部分のURL調べれば答え出てますけど…)
>['あたし', 'あなた', '会え', '本当に', '嬉しい', '前', 'それら', 'すべて', '悲しい', '今', '痛い', '幸せ', '思い出', 'いつか', '来る', '別れ', '育て', '歩く', '誰か', '居場所', '奪い', '生きる', 'もう', 'あたし', '石ころ', 'なれ', 'ならい', 'いなだ', 'し', '勘違い', '戸惑い', 'ない', 'そう', 'やっ', 'あなた', '知ら', 'まま', 'あなたに', 'あたし', '思い', '全部', '伝わっ', 'ほしい', '誰にも言えない', '秘密', 'あっ', '嘘', 'つい', 'しまう', 'あなた', '思え', '思う', 'いくつ', 'あたし', '意気地', 'ない', 'どうして', '消え', '悲しみ', '綻び', 'あなた', 'いれ', 'よかっ', '笑える', 'どんなに', '嬉しい', '目', '前', '全て', 'ぼやけ', '溶け', 'ゆく', '奇跡', 'あふれ', '足り', 'あたし', '名前', '呼ん', 'くれ', 'あなた', '居場所', '失', 'くし', '彷徨', 'もう', '誰か', '身代わり', 'なれ', '思う', '細やか', '確か', '見', 'ふり', 'きっと', '繰り返し', '笑い', '合う', '何', '度', '誓っ', '何', '度', '祈っ', '惨憺', '夢', '見る', '歪み', 'いつか', 'あなた', '呑ん', 'なくし', 'しまう', 'あなた', '思え', '思う', '大げさ', 'あたし', '不甲斐ない', 'どうして', 'お願い', 'いつまでもいつまでも', '超え', 'られ', '夜', '超えよ', '手', 'つなぐ', '日々', '続き', '閉じ', '瞼', '鮮やか', '彩る', 'ため', 'そのため', '何', 'できるかな', 'あなた', '名前', '呼ん', 'いい', '産まれ', 'き', '瞬間', 'あたし', '消え', 'しまい', '泣き', '喚い', 'それ', 'ずっと', '探し', 'いたん', 'いつか', '出会える', 'あなた', 'こと', '消え', '悲しみ', '綻び', 'あなた', 'いれ', 'よかっ', '笑える', 'どんなに', '嬉しい', '目', '前', '全て', 'ぼやけ', '溶け', 'ゆく', '奇跡', 'あふれ', '足り', 'あたし', '名前', '呼ん', 'くれ', 'あなた', '名前', '呼ん', 'いい']
kashiの部分のcp932
はWindowsで使われている文字コードです。その程度の知識しかない。
詳しく知りたい方は調べて下さい。
そしてぜひ教えてください。
MeCab.Tagger('-Ochasen')
については、MeCabはほかにもパラメータがあるので、いろいろ試してみてください。
可視化(WordCloud)
from wordcloud import WordCloud
#形態素解析された単語のリストをWordCloud用に処理している。
text = ' '.join(output)
#日本語はWindowsのフォントのパスを貼り付ける
fpath = "C:/Windows/Fonts/YuGothM.ttc"
wordcloud = WordCloud(background_color="white",
font_path = fpath, width=800,height=600).generate(text)
#WordCloudの画像は同じディレクトリ内に保存されます。
wordcloud.to_file("./wordcloud_sample.png")
WordCloud系の記事はたくさんあるので、その辺を参考にしながら作成しました。
日本語のフォントのパスをつけないと豆腐みたいになるので、お気を付けください。僕は豆腐になりました。
豆腐↓
成功↓
まぁ上でも見せてますが…一応。
WordCloudのパラメータをいじれば色とか変えられると思います。
この記事ではまぁFuture Workということで・・・。
参考記事
終わりに
とまぁ歌詞をWordCloudで可視化するのは、割と簡単にできて楽しかったです。
この記事自体はテンションで書ききったので、後日けっこう加筆修正を多分します。やらない
すべての曲をスクレイピングで取得したのに、一曲しか可視化してなくない?ってツッコミはやめましょう。
何度かグダグダしてしまいましたが、ここまでお読みいただきありがとうございます。