質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

18096閲覧

Python AI 宝くじ当選番号予測 ロト7

EDM

総合スコア30

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2020/09/24 07:33

編集2020/09/29 05:19

pythonで機械学習、深層学習によって宝くじ当選番号予測プログラム ロト7Versionを作っています。
参考資料はこちら
(実行時は時間短縮のためself.epochsを1にしています。)

整理整頓しました。

質問
個人的にパラメータの部分がよくわからないのですが、コメントのような理解でよろしいでしょうか?self.units = 6これについては何の意味があるのか 単位?単位が6?

ロト7のcsvはこちらからダウンロードしています。ボーナス数字以下については使わないため、削除しています。

python

1#各インポート宣言 2#numpy 数値計算を効率的に行うためのライブラリ 3#pandas データ分析を効率的に行うためのライブラリ 4#tflearn 深層学習ライブラリ 5#time 時刻に関するさまざまな関数を提供 6#itertools 効率的なループ実行のためのイテレータ生成関数 7#sklearn 機械学習ライブラリ 8#preprocessing 前処理用のライブラリ 9import numpy as np 10import pandas as pd 11import tflearn 12import time 13import itertools 14from sklearn import preprocessing 15 16#予測LSTMクラス 17class PredictionLSTM: 18 def __init__(self): 19 #LSTM訓練パラメータ 20 #steps_of_history いくつ前のデータまでを学習に用いるか 21 #steps_of_history いくつ先のデータを予測するか 22 #units よくわからない 23 #epochs 一つの訓練データを何回繰り返して学習させるか 24 #batch_size バッチサイズ 25 self.steps_of_history = 10 26 self.steps_of_future = 1 27 self.units = 6 28 self.epochs = 1 29 self.batch_size = 1 30 31 #データセット作成 32 def create_dataset(self,data): 33 x,y = [],[] 34 for i in range(0,len(data) - self.steps_of_history,self.steps_of_future): 35 a = i + self.steps_of_history 36 x.append(data[i:a]) 37 y.append(data[a]) 38 x = np.reshape(np.array(x),[-1,self.steps_of_history,1]) 39 y = np.reshape(np.array(y),[-1,1]) 40 return x,y 41 42 #予測データ作成 43 def create_predict_dataset(self,data): 44 latest_x = np.array([data[-self.steps_of_history:]]) 45 latest_x = np.reshape(latest_x,(-1,self.steps_of_history,1)) 46 return latest_x 47 48 #訓練評価データ分割 49 def split_dataset(self,x,y,test_size=0.1): 50 pos = round(len(x) * (1 - test_size)) 51 train_x,train_y = x[:pos],y[:pos] 52 test_x,test_y = x[pos:],y[pos:] 53 return train_x,train_y,test_x,test_y 54 55 #モデル作成 56 def _create_model_by_tflearn(self): 57 net = tflearn.input_data(shape=[None,self.steps_of_history,1]) 58 59 #LSTM 60 net = tflearn.lstm(net,n_units = self.units) 61 62 net = tflearn.fully_connected(net,1,activation = "linear") 63 net = tflearn.regression(net,optimizer = "adam",learning_rate = 0.001,loss = "mean_square") 64 65 model = tflearn.DNN(net,tensorboard_verbose = 0) 66 67 return model 68 69 #訓練 70 def train(self,train_x,train_y): 71 model = self._create_model_by_tflearn() 72 model.fit(train_x,train_y,validation_set = 0.1,batch_size = self.batch_size,n_epoch = self.epochs) 73 74 return model 75 76 #予測 77 def predict(self,model,data): 78 return model.predict(data) 79 80 #評価誤差アルゴリズム 81 def rmse(self,y_pred,y_true): 82 return np.sqrt(((y_true - y_pred) ** 2).mean()) 83 84 def rmsle(self,y_pred,y_true): 85 return np.sqrt(np.square(np.log(y_true + 1) - np.log(y_pred + 1)).mean()) 86 87 def mae(self,y_pred,y_true): 88 return np.mean(np.abs((y_true - y_pred))) 89 90 def mape(self,y_pred,y_true): 91 return np.mean(np.abs((y_true - y_pred) / y_true)) * 100 92 93#メイン処理 94if __name__ == "__main__": 95 96 #処理の速さを図る 97 START_TIME = time.time() 98 99 #1~37までの数字を用意 100 a = {m for m in range(1,38)} 101 d = {tuple(p): i for i, p in enumerate(itertools.combinations(a,7))} 102 e = {v: k for k, v in d.items()} 103 104 dataframe = pd.read_csv("./loto7.csv",encoding='cp932') 105 dataframe = dataframe[["第1数字","第2数字","第3数字","第4数字","第5数字","第6数字","第7数字"]] 106 data = dataframe.index.map( 107 lambda _:d[ tuple(sorted( 108 [(dataframe.1数字[_]), 109 (dataframe.2数字[_]), 110 (dataframe.3数字[_]), 111 (dataframe.4数字[_]), 112 (dataframe.5数字[_]), 113 (dataframe.6数字[_]), 114 (dataframe.7数字[_]) 115 ] 116 )) 117 ] 118 ) 119 data = data.values.reshape(data.shape[0], 1).astype(dtype=np.float32) 120 121 #正規化 122 #データが0~1に入るよう変換 123 #fit_transform()について 124 #fit()を実施した後に、同じデータに対してtransform()を実施する 125 #fit()とは 126 #渡されたデータの最大値、最小値、平均、標準偏差、傾き...などの統計を取得して、内部メモリに保存する 127 #transform()とは 128 #fit()で取得した統計情報を使って、渡されたデータを実際に書き換える 129 scaler = preprocessing.MinMaxScaler() 130 data = scaler.fit_transform(data) 131 132 #LSTMインスタンス作成 133 lstm = PredictionLSTM() 134 135 #訓練,評価データ作成 136 #create_datasetの処理を正規化したデータを用いてx,yに代入 137 #split_datasetの処理をx,yを用いて訓練、評価データに代入 138 x,y = lstm.create_dataset(data) 139 train_x,train_y,test_x,test_y = lstm.split_dataset(x,y) 140 141 #訓練 142 #trainの処理を作成したtrain_x,train_yを使って行い、結果をmodelに代入 143 model = lstm.train(train_x,train_y) 144 145 #評価 146 #訓練予測にpredictの処理を訓練したデータとtrain_xを用いて行う 147 #評価予測にpredictの処理を訓練したデータとtest_xを用いて行う 148 train_predict = lstm.predict(model,train_x) 149 test_predict = lstm.predict(model,test_x) 150 151 #RMSE(Root Mean Squared Error) この値が小さければ小さいほど、誤差の小さいモデルである 152 #訓練誤差にrmseの処理をtrain_yと訓練予測データを用いて行う 153 #評価誤差にrmseの処理をtest_yと評価予測データを用いて行う 154 #Train ScoreとTest Scoreを出力 155 train_score = lstm.rmse(train_y,train_predict) 156 test_score = lstm.rmse(test_y,test_predict) 157 print("Train Score: {0:.3f} RMSE".format(train_score)) 158 print("Test Score: {0:.3f} RMSE".format(test_score)) 159 160 #予測 161 #latest_xにcreate_predict_datasetの処理を正規化したデータを用いて行う 162 #次の予測に訓練データをlatest_xを用いて行う 163 #予測に正規化のinverse_transformを”次の予測”を用いて行う 164 latest_x = lstm.create_predict_dataset(data) 165 next_prediction = model.predict(latest_x) 166 next_prediction = scaler.inverse_transform(next_prediction) 167 #予測結果を出力 168 print("次の当選番号の予測は: {}".format(e[np.round(next_prediction[0][0])])) 169 170 #測定時間を出力 171 print("時間: {0:.1f}sec".format(time.time() - START_TIME))

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toast-uz

