15
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

競艇はスタート位置で決まるんじゃね?

Last updated at Posted at 2021-08-06

#はじめに
競艇のルール,予想の仕方など私自身何もその辺の知識がないことをご了承ください.

それらすべてをデータ分析,機械学習に任せることによって知識のない人間でも利益をプラスにできるのではないか,そういう魂胆でこの記事を書いています.

環境

MacOS BigSur 11.4
Jupyter Notebook(Colaboratoryでも可)

データについて

競艇公式ホームページ BOAT RACEからスクレイピングによってデータを取得しました.

会場:住之江会場
データ数:43560件
期間:2019/01 ~ 2020/04

今回の目的

競艇はスタート位置でほぼ決まる.みたいな話を聞いたことがあります.

データ分析によってこれが本当なのかを調べるのが今回の目標です.

本編

ライブラリのimport

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from  itertools import product

## 前処理
データはsuminoe_40000_program.csvsuminoe_40000_answer.csvに格納されているため,PandasによってDataFrame形式でデータを読み込みます.

説明変数

names = ["Place", "Number", "Name", "Age", "Live", 
                 "Weight", "Rank", "A_1st", "A_2nd", "B_1st", 
                 "B_2nd", "Moter_No", "Moter_2nd", "Bote_No", "Bote_2nd"]
df_program = pd.read_csv("../../Boat-Race-Prediction/suminoe_40000_program.csv", names=names)
print(f"shape: {df_program.shape}")
df_program.head()

スクリーンショット 2021-08-06 11.25.05.png

目的変数

df_answer = pd.read_csv("../../Boat-Race-Prediction/suminoe_40000_answer.csv", names=["idx", "target"])
print(f"shape: {df_answer.shape}")
df_answer

スクリーンショット 2021-08-06 11.28.39.png

OneHotEncoding

説明変数を見ると,Name, Live, Rankはカテゴリ変数となっていることがわかります.

名前Nameと地域LiveについてはOneHotEncodingしてしまうと ,列数がとんでもないことになってしまうため今回はデータから弾くことにします.
よってRankをOneHorEncodingによって,A1, A2, B1, B2の列を新たに作成します.
(目的変数のidxも必要ないため弾いています.)

df_data = df_program.merge(df_answer, how="inner", right_index=True, left_index=True)
df_data = df_data.drop(["idx", "Name", "Live"], axis=1)
df_dummies = pd.get_dummies(df_data, columns=["Rank"])
df_dummies.head()

スクリーンショット 2021-08-06 11.38.52.png

目的変数の前処理

競艇には転覆やスタートミスによって失格判定になる場合があります.

生データではtargetの部分がK, Fのようなカテゴリ変数となっています.

できるだけ数値のみのデータとして扱いため,10, 11, 12の値に変換してあります.

今回の分析でこれらのデータは使用しないため,np.nanによって欠損値扱いとします.

df_dummies.target[df_dummies.target == 10] = np.nan
df_dummies.target[df_dummies.target == 11] = np.nan
df_dummies.target[df_dummies.target == 12] = np.nan

各列とtargetの相関を見る

targetと各変数の関係を相関係数を計算することによって調べます.

わかりやすさのために,Seaboanのヒートマップを使用しています.

# 相関係数を表示
plt.rcParams['figure.figsize'] = (20.0, 10.0)
plt.rcParams['font.family'] = 'serif'
sns.heatmap(df_data.corr(), annot=True, square=True, cmap='coolwarm');

スクリーンショット 2021-08-06 11.50.20.png

このヒートマップから,targetPlaceの間には,0.38の正の相関があることがわかります.
0.38という値は強い相関とは言えませんが,やや相関があると言えます.

なので,targetPlaceをヒストグラムで示してみましょう.

targetPlaceの関係をヒストグラムで可視化する

各スタート位置に対する順位をヒストグラムによって可視化してみます.

これによって位置がどのくらい順位に影響するのかがわかるはずです.

fig, ax = plt.subplots(2, 3, figsize=(15, 10))
for i, tu in zip(range(1, 7), product(range(2), range(3))):
    df_place = df_dummies[df_dummies.Place == i]
    ax[tu[0], tu[1]].hist(df_place.target, bins='auto')
    ax[tu[0], tu[1]].title.set_text(f'Place {i}')
    ax[tu[0], tu[1]].set_xlabel('Ranking')
    ax[tu[0], tu[1]].set_ylabel('Count')
plt.tight_layout()

スクリーンショット 2021-08-06 11.55.47.png

スタート位置が1である場合に1位になる確率はとてつもなく高そうです.

スタート位置が6に近づくにつれて1位になる確率は下がっていっていることがわかります.

では,位置に対する順位の確率を算出してみましょう.

for i in range(1, 7):
    df_place = df_dummies[df_dummies.Place == i]
    print(f"Place: {i}")
    for j in range(1, 7):
        df_target = df_place[df_place.target == j]
        probability = df_target.shape[0] / df_place.shape[0] * 100
        print("\t{}: {:.1f}%".format(j, probability))
Place: 1
	1: 55.9%
	2: 16.9%
	3: 9.1%
	4: 6.8%
	5: 5.5%
	6: 4.6%
Place: 2
	1: 15.7%
	2: 25.4%
	3: 18.3%
	4: 15.1%
	5: 13.0%
	6: 11.3%
Place: 3
	1: 11.3%
	2: 21.5%
	3: 20.3%
	4: 18.2%
	5: 15.1%
	6: 12.2%
Place: 4
	1: 8.7%
	2: 16.1%
	3: 19.5%
	4: 19.0%
	5: 17.8%
	6: 17.3%
Place: 5
	1: 5.4%
	2: 11.7%
	3: 17.0%
	4: 20.0%
	5: 23.0%
	6: 21.4%
Place: 6
	1: 3.0%
	2: 8.4%
	3: 15.7%
	4: 20.6%
	5: 24.4%
	6: 26.4%

スタート位置が1であったときに1位になる確率は,55.9%であることがわかりました!

よって,1レース6人であるため,データでは1レース6行で表現されます.なので,今回のデータは43560件であるため,
43560 / 6 = 7260レース分のデータが存在しています.

この7260レース中のうち,55.9%が1位になるため,スタート位置が1である選手は73604058回1位になっていることが今回のデータからわかりました.

まとめ

絶対というわけではないですが,スタート位置だけでも順位にそれなりに影響するようです.

しかしスタート位置が2, 3, 4の場合は順位にあまり差がないため,3連単などを当てるためには他の点で分析していく必要があると思います.

ここまでのデータ分析で使えるのは単勝予想くらいだと思います.

15
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?