目次
1. はじめに
この文章ではロト6の当選数字の出方に偏りがあるかどうかを統計的に考える。
ロト6とは、多くの人は知っていると思うが宝くじの一種で、1から43までの数字から6個の数字を選び、6個の当選番号と3個以上一致すると、 一致した数字の個数に応じて賞金がもらえるというものである。 詳しいルールについては以下のオフィシャルな説明を読んでほしい。
考えたいのは、この数字の出方に統計的な偏りがあるかである。 ここでは「統計的」という部分に力点があり、単に偏りがあるかという話ではない。
例えば、ロト6の第1回から第1820回までで最もよく出た数字は6で282回、 最も出ていない数字は9で225回であり、57回分の差がある。 しかしこれをもって、ロト6では6を選ぶと当たりやすく、9を選ぶと外しやすいと結論することはできない。 全ての数字が同じ確率で現れるとしても、偏りは生じるからだ。
偏りには自然なものと不自然なものがある。 例えば、コインを100回投げて表が20回しか出なかったら、裏が出やすいコインだと疑うのは当然である。 しかし、表が35回出るのが自然か不自然かというと、判断に困るのではないだろうか。 同じく、ロト6の57回分の差も、これが自然かどうかは直感的には判断しにくい。
統計学を用いると、自然な偏りと不自然な偏りを区別できる。 特に適合度検定(の一般化)を使って、ロト6の数字の出方に偏りがあるかを考えるのが、この文章の趣旨である。 ただし、統計学の結論は確率に基づいているため100%確かではなく、常に一定の不確実性があることは理解しておいてほしい。
2. 目的
過去のロト6の結果(第1回から第1820回)までを集計し、各数字および2つの数字の組の出現頻度に偏りがあるかを調べる。これは例えば、特定の数字(例えば5)や数字の組(例えば11と13の組)が当選番号に出やすいというような偏りがあるかを調べるということ。 また、3つ以上の数字の組の出やすさは調べない。これは今回の手法では調べられないからである(以下の「方法」のセクションの末尾の注意を参照)。
注意: 頻度のみに着目して調べるため、抽選同士の相関は分からない。例えば、ある回とその次の回の当選番号に相関があるかは今回の考察からはわからない。
3. 方法
(注意: 統計学をあまり知らなかったり、数式に抵抗があったりする人にとってはこれ以降は読みづらいと思うが、細かい部分は飛ばしても大まかな論旨は把握できるように書いたつもりなので、適当に飛ばし飛ばし読んでほしい。)
よく知られた適合度検定を修正したものを用いる。 適合度検定は統計学を学んだ人なら誰でも知っている方法だが、 今回のケースには素朴には適用できず、修正が必要になる。
3.1. 適合度検定とは
念のため、通常の適合度検定について簡単に振り返る。詳しくは以下のWikipediaの記事または統計学の入門書を参照。
ある試行において、 の 個の結果が起こりうるとする。これらの結果は1回の試行でただ1つだけが起こるとする。 それぞれの結果が起こる確率を と予想したとき、これが正しいか否かを検定するのが適合度検定である。1
個の観測結果 が与えられたとしよう。つまり、 はそれぞれ のいずれかである。このとき、検定統計量は
である。ここで、 は結果 の観測度数、つまり、 となるような の個数である。の値はが期待される観測回数から離れるほど大きくなる。よって、が大きいほど予想が外れている可能性が高いことになる。
の分布は の極限で、パラメータ のカイ二乗分布に近づくため、大きい について がカイ二乗分布に従うと見なすことでカイ二乗分布表を用いて検定を行うことができる。 をどれくらい大きくとればいいかについては実用的な基準として、すべての に対し となれば良いとされているようである。
適合度検定のイメージを掴んでもらうため、簡単な例を1つ挙げる。サイコロの各目が同じ確率で出るかを検定することを考える。各目 が出るという結果を とし、 と定める。サイコロを 回振って、上に挙げたカイ二乗値 を計算する。この値は各目が出る頻度が からズレるほど大きくなる。よって、これがある値よりも大きい場合、 という仮説は棄却され、サイコロは公正ではないと見なされる。
3.2. 適合度検定の修正の必要性
ロトで各数字の出現確率を検定するには、上に書いたような適合度検定は適用できず、工夫が必要となる。
素朴に考えると、1回の抽選で6個選ばれた数字のうちに が含まれることを結果 として適合度検定を行えばいいと思うかもしれない。しかし、1回の抽選で複数の数字が同時に選ばれるため、これでは異なる と に対して と は同時に起こらないという適合度検定の前提に反してしまう。
では、6個の数字を選ぶことを、1個の数字を6回選ぶことと見なせばいいと思うかもしれないが、これにも問題がある。なぜなら、各数字の選択確率は、1回目から6回目まで変わってしまうからだ。例えば、1回目に取り出した数字は次の5回では選ばれない。このことは、観測結果が独立でなければならないという適合度検定の前提(上では明示的には書かなかったが)に反してしまう。
結局、ロトに関しては、単純な適合度検定を適用することはできない。検定統計量の導出から修正を加える必要がある。 幸いそのような場合に適合度検定を一般化した先行研究がある: Joe (1993), Genest et. al. (2002). 2
これら2つの先行研究ではそれぞれ、ロトのように複数の数字からいくつかの数字を同時に選出する試行に対し、数字(または数字の組)の出現確率が等しいかを検定する方法を与えている。この2つの論文では異なる形の検定統計量を与えているが、各数字(つまり1つの数字)の出現確率の場合は統計量は等しくなる。
今回は特に理由はないが、Joe (1993) ではなく Genest et. al. (2002) の方法を採用する。
3.3. 検定統計量
以下では観測回数をと表している。今回の場合は1820回分の結果がわかっているのでである。 Genest et. al. (2002)の結果から、以下のように検定統計量を定めることができる。
各数字の出現確率の等しさの検定
検定統計量を次のように定める:
.
の分布は の極限において、パラメータ42のカイ二乗分布に近づく。
- は各数字の理論出現確率 (選出に偏りがない場合に、1回の抽選で特定の数が出る確率)。
- よく見ると、 は上で言及した、数字を1つずつ選出したとみなして計算した場合のカイ二乗値の42/37倍。よって、通常の適合度検定の計算を流用できる。
2つの数字の組の出現確率の等しさの検定
検定統計量を次のように定める:
.
- で、これは各ペアの理論出現確率のn倍。
- はペア の観測度数。
の分布は の極限において、次の確率変数の分布に近づく: .
ここで、 と はそれぞれパラメータ と のカイ二乗分布に従う独立な確率変数であり、 、。
上記2つの統計量の極限分布について、数値計算によってp値を求めた。
注意: 3つ以上の数字の組について検定を行わない理由
先に言及した2つの先行研究では3つ以上の数字の組に対しても検定統計量を与えている。しかし、それらに対して検定を行うには現状ではデータが少なすぎると考えられる。 既に述べたように、適合度検定を適用する実用的な基準として、(観測の総回数) × (理論出現確率) が10以上というのがある。 この基準が今回の修正した適合度検定に対しても適切かは明らかではないが、ここでは同じ基準を適用することにする。 このとき、それぞれの場合について(観測の総回数) × (理論出現確率)の値を求めると以下のようになる:
- 1つの数字のときは、 .
- 2つの数字の組のときは、 .
- 3つの数字の組のときは、 .
このように3つ以上の数字の組に対しては10を下回ってしまう。よって、現状ではこの検定統計量を用いるのは恐らく適切ではない。
4. 結果
以下が結果である。
- 各数字の出現確率の等しさの検定のp値 ≒ 0.88.
- 2つの数字の組の出現確率の等しさの検定のp値 ≒ 0.87.
5. 結論
初めに少しだけp値についての一般的な説明をする。 p値は0から1の間の値を取り、この値が小さいとき、仮説 (今回の場合は例えば全ての数や組が等確率で現れるという仮説)は怪しいとされる。通常、0.05や0.01などのしきい値を設定し、これより小さい場合は統計的に有意な差があるとされ、元々の仮説は棄却される。注意点としては、p値が大きいほど仮説の信頼性が一層高まるわけではなく、単にデータが仮説と整合していることを示しているに過ぎない事である。
結論を言うと、今回のp値は極めて大きい。よって、等確率性を疑うことは難しい。
6. 余談
先行研究である Genest et. al. (2002) ではカナダのロトの1798回分の結果に対し検定を行い、p値はそれぞれ0.104, 0.300としている。 これはそれなりに大きいとはいえ、日本のものほど極端に大きくはない。 カナダのロトは49個の数字から6個を選ぶので、日本のものとは少し異なるが、 それだけでこれほど差が出るとは思えない。 また、同論文ではボーナスナンバーを含めた場合、各数字の出現確率の検定のp値は0.044となると報告している。これは有意水準5%の場合には仮説は棄却されてしまうほど低い。 カナダのロトの等確率性はやや怪しいのかもしれない。3
ついでなので、日本のロトの場合も、ボーナスナンバーを含めた等確率性の検定を各数字、2つの数字の組にそれぞれ試してみたところ、どちらもp値はほぼ0.90となった。 やはりp値は十分に大きい。
参考文献
・H. Joe. Tests of uniformity for sets of lotto numbers. Statist. Probab. Lett., 16(3):181–188, 1993.
・C. Genest, R. A. Lockhart, and M. A. Stephens. and the lottery. The Statistician, 51(2):243–257, 2002.
付録: 検定に用いたコード
検定に用いたコードを載せておく。私は簡単なコードを読めるぐらいの実力しかないので、 ChatGPTに大いに頼ってプログラムを組んだ。多分正しく動作していると思うが確証はない。 ロトの当選番号のデータ(コード内では"loto_results.txt"として読み込まれている)はここには載せないが簡単に手に入る。
各数字の出現確率の等しさの検定
コードを開く
# 各数字の等確率性の検定 import numpy as np from scipy.stats import chisquare, chi2 # 1からlまでの数値 l = 43 with open('loto_results.txt') as f: nums = np.array([int(x) for x in f.read().split()]) # ビンのカウント bins, _ = np.histogram(nums, bins=range(1, l+2)) # 1からlまでの数値が等確率で選ばれるという仮説に基づいて、期待される頻度を計算 expected_frequencies = [len(nums) / l] * l # カイ二乗適合度検定を実行 chi2_stat, p_val = chisquare(bins, expected_frequencies) # カイ二乗統計量の調整 adjusted_chi2_stat = chi2_stat * (42 / 37) # 自由度42のカイ二乗分布でp値を計算 adjusted_p_val = 1 - chi2.cdf(adjusted_chi2_stat, 42) print("統計量:", adjusted_chi2_stat) print("p値:", adjusted_p_val)
統計量: 31.529937629937628
p値: 0.8809230858481042
2つの数字の組の出現確率の等しさの検定
統計量の数値積分がうまくできなかったので、モンテカルロ法を用いて積分の近似値を求め、そこからp値を算出している。
コードを開く
# 2つの数の組の等確率性の検定 import numpy as np from itertools import combinations from scipy.stats import chi2 # 43 x 43の全ての成分が0からなる配列pairsを作る pairs = np.zeros((43, 43), dtype=int) # ファイルから読み取り with open('loto_results.txt') as f: given_array = np.array([int(x) for x in f.read().split()]) # 6個ずつに区切る nums = np.array_split(given_array, len(given_array) // 6) # numsの各要素xの2つの要素の組(i,j)に対し、pairs[i][j] += 1する for num_group in nums: for i, j in combinations(num_group, 2): small, large = min(i, j), max(i, j) pairs[small-1][large-1] += 1 # 定数E E = 1820 * 5 * 6 / (42 * 43) # (pair[i][j] - E)^{2} / E をi < jで和を取る計算 result = sum((pairs[i][j] - E)**2 / E for i in range(pairs.shape[0]) for j in range(i+1, pairs.shape[1])) # モンテカルロ法によるp値の計算 # 定数とパラメータ a = 5 * 37 / 41 b = 36 * 37 / (40 * 41) df_U = 42 df_V = 860 p = 0.1 n_samples = 10000000 # サンプル数 # UとVのサンプルを生成 samples_U = chi2.rvs(df_U, size=n_samples) samples_V = chi2.rvs(df_V, size=n_samples) # Wのサンプルを計算 samples_W = a * samples_U + b * samples_V # サンプル集合samples_Wと値xが与えられたと仮定 p_value = np.mean(samples_W > result) print("統計量:", result) print("p値:", p_value)
統計量: 828.0200000000001
p値: 0.8728807