なんじゃくにっき

プログラミングの話題中心。

単語の出現頻度を数える

英文に出現する単語の頻度を数えてみます。
とりあえずは形態素解析とか難しいことは使わずに、アルファベット以外の文字を区切り文字として単語を切り出します。
 
題材はシェイクスピアハムレット
何故か自然言語処理でよく使われます。
約400年前の文章で、現代英語ではなく、近代英語に属するものですが、まあ殆ど現代英語と一緒です。
 
以下、コードと結果


package nlp.nanjakkun.com.github

import io.Source
import java.io._

object Main {
val inFileName = """/hamlet.txt"""
val outFileName = """result.csv"""
val wordExp = """[a-zA-Z]+""".r

def using[A, R <: { def close() }](r : R)(f : R => A) : A = {
try {
f(r)
} finally {
r.close()
}
}

def main(args: Array[String]): Unit = {
using(Source.fromURL(getClass.getResource(inFileName))) {
in => {
val wordList = wordExp.findAllIn(in.getLines.toList.mkString).map(_.toLowerCase())

val map = wordList.toList.groupBy(identity).mapValues(_.length)

using(new FileWriter(new File(outFileName))) {
out => {
map.toList.sortBy(- _._2).foreach({ x =>
out.write(x._1 + "," + x._2 + "\n")
})
}
}
}
}
}
}

まあこんな感じ。
結果をCSVに書き出すと、
 
the,1070
and,981
to,744
of,681
i,626
a,555
you,544
my,510
in,439
it,415
that,408
is,360
ham,358
not,314
d,305
this,304
his,295
with,275
but,271
for,269
your,239
as,234
me,230
s,229
lord,224
he,220
be,217
what,216
so,202
king,200

となります。
 
結果は皆さん予想通りと言うか、上位は冠詞、代名詞、前置詞が占めます。 
dとかがカウントされているのは
back'd(現代英語でのbacked)みたいな語が分割されてしまっているからです。
短縮形や格変化をちゃんと追おうと思えば形態素解析が必要ですが、それはまたの機会に。
 
 
あとでグラフ描きます・・
PCに表計算ソフト入ってなかった・・