22
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

P&Dアドベントカレンダー21日目の記事です。もうすぐクリスマスですね:santa:
クリスマスプレゼントは最近iPhone6sが頻繁に強制終了をするので新しいiPhoneが欲しいです:santa:
## はじめに
いきなりですが、していますか?
Wikipediaには、

恋(こい)とは、特定の相手のことを好きだと感じ、大切に思ったり、一緒にいたいと思う感情。

とは書いてありますが、「恋」とは何なのかがよく分からなかったので、恋愛ソングを数多く書いている秋元康先生に聞いてみる事にしました。

どうやって聞くのか

さすがに、直接秋元康先生に尋ねる事はできないので、先生が執筆された歌詞を使って
「恋」と類似度が高い言葉は何かを解析して求めることにしました。

使う技術

  • Python 3.6.5
  • スクレイピング(BeautifulSoup)
  • MeCab(形態素解析)
  • Word2Vec(単語をベクトル化)

## 方法

1.歌詞データ収集

歌詞検索サービスUta-netから歌詞を取得しテキストファイルに保存するPythonのスクリプトを作成しました。
https://github.com/KohheiAdachi/getWordofSong/blob/master/getSong.py
このスクリプトを使用し、Uta-netで各アーティストをキーワード検索した時に出てきた曲をテキストファイルに保存しました。

歌詞取得
from getWordofSong import getSong as gt
import os

song = gt.GetSong()
# ディレクトリ作成
Input_dirTitle = input("dirTitle:")
make_dir = "kashi/"+Input_dirTitle
os.mkdir(make_dir)
# 歌詞サイトのURL入力(検索ページ)
Input_url = input("urlを入力:")
print(Input_url)
# 歌詞ページのURL取得
kashiList = song.getSongList(str(Input_url),match="search")
for kashi in kashiList:
    title,data = song.getWordofsong(kashi)
    print(title)
    song.save_kashi(title,data,make_dir)
アーティスト 曲数
AKB48 609
SKE48 230
NMB48 187
HKT48 78
NGT48 28
STU48 17
乃木坂46 183
欅坂46 81

合計1413曲分の歌詞を収集しました。

2.データの前処理

歌詞には英語も含まれており、英数字、記号を正規表現で削除し、日本語のみの歌詞にし、解析結果に影響が出ないようにします。

歌詞データの読み込む関数
def read_doc(directory):
    text = ""
    for path in directory:
        with open(path,'r',errors='ignore') as f:
            text += f.read()
    return text
ファイルパスを取得後、歌詞を読み込み英数字、記号を正規表現で削除
from glob import glob
# ファイルパスを取得
filePathList = glob.glob("kashi/*/*")
# すべての歌詞を1つの文字列にする
kashi = read_doc(filePathList)

# 英数字の削除
kashi = re.sub("[a-xA-Z0-9_]","",kashi)
# 記号の削除
kashi = re.sub("[!-/:-@[-`{-~]","",kashi)

###3.形態素解析

MeCabを使用し取得した歌詞に対して形態素解析を行い、解析に使用する単語である名詞、動詞、形容詞、形容動詞を取り出し、動詞、形容詞、形容動詞に対しては基本形に直しました。
また、ストップワードを設定し、関係なさそうな単語は除きました。

形態素解析
def split_into_words(doc):
    mecab = MeCab.Tagger("-Ochasen")
    lines = mecab.parse(doc).splitlines()
    words = []
    stop_word = create_stop_word()
    for line in lines:
        chunks = line.split('\t')
        if len(chunks) > 3 and not chunks[2] in stop_word:
            if chunks[3].startswith('動詞'):
                words.append(chunks[2])
            if chunks[3].startswith('名詞') and not chunks[0] in stop_word:
                words.append(chunks[0])
            if chunks[3].startswith('形容詞'):
                words.append(chunks[2])
            if chunks[3].startswith('形容動詞'):
                words.append(chunks[2])    
    return words
ストップワードリスト生成
def create_stop_word():
    target_url = 'http://svn.sourceforge.jp/svnroot/slothlib/CSharp/Version1/SlothLib/NLP/Filter/StopWord/word/Japanese.txt'
    r =requests.get(target_url)
    soup=BeautifulSoup(r.text, "html.parser")
    stop_word=str(soup).split()
    return stop_word

4.Word2vecで学習

Word2Vecで学習させ各単語をベクトル化させました。

Word2Vecdで学習
from gensim.models import word2vec

def learnig_word2vec(kashi)
    sentence = [kashi]
    model = word2vec.Word2Vec(sentence, size=200, min_count=4, window=5, iter=40)
    # モデルを保存
    model.save("AkimotoYasushi.model")

