むかし、ちょっとしたアルバイトを頼まれました。
彼の国に出向している現地法人のトップが不正を働いているらしいとのこと。
明確な証拠はつかめないけど、
なんとか出来ない?ともの凄くあいまいな依頼でした。
料金がそれなりに魅力的な金額だったので、色々調べてみました。
そこで発見したのが今回のエントリのペンフォードの法則。
ペンフォードの法則とは、ざっくりいうと
人為的な作意のない多くの自然発生的なデータにおいて数値先頭一桁目の出現分布は、下記に従うというもの。
Number 理論値
1 0.301
2 0.176
3 0.125
4 0.097
5 0.079
6 0.067
7 0.058
8 0.051
9 0.046
この理論値を導出する数学的な表現については、wikiに記載があります。
http://ja.wikipedia.org/wiki/%E3%83%99%E3%83%B3%E3%83%95%E3%82%A9%E3%83%BC%E3%83%89%E3%81%AE%E6%B3%95%E5%89%87
いくつか会計書類を貰って、スクリプトを書いて検証してみたら、
法則が示す期待値とは大幅に違う結果を得たのでした。
その後、どういう経緯を経てかは知りませんが解雇となったそうです。
ただ、彼の国で、不正を働くということは危険な筋とキッと
それなりの結びつきを持っていたはずで...その後、どうなったのでしょうか。
この法則は、自然な数字の分布割合を示してくれて、
会計書類の数字、株価、住所の番地、河川の長さ、無作為に拾った数字、etcが
これに従うのだそうです。
実際に、アメリカの税務局(※)などは虚偽の税務申告などを見抜くのに使ったり、
各種不正検知アルゴリズムは、コイツを利用しているみたいです。
※日本の場合はどうなんでしょうか?ちょっと知りません。
今回は、身近で、簡単に手に入る自分のPCのデータを使って、この法則への
適合性をみることにしました。
利用するデータは、僕のPC上に存在するファイル君達のサイズ...。
そこで、まずは、
ubuntu homeフォルダ配下のファイルをfindし、ファイルサイズを出力してみました。
~$sudo find -printf "%s:%f\n" > filesize
次に、ファイルサイズの先頭数値を取得
~$perl -wnl -e '/^[1-9]/ and print $&;' filesize > top_num
今回の目的のために作ったperlスクリプトをかまして、数字ごとの出現分布を計測すると、
~$perl cnt_num.pl top_num
Number Frequency
1 0.312179
2 0.143945
3 0.081360
4 0.242248
5 0.060865
6 0.045818
7 0.035770
8 0.040318
9 0.037498
perlスクリプトはこちら。。。
cnt_num.pl
----------------------------------------------------------------
#! /usr/bin/perl -wnlaF'\W+'
foreach $number (@F){
$count{$number}++;
$total++;
}
END {
printf "%5s%10s\n", 'Number', 'Frequency';
foreach $number(sort keys %count){
$frequency=$count{$number} / $total;
printf "%6s%10f\n", $number, $frequency;
}
}
----------------------------------------------------------------
ペンフォードの法則からあらかじめ求めた理論値と比較すると
結果2
Number Frequency 理論値
1 0.312179 0.301
2 0.143945 0.176
3 0.081360 0.125
☆4 0.242248 0.097
5 0.060865 0.079
6 0.045818 0.067
7 0.035770 0.058
8 0.040318 0.051
9 0.037498 0.046
となりました。
これはちょっと面白い結果で、
☆で示した4が大きく理論値とかけ離れています。これは何故なんでしょうか?
ここで、
先頭が4の数字だけをひろって数字ごとのカウントを数えてみると、
~$perl -wnl -e '/^4\d+/ and print $&;' filesize > four_num
~$perl cnt_num.pl four_num | sort -r -n -k2 > four_num_hist
以下、結果のTOP20...
Number Frequency
4096 0.711812
40 0.030239
475 0.003475
465 0.003140
450 0.002561
400 0.001951
41 0.001738
4013056 0.001463
457 0.001372
4147 0.001341
455 0.001311
453 0.001280
449 0.001219
463 0.001128
440 0.001097
436 0.001097
424 0.001097
422 0.001097
438 0.001067
なるほど、4096(4KB)のファイルサイズが特異な数字ということが判明。
4KBっていえば、たしかlinuxファイルシステムのブロックサイズ。。。
ためしに、/homeディレクトリに対して、
~$stat /home
とすると...
File: `/home'
Size: 4096 Blocks: 8 IO Block: 4096 ディレクトリ
Device: 801h/2049d Inode: 16384001 Links: 4
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2012-04-21 15:38:56.671861009 +0900
Modify: 2012-03-17 06:14:58.534658633 +0900
Change: 2012-03-17 06:14:58.534658633 +0900
なので、ディレクトリ毎にファイルサイズ4096が割り当てられるわけで、
サイズ4096の割合が多いのはここら辺に理由がありそうな感じがします。
実際に、この法則を適用できるシチュエーションは、いくつか制約があるようで、
データにばらつきがない場合、無作為にデータが選択されていない場合などには
適用が出来ないようです。
今回、”4”に関して、法則と大きなミスマッチが生じたのは、Linuxファイルシステムの
特質によるものなのかな?っと思ったり。