「笑い声」を分析・検証してみる


　　
この記事は[カバー株式会社 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/cover) 16日の記事になります。

# はじめに
日頃から配信や動画でタレントさんが楽しそうにしている姿や笑っている姿をみて、視聴側も幸せな気持ちになることがあるかと思います。
実際に笑顔は自身・他者に限らず、幸福度を向上させる可能性も秘めているとされています。

代表的な話でいうと、表情フィードバック仮説（顔の表情から脳にフィードバックされることでその感情が引き起こされるという仮説）というものが挙げられます。つまりは、笑顔を形成することで、ポジティブな感情を引き出せることを意味します。仮説が提唱されてから今もなお様々な実験によって検証され続けています[^3]（仮説を批判する内容のものもあります）。

こうして仮説に基づき、ユニークな応用例として、「笑わないと開かない冷蔵庫[^1]」のような取り組みがあります。 冷蔵庫にセンサを設置し、開ける際に笑顔を作らないとスムーズに開けることができない仕組みとなっています。これは生活の中で笑顔を形成させることを促すことによって幸福度を高めることを狙うものです。他には、ビデオ会議において、画像処理で表情を変形させ、ポジティブな感情を形成することで創造的な活動が推進されることを示した事例もあります[^2]。

笑顔に限らず、笑うこと[^4]で同様にポジティブな影響を与えうるものだと考えられたり、単純に笑い声を聞くことで笑いが誘発されることが示されています[^5]。

