PythonでLOTO6のデータ分析をしてみた ~その3~

はじめに

その3では、「loto6で期待値の高い数値の選び方はあるのか?」について以下の手順で分析・解析していきます。

  1. 期待値の定義と算出
  2. 期待値を最大化する数字の選び方

なお、本記事ではその2の内容を踏まえて、「loto6で特別に出やすい数字はない(出目は完全にランダム)」という前提で進めていきます。

PythonでLOTO6のデータ分析をしてみた ~その2~


出目がランダムじゃ期待値を上げることなんて出来ないのではないか?と思うかもしれませんが、loto6は4等賞以上の当たりでは当選者で賞金を分配するシステムになっているため、人が選びにくい数字を選ぶことで期待値を上げられる可能性があります。仮説としては、例えば数字を誕生日等から選ぶ人が多ければ、月である1〜12、日である1〜31に選択される数字が集中するため、この範囲を選ばなければ当選が他人と被りにくく、期待値を上げられるというようなことがありえるのでは、と考えました。

期待値の定義と算出

期待値の定義

loto6は1口200円で購入することが出来るので、期待値とは「当選確率を考慮した当選金額が1口当たり何円か」であると言えます。また、この期待値が高くなるような数字の選び方を見つけ出すことが本記事の目的になります。
上記より、1口の期待値(E(1口))は以下の式で表すことが出来ます。

\begin{equation*}
E(1口) = \Sigma_{k=1}^{5}{(k等賞の当選確率×k等賞の当選金額)}
\end{equation*}

期待値の算出

上記に示したとおり、期待値を算出するためには1〜5の各等賞の当選確率と当選金額を求める必要がありますので、以下順をおって算出していきます。

当選確率の理論値

loto6は1〜43の数字の中から6つの数字を選び、全て的中していれば1等賞、5つ的中していて残りの1つがボーナス数字と一致していれば2等賞、5つ的中していれば3等賞、4つ的中していれば4等賞、3つ的中していれば5等賞というように決まっていますのでそれぞれ以下のような式で理論値を求めることが出来ます。

\begin{equation*}
p(1等賞) = \frac{{}_{6} C _6}{ {}_{43} C _6}
\end{equation*}
\begin{equation*}
p(2等賞) = \frac{{}_{1} C _1 \cdot {}_{6} C _5 }{ {}_{43} C _6}
\end{equation*}
\begin{equation*}
p(3等賞) = \frac{{}_{36} C _1 \cdot {}_{6} C _5 }{ {}_{43} C _6}
\end{equation*}
\begin{equation*}
p(4等賞) = \frac{{}_{37} C _2 \cdot {}_{6} C _4 }{ {}_{43} C _6}
\end{equation*}
\begin{equation*}
p(5等賞) = \frac{{}_{37} C _3 \cdot {}_{6} C _3 }{ {}_{43} C _6}
\end{equation*}
\begin{equation*}
p(ハズレ|2個的中) = \frac{{}_{37} C _4 \cdot {}_{6} C _2 }{ {}_{43} C _6}
\end{equation*}
\begin{equation*}
p(ハズレ|1個的中) = \frac{{}_{37} C _5 \cdot {}_{6} C _1 }{ {}_{43} C _6}
\end{equation*}
\begin{equation*}
p(ハズレ|0個的中) = \frac{{}_{37} C _6 \cdot {}_{6} C _0 }{ {}_{43} C _6}
\end{equation*}

pythonのscipyを使って計算してみます。