2020/09/24 12:10

質問は1投稿で1つにして、質問に関係ある範囲に絞りかつ実行可能で問題を再現可能なコードを提示いだたくと、回答がつきやすいと思います。
EDM

2020/09/25 00:11

意見ありがとうございます。見直してみます。
guest

回答1

0

ベストアンサー

”csvを読み込んだ後に頭に一桁があれば0をつける”

こちらをプログラムで行うにはどのようにすればいいのでしょうか。

はい、こちらになります。

data = dataframe.index.map(lambda _:int(str(dataframe.第1数字[_]).zfill(2) + str(dataframe.第2数字[_]).zfill(2) + str(dataframe.第3数字[_]).zfill(2) + str(dataframe.第4数字[_]).zfill(2)) + str(dataframe.第5数字[_]).zfill(2) + str(dataframe.第6数字[_]).zfill(2) + str(dataframe.第7数字[_]).zfill(2)))

しかし、これを行なっても、正しいこたえは得られません。

コピペ元のプログラムをきちんと読みましょう。

元のプログラムは、どのようにしてこたえを導いていますか?

元のプログラムは、3つの数字データを元に予測するものですが、
日本で発売されている数字選択式全国自治宝くじのひとつである「NUMBERS3」が使う各数字が
0〜9で成り立っていることを奇貨として、
3つの数を10進法で最大3桁となる整数yに変換し、各時点xに対するyを線形にプロットしたグラフを分析・予測するものです。

