脳ざらし紀行


2006-08-17

_ 日本語と n-gram でも Zipf の法則は成り立つか

Zipf の法則というのは以下のようなものです。英語で書かれた長編小説を用意します(小説でなくてもいいんだけど)。そして、本文中に出てくる英単語を頻度順に並べます。すると、第2位の単語の頻度は第1位の単語の頻度の半分になります。第10位の単語の頻度は第1位の単語の頻度の1/10です。第100位の単語の頻度は第1位の単語の頻度の1/100です。そんな感じの法則です。リンク先にもあるように対数グラフにプロットするときれいな直線になります。

さて、Zipf の法則は日本語に対して当てはまるでしょうか。とはいっても、日本語は英語みたいに単語毎に区切ることが簡単ではないので、ここでは n-gram を使います。2文字毎に文を区切って、その2文字を単語だと思って頻度を数えます。ひらがなと漢字だけを対象にしました。日本語のデータとしてはこの日記の本文を使いました。

REG = /([ぁ-ん亜-腕]([ぁ-ん亜-腕]))/e
H = Hash.new(0)

def count(line)
  while REG =~ line
    word = $1
    c = $2
    H[word] += 1
    line = c + (Regexp.last_match.post_match || '')
  end
  return line
end

def read_and_count(io)
  ret = ''
  io.each_line{|l|
    ret += l.chop
    ret = count(ret)
  }
end

def plot2(h)
  h = h.to_a.sort{|a, b| b[1] <=> a[1] }
  500.times{|n|
    e = h[n]
    puts "#{n+1} #{e[1]}"
  }
end

read_and_count(ARGF)
plot2(H)

結果です。横軸が順位、縦軸が頻度です。割ときれいな直線になっていると言えなくもないですね。英語の場合、直線の傾きはだいたい -1 になるそうです。しかし、この場合、直線の傾きは約 -0.734 です。この違いはどこから来るのでしょうか。英語と日本語の違い?

■追記(2006/8/21)。

http://www.jmuk.org/d/?path=2006/08/21#d21t01

お名前:
E-mail:
コメント:
本日のリンク元

最近のコメント

2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|04|05|
2011|04|
2012|03|07|
2013|01|02|07|
トップ «前の日記(2006-08-16) 最新 次の日記(2006-08-19)» 編集