In [1]:
import scipy.misc
import scipy as sp
#1等賞が当たる確率
sp.misc.comb(6, 6) / sp.misc.comb(43, 6)
Out[1]:
1.6402977862213017e-07
In [2]:
#2等賞が当たる確率
sp.misc.comb(1, 1) * sp.misc.comb(6, 5) / sp.misc.comb(43, 6)
Out[2]:
9.84178671732781e-07
In [3]:
#3等賞が当たる確率
sp.misc.comb(36, 1) * sp.misc.comb(6, 5) / sp.misc.comb(43, 6)
Out[3]:
3.543043218238012e-05
In [4]:
#4等賞が当たる確率
sp.misc.comb(37, 2) * sp.misc.comb(6, 4) / sp.misc.comb(43, 6)
Out[4]:
0.0016386574884350805
In [5]:
#5等賞が当たる確率
sp.misc.comb(37, 3) * sp.misc.comb(6, 3) / sp.misc.comb(43, 6)
Out[5]:
0.025490227597879028
In [6]:
#ハズレの確率
(sp.misc.comb(37, 4) * sp.misc.comb(6, 2) + sp.misc.comb(37, 5) * sp.misc.comb(6, 1) + sp.misc.comb(37, 6) * sp.misc.comb(6, 0)) / sp.misc.comb(43, 6)
Out[6]:
0.9728345362730532

整理すると下記のような感じです。5等すら2.5%程度しかなく、ほぼほぼ外れるギャンブルであることが分かります。
1等賞:およそ600万分の1
2等賞:およそ100万分の1
3等賞:およそ3万分の1
4等賞:およそ600分の1
5等賞:およそ40分の1
ハズレ:およそ40分の39

(参考)当選確率の実績値との比較

念の為、実データを使った当選確率の算出も実施してみます。データは以下で作ったものを使います。

Pandasを使ってloto6のデータを整形・加工する


In [7]:
import pandas as pd
#データ読み込み
df = pd.read_csv("loto6_allData.csv", index_col=1, parse_dates=True)
In [8]:
#データの上位5行を確認
df.head()
Out[8]:
抽せん回曜日本数字1本数字2本数字3本数字4本数字5本数字6ボーナス数字1等口数34353637383940414243
抽せん日
2000-10-05128101327303920000070000
2000-10-1221916202143500000000006
2000-10-19315153136381320050600000
2000-10-2641618262734401305000006000
2000-11-025915212327284300000000007

5 rows × 65 columns

データには1等口数等の当選数があり、販売実績額を200(円/口)で割れば総口数が求まることから、これらを使って当選確率の実績値を求めることが可能です。

In [9]:
#総口数を計算
df['総口数'] = df['販売実績額'] / 200
#各等賞の割合を計算
for i in range(1, 6):
    df[str(i)+'等割合'] = df[str(i)+'等口数'] / df['総口数']
#データ確認
df.iloc[:, -5:].head()
Out[9]:
1等割合2等割合3等割合4等割合5等割合
抽せん日
2000-10-053.380711e-073.380711e-070.0000440.0020980.029489
2000-10-120.000000e+001.149056e-060.0000320.0013830.023779
2000-10-192.457452e-079.829807e-070.0000200.0011610.022294
2000-10-260.000000e+004.044960e-070.0000180.0011700.021693
2000-11-020.000000e+001.049850e-060.0000300.0019220.027994

通算の平均値を計算してみます。

In [10]:
df[[str(i)+'等割合' for i in range(1, 6)]].mean()
Out[10]:
1等割合    1.700584e-07
2等割合    1.161114e-06
3等割合    3.513919e-05
4等割合    1.637770e-03
5等割合    2.538049e-02
dtype: float64

先ほどの結果と比較してみましょう。

In [11]:
#理論値
percentList = [
    sp.misc.comb(6, 6) / sp.misc.comb(43, 6),
    sp.misc.comb(1, 1) * sp.misc.comb(6, 5) / sp.misc.comb(43, 6),
    sp.misc.comb(36, 1) * sp.misc.comb(6, 5) / sp.misc.comb(43, 6),
    sp.misc.comb(37, 2) * sp.misc.comb(6, 4) / sp.misc.comb(43, 6),
    sp.misc.comb(37, 3) * sp.misc.comb(6, 3) / sp.misc.comb(43, 6),
]
#実績値
tdf = df[[str(i)+'等割合' for i in range(1, 6)]].mean()
#結合
tdf = pd.concat([tdf, pd.DataFrame(index=tdf.index, data=percentList)], axis=1)
tdf.columns = ['実績値', '理論値']
tdf['誤差率%'] = 100 * (tdf['実績値'] - tdf['理論値']).abs() / tdf['実績値']
#表示
tdf
Out[11]:
実績値理論値誤差率%
1等割合1.700584e-071.640298e-073.545037
2等割合1.161114e-069.841787e-0715.238411
3等割合3.513919e-053.543043e-050.828823
4等割合1.637770e-031.638657e-030.054174
5等割合2.538049e-022.549023e-020.432357

