blechmusikの日記

キー・カスタマイズ・ソフトウェア "DvorakJ" の覚え書きをはじめとして様々なことを書いています。

kouyさんの「100万字日本語かなn-gramデータ」のn-gramの情報を整理してみた

kouyさんの「100万字日本語かなn-gramデータ」の1-gramの情報を整理してみた - blechmusik2の日記の続きである。
今回は1-gramから4-gramまでの集計データについて、割合と累積割合に注目した二種類のグラフを作成した。グラフを作成するにあたり、もとの集計データのエクセルファイルをただcsv形式のファイルとして保存すればよいように改変している*1

calculate_cumproportion <- function(fname){
  ## ローマ字入力でもなく、かな入力でもなく : 100万字日本語かなn-gramデータ
  ## http://kouy.exblog.jp/9731073/
  ## データが集計されているファイルをcsvで保存しなおすこと
  x <- read.csv(fname
                , header=F
                , col.names=c("freq","char","number of n"))
  freq <- x$freq
  totalfreq <- sum(freq)
  totalfreq
  proportion <- round((freq / totalfreq) * 100, 2)
  cumfreq <- cumsum(freq)
  cumproportion <- round((cumfreq / totalfreq) * 100, 2)
  return(list(x=x, proportion=proportion, cumproportion=cumproportion))
}

detail_cumproportion <- function(fname){
  ret <- calculate_cumproportion(fname)
  cbind(ret$x, proportion=ret$proportion, cumproportion=ret$cumproportion)
}


plot_proportions <- function(fname, ret){
  ## Rで2軸PLOT(y軸の左右に値を表記)する方法 - My Life as a Mock Quant
  ## http://d.hatena.ne.jp/teramonagi/20120107/1325922512
  
  mai <- par()$mai
  mai[4] <- mai[1]
  par(mai = mai)

  ret <- calculate_cumproportion(fname)
  plot(
    ret$proportion, type = "p", col = "#40e0d0", pch=20, #
    ylab="",
    panel.first = grid(NA, NULL, lty = 1, col = "#E9E9E9") #
    + grid(NULL, NA, lty = 1, col = "#E9E9E9")             #
    )
  par(new =T)
  plot(
    ret$cumproportion, type = "p", col = "#0000cd", pch=20, #
    ylab="",
    axes = FALSE, 
    panel.first = grid(NA, NULL, lty = 1, col = "#E9E9E9") #
    + grid(NULL, NA, lty = 1, col = "#E9E9E9")             #
    )
  axis(4)

  ngram <- unlist(strsplit(fname, "\\.|/"))[2]
  title(paste("proportions of", ngram))

  mtext("proportion", side = 2, line = 3)
  mtext("cumulative proportion", side = 4, line = 3)
}



## example
detail_cumproportion("z:/2-gram.csv")

plot_proportions("z:/2-gram.csv")





これらのグラフを見て分かるのは、全体にしめる割合が大きいのは少数のパターンだと言うことである。このことは四分位数と平均のデータを参照することでより理解できる。

> for (i in 1:4) {
+   print(sapply(paste("z:/", i, "-gram.csv", sep=""),
+                function(fn){
+                  summary(calculate_cumproportion(fn)$proportion)
+                }))
+ }
        z:/1-gram.csv
Min.            0.000
1st Qu.         0.215
Median          0.840
Mean            1.190
3rd Qu.         1.792
Max.            6.270
        z:/2-gram.csv
Min.          0.00000
1st Qu.       0.00000
Median        0.00000
Mean          0.01784
3rd Qu.       0.02000
Max.          1.31000
        z:/3-gram.csv
Min.        0.0000000
1st Qu.     0.0000000
Median      0.0000000
Mean        0.0009085
3rd Qu.     0.0000000
Max.        0.3600000
        z:/4-gram.csv
Min.        0.0000000
1st Qu.     0.0000000
Median      0.0000000
Mean        0.0002115
3rd Qu.     0.0000000
Max.        0.1100000

*1:エクセルファイルからデータを直接読み込めばよいのだが、xlsReadWriteを使っても正常にうまく読み込めなかった。