【Python】競艇データをWebスクレイピング

プログラミング

競艇予測をするにあたり、競艇のデータを集めないといけません。探してみたらわかると思いますが、各レースごとの番組表・オッズなどのデータはブラウザで閲覧できますが、機械学習にポンと使えるようなデータセットはネットには転がっておらず、作ってやる必要があります。そこで、今回はPythonを用いて競艇予測に使用したデータセットを、Webスクレイピングを用いて自動で作成する方法をご紹介したいと思います。

また、競艇予測そのものに関しては以下をご覧ください!

【Google Colab】XGBoostによる競艇予測(めっちゃ儲かる?)
XGBoostを使って何かいいことしてみようということで、競艇予測をしてみます!開発環境はお財布が寂しい人は大好き、Google Colaboratory! また、GitHubにもあげてます。そっちのが分かりやすいかも。

競艇に関しては、下みたいなこともしてます!

【Python】混合正規分布EMアルゴリズムによるボートレーサクラスタリング
今回行うのは、1コースを走るレーサーの勝率データから、各レーサーのランク(A1、A2、B1、B2)を推定することが目的となります。データの便宜上、1コースを走るレーサーのみを対象としています。これをやることに何の意味もありません(;´・ω・)EMアルゴリズムを私が持っているデータで使ってみたかっただけです(;´・ω・)

また、機械学習を勉強するための参考書を以下で紹介しています!よかったら見ていってください。