5.類似度の計算

学習したモデルに対して、「恋」という単語に対して類似度の高い上位10個の単語を出力します。

類似度の計算
# モデルの読み込み
model = gensim.models.Word2Vec.load('AkimotoYasushi.model')
word = model.wv.most_similar(positive=[u""], topn=10)
# 結果を出力
for i, lv in enumerate(word):
    print(str(i) + "    " + lv[0] + "    " + str(lv[1]))

結果

「恋」という単語に対して類似度の高かった単語を出力した結果を以下に示します。

結果
0    証拠    0.9997125864028931
1    浮気    0.999591588973999
2    ぃ    0.9995723962783813
3    縄    0.9995304346084595
4    キス    0.9995051622390747
5    頂戴    0.9995023012161255
6    傾向    0.9994885325431824
7    せる    0.9994684457778931
8    喧嘩    0.9994481801986694
9    起きる    0.999412477016449

証拠??
浮気??
縄(意味深)!!??
キス:kiss:!!??

結果がいろいろと辛いので、さらにストップワードを追加したいと思います。

追加でストップワードを追加
my_stop_word = ["","無理","予約","ボウリング","立ち読み","ファッション","雑誌","","","ただ","すぎ","","","偏差","","せる","頂戴","浮気","くる","びっくり","いじめ","しまう","くん","ふう","ちょうだい","コーヒー"]
# ストップワード追加
stop_word.extend(my_stop_word)
ストップワードを追加した結果
0    キス    0.9993709325790405
1    弱い    0.9993308186531067
2    存在    0.9993278384208679
3    負け    0.9993095397949219
4    生物    0.9992963075637817
5    起きる    0.9992321133613586
6    傾向    0.9991904497146606
7    克服    0.9991508722305298
8    逆転    0.9991446137428284
9    喧嘩    0.9991180300712585

恋とは、キスに弱くて、存在に負けて?、生物的で、起きる傾向があって?、克服して、逆転して、喧嘩するものなんですね!(適当)

グループごとで再計算してみた

学習する歌詞を各グループごとに絞って再びWord2Vecで学習させ、「恋」と類似度の高い単語を再計算させました。

AKB48にとって**「恋」**とは

AKB48にとって「恋」とは
0    美学    0.9974193572998047
1    理由    0.9970353245735168
2    閉じる    0.99690842628479
3    恋人    0.996814489364624
4    事件    0.9967169761657715
5    恥ずかしい    0.9966646432876587
6    舐める    0.9965479969978333
7    とこ    0.9963464140892029
8    わかる    0.996084451675415
9    奥    0.9960130453109741

乃木坂46にとって**「恋」**とは

乃木坂46にとって「恋」とは
0    意外    0.9484642148017883
1    告白    0.948411226272583
2    ハート    0.9470661282539368
3    キス    0.9470518827438354
4    ひらく    0.9429705142974854
5    絶対    0.9425839781761169
6    秘密    0.9415342807769775
7    大人    0.9398925304412842
8    許す    0.9393779635429382
9    磨く    0.9379326701164246

欅坂46にとっての**「恋」**とは

欅坂46にとって「恋」とは
0    輝く    0.9968976974487305
1    ときめき    0.9954394102096558
2    奥    0.9930803775787354
3    大切    0.9909152388572693
4    過ごす    0.9906127452850342
5    日常    0.9903433918952942
6    昨日    0.9902833700180054
7    感じる    0.9896537661552429
8    思い出    0.9886585474014282
9    教える    0.9869102239608765

AKB48は美学
乃木坂46は意外
欅坂46は輝く
でした。
※それぞれに対して、ストップワード変更してます。

西野カナ先生にも聞いてみた

西野カナにとって「恋」とは
0    知る    0.9580930471420288
1    追いかける    0.9487483501434326
2    出会える    0.9459880590438843
3    失う    0.9414538145065308
4    向く    0.9401863813400269
5    言い聞かせる    0.9368431568145752
6    傷つく    0.9362004995346069
7    押す    0.9356939196586609
8    不思議    0.934490442276001
9    無理    0.9331055879592896

まとめ

  • ストップワードをうまく設定しないと意味深な結果となってしまう。
  • 秋元康の歌詞のエキスパートくらいの知識がないと結果に対して考察が難しい。
  • 西野カナ先生に聞いたほうが良い結果が得られた。

最後に

結局「恋」とはなんだろうか...
ソースコードはGitHubにまとめてあります。

## 参考文献

西野カナに「恋」とは何か聞いてみた
https://blog.aidemy.net/entry/2018/06/15/174827

22
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?