LoginSignup
17
15

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-04-19

 概要です。

ACIDMAN の歌詞によく使われる単語とは - ニコニコ大百科

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

 試した環境です。

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

準備

 インストールとプロジェクト作成の様子です。この辺りは、前の記事と同じです。

# 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 を編集します。

(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 でテキストマイニング入門 ~形態素解析からワードカウントまで~ - あんちべ!

ということです。

$ lein repl
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 を編集します。

(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)))
$ lein repl
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 の歌詞によく使われる単語とは - ニコニコ大百科

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

ワードカウント

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

src/acidman/core.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)))))
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

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

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
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
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

ACIDMAN の歌詞によく使われる単語とは - ニコニコ大百科

ACIDMAN の歌詞リスト - J-Lyric.net

Clojure/kuromoji でテキストマイニング入門 ~形態素解析からワードカウントまで~ - あんちべ!

Kuromoji - Atilika

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

17
15
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
17
15