Statistical Programming

テキストマイニング入門が簡単な時代になったのですなあ〜

kuromojiという形態素解析ライブラリを利用してテキストマイニングしてみる。やってみたけど超簡単。やばい、これ。しかもScalaから利用するからJavaと比べてさらにすっきりするしいいね。以下からjarファイルをダウンロード。

Downloads · atilika/kuromoji · GitHub

ビルドパスを通すだけでおっけ。プロジェクトにビルドパスを通したらあとは org.atilika.kuromoji.Tokenizer をimportしてついでにJavaのリストをScalaに変換できるよう scala.collection.JavaConversionsもimport。importするのはこれで終わり。
まずはTokenizerのインスタンスをゲットしてからtokenize()の中に解析したい文字列をいれ、それをもとにTokenの入ったListをげっと!最後にそれらをjavaからscalaのListに変換してforeachでまわせばおけ!

kuro.scala
package textmining
import org.atilika.kuromoji.Tokenizer
import scala.collection.JavaConversions._
object  Kuromoji extends App{
val tokenizer=Tokenizer.builder().build()
val tokens=tokenizer.tokenize("明日ははやいよーー!!ねむた!ねむた!")
val stokens=tokens.foreach(x=>println(x.getAllFeatures()))
} 

名詞,副詞可能,*,*,*,*,明日,アシタ,アシタ
助詞,係助詞,*,*,*,*,は,ハ,ワ
形容詞,自立,*,*,形容詞・アウオ段,基本形,はやい,ハヤイ,ハヤイ
助詞,終助詞,*,*,*,*,よ,ヨ,ヨ
名詞,一般,*,*,*,*,*
記号,一般,*,*,*,*,!,!,!
記号,一般,*,*,*,*,!,!,!
形容詞,自立,*,*,形容詞・アウオ段,ガル接続,ねむたい,ネムタ,ネムタ
記号,一般,*,*,*,*,!,!,!
形容詞,自立,*,*,形容詞・アウオ段,ガル接続,ねむたい,ネムタ,ネムタ
記号,一般,*,*,*,*,!,!,!

ちなみにこんな感じで1行でも書ける。見づらいけど笑

Tokenizer.builder().build().tokenize("やっはろー!?元気してる?").foreach(x=>println(x.getAllFeatures()))

ちょっとだけ手を加えてファイルから読み取る感じに。

kuro.scala
package textmining
import org.atilika.kuromoji.Tokenizer
import scala.collection.JavaConversions._
import scala.io.Source
object  Kuromoji extends App{

def analyze(file:String)={
val files=Source.fromFile(file)
  val tokenizer=Tokenizer.builder().build()
    for(lines <- files.getLines){
      val tokens=tokenizer.tokenize(lines)
      val stokens=tokens.foreach(x=>println(x.getAllFeatures()))
    }
    files.close()
}
analyze("/Users/kyu/Documents/assignment/Exercise/
src/textmining/shayo.txt")
} 

こんな感じでカウント数でソートも!        
 

tokens.groupBy(x=>x.getBaseForm)
  .values
  .toList
  .sortWith( (a,b)=>a.length>b.length)
  .foreach(x=>println("count: " +x.length+" "+x(0).getBaseForm))

でもこのままだと”た”とか”て”とかあまり意味のない助詞とかが上の方にでてきてしまた(よく考えれば当たり前)。それを防ぐには多分どの品詞だけ適用みたいなことを指定する必要があるのかな。というわけでfilterを途中に挟み込む。 というわけで名詞だけにしぼってみた。最終的なコードは以下っす。

kuro.scala
package textmining
import org.atilika.kuromoji._
import scala.collection.JavaConversions._
import scala.io.Source
object  Kuromoji extends App{
def analyze(file:String)={
val files=Source.fromFile(file)
val content=files.getLines.mkString
  val tokenizer=Tokenizer.builder().build()
  valtokenlist=tokenizer.tokenize(content)
  val sorted=
    tokenlist
  .filter(x=>x.getPartOfSpeech().startsWith("名詞"))
  .groupBy(x=>x.getBaseForm)
  .values
  .toList
  .sortWith( _.length>_.length)
  sorted.foreach(x=>println("count: " +x.length+" "+x(0).getBaseForm()))  
}
analyze("/Users/kyu/Documents/fruits
/Exercise/src/textmining/shayo.txt")
} 

<各変数の値、メソッドの返り値はこんな感じ>
tokenlist ; List(Token(),Token()......)

→filter ; List(Token(~),Token(~),....) 
※名詞のみを取り出す

→groupBy ; Map("~"->List(),"~"->List(),....) 
※原型が同じ単語をまとめる。"~"がその原型、List()にはその単語が入っている。例えばもし文中に2回”世界”という単語が出現していれば "世界"->List(Token(),Token()) となる

→values ; MapLike(List(),List(),...)
※先ほどのMapのListの部分だけを抽出

→toList ; List(List(),List(),....)

→sortWith ; List(List(),List(),...)
※各リストの要素が多い順、つまり単語の出現頻度順にソートする

→foreach以下 ; それらを出力

効率をもっと良くしたいですね…コレクションの使い方をべんきょうせねば。