ほぼ実績値と理論値が一致していますが、2等だけ15%程度違いがありますね。調べてみると、過去にドラマの数字と同じのを選ぶと2等が当選する!?というとんでもない事象があったようで、3等よりも多い3000口以上が当たったそうです。これは外れ値と考えられますので除外してもう一度見てみます。
https://www.news-postseven.com/archives/20120913_143230.html

In [12]:
#極端なケースを除外する
df = df[df['2等口数'] < 3000]
In [13]:
#実績値
tdf = df[[str(i)+'等割合' for i in range(1, 6)]].mean()
#結合
tdf = pd.concat([tdf, pd.DataFrame(index=tdf.index, data=percentList)], axis=1)
tdf.columns = ['実績値', '理論値']
tdf['誤差率%'] = 100 * (tdf['実績値'] - tdf['理論値']).abs() / tdf['実績値']
#表示
tdf
Out[13]:
実績値理論値誤差率%
1等割合1.700234e-071.640298e-073.525169
2等割合9.571105e-079.841787e-072.828116
3等割合3.512710e-053.543043e-050.863517
4等割合1.637609e-031.638657e-030.064031
5等割合2.537762e-022.549023e-020.443740

概ね一致してきましたね。loto6はほぼ理論通りの確率で当選者を出していると言えそうです。

各回での1口当たりの実績的な期待値の算出

理論通りの確率で当選するとして、当選確率は理論値を、当選金額は実績値を使うと、1回1回のloto6での期待値は以下のように計算できます。

\begin{equation*}
E(1口) = \Sigma_{k=1}^{5}{(k等賞の当選確率×k等賞の当選金額)}
\end{equation*}
In [14]:
#数式に基づいて計算
df['1口の賞金期待値'] = 0
for i in range(1, 6):
    df['1口の賞金期待値_' + str(i) + '等'] = df[str(i)+'等賞金'] * percentList[i-1]
    df['1口の賞金期待値'] += df['1口の賞金期待値_' + str(i) + '等']
#表示
df['1口の賞金期待値'].head()
Out[14]:
抽せん日
2000-10-05     97.869876
2000-10-12     77.442953
2000-10-19    116.705072
2000-10-26    123.413250
2000-11-02     71.617009
Name: 1口の賞金期待値, dtype: float64
In [15]:
#統計量を確認
df['1口の賞金期待値'].describe()
Out[15]:
count    1196.000000
mean      102.316818
std        30.363657
min        39.939939
25%        79.551666
50%        97.834840
75%       119.104450
max       230.387829
Name: 1口の賞金期待値, dtype: float64

平均的な期待値は102円で、200円に対してほぼ半減することが分かります。一方で、最大は230円と、期待値が1口の価格を上回ることもある、という結果です。高い期待値を狙う数字の選び方はあるのでしょうか。

期待値を最大化する数字の選び方

おおまかな傾向の確認

まず時系列的な変化を確認してみます。

In [16]:
%matplotlib inline
#単純に期待値をプロット
df['1口の賞金期待値'].plot()
#100点の移動平均をプロット
df['1口の賞金期待値'].rolling(100, center=True).mean().plot()
Out[16]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f4c5e61a668>

ばらつきは大きいですが、移動平均を取るとあまり全体としての傾向には差がないことが分かります。そのため、時期的に傾向が変わっているということはなさそうです。次にヒストグラムでばらつきの形状を見てみましょう。

In [17]:
df['1口の賞金期待値'].plot.hist()
Out[17]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f4c5e516160>

単峰性ですが歪んだ形状をしていることが分かります。特に、期待値が高くなる側にロングテールな傾向があります。期待値が高い5ケースと低い5ケースについて、データを確認してみましょう。

