深層学習を用いたJ-POPの歌詞の分散表現

# 日本語のベクトル化(分散表現)の実装 - J-POPを題材に
### 動機
- G検定で習った言語の分散表現(ベクトル)に興味を持った
- スクレイピングでデータを取得できたので使いたかった

目次
- スクレイピングでJ-POPデータの読み込み
- 自然言語処理（形態素解析、わかち書き）
- J-POPデータで歌詞のベクトル化の実装と問題
- 学習済みモデルを用いた文字のベクトル化
- 歌詞の3Dプロットとクラスタリング
- 課題・改善点

## スクレイピングでJ-POPデータの読み込み
歌ねっとから任意の歌手の人気順の歌の歌詞データを取得
データ数：140曲
列：歌手名、歌名、歌詞

スクレイピングの詳細については省略

## 自然言語処理(形態素解析、わかち書き)
使用ライブラリ：janome
歌詞データを形態素解析し、名詞と動詞の単語だけ抽出し、単語のリストを構成
関数の定義

```Python
from janome.tokenizer import Tokenizer

t=Tokenizer()
def extract_words(text):
        tokens = t.tokenize(text)
        return [token.base_form for token in tokens 
            if token.part_of_speech.split(',')[0] in['名詞', '動詞']]
```

上記の関数を使って単語リストを名詞と動詞だけの単語リストを作成する。

```Python
for x in kashi_split:
    sentences = x.split()
    word_list = [extract_words(sentence) for sentence in sentences]
```


これで単語リストが作成完了、出力は以下。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1638533/b521a8bf-c867-0b2a-617a-533cd4682838.png)

内部の処理がわからないが、二次元のリストになってないと単語1文字ずつ読み込まれてしまうのでうまくやる。


## 単語リストから歌詞のベクトル化の実装と問題

使用ライブラリ:gensim
上の単語リストでWord2vecのスキップグラムで分散表現のモデルを構築

公式チュートリアル参照
https://radimrehurek.com/gensim/auto_examples/index.html

あいみょんのマリーゴールドを10次元ベクトル化
（単語一つずつをベクトル化する）

```Python
from gensim.models.word2vec import Word2Vec
model=Word2Vec(sentences=word_list,vector_size=10,min_count=1,workers=4,epochs=1700,sg=1)
```

####単語「風」のベクトルを確認
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777576/86bc1ead-6ff2-aa70-87e1-0ec2d446cd45.png)
#### 似た意味を持つ単語を確認(most_similar)
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777576/cfc67a08-8209-2fd7-c15d-22ecff37590d.png)

### 問題点：サンプルが少なすぎて位置的に近くにある単語＝近い意味を持つ単語と認識しており、うまくベクトル化できていない → 学習済みモデルで解決

## 学習済みモデルを用いた文字のベクトル化

日本語の分散表現の学習済みモデルはインターネット上に複数公開されている。
gensimライブラリを用いることで、非常に簡単に実装が可能
特に、無料で使えるWikipediaの大量の文字データを使ったモデルは多くの方が公開しており、今回はその一つを用いた。
詳細・スキップグラムを使用した200次元のベクトル表現
　　・2017年に作成されたモデル
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777576/c78e88e8-1946-2875-29ef-95bd0b8abc27.png)
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777576/171f5e4e-825d-2047-f389-38f7f9e8561c.png)

# 本題：歌詞のグラフ化とクラスタリング

#####１．歌詞に含まれる名詞・動詞を全てベクトル化し、全ての単語の平均を取り、それを歌詞ベクトルとする
歌詞データをベクトル化したデータセット
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777576/905028f1-f302-68e0-e336-c4407876925d.png)

#####２．歌詞ベクトルは200次元のベクトルとなるので、主成分分析を適用し次元削減を行う。

累積寄与率は全体の何％がその主成分で説明できるかを示す。
今回は上位3個(約63％)と上位10個（約82％）の主成分を抽出する。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777576/dd2ed6d9-9dc6-adf6-b5f9-e3028e3b11d0.png)

#####３．次元削減した歌詞ベクトル(3次元)を3Dグラフにプロットし、出力結果を確認する。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777576/77e27289-70c5-03a8-21d3-80790fb06b40.png)

#####４．同様に次元削減した歌詞ベクトル(10次元)にクラスタリングを適用し、出力結果を確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777576/541467ea-2afb-c7ca-b994-f691565ff673.png)

結果、クラスター１が合計121曲、2が4曲、３が15曲となった。

## 結果の解釈
#### ほぼ間違いなく、英語が多い(または、すべて英語で機械が判別できないやつ)、少ない、全くないの３つのグループにわかれている。
つまり、歌詞の分散表現といいながら英語を使いがちな歌手に分けただけである。
Exileの歌がやたらとクラスター3に分類されているのが特徴的で、思い返してみれば西野カナも結構英語を使っていたなあといった感想である。

# 改善点・課題

- 今回使用したモデルより高性能なモデルを使用する。  
アルゴリズムの変更　例.Word2vec → BERT  
最新のテキストデータから作られたモデルの使用  
口語ベースのテキストで学習されたモデル(SNSなどから抽出)    
例.( ；∀；) → 泣く、涙と認識可能
- 目的に合わせたデータの抽出を行う・データ量を増やす  
今回は適当な歌手の人気順の歌のデータを取得したため良い結果が出なかった。  
例.ヒット作とその他の違いの分析を目的としたデータ抽出  
データ数は140と個人でも取得が容易なサイズであった。 

追記（2021/08/28）
そのうちデータ数をさらに増やし、日本語BERTを使った分散表現の獲得を実装してみます。頑張る。