こんにちは!こちらはStan Advent Calendar 2018 12日目の記事です。
2018年も終わりに近づいてきていますね。皆さんはカラオケに良く行くでしょうか?私たちは良く行きます。
世は年末。
忘年会の二次会でカラオケという流れは良くある事だと思います。皆さんもカラオケに行く機会がもしかしたらあるのではないでしょうか。
カラオケの醍醐味の1つとして、”採点”があります。簡単にいうと、自分が歌った歌を100点満点で評価するものです。
高ければ高いほど自分の歌が上手いことを示し、低ければ低いほど自分の歌が残念な事を示します。100点なんか取ろうものなら、ドヤ顔で人前で披露できるレベルですね。
このカラオケの採点、実に様々な所で使われています。例えば、「芸能人の中で誰が一番歌が上手いのか?」「素人の中で誰が一番歌が上手いのか?」などの企画には、カラオケの採点を用いて誰が歌が上手いのかを判断します。何かの余興に向けて「歌が上手くなりたいなぁ」など、歌を練習する時はカラオケの採点で出る点数を高くする様に練習するのではないでしょうか。
私たちはまだ学生ですので、「カラオケの採点が一番低い奴が罰ゲームな」という具合にカラオケの採点を活用しています。カラオケの採点機能は、歌唱力の評価や場を盛り上げるなど、様々な用途で使用されています。
私たちは学生という身分ではありますが、そこそこに忙しい身ではあります。現代の日本人は時間に追われ、非常に忙しく、時間の余裕が無いという事がつい最近テレビで言われていました。
そう、本記事の筆者、読者をはじめ日本人は忙しいのです。もし、その曲に対する歌唱力を手っ取り早く知りたい時に、最初から最後まで歌を歌うのはとても非効率的では無いでしょうか。また、早く採点結果に応じて罰ゲームを行いたい時に最初から最後まで歌を歌っていたら、飽きが来て場の空気が冷めてしまう可能性もあります。
つまり、短時間歌うだけで、その人の歌唱力を評価出来るに越したことは無いのです。本ブログでは、実際に私たちが思い思いに好きな曲を熱唱し、その採点結果を用いて、「一体、1曲に対してどれだけ歌を歌えば採点結果を予測できるのか」について考えてみようと思います。
本記事では、私たちが日ごろから愛用している株式会社エクシングが提供するJOYSOUNDシリーズの採点システムについて検討しました。JOYSOUNDの分析採点マスターは、音程や安定感などの5つの項目から総合得点が算出されます。この分析採点マスターでは、曲の途中で演奏を中止しても歌った所までで採点をしてくれます。
そこで私たちは、1番のみ(半曲)を歌うだけで、どの程度最後まで(全曲)歌い切った点数を予測できるのかについて調査しました。もしこの予測の精度が高ければ、1番(半曲)を歌うだけで得点を知るのには十分であるといえるでしょう。忙しい現代人にとってこれほど素晴らしい時短はないのではないでしょうか。
JOYSOUNDの分析採点マスターの公式ホームページによると、曲の途中で演奏中止をすると点数が若干下がる傾向にあると書かれていました。さぁ、果たして予測の精度は如何ほどなものか。
私たちは、数日に分けて全部で62曲の半曲・全曲データを集めました。全曲・半曲を歌う順番は各々でカウンタバランスをとり、また自身の性別と同様の性別の歌手の曲を歌いました。
ひとまず、同じ曲を半曲歌った時の得点と全曲歌った時の得点をプロットしてみましょう。 このような感じになりました。
図の左上には両者の相関係数をプロットしてあります。
非常に強い正の相関が見て取れますね。
重相関係数も0.9375226と高く、半曲歌うだけで全曲歌った時の得点をほとんど予測できそうです。
というわけで、半曲歌った時の得点から全曲歌った時の得点を説明するモデルを考えてみます。
とはいえ歌の得点は個人差が大きそうです。
今回は男女合計4人でデータを取得しました。半曲と全曲の得点について、歌い手ごとに回帰直線を引いてみます。
この中では2番の歌い手の歌唱力が抜けて高そうに見えます。
個人ごとの歌唱力の差についても考慮する必要がありそうですね。
以上のことを踏まえて、半曲歌った時の得点(\(score.half\))から全曲歌った時の得点(\(score.all\))を予測するモデルを、 \[score.all_{ij} \sim Normal(\beta0_j + \beta1 * score.half, \sigma)\] としました。
添え字の\(i\)は各曲の番号、\(j\)は歌い手を表しています。
切片の\(\beta0_j\)は歌い手ごとに異なる切片、\(\beta1\)は歌い手全体で共通の傾きです。
標準偏差\(\sigma\)も全体で共通にしてあります。
使用したstanコードは以下の通りです。
data{
int <lower=1> N; //データの個数
real scoreall [N]; //全曲歌った時の得点
real scorehalf [N]; //半曲歌った時の得点
int P; //歌い手の人数
int person[N]; //歌い手
}
parameters{
real b0[P]; //切片(個人ごと)
real b1; //傾き(全体で共通)
real<lower=0> sigma; //標準偏差
}
model{
for(n in 1:N){
scoreall[n]~normal(b0[person[n]] + b1*scorehalf[n], sigma); //モデル
}
}
generated quantities{
real predall[N];
for (n in 1:N){
predall[n] = normal_rng(b0[person[n]] + b1*scorehalf[n], sigma); //推定したパラメータを使って予測値の乱数を発生
}
}
長さ2000のチェインを4本走らせて乱数を発生させ、半分をバーンイン期間として捨てました。
すべてのパラメータについてRhatが1.1を下回っており、収束したと判断しました。
まず、推定された切片\(\beta 0\)について見てみます。
下図は歌い手ごとの\(\beta 0\)の事後分布です。
4人の間にそこまで大きな差はありませんが、やはり2番の歌い手の分布のピークが他と比べて若干右に寄っており、得点が高いように見えます。
それぞれの事後平均などは以下の通りです。
## mean 2.5% 50% 97.5%
## b0[1] 15.887 3.423 15.764 28.776
## b0[2] 17.151 3.280 17.045 31.337
## b0[3] 15.172 2.848 15.091 27.655
## b0[4] 15.865 3.298 15.763 28.738
また、\(\beta1\)と\(\sigma\)の事後分布と各種要約統計量は以下の通りです。
## mean 2.5% 50% 97.5%
## b1 0.813 0.663 0.814 0.961
## sigma 1.326 1.105 1.310 1.628
さて、各種パラメータの推定ができました。本題はここからです。
今回のモデルは、半曲歌った得点から全曲歌った時の得点をどの程度予測できるのでしょうか?
stanコードのgenerated quantitiesブロックで、今回推定したパラメータと半曲歌った得点を用いて全曲歌った時の得点の予測値(\(predall\))の乱数を発生させています。
発生させた乱数について、各曲の番号ごとに平均値をとることで全曲歌った時の得点の予測値としました。
それぞれ対応する曲番号の予測値と実際に全曲歌った時の得点の組をプロットするとこのような感じになります。
左上にある数値は相関係数です。
非常に強い正の相関があります。
重相関係数も0.9417041で非常に高い値が得られました。
つまり、1番を歌った時の得点で全曲歌った時の得点の9割以上を説明できることになります。
大体の曲は、1番→2番→ラスサビ(ラストのサビ)という構成で1曲が構成されているので、この結果より大幅な時間を削減して歌唱力を推定できると言えます!!!おおよそ時間にして1分30秒から3分程度で歌唱力を推定できると言えます!!!
・・・この結果、読者の皆さん、多忙な日本の皆さんは満足でしょうか。私たちは満足していません。確かに半分近い時間で、歌唱力は推定できますが、非常に忙しい現代社会を生きる私たちにとって1分1秒とも無駄にしてはなりません。従って1番(半曲)を歌うだけで最後まで(全曲)歌った時の点数を予測出来ると言う結果に満足する事なく、もっと短い時間での予測を試みたいと強く思いました。
当初の予定ではここで調査終了だったのですが、私たちの短時間で歌唱力を推定したいと言う熱い思いが込み上げて来たので、曲の歌いだしから30秒間歌った追加のデータを3人で合計37曲分とってきました。この追加のデータを用いて、より短時間での歌唱力推定を試みます。
さて、ここでもまずはデータのプロットから見てみましょう。
これまで同様、数値は相関係数です。
相変わらず強い相関関係が見て取れますが、半曲の時よりも値がだいぶ低くなっています。
重相関係数も0.6493262と先ほどよりも低くなっています。
やはり歌った時間が短くなった分、予測精度が落ちてしまっているのでしょうか?
下の図は先ほどと同様に歌い手ごとの回帰直線を描いています。
ここでも個人差についてはある程度考慮する必要がありそうです。
今回も、半曲歌った時の得点による予測と同様のモデルと用いて推定してみます。30秒歌った時の得点(\(score.thirty\))から全曲歌った時の得点(\(score.all\))を予測するモデルを、 \[score.all_{ij} \sim Normal(\beta0_j + \beta1 * score.thirty, \sigma)\] としました。基本的には先ほどのモデルと同様で、\(\beta1\)にかかる説明変数が30秒歌った時の得点に変わっています。
使用したstanコードは以下の通りです。
data{
int <lower=1> N; //データの個数
real scoreall [N]; //全曲歌った時の得点
real scorethirty [N]; //30秒歌った時の得点
int P; //歌い手人数
int person[N]; //歌い手
}
parameters{
real b0[P]; //歌い手ごとの切片
real b1; //傾き(全体で共通)
real<lower=0> sigma; //標準偏差
}
model{
for(n in 1:N){
scoreall[n]~normal(b0[person[n]] + b1*scorethirty[n], sigma); //モデル
}
}
generated quantities{
real thirtypre[N];
for (n in 1:N){
thirtypre[n] = normal_rng(b0[person[n]] + b1*scorethirty[n], sigma); //推定したパラメータを使って予測値の乱数を発生
}
}
先ほどと同様に長さ2000のチェインを4本走らせて乱数を発生させ、半分をバーンイン期間として捨てました。
すべてのパラメータについてRhatが1.1を下回っており、収束したと判断しました。
切片\(\beta 0\)の事後分布と各種要約統計量を見てみます。
## mean 2.5% 50% 97.5%
## b0[1] 50.691 20.299 50.957 80.607
## b0[2] 55.107 22.475 55.319 87.210
## b0[3] 50.700 19.985 50.889 81.104
相変わらず2番の人は分布のピークが右によっていますね。
以下、\(\beta1\)と\(\sigma\)の事後分布と各種要約統計量です。
## mean 2.5% 50% 97.5%
## b1 0.404 0.054 0.401 0.760
## sigma 2.285 1.791 2.257 2.955
ではいよいよ、30秒でどれほど全曲歌った時の得点を予測できるのか見てみましょう。
半曲の時と同様に、stanコードのgenerated quantitiesブロックで、今回推定したパラメータと30秒歌った得点を用いて全曲歌った時の得点の予測値(\(thirtypre\))の乱数を発生させています。
乱数について平均値をとり、それぞれ対応する曲番号の予測値と実際に全曲歌った時の得点の組をプロットします。 毎度のことながら、左上にある数値は相関係数です。
相関係数は半曲の時と比較して低くなっています。
重相関係数も0.6493262で若干説明率が低下しているようです。
やはり、30秒では半曲の時よりも採点の精度が落ちてしまうようです。
しかしそれでもたった30秒歌っただけで約65%も予測できるのです。
この数値をどう評価するかはあなた次第です!
ちなみに30秒で演奏停止するのは虚無感しか生まないので個人的にお勧めしません。
今回は採点の総合得点に焦点をあてたモデリングを行いました。JOYSOUNDの採点は、音程(40点)・安定感(30点)・抑揚(15点)・ロングトーン(10点)・テクニック(5点)の5つの項目から歌唱力を分析してくれます。また、テクニックには”こぶし”・”しゃくり”・”ビブラート”の3つの歌唱テクニックによって評価されています。今回はできませんでしたが、これらの細かい採点結果も組み込んだモデリングができると楽しいと思います。
また、30秒間よりも半曲歌った方が正確に歌唱力を予測できているという結果から、もしかしたらサビのデータが分析採点には重要なのかもしれません。
多くの楽曲の構成は、Aメロ・Bメロ・サビ・Aメロ・Bメロ・サビ・(Cメロ)・ラスサビ(ラストのサビ)というようにできています。一方で、SMAPの「世界に一つだけの花」やGLAYの「誘惑」、ポルノグラフィティの「アポロ」や岡本真夜の「TOMORROW」のようにサビからはじまる曲もあります。もし、サビが重要なのであれば、サビ始まりの曲を30秒間歌った場合は今回よりもっと精密に歌唱力を予測できるかもしれません。
これからも私たちは短時間での正確な歌唱力の推定に全力で向き合います。そのために、日頃のデータ蓄積、より良いモデルの検討に精進して行きます。
最後まで読んでいただき、ありがとうございました!
Let’s Enjoy Karaoke!
さて、ここからはおまけになります。
今回データを取得した4人の中で唯一90点台を連発していた2番の歌い手ですが、この人はほかの三人よりも本当に歌がうまいのでしょうか?
今回推定した結果を用いて簡単にではありますが調べてみよう思います。
まず、最初のモデル(半曲からの予測)で推定した個人ごとの切片\(\beta 0\)がそれぞれどれくらい異なるのかを調べました。
具体的には、generated quantitiesブロックで2番目の人の\(\beta 0\)から1番目、3番目、4番目の人の\(\beta 0\)をそれぞれ引いた差の事後分布を求めました。
1番と4番との差はほとんどなさそうですね。
一方で3番との差は0から離れていそうに見えます。
それぞれの事後平均値、95パーセンタイル値は以下の通りです。
## mean 2.5% 50% 97.5%
## dif21 1.264 -0.300 1.252 2.843
## dif23 1.979 0.071 1.971 3.910
## dif24 1.286 -0.382 1.270 3.006
1番と4番との差は0を含んでいるので今回の結果からは2番との差はあるとは言えないと結論づけられます!
やったね!()
ちなみに発生させた乱数から2番の人がほかの三人よりも高い確率を求めると、、、
## P2-P1 P2-P3 P2-P4
## [1,] 0.94775 0.979 0.9345
2番の人の得点が1番より高い確率は約94%!
この結果をどう解釈するかはあなた次第です!
これで本当に終わります。
最後までお付き合いいただきありがとうございました!
-本文・解析・歌い手(1番)
Twitter → https://twitter.com/K62Kuwakuwa
-本文・解析・歌い手(2番)・歌い手(3番)のデータを取った人
Twitter → https://twitter.com/akonno_o?lang=ja
Instagram → https://www.instagram.com/elestaglam/?hl=ja
-本文・解析・精読・茶化し担当・歌い手(4番)のデータを取った人
Twitter → https://twitter.com/mezase8glory