In [18]:
#期待値の上位5件
df.sort_values('1口の賞金期待値', ascending=False).iloc[:5].T
Out[18]:
抽せん日2015-05-11 00:00:002013-11-29 00:00:002004-06-03 00:00:002015-11-02 00:00:002005-02-17 00:00:00
抽せん回9668171891016226
曜日
本数字11016318
本数字22221321426
本数字33127353136
本数字43432363240
本数字53634393942
本数字64343404243
ボーナス数字304253421
1等口数11101
1等賞金1330720001457272002000000000200000000
2等口数11314
2等賞金1197638001311533009738890012724860080699600
3等口数134273357134274
3等賞金107250057640098200011395001413700
4等口数76131062816537798918629
4等賞金1660013000187001680018300
5等口数140833169749327872147595352899
5等賞金10001000100010001000
キャリーオーバー00124632575160113420158668297
キャリーオーバー_今回000187247520
販売実績額14759154001650770200356565700015636230003918720000
100010
200000
300100
400000
500700
600000
700000
800001
2600002
2703000
2800000
2900000
3070000
3130030
3204240
3300000
3445070
3500300
3650403
3700000
3800000
3900550
4000604
4100000
4207065
4366006
総口数7.37958e+068.25385e+061.78283e+077.81812e+061.95936e+07
1等割合1.35509e-071.21156e-075.60906e-0805.10371e-08
2等割合1.35509e-071.21156e-071.68272e-071.27908e-072.04148e-07
3等割合1.81582e-053.30755e-052.00244e-051.71397e-051.39842e-05
4等割合0.001031630.001287640.0009275710.001021860.00095077
5等割合0.01908420.0205660.01839060.01887860.0180109
1口の賞金期待値230.388220.197219.58218.628217.794
1口の賞金期待値_1等21.827823.903632.806032.806
1口の賞金期待値_2等117.869129.07895.8481125.23579.4228
1口の賞金期待値_3等37.999120.422134.792740.37350.088
1口の賞金期待値_4等27.201721.302530.642927.529429.9874
1口の賞金期待値_5等25.490225.490225.490225.490225.4902

77 rows × 5 columns

上位5件を見ると、2等の当選口数が少なく、2等の期待値が80円〜120円と非常に高いことが分かります。通常は中央値が100円程度ですので、この2等の期待値が全体の期待値を引っ張っているということのようです。また、当選数字を見ると、ボーナス数字を含めた当選数字に30とか40とかの大きい値が多いことが分かります。

In [19]:
#期待値の下位5件
df.sort_values('1口の賞金期待値').iloc[:5].T
Out[19]:
抽せん日2017-04-03 00:00:002016-02-04 00:00:002014-05-19 00:00:002012-08-30 00:00:002003-07-31 00:00:00
抽せん回11621042865689146
曜日
本数字134567
本数字24107817
本数字381181227
本数字41212121736
本数字52418232437
本数字63725253139
ボーナス数字103626384
1等口数0126821
1等賞金08291100167274002009430013944100
2等口数1517183431
2等賞金42285005267200501820042552008501300
3等口数5336636837532362
3等賞金128500162000158700230500133800
4等口数2036522031246932879746090
4等賞金35004300380053006000
5等口数265661257868302771381008495006
5等賞金10001000100010001000
キャリーオーバー2471879900000
キャリーオーバー_今回357669020000
販売実績額15142092001442538800154994100022515636003659103200
100000
200000
310000
421007
500100
600010
700201
830320
2600700
2700003
2800000
2900000
3000000
3100060
3200000
3300000
3400000
3500000
3607004
3760005
3800070
3900006
4000000
4100000
4200000
4300000
総口数7.57105e+067.21269e+067.74970e+061.12578e+071.82955e+07
1等割合01.66373e-067.74223e-077.10617e-071.14782e-06
2等割合1.98123e-062.35696e-062.32267e-063.02012e-061.6944e-06
3等割合7.03998e-059.19213e-058.81324e-056.68869e-050.000129103
4等割合0.002689850.003054480.003186310.002557960.0025192
5等割合0.03508910.0357520.03906870.03384390.0270561
1口の賞金期待値39.939944.8245.022549.825850.7168
1口の賞金期待値_1等01.359992.743793.296062.28725
1口の賞金期待値_2等4.16165.183874.938814.187888.3668
1口の賞金期待値_3等4.552815.739735.622818.166714.74059
1口の賞金期待値_4等5.73537.046236.22698.684889.83194
1口の賞金期待値_5等25.490225.490225.490225.490225.4902