イメージしやすい言い方をすれば、000から999の数字が書かれた「1000面体のサイコロ」を振って出た目の過去の記録を分析して、次に振って出る目を予測しているのです。(実際は実数で計算しているので語弊はありますが)

一方、LOTO7は1から37までの数字を7つ、重複なしに選択するものです。

したがって、仮に上記のように2桁で区切ってデータを与えても、
内部では、(データによるが)最大で37363534333231までの数が書かれたサイコロを仮定して出る目を予測することになってしまい、
実際に存在するパターン以外のパターンまで計算に使う可能性がある
ため、
正しそうな答えを導くことはできないのではないでしょうか。

そこで、ロト7の全パターンを、10進数に線形にあてはめた数字をデータとして投入する、というやり方になるかもしれませんね。

import itertools a = [m for m in range(37)] #1〜37の数字の組み合わせパターンを登録 d = {tuple(p): i for i, p in enumerate(itertools.combinations(a, 7))} e = {v: k for k, v in d.items()} #パターンをキーとしてインデックスをマッピングする。 data = dataframe.index.map( lambda _:d[ tuple(sorted( [(dataframe.第1数字[_])-1 , (dataframe.第2数字[_])-1 , (dataframe.第3数字[_])-1 , (dataframe.第4数字[_])-1 , (dataframe.第5数字[_])-1 , (dataframe.第6数字[_])-1 , (dataframe.第7数字[_])-1 ] )) ] )
--------------------------------- Run id: ;;;;;; Log directory: /tmp/tflearn_logs/ --------------------------------- Training samples: 304 Validation samples: 34 -- Training Step: 304 | total loss: 0.08920 | time: 2.274s | Adam | epoch: 001 | loss: 0.08920 | val_loss: 0.04319 -- iter: 304/304 -- Train Score: 0.216 RMSE Test Score: 0.187 RMSE 次の当選番号の予測は: 5597193.5 Time: 3.3sec

で、あとは出てきたnext_prediction(上で言えば「5597193.5」)を、求めるべきこたえに戻せばよい。

戻し方を明かしちゃうと勉強にならないので、明日までに考えてみてください。

next_prediction[0][0]は予測されたインデックスを表しているのですから、
単純に次のようにすればよいと思います。

from decimal import Decimal, ROUND_HALF_UP n0 = next_prediction[0][0] n1 = Decimal(str(n0)) n2 = n1.quantize(Decimal('0'), rounding=ROUND_HALF_UP) print("次の当選番号の予測は: {}".format(e[n2]))

※私は数学に詳しくないので、このアプローチが本当に正しい答えを導くかどうかについては保証しません。
あくまでコピペ元のプログラムのアプローチを生かす形での、正しそうな答えを導くためのショートカットを示しただけです。
(組み合わせをマッピングしたインデックスのトレンドが、組み合わせの予測に使えるかといわれれば、大いに疑問)
たぶん、各数字の出現頻度等を考慮した、もっとまっすぐなアプローチをご存知の方がいるはず。

