「凶星のデストラップ」にハマってるko_ya346です。
bodoge.hoobby.net
大体いつも最初にエイリアンに食べられる雑魚っぷりを発揮しています。
先日connpassのイベントのMusic×Analytics Meetup Vol.2に参加したのですが、
Bump Of Chickenの歌詞分析のLTがすごい面白かったので自分も真似してみました。何番煎じか分かりませんが…
手順は
1.スクレイピングで歌詞を集める
2.ワードクラウドのライブラリに突っ込む
です。
収集する歌詞
自分はヘヴィメタルが好きなのですが、メタルには非常に多くのジャンルが存在し(少なくとも60以上)、それぞれで思想が異なるようです。
ja.wikipedia.org
そこで今回は各ジャンルを代表するバンドを勝手に選び、ワードクラウドで歌詞の頻出単語を可視化してみました。
代表バンド
Cannibal Corpse(代表曲 Hammer Smashed Face)
一言:ずっと人間食べてる。安心して聴ける高クオリティのデスメタルの重鎮。
Behemoth(代表曲 demigod)
一言:教会燃やしがち。ボーカルは悪魔が憑りついてるみたいな怖い人だけど普段は優しい。ベースがゴツイ。
Darkmoor(代表曲 Quest for the Eternal Fame
一言:この人たちのせいでメタルにハマった。2ndと3rdは人類史上最も美しい名盤。ボーカルが変わって変な感じになった。
Rhapsody(代表曲 Emerald Sword)
一言:剣と魔法とドラゴン。ルカ(ギター)のギターソロは天才。最近ボーカルと仲直りして嬉しい。
ブルデス代表
Dying Fetus(代表曲 Your Treachery Will Die With You)
一言:攻撃力が高い。演奏技術がエグイ。ブルデスなのにメロディが特徴的で聴きやすいという矛盾したバンド。個性が強すぎて似ているバンドが思い当たらない。好き。
パワーメタル代表
Manowar(代表曲 Hail and Kill)
一言:筋肉がすごい。ジャケットが少しダサい。
Slayer(代表曲 Angel of Death)
一言:メタラーが全員好きなバンド(ホントに)。初期のメロ重視の作風も好き。
各バンドのイメージを何となく掴んで頂いたと思うので早速歌詞を収集しましょう。
こちらのサイトを使用させて頂きました。
www.darklyrics.com
コードはこちら(すごく…汚いです…)
import time
import os
import re
import requests
from bs4 import BeautifulSoup
artist = "slayer"
input_dir = "./input/"
if not os.path.exists(input_dir+artist):
os.mkdir(input_dir+artist)
url = "http://www.darklyrics.com/" + artist[0] + "/"+artist+".html"
base_url = "http://www.darklyrics.com/lyrics/"+artist+"/"
res = requests.get(url)
res.raise_for_status
soup = BeautifulSoup(res.content, "html.parser")
sound_list = soup.find_all("strong")
album_title = []
for i in sound_list:
album_title.append(i.get_text().lower().replace(" ", "").replace("...", "").replace("-", "").replace("'", "").replace(":", "").replace(")", "").replace(".", "")[1:-1])
for i in range(len(album_title)):
print(f"{i+1} album_title {album_title[i]}")
with open(f"{input_dir+artist}/{album_title[i]}.txt", "w") as f:
base_url1 = base_url+album_title[i]+".html"
res1 = requests.get(base_url1)
res1.raise_for_status
soup1 = BeautifulSoup(res1.content, "html.parser")
song_list = []
for num in range(1, 31):
song_title = soup1.find("a", {"href":f"#{num}"})
if song_title:
song_list.append(song_title.text)
else:
break
text = soup1.get_text()
lines = [line.strip() for line in text.splitlines()]
end_word = "Submits, comments, corrections are welcomed at webmaster@darklyrics.com"
end_point = lines.index(end_word)
lyrics = ""
index_list = [j for j, x in enumerate(lines) for sl in song_list if x == sl ][len(song_list):] + [end_point]
for k in range(len(index_list)-1):
ly = " ".join(lines[index_list[k]+1:index_list[k+1]]).replace(" ", " ").replace("...", " ").lower()
ly = re.sub(r'[<>♪`‘’“”・…_!?!-/:-@[-`{-~]', '', ly)
lyrics += ly
lyrics = lyrics.encode("cp932", "ignore").decode("cp932")
f.write(lyrics)
time.sleep(1)
こちらのサイトではアルバム毎に歌詞が管理されているので、一度全てテキストを取得し、曲名を頼りに歌詞部分を抽出しています(index_listが目安)。
正直歌詞の抽出はすごく手こずりました。もうちょいうまいやり方はないのか?
アルバムタイトルに記号が含まている場合は取り除く必要があります(アドレスに含まれないため)。
本当はフォーク、ペイガンのジャンルも試したかったのですが、大量のエラーが予想されるので怖くて諦めました(キリル文字が多用されてたりする)。
word_cloudを作る
qiita.com
こちらを参考にしました。
txtファイルを放り込むだけなので楽ちんです。
import matplotlib.pyplot as plt
from wordcloud import WordCloud
def create_wordcloud(text, ar, dir):
stop_words = [ u'am', u'is', u'of', u'and', u'the', u'to', u'it', u'for', u'in', u'as', u'or', u'are', u'be', u'this', u'that', u'will', u'there', u'was', u'by', u'from', u'with', u'on', u"an", u"into", u"their", u"you", u"your", u"my", u"his", u"me", u"we", u"im", u"our", u"so", u"they", u"he"]
wordcloud = WordCloud(background_color="white", width=900, height=500, \
stopwords=set(stop_words)).generate(text)
fig = plt.figure(figsize=(15,12))
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
fig.savefig(dir + ar + ".png")
artist = ["behemoth", "darkmoor", "manowar", "dyingfetus", "rhapsody", "cannibalcorpse", "slayer"]
for ar in artist:
print("now", ar)
input_dir = f"./input/{ar}/"
output_dir = "./word_cloud/"
txt_list = [i for i in os.listdir(input_dir) if ".txt" in i ]
lyrics = ""
for i in txt_list:
with open(input_dir + i) as f:
tmp = f.read()
lyrics += tmp
create_wordcloud(lyrics, ar, output_dir)
結果
Cannibal Corpse
blood、dead、killなどらしい単語が目立ちます。
flesh、bone、eye、body、など体に関する単語は他のバンドには見られませんでした。やっぱ人肉ばっかり食べてるからですかね?(バンド名を和訳すると「食人死体」)
Behemoth
godが目立つところからも彼らの音楽性が伺えます。blood、fireなどは儀式で使用するのでしょうか?
DarkMoor
chorusはおそらく歌詞ではなく曲中のコーラス部分を示す言葉のようです。やっつけ仕事なので仕方ないですね…
これまでのバンドと違いlove、dreamなど前向きな単語が多いかと思いきや右上にしっかりdeathの文字。
Rhapsody
nowとallの二大巨頭。「皆の者、今こそ立ち上がるのだ!」的なことでしょうか?
holy、king、ancient、gloryなどは中世の聖騎士が連想されます。
Dying Fetus
no、f〇cking、deadなど強い単語が目立ちます。
歌詞を読むと政治批判などが書かれているので、強烈な単語で否定し続けているのでしょうか。
Manowar
Rhapsodyと同様にall、nowが目立ちます。
右下のheavy metalで彼らのメタル愛が感じられます。
Slayer
god、death、blood、painと世間が抱くメタルのイメージが全部乗っかったような画像になりました。
感想
想像通りというか、全体的にdeathやkillなど死に関するワードが多めなのが面白かったです。曲自体が強烈なので歌詞も強い言葉を載せないと釣り合いが取れないのかな~と感じます。
また、正直これまでメタル楽曲の歌詞に注目したことはほとんどありませんでしたが、各ジャンルの特徴が垣間見えたのが良かったです。
今回は各アーティストの楽曲を全てひっくるめて集計しましたが、アルバム毎などにすると特色が見れてさらに面白いかもしれません。
感情分析を取り入れると歌詞から彼らの心情も得られて楽しいかもしれませんね。
また機会があれば挑戦したいと思います。