77 rows × 5 columns

下位5件を見ると、1等から4等までの期待値が非常に低いことが分かります。また、当選数字を見ると、5位を除き、当選数字に30未満の小さい数字が多いことが分かります。本当にカレンダーから数字を選ぶ人が多く期待値が上がりにくいのかもしれません。

次に特定の数字が出た時の期待値を計算してみましょう。具体的には1が出た時の期待値、2が出た時の期待値、という具合です。

In [20]:
tmp = []

#特定の数値が出た場合の期待値を計算する
for i in range(1, 44):
    tmp.append(df[df[str(i)] >= 1][['1口の賞金期待値_' + str(i) + '等' for i in range(1, 6)] + ['1口の賞金期待値']].mean())
    
df_a = pd.concat(tmp, axis=1).T
df_a.index += 1
df_a.head()
Out[20]:
1口の賞金期待値_1等1口の賞金期待値_2等1口の賞金期待値_3等1口の賞金期待値_4等1口の賞金期待値_5等1口の賞金期待値
119.41240621.26679721.23214217.26583225.490228104.667405
217.80342120.00089219.24981815.90269925.49022898.447058
317.21529019.82845217.38887714.74353625.49022894.666383
421.46144117.94357418.54479715.40674225.49022898.846781
520.29038718.07477217.79206415.09492725.49022896.742378

1口の賞金期待値について棒グラフで確認してみましょう。

In [21]:
df_a['1口の賞金期待値'].plot.bar(figsize=(9, 6), ylim=(90, 120))
Out[21]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f4c5ac6fcf8>

上位から43、32、42、34、31と大きい数字が並んでいることが分かります。逆に3や8はとても小さい傾向が読み取れます。これらは上の結果を裏付けるものであると言えます。一方で、20や21、16、1などの数字も高めの傾向があるようです。その2で見たように、1は最も出ていない、や、21は多め、等の傾向があるので、これらを元に戦略を練っている人の影響が出ているのかもしれません。

また、上記のグラフを等賞ごとの期待値の積み上げ棒グラフで描いた結果がこちら。

In [22]:
df_a[['1口の賞金期待値_' + str(i) + '等' for i in range(5, 0, -1)]].plot.bar(figsize=(9, 6), stacked=True)
Out[22]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f4c5ab42ef0>

ぱっと見ですが、2等のばらつきが大きそうです。それぞれの標準偏差をプロットしてみましょう。

In [23]:
df_a[['1口の賞金期待値_' + str(i) + '等' for i in range(5, 0, -1)]].std().plot.bar(figsize=(9, 6), stacked=True)
Out[23]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f4c5a908208>

ばらつきは、2等、3等、1等、4等の順番のようです。これも上記の結果(上位5件は2等の期待値の影響が大きかった)を裏付けるものであると言えますね。

次にキャリーオーバーの額との関係を見てみましょう。

In [24]:
df.plot.scatter(x='キャリーオーバー_今回', y='1口の賞金期待値')
Out[24]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f4c5a89c5f8>

散布図では良くわからないですね。カテゴライズして集計してみましょう。

In [25]:
df['キャリーオーバー_今回_category'] = pd.cut(df['キャリーオーバー_今回'], 10)
df.pivot_table(index='キャリーオーバー_今回_category', values='1口の賞金期待値', aggfunc='median').plot.bar()
del df['キャリーオーバー_今回_category']

平均的には、キャリーオーバーが高いほど期待値も高くなる傾向が見て取れます。以上より、データの可視化により以下の傾向が見て取れました。

