日向坂46の歌詞をベクトル化してみた！

# 0:やりたいこと
日向坂46の全曲の歌詞データを元に**word2vec**を用いて、
**自然言語⇒数値**
に変換して遊んでみたいと思います。

## Word2vecとは？
**単語をベクトルに変換する魔法**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/a90a475b-1872-4972-99d2-ae3d4ca7c9ec.png)

**単語がどのようにベクトルに変化するか？**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/ded75e04-7c51-f348-4d7a-ca7d589e7217.png)

入力単語の周辺の単語(**今回は距離1とする**)を教師データとすることで、重みW,W"を計算する。
**計算された重みWがそれぞれの単語のベクトルを表す。**

## 自然言語処理の流れ
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/b5f38b2d-ad51-ce64-2e85-ab3610a9586b.png" class="img" alt="自然言語処理の流れ">

# 1:データの収集
解決したいタスクに応じてデータを収集する

# 2:クリーニング処理
HTMLのタグなど意味を持たないノイズを削除する
・**Beautiful Soup**
・**標準ライブラリ re モジュール**

# 1,2:データの収集&クリーニング処理

```py
#1.スクレイピング
import requests
from bs4 import BeautifulSoup
import warnings
warnings.filterwarnings('ignore')
```

```py
target_url = "https://www.uta-net.com/search/?Aselect=1&Keyword=%E6%97%A5%E5%90%91%E5%9D%82&Bselect=3&x=0&y=0"
r = requests.get(target_url)
soup = BeautifulSoup(r.text,"html.parser")
```
```py
music_list = soup.find_all('td', class_='side td1')
url_list = [] #曲一覧から各曲名のURLを取り出してリストに入れる
for elem in music_list:
    a = elem.find("a")
    b = a.attrs['href']
    url_list.append(b)

#＜td class="side td1"＞
#    ＜a href="/song/291307/"＞アザトカワイイ＜/a＞
#＜/td＞  
#＜td class="side td1"＞
#    ＜a href="/song/250797/"＞居心地悪く、大人になった＜/a＞
#＜/td＞  
```
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/0fb87ebb-5bb3-a5c9-564e-d48b7becdff4.png" class="img" alt="自然言語処理の流れ">

```py
hinataza_kashi = "" #曲ごとにRequrestを送り歌詞を抽出する
base_url = "https://www.uta-net.com"
for i in range(len(url_list)):
    target_url = base_url + url_list[i]
    r = requests.get(target_url)
    soup = BeautifulSoup(r.text,"html.parser")
    div_list = soup.find_all("div", id = "kashi_area")

    for i in div_list:
        tmp = i.text
        hinatazaka_kashi += tmp

#＜div id="kashi_area" itemprop="text"＞
#釣られてしまいました (一目でYeah, Yeah, Yeah)
#＜br＞
#僕が勝手に恋をしてしまったんです
#＜br＞
#君のせいじゃない
```
<img width="1000" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/dc76a178-7809-c7d9-a585-b34f0e5b0bf6.png" class="img" alt="自然言語処理の流れ">



```py
#前処理(英語や記号を正規表現で削除)
import re
kashi=re.sub("[a-xA-Z0-9_]","",hinatazaka_kashi)#英数字の削除
kashi=re.sub("[!-/:-@[-`{-~]","",kashi)#記号の削除
kashi=re.sub(u"\n\n","\n",kashi)#改行の削除
kashi=re.sub(u"\r","",kashi)#空白の削除
kashi=re.sub(u"\u3000","",kashi)#全角の空白を削除
```

```py
kashi=kashi.replace(' ','')
kashi=kashi.replace('　','')
kashi=kashi.replace('？','')
kashi=kashi.replace('。','')
kashi=kashi.replace('…','')
kashi=kashi.replace('！','')
kashi=kashi.replace('！','')
kashi=kashi.replace('「','')
kashi=kashi.replace('」','')
kashi=kashi.replace('y','')
kashi=kashi.replace('“','')
kashi=kashi.replace('”','')
kashi=kashi.replace('、','')
kashi=kashi.replace('・','')
kashi=kashi.replace('\u3000','')
```
<img width="1000" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/9e049907-2d9b-3a58-0ba0-de00474bc174.png" class="img" alt="自然言語処理の流れ">

```py
with open("hinatazaka_kashi_1.txt",mode="w",encoding="utf-8") as fw:
    fw.write(kashi)
````

# 3:単語の正規化
半角や全角、小文字大文字などを統一する
・**送り仮名によるもの**
「行う」と「行なう」
「受付」と「受け付け」

・**文字の種類**
「りんご」と「リンゴ」
「犬」と「いぬ」と「イヌ」

・**大文字と小文字**
 Apple と apple

**※今回は無視する**

# 4:形態素解析(単語分割)
文章を単語ごと分割する
・**MeCab**
・**Janome**
・**JUMAN++**

