今回の記事では前回の記事で収集したロト6の当選番号を用いて、機械学習を使って当選番号を予測してみました。

どの機械学習の手法を使うか悩んだのですが、今回は過去の当選番号を時系列データとして扱い次の当選番号を予測しようと思ったためSVRを使うことにしました。RNNを使うのもありだとは思ったのですが、学習に時間がかかりそうだったのでとりあえず手軽に実装できるSVRで試してみます。



ライブラリのインストール


今回、SVRを実装するにあたり scikit-learn を使用しました。scikit-learnは以下のコマンドでインストールすることができます。
pip install scikit-learn
また、こちらはインストールしなくてもいいのですがデータをグラフ化して分析するのにはMatplotlibを使用しました。Matplotlibは次のコマンドでインストールすることができます。
pip install matplotlib


Matplotlibを使って過去の当選番号をグラフ化してみる


とりあえず過去の当選番号の第1回目から第100回目までの結果を本数字1~6にわけてグラフ化してみます。
import pandas as pd
import matplotlib.pyplot as plt

train = pd.read_csv("loto6.csv") # 前回の記事で保存したデータの読み込み

# 第1回目から第100回目までの本数字をリスト化
x = train["round"].values[:100] main1 = train["main1"].values[:100] main2 = train["main2"].values[:100] main3 = train["main3"].values[:100] main4 = train["main4"].values[:100] main5 = train["main5"].values[:100] main6 = train["main6"].values[:100]

%matplotlib inline # jupyter notebookで描画 plt.plot(x, y1, color="red", label="main1") plt.plot(x, y2, color="darkorange", label="main2") plt.plot(x, y3, color="yellow", label="main3") plt.plot(x, y4, color="greenyellow", label="main4") plt.plot(x, y5, color="cyan", label="main5") plt.plot(x, y6, color="blue", label="main6") plt.legend(bbox_to_anchor=(1.05, 1)) plt.show()
loto2_1

グラフを見ている限り、ロト6の当選番号に規則性がなくて機械学習で予測するのは無理そうですが、ロマンを追い求めるために予測しようとしているので気にしない方向で行きます。




SVRを使って予測してみる


サポートベクター回帰(SVR)とはサポートベクターマシン(SVM)を回帰分析に応用した手法です。SVRについて詳しく知りたい方は下記のページが参考になると思います。

https://datachemeng.com/supportvectorregression/

今回は第n回目の当選番号を予測するのに、第1回目から第n-1回目までの当選番号を訓練データとしてSVRで予測します。また本番号は6つありますが、各番号が独立したデータと考えます。

上記の方法で1261回目~1340回目までの結果を予測してみたところ5等が3回だけ当たりました。16000円分宝くじを購入して、3000円しか返ってこないのは悲惨です。わざわざ機械学習をつかっているのに乱数で番号を選択した場合とあまり変わらない気がします…。

訓練データの数を変更したりしてみたのですが結果はあまり変わらずSVRでロト6の予測するのは難しそうです。各本番号を独立したデータとして考えたのも失敗した要因なのかもしれません。ハイパーパラメータをもっと細かく調整すればもう少しマシになる可能性もありますが、正直そこまで変わらない気がします…。

一応SVRでロト6の当選番号を予測するコードを載せておきます。コードが無駄に長くて申し訳ありません。
# -*- coding: utf-8 -*-
# loto6の番号をSVRを使って予想

import pandas as pd
import numpy as np
from sklearn import svm

# 訓練データとテストデータの読み込み
train = pd.read_csv("loto6.csv") # 第1~1260回目
test = pd.read_csv("loto6_test.csv") # 第1261~1340回目

train_x = train["round"].values
train_X = train_x[:, np.newaxis] # SVRで学習できるように変換
train_y1 = train["main1"].values
train_y2 = train["main2"].values
train_y3 = train["main3"].values
train_y4 = train["main4"].values
train_y5 = train["main5"].values
train_y6 = train["main6"].values
test_y1 = test["main1"].values
test_y2 = test["main2"].values
test_y3 = test["main3"].values
test_y4 = test["main4"].values
test_y5 = test["main5"].values
test_y6 = test["main6"].values
pre_list = np.array([np.zeros(7)]) # 予測結果を格納

# 学習の設定
my_svr = svm.SVR(kernel="rbf", C=1e1, gamma=0.1, epsilon=0.1)

# 1261回~1340回まで学習と予測を繰り返す
for i in range(1, len(test_y1)+1):
  print(i+1260)
  pre_num = np.array([])
  
  # 学習して結果を予測
  #第1回目~1260+i-1回目までの結果を使って1260+i回目の結果を予測
  my_pre_1 = my_svr.fit(train_X, train_y1).predict(np.array([[1260+i]]))
  my_pre_2 = my_svr.fit(train_X, train_y2).predict(np.array([[1260+i]]))
  my_pre_3 = my_svr.fit(train_X, train_y3).predict(np.array([[1260+i]]))
  my_pre_4 = my_svr.fit(train_X, train_y4).predict(np.array([[1260+i]]))
  my_pre_5 = my_svr.fit(train_X, train_y5).predict(np.array([[1260+i]]))
  my_pre_6 = my_svr.fit(train_X, train_y6).predict(np.array([[1260+i]]))
  
  pre_num = np.append(pre_num, np.round(my_pre_1))
  pre_num = np.append(pre_num, np.round(my_pre_2))
  pre_num = np.append(pre_num, np.round(my_pre_3))
  pre_num = np.append(pre_num, np.round(my_pre_4))
  pre_num = np.append(pre_num, np.round(my_pre_5))
  pre_num = np.append(pre_num, np.round(my_pre_6))
  pre_list = np.insert(pre_list, len(pre_list), pre_num, axis=0) # 四捨五入した結果を予測結果とする
  
  # train_X, train_y1に1260+i回目の結果を追加
  train_X = np.insert(train_X, len(train_X), 1260+i, axis=0)
  train_y1 = np.append(train_y1, test_y1[i-1])
  train_y2 = np.append(train_y2, test_y2[i-1])
  train_y3 = np.append(train_y3, test_y3[i-1])
  train_y4 = np.append(train_y4, test_y4[i-1])
  train_y5 = np.append(train_y5, test_y5[i-1])
  train_y6 = np.append(train_y6, test_y6[i-1])

# 予測結果を出力
pre_list = np.delete(pre_list, 0, 0) # 1行目を削除
df = pd.DataFrame(pre_list, columns = ["main1", "main2", "main3", "main4", "main5", "main6", "bonus", ])
df.index = df.index + 1
df.to_csv('loto6_pre.csv')




最後に


SVRでの予測は失敗に終わりました。気が向いたらRNNを使って予測する記事を作るかもしれません。