・ 期待値は時系列的にはほとんど変化していない
・ 期待値のばらつきは単峰性だが歪があり、高い側がなだらかな傾向がある
・ 期待値のばらつきの要因は特に2等賞の期待値が影響している
・ 当選番号に30以上の数字が多い場合は期待値が高く、それ以下の数字が多い場合には期待値が低い傾向がある
・ キャリーオーバーが高いほど期待値が高くなる傾向がある

決定木分析を用いた期待値の分析

さあ、とうとう本題に近づいてきました。決定木分析を使って期待値を分析してみます。

In [26]:
#必要なモジュールのインポート
from sklearn import tree
from sklearn.externals.six import StringIO
import pydotplus
from IPython.display import display, Image

説明変数として、本数字の値とボーナス数字、キャリーオーバーの金額、加えてそれぞれの数字が出たかどうかを与えます。

In [27]:
Exvar = df.columns[2:9].tolist() + df.columns[20:21].tolist() + df.columns[22:-12].tolist()
display(Exvar)
['本数字1',
 '本数字2',
 '本数字3',
 '本数字4',
 '本数字5',
 '本数字6',
 'ボーナス数字',
 'キャリーオーバー_今回',
 '1',
 '2',
 '3',
 '4',
 '5',
 '6',
 '7',
 '8',
 '9',
 '10',
 '11',
 '12',
 '13',
 '14',
 '15',
 '16',
 '17',
 '18',
 '19',
 '20',
 '21',
 '22',
 '23',
 '24',
 '25',
 '26',
 '27',
 '28',
 '29',
 '30',
 '31',
 '32',
 '33',
 '34',
 '35',
 '36',
 '37',
 '38',
 '39',
 '40',
 '41',
 '42',
 '43']

目的変数には1口の賞金金額の期待値を与えます。

In [28]:
#決定木で期待値を分析
clf = tree.DecisionTreeRegressor(max_depth=5)
clf.fit(df[Exvar], df[['1口の賞金期待値']])
Out[28]:
DecisionTreeRegressor(criterion='mse', max_depth=5, max_features=None,
           max_leaf_nodes=None, min_impurity_split=1e-07,
           min_samples_leaf=1, min_samples_split=2,
           min_weight_fraction_leaf=0.0, presort=False, random_state=None,
           splitter='best')

学習結果の確認のため、feature_importanceを確認してみます。

In [29]:
pd.DataFrame(index=df[Exvar].columns, data=clf.feature_importances_).sort_values(0, ascending=False).head(10)
Out[29]:
0
本数字40.276258
キャリーオーバー_今回0.174660
本数字20.137266
本数字60.089945
本数字30.085130
本数字10.070498
360.040758
300.032942
ボーナス数字0.025772
400.016534

本数字4が最も影響し、次にキャリーオーバーが来ることが分かります。本数字4が来るということは、少なくとも値の大きい上位3つの数字の選び方が重要ということになります。(本数字5や6は必ず本数字4よりも大きい値になるため)

決定木を表示してみます。見やすさの都合で以下では深さ3までを表示しています。

In [30]:
# 決定木の描画
dot_data = StringIO() #dotファイル情報の格納先
tree.export_graphviz(clf, out_file=dot_data,  
                     feature_names=df[Exvar].columns,   
                     filled=True, rounded=True,  
                     special_characters=True, max_depth=3) 
graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) 
Image(graph.create_png())
Out[30]:

色が濃いほど期待値が高いことを示しています。これによると最も期待値が高いノード(右端)にたどり着くためには、

  1. 本数字4を31.5以上にする。(つまり、32以上から3つの数字を選ぶ)
  2. 本数字3を30.5以上にする。(つまり、31以上から4つの数字を選ぶ)
  3. 30が本数字の2番目以上の数字になっている。(つまり、30を含めて30以上から4つ又は5つの数字を選ぶ)

を満たすことが必要で、そのときはなんと期待値が180円!!まで上がることが分かります。通常の期待値は102円ですから、約倍まで上昇しています。またこの経路にはキャリーオーバーは関係ないというのもポイント(常にこの買い方をして良い)です。

