##目的
実際のラッパーの歌詞を分析することで、何か発見がないかという試みで、特に最終目標があるわけではない。「韻を扱いたい」で行った、テキストがどんな母音の並びを持っているか、に着目して分析していく。用意したデータは対照的な2人のラッパーがいるグループのアルバム8曲分(約90曲分)である。フリーキーフロウ(音への乗せ方が上手い?!)と韻が固いという違いのある2人だが(説明が難しい)、韻の踏み方や出現回数、好む母音などが見つかることを期待している。「123」を「ひーふーみー」と読んだり「アンドゥトロワ」と読んだりするので、データはその点に注意してお手製で用意した
##テキストデータをDataFrameへ
from pykakasi import kakasi
import re
import pandas as pd
import itertools
with open("./data/yoshi.txt","r", encoding="utf-8") as f:
data = f.read()
#単語リスト。母音のみ使ってできる2文字から4文字の単語。775種類
word_list2 = [i[0]+i[1] for i in itertools.product("aiueo", repeat=2)]
word_list3 = [i[0]+i[1]+i[2] for i in itertools.product("aiueo", repeat=3)]
word_list4 = [i[0]+i[1]+i[2]+i[3] for i in itertools.product("aiueo", repeat=4)]
word_list = word_list2 + word_list3 + word_list4
#一曲ずつに分割。{番号:全角スペース、改行で分割された歌詞のリスト}
text_data = data.split("!")
text_data_dic = {k:re.split("\u3000|\n", v) for k,v in enumerate(text_data)}
kakasi = kakasi()
kakasi.setMode('J', 'a')
kakasi.setMode('H', 'a')
kakasi.setMode('K', 'a')
conv = kakasi.getConverter()
#{番号:母音に変換したリスト}
vowel_text_dic = {}
for k,v in text_data_dic.items():
vowel_text_dic[k] = [conv.do(d) for d in v]
for k,v in vowel_text_dic.items():
vowel_text_dic[k] = [re.sub(r"[^aeiou]+","",d) for d in v]
#カラム名"aa"等で、値は出現回数。一曲分のカウント表現
count_dic = {}
temp1 = []
temp2 = 0
for word in word_list:
for k,v in vowel_text_dic.items():
for vowel in v:
temp2 += vowel.count(word)
temp1.append(temp2)
temp2 = 0
vowel_text_len = 0
count_dic[word] = temp1
temp1 = []
df = pd.DataFrame(count_dic)
df["label"] = 0
df.to_csv("./data/yoshi.csv", index=False)
aa | ai | au | … | ooou | oooe | oooo | label | |
---|---|---|---|---|---|---|---|---|
0 | 4 | 9 | 7 | … | 1 | 1 | 0 | 0 |
1 | 21 | 18 | 7 | … | 1 | 1 | 2 | 0 |
2 | 8 | 18 | 18 | … | 1 | 0 | 0 | 0 |
3 | 19 | 26 | 23 | … | 0 | 0 | 0 | 0 |
… | … | … | … | … | … | … | … | … |
88 | 12 | 14 | 2 | … | 0 | 0 | 0 | 0 |
89 | 17 | 17 | 10 | … | 1 | 0 | 1 | 0 |
用意したテキストファイルは各ラッパー毎に2つある。テキスト内で「!」で曲が変わる部分を表し、歌詞中には歌詞カード通り「全角スペース、改行」がある。それをまたいで母音を連続させないようにしている。もう一つのテキストファイルはdf["label"]=1として区別しやすいように保存した。
##データの中身を見てみる
import pandas as pd
df1 = pd.read_csv("./data/pochomkin.csv")
df2 = pd.read_csv("./data/yoshi.csv")
#2文字部分の平均値に着目
df1_2vowel = df1.describe().iloc[:, :25]
df1_2vowel = df1_2vowel.loc["mean", :]
print(df1_2vowel.sort_values(ascending=False))
df2_2vowel = df2.describe().iloc[:, :25]
df2_2vowel = df2_2vowel.loc["mean", :]
print(df2_2vowel.sort_values(ascending=False))
カラムが776列あるので、分けて見ていく。カラムの文字数毎に平均値が高いものはどうなっているかを確認した(3文字ならiloc[:, 25:150]、5×5×5の125種類、4文字ならiloc[:, 150:775])。2文字の場合、print
結果はdf1,df2ともに上位4つが「ai,ia,ou,aa」で一致し、3文字の場合上位2つ「aia,aai」が一致した。また、どの場合もdf2の方が平均値が高くなっていた。
#それぞれ列方向に合計し、その値を取得。(約90曲でのカウント数)
value_count_1 = df1.sum(axis=0).values
value_count_2 = df2.sum(axis=0).values
#カウント10回未満となるbool値。10未満がTrue
bool_1 = value_count_1 < 10
bool_2 = value_count_2 < 10
#両方でカウント10回未満の母音の並びをprint
print(df1.columns[bool_1 * bool_2])
2つのデータ両方で頻度が少ない母音の並びを調べると、37個が該当しその多くは「ee」を含む4文字母音だった。
##まとめと今後の方針
上位に一致が見られた結果は、日本語にその母音の並びが多いのかもしれないし、ラッパーが好むものなのかもしれない。はたまた「餓鬼(ai)レンジャー」というグループ名ゆえに、用意したデータで頻出しているかもしれない。自分は「aa」という並びは「だらだら、体が、さまざま」等「aaaa」の言葉が数多く存在するため、「aa」が一番頻出していると予想していたが、違った結果が出ておもしろい。しかしながら、いくらラッパーの歌詞をデータにしているとはいえ、全ての母音が韻に関係しているわけではないので、何とも言えない。もう一つ予想していた「ラッパー毎に好む母音の並びがある」についても思っているほど顕著に特徴の違いが出ておらず、そこに焦点を当ててもどうだろう?という感じである。今回言えるのは、df2側のラッパー(韻が固い)はdf1のラッパーより同じ母音の並びを頻出させているようだ。これは予想通りではある。
「ee」の頻度が少ないことも新たな発見だ。音が取りにくい等、ラッパーが避ける理由があるのかもしれない。
データを2つに分けておけば、その分類が出来るかも?という感覚だったが、どうもそう簡単にはいかなそうである。今後もう少しデータを見ていき、2人の違いがあるのか、またはないのか調べていこうと思う。