なんじゃくにっき

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

文字の出現頻度を数える

 前回、英文に出現する単語の出現頻度を数えてみましたが、
今回は前回よりもさらに細かい単位、文字単位で分割してみます。
 
前置きとして、シャノンの情報量 
の定義では、
確率pで起こる事象の情報量I(p)は
 
I(p) = -log2p bit で与えられます。 
 
簡単のため、アルファベット26文字とそれ以外の文字(空白文字とする)27字で文章が構成されるとします。
そうすると、全27字の出現頻度が同一で、並び順も完全ランダムだとすると、
その情報量は1文字あたり、
 
27 * (1/27 * -1 * log21/27) = log227 = 4.76 bit
 
となります(アルファベット26字 + 数字10字 + その他 なら 5.21 bit)。
 
 
実際の文章では文字の出現頻度には偏りが生じるために、
1文字あたりの情報量はもっと少なくなります。
(例えばすべてAからなる文章では、一文字あたりの情報量はlog1 = 0 bit。)*1
 
 
コードを書いて、ハムレットを集計してみます。

 
結果は・・


others,57350
e,15262
t,12013
o,11439
a,10080
h,8816
i,8755
s,8544
n,8421
r,8002
l,5958
d,5139
u,4403
m,4343
y,3286
w,3165
c,2741
f,2727
g,2454
p,2090
b,1919
k,1282
v,1252
q,219
x,187
j,118
z,71
 
で、others(その他の文字)を除けば、
e, t, o, a, h・・の順になっています。
一般的な英文での順、e, t, a, o, i・・とは少し違いますね、といったところ。
 
各アルファベットの出現率を piとすると、
1文字あたりのエントロピー
 
 -pilog2pi bit
 
の合計で、実際に計算すると、
3.81 bitとなりました。
 
ちょっとothers(その他の文字)が多すぎるせいで、
エントロピーが低くなっているようです(解析に使ったテキストが注釈などの記号が多いため)。
 
記号抜きでアルファベットのみだとエントロピー
4.19 bitとなりました。
 
この計算法で求めた場合、通常の英文の1文字のエントロピーは4 bit前後になるので、
大体合ってるといえるでしょう。
 
 
さて、情報量なんて求めて何になるの?
と思うかもしれませんが、実はファイル圧縮に使われています。
普段使ってるZIPやLHA形式のファイルの圧縮に役立ってます。
符号化処理によって、情報を圧縮できます。 
今日は力尽きたので、
wikipedia
シャノン符号化ハフマン符号化の項を見てください・・
 
 
今回の例で言うと、元々のテキストファイルが1文字1バイト(= 8ビット)だとすると、
1文字を4ビットに符号化できますので、約50%の圧縮を行えることになります。
もっと圧縮率をあげようと思うと、1文字でずつではなく、複数文字で符号化する必要があります。
  
 
 



 *1 話はそれますがAというプログラミング言語もありましたね。
 Aの個数が意味をもっている場合は一文字あたりの情報量が完全に0ではない気もしますが、
 シャノンの定義によればあくまでも0 bit?