また、その2つ隣にも期待値150円というルートがありますので見てみます。これにたどり着くためには、

  1. 本数字4を31.5以上にする。(つまり、32以上から3つの数字を選ぶ)
  2. 本数字3を30.5以下にする。(つまり、30以下から3つの数字を選ぶ)
  3. キャリーオーバーが約3億7千万円以上。

を満たすことが必要で、そのときは期待値が150円!まで上がることが分かります。通常の期待値は102円ですから、これも約1.5倍まで上昇しています。ただし、こちらはキャリーオーバが絡むので、いつもできる戦略ではないです。

上記の例では、30という特定の数字の有無が出てきて少し過学習の気配があるので、特定の数字は説明変数から除いたケースでも検討してみます。

In [31]:
Exvar = df.columns[2:9].tolist() + df.columns[20:21].tolist()
display(Exvar)
['本数字1', '本数字2', '本数字3', '本数字4', '本数字5', '本数字6', 'ボーナス数字', 'キャリーオーバー_今回']
In [32]:
#決定木で期待値を分析
clf = tree.DecisionTreeRegressor(max_depth=5)
clf.fit(df[Exvar], df[['1口の賞金期待値']])
Out[32]:
DecisionTreeRegressor(criterion='mse', max_depth=5, max_features=None,
           max_leaf_nodes=None, min_impurity_split=1e-07,
           min_samples_leaf=1, min_samples_split=2,
           min_weight_fraction_leaf=0.0, presort=False, random_state=None,
           splitter='best')
In [33]:
pd.DataFrame(index=df[Exvar].columns, data=clf.feature_importances_).sort_values(0, ascending=False).head(10)
Out[33]:
0
本数字40.277535
キャリーオーバー_今回0.194414
本数字20.161778
本数字60.113494
本数字30.093391
本数字10.081763
ボーナス数字0.050853
本数字50.026772

特定の数字を除いたことにより、feature_importanceの傾向も少し変わっています。決定木も見ていきます。

In [34]:
# 決定木の描画
dot_data = StringIO() #dotファイル情報の格納先
tree.export_graphviz(clf, out_file=dot_data,  
                     feature_names=df[Exvar].columns,   
                     filled=True, rounded=True,  
                     special_characters=True, max_depth=3) 
graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) 
Image(graph.create_png())
Out[34]:

これによると最も期待値が高いノード(右端)にたどり着くためには、

  1. 本数字4を31.5以上にする。(つまり、32以上から3つの数字を選ぶ)
  2. 本数字3を30.5以上にする。(つまり、31以上から4つの数字を選ぶ)
  3. キャリーオーバーが約1億7千万円以上。

を満たすことが必要で、そのときは期待値が160円程度まで上がることが分かります。通常の期待値は102円ですから、これも約1.5倍まで上昇しています。これもキャリオーバーが絡む買い方ですね。それ以外に関しては、あまり形状に変化がなさそうです。

上記をまとめると、1口当たりの期待値を上げるための数字の選び方として、以下のことが言えそうです。
・ なるべく大きい数字から選ぶ。具体的には、①32以上から3つ以上、又は②31以上から4つ以上の数字を選ぶ。
・ キャリーオーバの額が多い時を狙う。①の時は約4億円、②の時は約2億円以上あれば期待値は約1.5倍(1口当たり150円程度)まで上がる。
・ 過学習気味だが、②の時にさらに30を選んでいると期待値が180円!まで跳ね上がる可能性もある。

まとめ

本記事では、「loto6で期待値の高い数値の選び方はあるのか?」について分析を実施しました。当初の予想が当たっていたのか、決定木分析等で得られたルールを見ると、予想以上に(1〜31)から数字を選ばないほうがいいという結果になっており、裏を返せばカレンダ情報等から数字を選ぶ方が多い傾向が見て取れました。loto6は当選者数が少ないほど賞金が増えるシステムのですので、loto6で損をしにくくするためには、カレンダ情報から数字を選ぶときは多くとも3個まで、という考えが必要そうです。

とはいえ、期待値が上がると言っても1口の費用(200円)を超えるわけではありませんので、買えば買うほど損をしてしまうことは変わりませんので、ギャンブルはほどほどに、楽しんで遊べるといいですね!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA