ACIDMANの歌詞によく使われている単語

　概要です。

> [ACIDMAN の歌詞によく使われる単語とは - ニコニコ大百科](http://dic.nicovideo.jp/a/acidman%E3%81%AE%E6%AD%8C%E8%A9%9E%E3%81%AB%E3%82%88%E3%81%8F%E4%BD%BF%E3%82%8F%E3%82%8C%E3%82%8B%E5%8D%98%E8%AA%9E)

これを、Clojure と形態素解析ライブラリの Kuromoji を使って求めます。

　試した環境です。

* Mac OSX 10.9.2
* Kuromoji 0.7.7
* Clojure 1.6.0
* Java 1.7.0_45

##準備

　インストールとプロジェクト作成の様子です。この辺りは、[前の記事](http://qiita.com/woxtu/items/bf39e3d53cbf60396d2c)と同じです。

```sh
# Homebrew
$ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
$ brew update

# Leiningen
$ brew install leiningen

# プロジェクトをつくる
$ lein new acidman
$ cd acidman
```

`project.clj` を編集します。

```clj
(defproject acidman "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}

  ;; 以下を編集、追記
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [clj-http "0.9.1"]
                 [org.atilika.kuromoji/kuromoji "0.7.7"]]
  :repositories [["Atilika Open Source repository"
                  "http://www.atilika.org/nexus/content/repositories/atilika"]])
```

Kuromoji は、Maven にも Clojars にも登録されていないので、`:repositories` でリポジトリを指定しています。

## 形態素解析

　形態素解析やります。形態素解析とは？

> 　形態素解析とは、1.文を形態素という意味の最小単位に分割し、2.各形態素を原型に復元し、3.各形態素に品詞を付与する処理です。

> [Clojure/kuromoji でテキストマイニング入門　～形態素解析からワードカウントまで～ - あんちべ！](http://antibayesian.hateblo.jp/entry/2013/09/10/231334)

ということです。

```sh
$ lein repl
```

```clj
user=> (import [org.atilika.kuromoji Token Tokenizer])
org.atilika.kuromoji.Tokenizer
user=> (def tokenizer (.build (Tokenizer/builder)))
#'user/tokenizer
user=> (def tokens (.tokenize tokenizer "緩やかな波音赤く染まる頃華やいだ白い砂に影が映る"))
#'user/tokens
user=> (doseq [t tokens] (println (.getSurfaceForm t) "\t" (.getAllFeatures t)))
緩やか 	 名詞,形容動詞語幹,*,*,*,*,緩やか,ユルヤカ,ユルヤカ
な 	 助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
波 	 名詞,一般,*,*,*,*,波,ナミ,ナミ
音 	 名詞,一般,*,*,*,*,音,オト,オト
赤く 	 形容詞,自立,*,*,形容詞・アウオ段,連用テ接続,赤い,アカク,アカク
染まる 	 動詞,自立,*,*,五段・ラ行,基本形,染まる,ソマル,ソマル
頃 	 名詞,非自立,副詞可能,*,*,*,頃,コロ,コロ
華やい 	 動詞,自立,*,*,五段・ガ行,連用タ接続,華やぐ,ハナヤイ,ハナヤイ
だ 	 助動詞,*,*,*,特殊・タ,基本形,だ,ダ,ダ
白い 	 形容詞,自立,*,*,形容詞・アウオ段,基本形,白い,シロイ,シロイ
砂 	 名詞,一般,*,*,*,*,砂,スナ,スナ
に 	 助詞,格助詞,一般,*,*,*,に,ニ,ニ
影 	 名詞,一般,*,*,*,*,影,カゲ,カゲ
が 	 助詞,格助詞,一般,*,*,*,が,ガ,ガ
映る 	 動詞,自立,*,*,五段・ラ行,基本形,映る,ウツル,ウツル
nil
```

楽しい！(☝ ՞ਊ ՞)☝

## ACIDMAN の歌詞によく使われている単語

### 歌詞の収集

　歌詞を J-Lyric.net より拝借します。このサイトでは、アーティスト毎に ID が振られていて、`artist/*アーティストのID*/` でアーティストの曲一覧、`artist/*アーティストのID*/*曲のID*.html` で歌詞を引くことができます。ACIDMAN の場合、 ID は a00b172 です。

`src/acidman/core.clj` を編集します。

```clj
(ns acidman
  (:require [clojure.java.io :as io])
  (:require [clj-http.client :as client])
  (:import [org.atilika.kuromoji Token Tokenizer]))

;; アーティストの曲と題名のリストを返す
(defn collect-songs [artist]
  (->> (:body (client/get (str "http://j-lyric.net/artist/" artist)))
       (re-seq #"<div class='title'><a href='/artist/.+?/(.+?).html'>(.+?)</a> </div>")
       (map (partial drop 1))))

;; 曲の歌詞を取得する
(defn get-lyric [artist song]
  (as-> (:body (client/get (str "http://j-lyric.net/artist/" artist "/" song ".html"))) x
        (re-find #"(?s)<p id='lyricBody'>.+?</p>" x)
        (clojure.string/replace x #"<.+?>|\r\n" "")))

;; アーティストの曲をダウンロードしてその曲数を返す
(defn download-songs [artist]
  (.mkdir (io/file artist))
  (let [songs (collect-songs artist)]
    (doseq [[song title] songs]
      (spit (str artist "/" title) (get-lyric artist song)))
    (count songs)))
```

```sh
$ lein repl
```

```clj
user=> (def ^:dynamic *acidman* "a00b172")
#'user/*acidman*

user=> (require '[clojure.pprint :only pprint])
nil

user=> (load-file "src/acidman/core.clj")
#'acidman.core/download-songs

user=> (pprint (acidman/collect-songs *acidman*))
(("l0021c4" "リピート")
 ("l00ceb5" "金色のカペラ")
 ("l00ceb6" "街の輪郭")
 ("l01a1a6" "±0")
 ("l023548" "レガートの森")
 ("l02bfc2" "ラストコード")
 ("l023546" "2145年")
 ("l009df7" "and world")
 ("l022828" "ALMA")
 ("l01a1a1" "Bright & Right")
 ("l009ee0" "calm")
 ...
 ("l023545" "ワンダーランド"))
nil

user=> (acidman/get-lyric *acidman* "l0044aa")
"鮮やかだったあの太陽が ... 今 鐘は響く何度でも息を深く吸い込むのだろう"

user=> (acidman/download-songs *acidman*)
98
```

これを書いている現在、98曲登録されているみたいです。ただし、

> 英語詞は歌詞カードの対訳を参照した。なお、「equal」収録の「colors of the wind」は ACIDMAN 作詞ではないので除外。また second line も元の曲と同一とみなし除外した。

> [ACIDMAN の歌詞によく使われる単語とは - ニコニコ大百科](http://dic.nicovideo.jp/a/acidman%E3%81%AE%E6%AD%8C%E8%A9%9E%E3%81%AB%E3%82%88%E3%81%8F%E4%BD%BF%E3%82%8F%E3%82%8C%E3%82%8B%E5%8D%98%E8%AA%9E#h2-1)

というルールがあるので、「COLORS OF THE WIND」と「spaced out(second line)」を削除し、対象は96曲とします。それに加えて、今回は英語詞を考慮しません。


### ワードカウント

　本題です。使われている単語を使用頻度の多い順にリストアップします。

`src/acidman/core.clj` に追記します。

```clj
;; ディレクトリにあるファイルのリストを返す
(defn find-files [directory]
  (->> (io/file directory) file-seq (filter (memfn isFile))))

;; 文章を形態素解析して含まれる単語とその品詞を返す
(defn morphological-analize [sentence]
  (->> (.tokenize (.build (Tokenizer/builder)) sentence)
       (map #(vector (.getSurfaceForm %) (.getAllFeatures %)))))

;; 文章に含まれる指定したパターンと品詞を持つ単語を返す
(defn search-words [word class sentence]
  (->> (morphological-analize sentence)
       (filter (fn [[w f]] (and (re-find (re-pattern word) w)
                                (re-find (re-pattern (str "^" class ",")) f))))
       (map first)))

;; 全ファイルに含まれる単語とそれを含むファイルの個数を返す
;; オプションで単語のパターンと品詞を指定できる
;;（デフォルトでは英単語や平仮名一文字の単語を除く）
(defn count-words
      [files & {:keys [word class] :or {word "([^ -~ぁ-ん]|[ぁ-ん][ぁ-ん]+)" class ".*"}}]
  (->> files
       (mapcat (fn [file] (->> (slurp (.getPath file))
                               (search-words word class)
                               (map #(hash-map % (hash-set (.getName file)))))))
       (apply merge-with into)
       (map (fn [[word titles]] (vector word (count titles))))
       (sort #(compare (second %2) (second %1)))))
```

```clj
user=> (load-file "src/acidman/core.clj")
#'acidman/count-words

user=> (pprint (acidman/find-files *acidman*))
(#<File a00b172/2145年>
 #<File a00b172/ALMA>
 #<File a00b172/and world>
 #<File a00b172/Bright & Right>
 #<File a00b172/calm>
 ...
 #<File a00b172/香路>)
nil

user=> (pprint (acidman/morphological-analize "時間は溶けて廻る星いつも通り"))
(["時間" "名詞,副詞可能,*,*,*,*,時間,ジカン,ジカン"]
 ["は" "助詞,係助詞,*,*,*,*,は,ハ,ワ"]
 ["溶け" "動詞,自立,*,*,一段,連用形,溶ける,トケ,トケ"]
 ["て" "助詞,接続助詞,*,*,*,*,て,テ,テ"]
 ["廻る" "動詞,自立,*,*,五段・ラ行,基本形,廻る,メグル,メグル"]
 ["星" "名詞,一般,*,*,*,*,星,ホシ,ホシ"]
 ["いつも" "副詞,一般,*,*,*,*,いつも,イツモ,イツモ"]
 ["通り" "名詞,一般,*,*,*,*,通り,トオリ,トーリ"])
nil

user=> (pprint (acidman/search-words ".*" "名詞" "時間は溶けて廻る星いつも通り"))
("時間" "星" "通り")
nil
```

名詞、動詞、形容詞でそれぞれ実行してみます。

```clj
user=> (pprint (acidman/count-words (acidman/find-files *acidman*) :class "名詞"))
(["世界" 48]
 ["音" 43]
 ["風" 39]
 ["君" 39] 
 ["今" 37] 
 ["空" 34] 
 ["声" 33] 
 ["何" 32] 
 ["中" 32] 
 ["光" 31] 
 ["全て" 31] 
 ["太陽" 30] 
 ["星" 30] 
 ["よう" 30] 
 ["日" 28] 
 ["日々" 25] 
 ["夢" 24] 
 ["手" 24] 
 ["夜" 23] 
 ["目" 22] 
 ["心" 21] 
 ["まま" 21] 
 ["僕ら" 21] 
 ["色" 21] 
 ["それ" 20] 
 ["一つ" 20] 
 ["達" 20] 
 ["人" 19] 
 ["様" 19] 
 ["事" 19] 
 ...
 ["染め" 1])
nil
```

```clj
user=> (pprint (acidman/count-words (acidman/find-files *acidman*) :class "動詞"))
(["いる" 29] 
 ["消え" 24] 
 ["ゆく" 24] 
 ["忘れ" 23] 
 ["響く" 22] 
 ["生まれ" 20] 
 ["行く" 18] 
 ["流れ" 16] 
 ["溢れ" 15] 
 ["探し" 14] 
 ["閉じ" 13] 
 ["ある" 12] 
 ["笑っ" 12] 
 ["見上げ" 11] 
 ["なる" 11] 
 ["笑う" 11] 
 ["重ね" 10] 
 ["揺れ" 10] 
 ["繋い" 10] 
 ["似" 10] 
 ["見" 10] 
 ["乗せ" 9]
 ["描い" 9]
 ["てる" 9]
 ["行こ" 9]
 ["求め" 9]
 ["変わる" 9]
 ["触れ" 9]
 ["混ざり" 8]
 ["浮かべ" 8]
 ...
 ["満ちる" 1])
nil
```

```clj
user=> (pprint (acidman/count-words (acidman/find-files *acidman*) :class "形容詞"))
(["遠く" 14]
 ["無く" 13]
 ["ない" 10]
 ["無い" 8]
 ["深く" 7]
 ["遠い" 7]
 ["強く" 7]
 ["正し" 7]
 ["美しく" 6]
 ["正しい" 6]
 ["いい" 5]
 ["欲しい" 5]
 ["なく" 5]
 ["良い" 4]
 ["白い" 4]
 ["古い" 3]
 ["遠き" 3]
 ["美し" 3]
 ["深い" 3]
 ["浅い" 3]
 ["儚き" 3]
 ["眩し" 3]
 ["高く" 3]
 ["儚く" 3]
 ["美しき" 3]
 ["悲しき" 2]
 ["小さく" 2]
 ["赤い" 2]
 ["儚" 2]
 ["優し" 2]
 ...
 ["鋭く" 1])
nil
```

楽しい！(☝ ՞ਊ ՞)☝

## 終わりに

　参考情報です。

> [ACIDMAN | Official Site](http://acidman.jp/)

> [ACIDMAN の歌詞によく使われる単語とは - ニコニコ大百科](http://dic.nicovideo.jp/a/acidman%E3%81%AE%E6%AD%8C%E8%A9%9E%E3%81%AB%E3%82%88%E3%81%8F%E4%BD%BF%E3%82%8F%E3%82%8C%E3%82%8B%E5%8D%98%E8%AA%9E)

> [ACIDMAN の歌詞リスト - J-Lyric.net](http://j-lyric.net/artist/a00b172/l0021c4.html)

> [Clojure/kuromoji でテキストマイニング入門　～形態素解析からワードカウントまで～ - あんちべ！](http://antibayesian.hateblo.jp/entry/2013/09/10/231334)

> [Kuromoji - Atilika](http://atilika.org/)

普段聞かないので作業中にずっと流していたのだけれど、ACIDMAN 最高っぽい(☝ ՞ਊ ՞)☝