そこで、日頃から耳にしているホロライブプロダクション所属タレントの「笑い声」を題材とし、簡単ではありますが、可視化・検証してみたいと思います。
今回はホロライブの[3期生](https://hololive.hololivepro.com/talents?gp=gen-3)に絞って実施してみました。

# コード
`python`及び`scikit-learn`を用いると限られたコードで簡単に処理することができます。

## 特徴量の抽出
データをロードしつつMFCC（メル周波数ケプストラム係数）を算出していきます。
また合わせて`0`から`3`のラベルデータを配列に格納しておきます。
今回は各タレントさんにつき10個のデータを用意し、[掲載順](https://hololive.hololivepro.com/talents?gp=gen-3)にラベルを定義しました。
`ファイル名の定義や全員分の処理は省略します`

サンプリングレートは16kで十分かと思われます。またMFCCの次元数は機械学習分野でよく使われる12次元を用います。
また今回は簡単のため、時間平均を利用してしまいます。
```これによって厳密には「笑い方」のような時間変化で表現される特徴は潰されてしまっている可能性もあります```
```python
import librosa
import numpy as np

sample_rate = 16000
mfccs = []
labels = []

for file_path in files:
    audio, _ = librosa.load(dir_path + file_path, sr=sample_rate, mono=True)
    mfcc = np.mean(librosa.feature.mfcc(y=audio, sr=sample_rate, n_mfcc=13)[1:], axis=1)
    mfccs.append(mfcc)
    labels.append(label)
```

## 主成分分析
標準化して第一主成分と第二主成分を抽出します。
```python
import sklearn 
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

scaler = StandardScaler()
mfccs_st = scaler.fit_transform(mfccs)
pca = PCA(n_components=2)
pca.fit(mfccs_st)
mfcc_pca = pca.transform(mfccs_st)
```
　　
描画して確認してみます。
色は[ホロジュール](https://schedule.hololive.tv/)で使用されているカラーコードです。　　

```python
import matplotlib.pyplot as plt

color_pekora = ['#7EC2FE']*10
color_flare = ['#FE3D1C']*10
color_noel = ['#ACBDC5']*10
color_marine = ['#BA2C2B']*10
color_list =  color_pekora +  color_flare + color_noel + color_marine

plt.figure(figsize=(6, 6))
plt.scatter(mfcc_pca[:,0], mfcc_pca[:,1] , c=color_list)
plt.grid()
plt.xlabel("PC1")
plt.ylabel("PC2")
plt.show()
```
![pca.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638145/5d5ba15a-5bb7-120e-a472-bab20cc7762f.png)

## t-SNE　　
比較のため、t-SNEについても同様にみてみます。
```python
from sklearn.manifold import TSNE

tsne = TSNE(n_components=2, init='random', random_state = 0)
mfcc_tsne = tsne.fit_transform(mfccs_st)

plt.figure(figsize=(6, 6))
plt.scatter(mfcc_tsne[:,0], mfcc_tsne[:,1] , c=color_list)
plt.grid()
plt.show()
```

![tsne_rand0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638145/a3435c75-5264-b66a-1e43-f4c395419b27.png)

どちらについてもなんとなくの傾向は捉えていそうです。

## SVMで検証　
ではさらにSVMで学習させて検証してみます。今回はハイパーパラメータはデフォルト値のままとします。
また交差検証もデフォルトが5-fold cross validationとなるのでそのまま利用します。
```python
from sklearn import svm
from sklearn.model_selection import cross_val_score

model = svm.SVC()
model.fit(mfccs_st, labels)
scores = np.mean(cross_val_score(model, mfccs_st, labels))
print(scores)
```
```:結果
0.775
```
77.5%という結果となりました。
一概に「笑い声」といっても控えめなものから爆笑と幅広いバリエーションが存在します。データの中にそれが混同していることもあり、今回の処理方法ではそれ相応の精度にしか至りませんでした。「笑い方」を含めて分類することを試みたり、十分なデータ数を確保したり、そのバランスを調整することで改善する可能性があるかと思います。


## おわりに　　
最後になんとなくですが、
今回のデータには含まれていない「**[儒烏風亭らでん](https://hololive.hololivepro.com/talents/juufuutei-raden/)**」さんの笑い声がどのように分類されるか試してみます。
```python
test_data = path + '/test_data.wav'

data, _ = librosa.load(test_data, sr=sample_rate, mono=True)
test_mfcc = np.mean(librosa.feature.mfcc(y=data, sr=sample_rate, n_mfcc=13)[1:], axis=1)

test_mfcc_st = scaler.transform(test_mfcc.reshape(1, -1))

test_result = model.predict(test_mfcc_st)

if test_result == 0: print('兎田ぺこら')
elif test_result == 1: print('不知火フレア')
elif test_result == 2: print('白銀ノエル')
elif test_result == 3: print('宝鐘マリン')
```

```:結果
兎田ぺこら
```

`*あくまでも今回の限られたデータとモデルに基づく分類結果であり、この結果をもって『似ている』と一概に言えるわけではありません。`  

[^1]:Hitomi Tsujita and Jun Rekimoto. 2011. Smiling makes us happier: enhancing positive mood and communication with smile-encouraging digital appliances. In Proceedings of the 13th international conference on Ubiquitous computing (UbiComp '11). Association for Computing Machinery, New York, NY, USA, 1–10. https://doi.org/10.1145/2030112.2030114

[^2]:Naoto Nakazato, Shigeo Yoshida, Sho Sakurai, Takuji Narumi, Tomohiro Tanikawa, and Michitaka Hirose. 2014. Smart Face: enhancing creativity during video conferences using real-time facial deformation. In Proceedings of the 17th ACM conference on Computer supported cooperative work & social computing (CSCW '14). Association for Computing Machinery, New York, NY, USA, 75–83. https://doi.org/10.1145/2531602.2531637

[^3]:Coles, N.A., March, D.S., Marmolejo-Ramos, F. et al. A multi-lab test of the facial feedback hypothesis by the Many Smiles Collaboration. Nat Hum Behav 6, 1731–1742 (2022). https://doi.org/10.1038/s41562-022-01458-9

[^4]:Martin, Rod. (2004). Sense of humor and physical health: Theoretical issues, recent findings, and future directions. Humor-international Journal of Humor Research - HUMOR. 17. 1-19. 10.1515/humr.2004.005. 

[^5]:Provine, R.R. Contagious laughter: Laughter is a sufficient stimulus for laughs and smiles. Bull. Psychon. Soc. 30, 1–4 (1992). https://doi.org/10.3758/BF03330380