golang で勝手にさだベントカレンダー

はじめに

これは,さだまさし x IT Advent Calendar 2015 - Qiita の17日目の記事ではありません. とても盛り上がってたので,golang で何かして投稿しようと思ったら,すでに埋まってしまっていました orz.

そんなわけで勝手に「さだベントカレンダー」です.

  • 歌詞を載せるのは引用の範囲にとどまるくらいになるようにと思ったので,読みづらいかもしれません.(さだまさしのファンの方なら歌詞をそらんじてらっしゃると期待してます!)
  • 同じような理由でスクレイピングのコードもここには載せないことにしました

ぼくとさだまさし

さだまさしはあんまり知りません.むかし,学生時代にラジオをながらで聞いていた気がします.それも.さだまさしより,アシスタントをしていたマネージャーの方との掛け合いが面白くて聞いていた気がします.そんな訳で書いているうちに申し訳ない気持ちになってきました.

なにかやってみる

さだまさしはあんまり知らないのですが,中島みゆきは割と知ってます.さだまさしの曲をスクレイピングして落としてきて,調べてたら,さだまさし中島みゆきの合作『あの人に似ている』という曲があることを知りました.そこで,この歌詞に出てくる語がどっちの人に由来するかを調べてみることにしました.

語という単位は難しいので,形態素解析器で解析される単位で調査します.

方針

ざっくり見れればいいかなと云うことで,次のような方針で見てみました.

歌詞をどうやって集めるか

歌詞を集めてるサイトからスクレイピングさせてもらいました. goquery を使うと楽ちんです.crawler は A Tour of Goの練習課題にもなってるくらいです. goroutine 便利.

形態素解析

形態素解析には pure golang 形態素解析kagome を使います(ステマ). 使い方はだいたいこんな感じになります.

package main

import (
    "fmt"
    "strings"

    "github.com/ikawaha/kagome/tokenizer"
)

func main() {
    t := tokenizer.New()
    tokens := t.Tokenize("寿司が食べたい。")
    for _, token := range tokens {
        if token.Class == tokenizer.DUMMY {
            // BOS: Begin Of Sentence, EOS: End Of Sentence.
            fmt.Printf("%s\n", token.Surface)
            continue
        }
        features := strings.Join(token.Features(), ",")
        fmt.Printf("%s\t%v\n", token.Surface, features)
    }
}

上のサンプルコードの出力は,

BOS
寿司    名詞,一般,*,*,*,*,寿司,スシ,スシ
が      助詞,格助詞,一般,*,*,*,が,ガ,ガ
食べ    動詞,自立,*,*,一段,連用形,食べる,タベ,タベ
たい    助動詞,*,*,*,特殊・タイ,基本形,たい,タイ,タイ
。      記号,句点,*,*,*,*,。,。,。
EOS

こうなります.この要領で1文ずつ処理していけばいいわけです.

名詞とか動詞といった品詞の情報が不要なら,token.Features() を求める必要はありません.今回は,形態素に区切ってその単位の文字列をカウントするだけの簡単な作業にしました.

文区切り

落としてきた歌詞は,空白で区切られていたり改行がまちまちでした.また,歌詞なので句点もありません.

たとえば『あの人に似ている』から少し引用させてもらうと,

昔 哀しい恋をした
街はきれい 人がきれい

その人を 護ってやれなかった
嘘がきれい 誰もがあこがれた

こんな感じです.句点はないけど,1行読み込んで解析単位とすればそれほど変なことにはならなそうです. これを golangbufio.Scanner を使って読み込むと,1行ごとに読み込めますが,空白入りの文字列になってしまいます. そんなときは,kagomeSentenceSplitterbufio.Scanner にセットしてあげることで適当になります.

package main

import (
        "bufio"
        "fmt"
        "strings"

        "github.com/ikawaha/kagome/splitter"
)

var sampleText = `
昔 哀しい恋をした
街はきれい 人がきれい

その人を 護ってやれなかった
嘘がきれい 誰もがあこがれた
`

