こんにちは。エンジニアリンググループの高島(id:rst76)です。 最近、私が翻訳した『実用的でない Python プログラミング』という本が出版されたので、内容の一部を紹介したいと思います。
原著者はこの本を、Python を勉強する人が 2 冊目に読むものと位置づけています。 つまり基本的な構文などは分かっていて、色々なプログラムを書いてみたいというときに読む本です。 他のプログラミング言語を知っていて、 Python を触ってみたいというときにもいいかもしれません。
この本で扱う手法は、遺伝的アルゴリズム、マルコフ連鎖解析、モンテカルロ・シミュレーションなど、多岐に渡ります。 これらについて既に知っている人はニヤリとするかもしれません。 どれも名前はカッコいいですが、それほど難しいものではないからです。
それらの手法を利用して扱う題材も様々で、暗号を解読したり、俳句を詠んだり、火星探査機を操縦したりします。 今回は、選挙の不正を暴くのに使われるベンフォードの法則を、実際に試してみたいと思います。
なお、この本の翻訳にあたっては、社内外の様々な方にレビュー等で助けていただきました。この場を借りてお礼を申し上げます。
ベンフォードの法則とは
株価、人口、死亡率、川の長さなど、様々な数の先頭の数字( なら )を見たときに、その分布は一様ではなく、以下の割合で分布するというのがベンフォードの法則です。
先頭の数字が となる確率を とおくと、以下のように表すことができます。
この法則はいつでも成り立つわけではなく、対象の数が 冪乗則 に近い分布をとる必要があります。 たとえば成人の身長などは分布の幅が狭い(分散が小さい)ので、この法則に従いません。
道路の長さで試してみる
ベンフォードの法則が実際に成り立つのか試してみたいと思います。手始めに道路の長さで試してみることにします。 国道の長さが 道路:道路統計年報2017 道路の現況 - 国土交通省 から入手できるので、それを利用します(表27 一般国道の路線別、都道府県別実延長内訳)。 本当は県道や市町村道の長さも利用した方が、幅広い値が集められるのですが、データの入手に手間がかかるため、いったん国道のみを扱うことにします。 先頭の数字の割合をグラフにすると、以下のようになりました。
あまりベンフォードの法則に従っていないようです(本の中ではカイ二乗検定を使って定量的に評価しています)。 特に、先頭の数字が や になる場合が少ないことが分かります。
どうしてこうなったか、もう少し詳しくみてみます。 もともとの値の対数(底は )をとって出現頻度をグラフにすると、以下のようになります。
このグラフを見ると、 前後の長さの国道が多いこと、 未満の国道もいくつかあることなどが分かります。
冪乗則に従う=このグラフで一様分布に近いほど、ベンフォードの法則に従うようになるのですが、対数をとったときの小数部が 、つまり元の数の先頭の数字が や のとき(グラフの赤い部分)の頻度が小さいので、ベンフォードの法則から外れることも納得できます。
人口で試してみる
道路の長さがあまりうまく行かなかったので、今度は別のデータを試してみます。 人口などはどうでしょうか。 国勢調査のデータがあるので、こちらを使ってみます(2015年のデータを利用)。
国勢調査 都道府県・市区町村別の主な結果 都道府県・市区町村別の主な結果 | ファイル | 統計データを探す | 政府統計の総合窓口
このデータには全国の人口も都道府県や市区町村の人口もすべて含まれているため、重複もありますが、幅広い数値を入手したいという意味では逆に都合がいいので、そのまま利用します。これをベンフォードの法則と比較したのが以下のグラフです。
今度は比較的合致しているようです。 先ほどと同様に対数をとって出現頻度をグラフ化すると以下のようになります。
あたりをピークに から くらいまで幅広くデータが分布しており、ベンフォードの法則を満たしやすくなっていることが分かるのではないでしょうか。
まとめ
ベンフォードの法則がどのようなものかを説明して、実際に成り立つか検証してみました。 『実用的でない Python プログラミング』には、こういう話が色々出てくるので、興味を引くテーマがあれば、ぜひ読んでみてください。
今回載せたグラフは Python と matplotlib で作成しており、元となったプログラムは原著者の GitHub にあります。
エンジニア募集中!
エムスリーは適材適所でプログラミング言語を選ぶ方針なので、 Python を利用しているサービスもたくさんあります。 エンジニアを鋭意募集中ですので、ぜひお問い合わせください。