データ取得編?
学習データを集めるところです。機械学習で一番重要な工程かも。
そうなの?
うん。データが無いことには予想も難しいからね。
機械学習でボートレース予想実現までの工程
今回は「4.機械学習用のデータ取得」を中心にまとめてます。
1.機械学習について調査
2.技術選定
3.環境構築
4.機械学習用のデータ取得(今回はここ!)
5.機械学習でモデル作成
6.作成したモデルで予測
この後に、舟券投票や機械学習モデルを改善する工程もありますが、このシリーズでは予測までをまとめてます。
どんなデータが取得できる?
BOAT RACE オフィシャルウェブサイトでは、下記ページよりデータのダウンロードができます。
他の公営ギャンブルでも必ずしもデータ提供があるわけではないので、とてもありがたいです。
・レーサー期別成績
・競争成績
・番組表
がダウンロードできます。
レーサー期別成績
選手個人の身長や体重、出身地、コース別の成績・スタートタイミングなどが記載されたファイルです。
1年につき前期、後期の2回分ダウンロードできます。
競争成績
レースの条件(進入固定、締め切り時間)、前日時点での選手の成績や節間の成績などが記載されたファイルです。
毎日1ファイル作成されます。
番組表
進入コースやレース結果、展示データ、レース時の気象情報、払戻金などの払戻情報が記載されたファイルです。
毎日1ファイル作成されます。
レーサー期別成績は、下記の通り2014年で途中でレイアウトが変わっていますので、公開されているすべてのデータを登録する場合は、レイアウトの違いを吸収する工夫が必要です。
2014年後期のファン手帳データから内容が一部変更になりました。
「モーターボートファン手帳」のレイアウト | BOAT RACE オフィシャルウェブサイト
また、うろ覚えで申し訳ありませんが、レーサー期別成績だけでなく、競走成績・番組表についても途中でレイアウトが変わっていた気がしますので、注意してください。
私は機械学習を始めることを優先したため、すべてのデータ取得することはいったん後回しにして2014年1月1日からデータを取得することにしました。
前準備
データを取得する前に以下の作業が必要になります。
プロジェクト作成
Visual Studioよりコンソールアプリとしてプロジェクトを作成します。
プロジェクトは役割ごとに下記のプロジェクトに分けました。
今回のメインはデータ取得のプロジェクトについてです。
・マイグレーション:DB作成用のプロジェクトです。
・データ取得:データをダウンロードし、データベースに登録するプロジェクトです。
・データ分析:取得したデータから機械学習モデルを作成するプロジェクトです。
・共通:上記3つのプロジェクトの共通処理をまとめた共有プロジェクトです。
データベース作成
取得可能なデータ内容に合わせて、データベースのテーブル設計やテーブル作成作業が必要になります。
私は「Entity Framework Core」を使用してモデルファーストでデータベースを作成しました。
データの内容に合わせたモデルクラスを作成して、モデルからテーブルを作成する方法です。
下記のような形でモデルクラスを作成しました。
・選手マスタ:年/期別の選手マスタデータ
・レース場マスタ:レース場のマスタデータ
・番組表データ:番組の共通情報
・番組表明細データ:明細として選手単位のデータ
・競争成績データ:競争成績の共通情報
・競争成績明細データ:明細として選手単位のデータ
・払戻金データ:払戻金や人気順、順位データ
データ取得に必要な工程は?
整理すると次の作業が必要になります。概要を説明すると以下の通りです。
1.ダウンロード
ボートレースオフィシャルサイトよりファイルをダウンロードします。
競争成績・番組表のダウンロードは日付単位になってるので、日付単位でダウンロードできるようにします。
2.ファイル解凍
オフィシャルサイトでダウンロードできるファイルはLZH形式になります。LZH形式を解凍します。
今回はNuget経由でインストールした「SevenZipExtractor」を使用して解凍するようにしました。
3.ファイル読込
解凍したファイルを読み込みます。
StreamReaderを使用してダウンロードし、解凍したファイルを読み込みます。
4.データ整形
読み込んだファイルを1行ずつ読込し、データ形式に合わせて整形しモデルクラスのリスト形式に足していきます。
レーサー期別成績
固定長のファイルなので、GetStringなどの関数を使用してデータレイアウトに合わせてデータを切り出していく作業が必要です。
全角や半角が混ざっているので、ズレないようにするのが結構大変です。。
競争成績・番組表
CSVなど扱いやすい形式ではありません。そのため1行ごとに読込判断する必要があります。
ファイルを大まかに分解すると、下記がレース場ごとに繰り返し記載されていることが分かります。
レース場単位の共通情報(レース名・開催日など) → レース単位(選手、成績など)の情報
私の場合は、次のような
レース場番号 +「BBGN」(※例:24BBGN)
など、特定の文字を目印にして、その行からの相対的な行数でループ処理をするように作成しました。
レースが途中で中止になったり、同着が発生したりすると途中から行数がズレてしまう場合があるので、そこは気を付けてください。
5.データ登録
整形したデータをデータベースに登録していきます。
ORMの「Dapper」とそれを拡張する「Dapper.FastCrud」を使用して整形したデータをデータベースに登録します。
まとめ
今回はデータ取得についてまとめてみました。
結構癖があるデータなのでデータベースに登録するまでは苦労しますが、機械学習をするうえでデータは欠かせないので、可能な限りの情報をデータベースに登録できるように頑張りました。
ただ、それでも後から「このデータも登録するように実装してたらよかった。。」後悔する箇所が何か所あったので、なるべく時間をかけて検討した上でこのデータ取得工程を実施することをおすすめします。
今回は大まかな流れを理解していただくまでとしており、具体的なサンプルコードなどは載せていないですが、今後記事をアップデートで記載していきます。
次回、モデル作成編に続きます。
※当ブログに掲載されている情報は、可能な限り正確性を重視していますが、正確性について保証するものではありません。読者の方々は、自己責任において情報を活用してください。
コメント
それで 読み込むためのコードは公開していただけないのでしょうか?
コメントありがとうございます。
全体の公開予定は今のところありません。
ただ、部分的には上げていけたらと思ってますが、他を優先していて動けてないので時期は未定です。