機械学習を勉強するためのオススメ参考書(理論・Python・Webアプリ)
統計・機械学習に関しては授業で習ったところありますが、結構忘れてしまっています(。また、Rの演習の授業はありましたが、Pythonは学生のころには使っていません。機械学習・データサイエンスを勉強するにあたり、私が参考にしている参考書を一挙ご紹介したいと思います。

Webスクレイピングってなーに?

スクレピングとは、Webサイトからデータを取得し、データセットとしてまとめることを言います。例えば、株価の変動をスクレイピングすることで、1分ごとの株価変動のデータセットを作ったりすることができます。

競艇の各レースごとの番組表・オッズなどのデータは簡単にWebから閲覧することができます。例えば、以下!

出走表|BOAT RACE オフィシャルウェブサイト

上のリンクはBoat Race公式サイトになりますが、あるレースの選手名や各選手の戦績、オッズや展示情報などを閲覧することができます。しかし、機械学習をするにはこれらのデータをまとめ一つのデータセットにする必要があります。とてもじゃないけど、手作業ではできまへーん!ということで、Webスクレイピングを用いて各レースのデータをぜーーんぶ自動で集めてきたいと思います!最終的には、次のようなデータセットを自動で作成することを目標にします。各一行、各レースに対応します。

Date Place Race 6th-rank 6th-num 5th-rank 5th-num 4th-rank 4th-num 3rd-rank 3rd-num 2nd-rank 2nd-num 1st-rank 1st-num 6th-ratio 5th-ratio 4th-ratio 3rd-ratio 2nd-ratio 1st-ratio 6th-ratio2 5th-ratio2 4th-ratio2 3rd-ratio2 2nd-ratio2 1st-ratio2 6th-ratioj 5th-ratioj 4th-ratioj 3rd-ratioj 2nd-ratioj 1st-ratioj 6th-ratioj2 5th-ratioj2 4th-ratioj2 3rd-ratioj2 2nd-ratioj2 1st-ratioj2 6th-st 5th-st 4th-st 3rd-st 2nd-st 1st-st 6th-mratio 5th-mratio 4th-mratio 3rd-mratio 2nd-mratio 1st-mratio 6th-bratio 5th-bratio 4th-bratio 3rd-bratio 2nd-bratio 1st-bratio 1st-exb 2nd-exb 3rd-exb 4th-exb 5th-exb 6th-exb 1st 2nd 3rd 4th 5th 6th 1-odds 2-odds 3-odds 4-odds 5-odds 6-odds (1, 2, 3) (1, 2, 4) (1, 2, 5) (1, 2, 6) (1, 3, 2) (1, 3, 4) (1, 3, 5) (1, 3, 6) (1, 4, 2) (1, 4, 3) (1, 4, 5) (1, 4, 6) (1, 5, 2) (1, 5, 3) (1, 5, 4) (1, 5, 6) (1, 6, 2) (1, 6, 3) (1, 6, 4) (1, 6, 5) (2, 1, 3) (2, 1, 4) (2, 1, 5) (2, 1, 6) (2, 3, 1) (2, 3, 4) (2, 3, 5) (2, 3, 6) (2, 4, 1) (2, 4, 3) (2, 4, 5) (2, 4, 6) (2, 5, 1) (2, 5, 3) (2, 5, 4) (2, 5, 6) (2, 6, 1) (2, 6, 3) (2, 6, 4) (2, 6, 5) (3, 1, 2) (3, 1, 4) (3, 1, 5) (3, 1, 6) (3, 2, 1) (3, 2, 4) (3, 2, 5) (3, 2, 6) (3, 4, 1) (3, 4, 2) (3, 4, 5) (3, 4, 6) (3, 5, 1) (3, 5, 2) (3, 5, 4) (3, 5, 6) (3, 6, 1) (3, 6, 2) (3, 6, 4) (3, 6, 5) (4, 1, 2) (4, 1, 3) (4, 1, 5) (4, 1, 6) (4, 2, 1) (4, 2, 3) (4, 2, 5) (4, 2, 6) (4, 3, 1) (4, 3, 2) (4, 3, 5) (4, 3, 6) (4, 5, 1) (4, 5, 2) (4, 5, 3) (4, 5, 6) (4, 6, 1) (4, 6, 2) (4, 6, 3) (4, 6, 5) (5, 1, 2) (5, 1, 3) (5, 1, 4) (5, 1, 6) (5, 2, 1) (5, 2, 3) (5, 2, 4) (5, 2, 6) (5, 3, 1) (5, 3, 2) (5, 3, 4) (5, 3, 6) (5, 4, 1) (5, 4, 2) (5, 4, 3) (5, 4, 6) (5, 6, 1) (5, 6, 2) (5, 6, 3) (5, 6, 4) (6, 1, 2) (6, 1, 3) (6, 1, 4) (6, 1, 5) (6, 2, 1) (6, 2, 3) (6, 2, 4) (6, 2, 5) (6, 3, 1) (6, 3, 2) (6, 3, 4) (6, 3, 5) (6, 4, 1) (6, 4, 2) (6, 4, 3) (6, 4, 5) (6, 5, 1) (6, 5, 2) (6, 5, 3) (6, 5, 4)
20170224 1 1 B1 3491 B1 2941 A1 4211 B2 3924 B1 3759 B2 3540 4.03 4.12 6.29 3.38 3.51 3.98 22.8 12.8 43.4 11.5 14.2 19.5 4.15 4.81 5.82 3.21 3.57 3.84 30.7 21.5 36.8 7.1 14.2 19.3 0.22 0.2 0.15 0.22 0.2 0.22 25 34 22.5 44.4 15.1 17.6 31.3 26.6 42.4 28.3 30.3 36.3 0.03 0.05 0.01 F.10 F.04 F.06 4 5 2 1 3 6 2.1 7.2 43.5 2 8.7 8.7 82 48.2 99.8 240.7 120.2 68.2 132.2 273.2 29.8 45.5 27.7 64.1 144.3 203.6 77 213.6 367.7 708.6 235.5 378.9 108.4 53.6 117.3 160.5 191.5 105.3 198.1 358.7 45.7 75.7 40.8 78.5 157.3 233.6 76.9 204.6 305.8 433.6 175 277.5 239.4 125.7 243.4 515.7 314.6 170.5 315.8 714.4 103.6 124.8 66.9 159.9 308 273.2 105.7 389.1 898.6 838.1 409.2 618.1 21.9 36.8 15.2 35.3 32.1 51.2 20.7 45.3 63.4 69.5 35.7 81.8 15.5 16.9 26.5 14 50.5 50.3 90.5 26.9 302.6 332.6 108.1 421 345.8 440.2 126.1 405.4 417 458.7 138.3 588.9 77.5 80.7 105.6 69.3 515.7 481.5 697.3 148.2 665.3 999.9 498 771.3 738.6 999.9 354.3 675.6 999.9 999.9 521.9 854.5 394.4 322.8 429.3 152.3 714.4 618.1 792.4 167.3
20170224 1 2 B1 3670 B1 3776 B1 3498 A1 3081 A2 3655 B1 2785 4.98 5.12 4 5.93 5.81 4.32 30.3 25 21.2 44.2 37.2 23.3 4.85 4.72 3.89 5.39 5.41 3.71 30.7 24 11.1 38.8 35 17.6 0.18 0.2 0.16 0.16 0.18 0.17 39.5 51.6 31.8 30.2 29.7 40 39.7 31.3 23.7 27.4 31.1 34.8 F.12 0.04 F.05 0.04 F.06 F.03 2 5 4 6 3 1 6.5 3.6 1.9 8.1 6.5 8.1 19.7 56.8 39.2 110.1 18.6 54.6 27.9 101.7 135.8 125.4 167.7 376.4 78.7 63.9 187.7 193.6 258.9 231.3 431.5 259.8 19 59.7 42.5 86.6 22.1 43.6 17.8 57.6 110.7 89.3 136.3 207.2 78.1 41.5 134.4 112.3 272.2 146.1 310 198.8 22.7 46.4 26.5 83.7 22.9 47.2 18.8 53.9 89.8 78.5 62.9 115.1 37.4 26.5 61 50.1 171.2 105.8 158.6 108.8 228.4 253.5 220.2 336.9 229.8 193.1 227 209 250.1 191.6 182.6 257.1 308.7 257.1 203.8 232.7 318 284.9 265.4 280.5 134.9 110.9 286 223.6 136.9 75.2 236.5 165.8 98.6 70.9 152.7 127.6 335.4 315.3 232 256.2 246.7 202.1 177.8 277.4 530.8 546.6 848.1 501.9 563.2 301.1 620 367.1 505.4 335.4 501.9 273.3 934 658.8 519.6 419.2 495.2 332.3 318 434
20170224 1 3 B1 4511 A1 4184 A2 4430 A2 3414 B1 3847 B1 3630 4.6 6.56 6.92 6.28 3.51 4.62 23.8 46.6 52.9 45 12.7 26.8 3.62 7.78 7.83 5.89 3.38 3.36 15.3 61.1 66.6 39.6 13.7 21.4 0.19 0.17 0.18 0.17 0.15 0.2 31.4 34.1 29.4 6 15.6 21.2 31.8 34.9 13.3 26.2 37.6 21.6 0.09 F.04 0.04 F.14 F.07 F.12 4 1 2 5 6 3 6.9 13.9 2.6 2 4.3 34.8 89.8 79.9 59.6 328.2 93.8 38.8 47.8 137.9 76.2 41 37.5 124.2 128.1 65.9 48.9 187.1 403.7 306.8 290.8 411.9 121 95.1 196 340.9 163.6 82.3 130.3 289.5 108 84.8 74.3 153.8 238.8 146.4 91.3 296.4 713.6 487 297.9 573.5 122.2 37.2 50.8 174.3 175.3 89.7 119.1 303.8 40.5 60.8 21.1 78.6 62.8 114.2 28.8 117.5 374.2 475.7 209.4 258.9 75.1 43.4 34 86.5 95.5 84.6 61.5 99.9 40.1 70 20.7 71.2 22.7 35.7 16.8 27.9 154.2 194.2 149.6 87.3 164.5 84.6 59.8 240.6 225.6 170.9 103.1 305.3 87.1 137.6 37.7 175.8 43.1 60.9 28.6 51.8 363.1 417.5 260 134.8 876.7 595.8 411.9 652.9 840.7 757.7 409.1 619.9 818.3 916 367.5 639.3 423.2 390.9 333.5 185.4 689.5 739.4 520.1 185.4
20170224 1 4 B1 3276 A2 3895 A2 3558 A1 3641 B1 4250 B1 3850 4.05 5.38 6.21 6.63 4.13 4.89 20.4 38.1 41.9 52.3 19.7 24.7 2.89 5.75 5.83 6.14 0 5.19 11.1 43.1 34.4 48.5 0 27.7 0.21 0.15 0.18 0.18 0.22 0.17 22.5 28.1 52.6 19.2 39.4 43.7 30.1 38.1 42.1 57.5 31.5 40.9 0.24 0.21 0.16 0.19 0.21 0.13 1 4 2 3 5 6 2.3 12.4 5.1 1.6 62.2 62.2 59.6 53.7 93.4 274.9 48.8 16.8 38.1 140.3 40.5 18.8 31.2 122 134.2 93.1 67.7 297.7 447.5 441.7 414.9 420 108 86.7 213.3 345.8 133.4 113.7 238.5 450.4 113.3 119.9 180.1 335.6 427.9 364.2 276.1 433.3 605.9 769.3 485.6 534.9 55 18.7 36.1 126.1 96.7 82.3 154.9 360.3 16.5 45 15.9 68.3 55.8 159.2 36.6 148.5 342.3 507.2 274.9 277.2 35 17.8 26.2 100.2 55.5 63.1 113.5 177.3 17.6 42.4 18.4 77.6 36.3 85.1 34.3 89.1 232.9 321.4 234.4 199.6 337.3 145.9 137.7 465.8 489 414.9 315.5 778.1 149.8 349.3 74.1 229 117 243.6 72.8 142 705.9 900.9 561.2 485.6 999.9 866.7 999.9 999.9 999.9 999.9 925.3 778.1 720.7 999.9 462.6 744.2 805.5 778.1 518.7 492.6 999.9 999.9 889.2 705.9
20170224 1 5 B1 3277 B1 3636 A2 3233 A1 4057 A2 3552 B1 3831 5.02 4.12 6.02 6.57 6.09 4.92 28.8 17.6 37.4 48 46 29.2 4.5 3 6.95 5.3 0 4 29.4 0 47.3 30 0 11.1 0.17 0.18 0.15 0.17 0.17 0.14 9.6 36.5 33.3 12.1 36.6 58.3 30 33.8 34 32.8 34.8 23.7 0.09 0.18 0.27 0.18 0.12 0.17 4 1 3 5 2 6 2.4 2.9 2.1 10.7 0 32.2 10.1 8.9 42.5 84.3 15.8 15.8 68.5 106.6 14.4 19.7 58.3 91.2 126.7 180.2 163.3 291.4 321.8 399.3 360.4 484.6 17.9 14.5 61.2 84.1 33.7 28 109.3 128.7 24.4 34.4 97.9 116.2 198.1 313.3 250.2 350.6 372.9 475.7 457.2 999.9 39.2 37.8 133.5 129.1 53.3 39.5 168.4 172.7 55.6 46.9 151.8 152.7 300.2 358.4 312.5 366.5 465.4 509.4 438.6 735.2 37.6 55.2 101 143.7 47.9 56.6 136 173.9 83.8 68.6 220.4 273.5 210 178.2 285.6 314.8 358.4 362.4 447.7 550.6 438.6 604.6 396.9 999.9 577.6 761.1 517.5 999.9 824.1 840.2 640.5 999.9 557.7 509.4 743.6 862.6 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 951.4 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9

競艇データの収集対象選定

まずはどういうデータを集めるかまとめておきます。集めるデータは番組表+オッズをベースとし、不要そうなデータは省いていきます。例えば、各選手の出身とかはあんまり関係無さそうなので省きます。

データ名称 csv上のカラム名 備考
日付 Date
会場 Place 1:桐生、2:戸田、3:江戸川、4:平和島、

5:多摩川、6:浜名湖、7:蒲群、8:常滑、

9:津、10:三国、11:びわこ、12:住之江、

13:尼崎、14:鳴門、15:丸亀、16:児島、

17:宮島、18:徳山、19:下関、20:若松、

21:芦屋、22:福岡、23:唐津、24:大村

レースNo. Race 基本的には1日12レース
nコースの選手級別 nth-rank A1、A2、B1、B2
nコースの選手番号 nth-num
nコースの選手全国勝率 nth-ratio
nコースの選手全国2連率 nth-ratio2
nコースの選手当地勝率 nth-ratioj
nコースの選手当地2連率 nth-ratioj
nコースの選手ST nth-st
nコースのモータ勝率 nth-mratio
nコースのボート勝率 nth-bratio
nコースの展示タイム nth-exb フライングの場合は-1
レース結果-1位-6位 1st,2nd,3rd,4th,5th,6th 1st = 3なら3コースが1位
nコース選手の単勝オッズ n-odds
3連単(1位=l,2位=m,3位=n)のオッズ (m,l,n) 120データある

以上のようなデータをWebスクレイピングにより集めていきます。

【Python】競艇データ Webスクレイピングの実装

Google Colabを用いてやっていきます。全部コピーして実行していけば、動かせると思います(Google Driveの出力先フォルダを変える必要があります)。また、ソースはGitHubにあげています。

Daisuke0209/DataAccess
Contribute to Daisuke0209/DataAccess development by creating an account on GitHub.

まずは、Google Driveへのマウントを取ります。

次にライブラリのインポートを行います。

Google Driveの所定フォルダに出力用ファイルを作成します。フォルダ名称は適宜変更してください。

出力ファイルにインデックスを記入します。

データ取得開始年月日および、取得日数を指定します。取得日数が現在を越えた場合にどうなるかの意地悪テストはしてません!また、作ったのがだいぶ前なので、どうなるか想像できません(;´・ω・)

さて、Webスクレイピングを実行します。以下を実行すると、データの収集およびファイル作成が実行されます。とても下手くそで効率もクソもない作りですが、ご容赦を!

Webスクレイピングが完了すると、finishが表示され終了します。すると、Google Driveの所定のフォルダにboat_file.csvというファイルができているものと思われます!以上!

コメント