func main() {

        // 基本設定は https://github.com/ikawaha/kagome/blob/fix/splitter_20151216/splitter/splitter.go#L31
        // これと同じでいいが,今回は改行でも文区切りするようにカスタマイズ
        s := splitter.SentenceSplitter{
                Delim:               []rune{'。', '.', '!', '!', '?', '?', '\n'}, // ここに改行追加する
                Follower:            []rune{'.', '」', '」', '』', ')', ')', '}', '}', '〉', '》'},
                SkipWhiteSpace:      true,
                DoubleLineFeedSplit: true,
                MaxRuneLen:          256,
        }

        scanner := bufio.NewScanner(strings.NewReader(sampleText))
        scanner.Split(s.ScanSentences)
        for scanner.Scan() {
                fmt.Println(scanner.Text())
        }
        if err := scanner.Err(); err != nil {
                panic(err)
        }
}

こうすると,結果は,

昔哀しい恋をした
街はきれい人がきれい
その人を護ってやれなかった
嘘がきれい誰もがあこがれた

とキレイに取れました.これで準備完了です.

さだまさし寄りか,中島みゆき寄りか

形態素ごとにさだまさし寄りか,中島みゆき寄りかを色づけします. 今回は,形態素の出現頻度をカウントしたので,そのカウント数がどちらのアーティストの方が多いかで判定します. しかし,それだけだと,いっぱい曲を書いている方が有利になるので,アーティストごとの全形態素数で割ることにします. 今回は簡単にこいつの比を取って,どっちよりかを判定することにします.そんなんでいいのか?という気もしますが,ネタなのでいいことにします.しました. 100に近ければさだまさし寄り,0に近ければ中島みゆき寄り.50付近なら中立ということにしておきます.

ちなみに,持ってきた歌詞全体で見ると,

アーティスト 曲数 形態素
さだまさし 449 100926
中島みゆき 440 105770

となって,だいたい同じくらいの作曲数に見えます.比較するにはちょうどいい感じです. にしてもすごい曲数.さすが芸歴が長い!

グラフにしてみた

歌詞を載せるのは気が引けたので,グラフにして表示してみました. 青っぽいのがさだまさし寄りで,赤っぽいのが中島みゆき寄りの形態素です.ノードが四角いのはこの曲でだけ使われている形態素です.

f:id:ikawaha:20151216194123p:plain

元の歌詞を見ないと分からないのですが,そこそこ偏りがあります.

特徴的な形態素

この曲でのみ使われている形態素

  • DeJaVu
  • 毀れ
  • のぞかせる
  • 振る舞う
  • 涼し気
  • 話し方

うーん,表記違いで他の曲にも入っている感じもしますけど,どうでしょうか.

それぞれの色が出ている形態素

アーティスト 形態素
さだまさし 護っ,横顔,時折,眼差し,時折,切ない,横顔,時折,眼差し,時折,あこがれ,千,明るく,許し,必ず
中島みゆき ほどか,街.鍵,今夜,逢い,困ら,流れ,夜,なのに,変わっ,なのに,偶然,淋し

さだまさしの方は分からないんですが,中島みゆきの方は確かにこんな感じよなと思いますね(個人の感想です).

後から知ったこと

Wikipedia みてたら,この曲の制作過程が書かれてまして,実は2つのパートを2人がそれぞれ作って合わせたと云うことが分かりました.

この曲は男の歌(さだ担当)・女の歌(中島担当)がそれぞれ同じコード進行の別メロディーで進行し、サビで一緒になるという複雑な構成になっている。これは、当初さだ・中島で作詞・作曲のどちらかをそれぞれ分担するというオファーになっていたものを、さだが「せっかく中島みゆきとやるのだから」と中島に提案し、あえて複雑にしたものである。

なるほど,そう思ってみてみると,それぞれの色が出ている部分がそれぞれのアーティストの担当部分になって・・・そうでもない部分もあってようわからんです. 両方で歌う歌詞は中島みゆきが使ったことがない形態素 時折とか眼差し とかさだまさしの方がよく使う 横顔 なんて形態素が見えるので,さだまさしが作ったのかな—と想像したりしてますが,あなたの判定はどうでしょうか?歌詞と照らし合わせて見てみてください.

お遊びですが,こんな楽しみ方もあると云うことで

おわりに

この曲知らなかったので,買って聞いてみました.いい歌でした.