# 5:基本形への変換
語幹(活用しない部分)への統一を行う
例：学ん(だ)→学ぶ
昨今の実装では基本形へ変換しない場合もある

# 4,5:形態素解析(単語分割)&基本形への変換

```py
path="hinatazaka_kashi_1.txt"
f = open(path,encoding="utf-8")
data = f.read()  # ファイル終端まで全て読んだデータを返す
f.close()
```

```py
#3.形態素解析
import MeCab

text = data
m = MeCab.Tagger("-Ochasen")#テキストをパースするためのTaggerインスタンス生成

nouns = [line for line in m.parse(text).splitlines()#Taggerクラスのparseメソッドを使うと、テキストを形態素解析した結果が返る
               if "名詞" or "形容動詞" or "形容詞" or"形容動詞" or "動詞" or "固有名詞" in line.split()[-1]]
```
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/e0007f9e-98d1-763d-e8f0-79f89275cef2.png" class="img" alt="自然言語処理の流れ">

```py
nouns = [line.split()[0] for line in m.parse(text).splitlines()
               if "名詞" or "形容動詞" or "形容詞" or "形容動詞" or "動詞" or "固有名詞" in line.split()[-1]]
```

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/fb4f6648-c81c-cb07-d228-7cf7a77a19c1.png" class="img" alt="自然言語処理の流れ">

# 6:ストップワード除去
出現回数の多すぎる単語など、役に立たない単語を除去する
昨今の実装では除去しない場合もある

```py

my_stop_word=["する","てる","なる","いる","こと","の","ん","y","一","さ","そう","れる","いい","ある","よう","もの","ない","しまう",
                 "られる","くれる","から","だろ","その","けど","だけ","つ","て","まで","つて","じゃ","たい","なら","たら","なく","られ","まま","たく"]

nouns_new=[]
for i in nouns:
    if i in my_stop_word:
        continue
    else:
        nouns_new.append(i)
```


<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/04c702fd-8585-6130-3194-5867623ae26e.png" class="img" alt="自然言語処理の流れ">

```py
import codecs
with codecs.open("hinatazaka_kashi_2.txt", "w", "utf-8") as f:
    f.write("\n".join(nouns_new))
```

# 7:単語の数値化
機械学習で扱えるよう文字列から数値へ変換を行う

# 8:モデルの学習
タスクに合わせ、古典的な機械学習~ニューラルネットワーク選択する
それでは、この流れのうち前処理にあたるものを把握する。


#7,8:単語の数値化&モデルの学習

```py
from gensim.models import word2vec

corpus = word2vec.LineSentence("hinatazaka_kashi_2.txt")
model = word2vec.Word2Vec(corpus, size=100 ,min_count=3,window=5,iter=30)
model.save("hinatazaka.model")
```



```py
model = word2vec.Word2Vec.load("hinatazaka.model")

# ドライバーと類似している単語を見る
print('好きと関連する単語ベスト10')
similar_words = model.wv.most_similar(positive=[u"好き"], topn=10)
for key,value in similar_words:
    print('{}\t\t{:.2f}'.format(key, value))

print('-----')
# # 2つの単語の類似度を計算
similarity = model.wv.similarity(w1=u"笑顔", w2=u"夏")
print('「笑顔」と「夏」の類似度=>' + str(similarity))

similarity = model.wv.similarity(w1=u"友達", w2=u"夏")
print("「友達」と「夏」の類似度=>" + str(similarity))

similarity = model.wv.similarity(w1=u"女の子", w2=u"男")
print('「女の子」と「男」の類似度=>' + str(similarity))
```
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/f35ab328-a7be-1c01-d09d-52a38f2e03e2.png" class="img" alt="自然言語処理の流れ">

## 類似度
この中で出てくる類似度というのは、**cos類似度**のことを言っています。
cos類似度とは簡単にいうと、２つのベクトルがどれだけ同じ方向を向いているか(類似しているか)を数値化したものです。cos類似度が0のときには、類似度が低く、1のときには類似度が低いことを示しています。
cos類似度は以下のような計算式で表されます。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449715/ef8eda99-3244-71a3-5585-8acb11e5f2fb.png" class="img" alt="自然言語処理の流れ">





#【総評】
***「パパデュワデュワデュワデュワデュワデュワパパパパ」***ってなんやねん。
歌詞じゃなくてメンバーのブログからデータを取得するとメンバーの仲良し度も分かるんじゃないかな。(次回やってみようかな…)








# 参考文献

1:[自然言語処理の基礎（TensorFlow）](https://www.kikagaku.ai/tutorial/basic_of_nlp/learn/tensorflow_ml_nlp)

2:[uepon日々の備忘録]
(https://uepon.hatenadiary.com/entry/2019/02/10/150804)

3:[Np-Urのデータ分析教室]
(https://www.randpy.tokyo/entry/word2vec_skip_gram_model)