麻雀AI開発その58・入力情報のデータベース化
2017-08-19(Sat)
前回で、評価値関数作りが止まってしまったので、現実逃避して別のことをやることにします。
・対染め手危険度指数について。
染め手に対してはまだパラメータを取ってなかったので後回しということにしていました。
さしあたって危険度指数を求めるために、牌ごとの放銃率と放銃時平均失点と聴牌率が必要なので牌譜解析でパラメータを取りました。
取ったのですけど、リーチや副露と比べてサンプル数が少ないので、手持ち枚数と見えてる枚数で分類するとばらつきが激しくて使えなさそうでした。
なので、従前の局収支シミュレーションのパラメータ(枚数分類なし)をそのまま使い回すことにしました。
・入力情報のデータベース化
前に評価値を計算するために必要な入力情報(牌の前後関係とか手役ごとのシャンテン数とか)を10000試合分で計算しようとするとOutOfMemoryのエラーを噴いたのがありました。
1万試合(約3GB)の情報を全部変数に保存して使い回そうとしたことが原因だったのですが(さすがに無理がありすぎた)、
これをしないとなると(前までは他家攻撃について場合分けしたうえで1000試合分に減らしていた)目的関数or偏微分の計算のたびに毎回CSVファイルから読み込み直して…となるとかなり時間を食いそうな気がしました。
なので王道を行くなら一時メモリに保存するのではなく、データベースを作ってそこに保存しておいて、必要な時に一行ごとに読みだして処理する方がいいのかなーと思いました。
データベースはかなり昔にACCESSで触って以来で、今のVB.NETの環境でやるのは初めてだったので、ちょっと手間取りましたが、一応CSVをデータベース(mdfファイル?)に保存するコードは書けました。
で、動かしてみてるのですが、感想。「超遅くない?」
列数が14×61個、行数は10000試合分で約200万行あるのですが、
100行進むのに10秒くらいかかっています。
このペースだと1分600行、1時間36000行、1日90万行、だから丸2~3日かかる計算になります。
待ち時間としてはかなり長い部類ですけど、完全に計画が破たんしているレベルではないという微妙な時間です。
現状だと1行ごとにSQL文でINSERTさせているのですが、なんかバルクコピーなる手法を使うともっと早くINSERTができるらしいです。
ただ、現状で一応は正常にデータベースへの移し替えができていて、作動中のプログラムを止めてまで新しくコードを作り直して正しい動作をしているかをチェックしてから新しいプログラムでやり直す、という手間とうまくいかなかったときのリスクを考えると、まぁ時間かかってもいいから確実に2~3日後にはできる現状のままでいいかな、という感じです。
なんですけども、INSERTだけでこれだけ時間かかるなら解析本番の段階で、DataReaderでデータベースから逐次呼び出しするのと、今のCSVのままでファイル読み出しするのとで、結局あまり時間が変わらない可能性があるという、ちょっと悲しい結末が待ってるかもしれませんね。そうなると頑張ってデータベースのやり方勉強した分が無駄になっちゃうなーとも思うけど、まぁしょうがないか。
・対染め手危険度指数について。
染め手に対してはまだパラメータを取ってなかったので後回しということにしていました。
さしあたって危険度指数を求めるために、牌ごとの放銃率と放銃時平均失点と聴牌率が必要なので牌譜解析でパラメータを取りました。
取ったのですけど、リーチや副露と比べてサンプル数が少ないので、手持ち枚数と見えてる枚数で分類するとばらつきが激しくて使えなさそうでした。
なので、従前の局収支シミュレーションのパラメータ(枚数分類なし)をそのまま使い回すことにしました。
・入力情報のデータベース化
前に評価値を計算するために必要な入力情報(牌の前後関係とか手役ごとのシャンテン数とか)を10000試合分で計算しようとするとOutOfMemoryのエラーを噴いたのがありました。
1万試合(約3GB)の情報を全部変数に保存して使い回そうとしたことが原因だったのですが(さすがに無理がありすぎた)、
これをしないとなると(前までは他家攻撃について場合分けしたうえで1000試合分に減らしていた)目的関数or偏微分の計算のたびに毎回CSVファイルから読み込み直して…となるとかなり時間を食いそうな気がしました。
なので王道を行くなら一時メモリに保存するのではなく、データベースを作ってそこに保存しておいて、必要な時に一行ごとに読みだして処理する方がいいのかなーと思いました。
データベースはかなり昔にACCESSで触って以来で、今のVB.NETの環境でやるのは初めてだったので、ちょっと手間取りましたが、一応CSVをデータベース(mdfファイル?)に保存するコードは書けました。
で、動かしてみてるのですが、感想。「超遅くない?」
列数が14×61個、行数は10000試合分で約200万行あるのですが、
100行進むのに10秒くらいかかっています。
このペースだと1分600行、1時間36000行、1日90万行、だから丸2~3日かかる計算になります。
待ち時間としてはかなり長い部類ですけど、完全に計画が破たんしているレベルではないという微妙な時間です。
現状だと1行ごとにSQL文でINSERTさせているのですが、なんかバルクコピーなる手法を使うともっと早くINSERTができるらしいです。
ただ、現状で一応は正常にデータベースへの移し替えができていて、作動中のプログラムを止めてまで新しくコードを作り直して正しい動作をしているかをチェックしてから新しいプログラムでやり直す、という手間とうまくいかなかったときのリスクを考えると、まぁ時間かかってもいいから確実に2~3日後にはできる現状のままでいいかな、という感じです。
なんですけども、INSERTだけでこれだけ時間かかるなら解析本番の段階で、DataReaderでデータベースから逐次呼び出しするのと、今のCSVのままでファイル読み出しするのとで、結局あまり時間が変わらない可能性があるという、ちょっと悲しい結末が待ってるかもしれませんね。そうなると頑張ってデータベースのやり方勉強した分が無駄になっちゃうなーとも思うけど、まぁしょうがないか。
スポンサーサイト