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

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

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

# 環境

MacOS BigSur 11.4
Jupyter Notebook(Colaboratoryでも可)

# データについて

競艇公式ホームページ [BOAT RACE](https://www.boatrace.jp/owpc/pc/extra/data/download.html)からスクレイピングによってデータを取得しました．

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

# 今回の目的

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

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

# 本編
## ライブラリのimport
```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from  itertools import product
```
##　前処理
データは`suminoe_40000_program.csv`と`suminoe_40000_answer.csv`に格納されているため，PandasによってDataFrame形式でデータを読み込みます．


### 説明変数
```python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562339/ef6760bd-8fbb-b8f8-f33b-75246e08e9ec.png)

### 目的変数
```python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562339/a3977cb9-1387-cf0e-d13e-4d8e4e46154b.png)

## OneHotEncoding

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

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

```python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562339/c0a728b0-cadd-0454-fee6-53338d8ffc28.png)

## 目的変数の前処理

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

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

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

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

```python
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`のヒートマップを使用しています．

```python
# 相関係数を表示
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562339/4e2e20b6-533f-b172-8721-fe71100f4efb.png)

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

なので，`target`と`Place`をヒストグラムで示してみましょう．

## `target`と`Place`の関係をヒストグラムで可視化する

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

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

```python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562339/eec8ba8a-0c2e-6901-2eca-5785ac75dd8a.png)

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

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

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

```python
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))
```
```text
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`である選手は`7360`中`4058`回１位になっていることが今回のデータからわかりました．

# まとめ

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

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

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