投稿2020/09/24 13:29

編集2020/09/29 12:14
sfdust

総合スコア1137

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

EDM

2020/09/25 00:21

貴重な意見ありがとうございます。 とても参考になりました。イメージについても自分の中で理解できました。 太文字で示してくれた部分がとても分かりやすかったです。 戻し方などは自分で調べてみてやってみます。
EDM

2020/09/25 08:05 編集

考え方を変えました。 全ての数値をまとめてしまうと太文字のようなことが起きてしまうので、 第1数字のみ取得させて学習させるプログラム、第2数字のみ取得させて学習させるプログラムのように計7つプログラムを作ればいいのではないかと考えました。 1つのプログラムの中に上記の内容をすべて詰めると、第1数字を学習したら第2数字を学習、学習したら第3数字となってしまいとても時間がかかってしまうので、7つに分け、それぞれ実行後、出力した数値を手動でまとめればきれいになると思いました。ただ、1つだけダメな点として学習させた際、どうしても出力結果が重複してしまう場合があるということです。例えば 1,2,3,4,5,6,7という場合と2,8,9,10,11,12,13がある場合、第1第2ともに2が出力されるときがあります。その際はリトライということで、再び学習させ出力させる。 どう思いますか? 長文失礼しました。
sfdust

2020/09/25 11:21 編集

1~7文字目それぞれを予測して集約するというやり方は、1~7文字目それぞれが独立であることが前提です。 しかし、LOTO7は、1~37の37個の数字から7個を選ぶものであるため、 1回目に選んだ数によって、2回目以降選べる数が制限されています。 つまり1文字目~7文字目は各々独立ではありません。 したがって、重複時にリトライすることによってそれっぽい答えは出せるとしても、本質的なアプローチとしては正しいとは言えないと思います。 (なお、私の上記コード及び元になっているコピペ元のアプローチが、本質的に正しいかといわれれるとそれも自信はありません)
EDM

2020/09/29 06:15 編集

なるほど。確かに本質的なアプローチとしては正しくないですね。及第点といったところでしょうか。 本日このような感じになったのですが この結果は1つのアプローチ方法ととらえてよいのでしょうか。 Train Score: 0.294 RMSE Test Score: 0.290 RMSE 次の当選番号の予測は: (4, 6, 8, 11, 13, 27, 31) 時間: 49.8sec 質問本体のところにコード載せます。 a = [m for m in range(37)]だと 0~36までの37個の数字になるため、a = [m for m in range(1,38)]にして、1~37までの数字にしています。
EDM

2020/09/29 06:45 編集

roundですが私のバージョンがpython3なので、五捨五入、銀行丸めになってしまうのでnp.roundにしました。 マッピングするときの-1はどういう意図ですか? つけるとkeyerrorになってしまうため、つけていません。
sfdust

2020/09/29 12:20 編集

roundについて全く抜けていました。ありがとうございます。 ただ np.roundも銀行家の丸めになってしまうとの記載が他サイトでありました。(https://www.sejuku.net/blog/70052)。 https://www.mathpython.com/ja/python-number-round/ を参考に直しました。 マッピングで-1をする意味ですが、組み合わせテーブルを作るときに。range(37)としており、0〜36 までの数で組み合わせを作成していることによります。 テーブル上の0は、loto7の実際の数の1に対応、テーブル上の1はloto7の2に対応・・・となっています。 したがって、−1することで、テーブルのインデックスと対応させている、ということになります。 結局私が回答の中でやっていることと、EDMさんが編集した後のソースは、内容は全く同じことになります。 私のコードは回りくどいため、直感的にわかりやすい(バグもうみにくい)という意味では、EDMさんの書き方の方が優れていると思います。
EDM

2020/09/30 02:05

回答ありがとうございます。 np.roundも銀行丸めになってしまうのですね。改善します。 -1の説明についてもありがとうございます。そのような意図だったのですね。理解できました。
stevediaz

2023/08/22 08:05

Hello Thanks for information
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問