機械学習でFormula 1レースの面白さを予測してみた


この記事は[ABEJA Advent Calendar 2020](https://qiita.com/advent-calendar/2020/abeja)の14日目です。

私はF1レースが大好きでもう２０年以上も見続けているのですが、F1に関わるデータ分析をしてみたいと思いKaggleを眺めていたところ、chrolss氏が面白い問題[「Formula 1: What makes a good race?」](https://www.kaggle.com/christianolsson/formula-1-what-makes-a-good-race)を紹介していました。

問題は「F1のレースデータから、そのレースがどれくらい面白かったかのユーザ評価を予測する」というもので、私も今回この問題に取り組んでみました。

（余談ですが、来年はF2でも今年大活躍した角田選手のF1アルファタウリチームへのの昇格が確実視されており、楽しみです:smile:！）

# データ
F1のレースデータと、各レースに対するユーザ評価データは以下の通り取得しました。

- **F1レースデータ**：Chris Gさんが公開してくれている[F1 Race Data](https://www.kaggle.com/cjgdev/formula-1-race-data-19502017)
    - 1950〜2017年までのレースデータ（予選・決勝順位、レース中のラップタイム、ピットストップ、リタイア原因などの詳細情報）
- **ユーザ評価データ**：[racefans.net](http://racefans.net)で公開されているユーザによる評価データ
    - 毎レース終了後、集計されるユーザー投票の平均値（0：非常につまらなかった〜10：非常に面白かった）
    - 2017シーズンのユーザ評価例（https://www.racefans.net/2017/12/26/2017-ended-with-second-worst-race-of-last-ten-years/ より引用） ![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/886b7e37-7441-72a6-dbc2-8c997a59016a.png)

# 特徴量
特徴量として、以下の３つを定義してみました。

## 特徴量①：アクシデント率
クラッシュやトップ周回中のドライバーにパンクが起こったりすると、レースが荒れて結果としてユーザ評価が高まることが考えられます。

今回のレースデータには、各ドライバーがどのようにレース終えたかを示すステータスが定義されており、その中でもアクシデント関連として以下のようなものが定義されています。

<img width="200" alt="accidents" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/92c3e0fb-c23f-6b17-8739-6a3cd41cba15.png">

そこで、あるレースでレースに出走したドライバーの内、どれくらいがアクシデントでレースを終えたかを**アクシデント率(accident_rate)**として以下のように定義しました。

```math
アクシデント率 = \frac{上記の表に含まれる理由でレースを終えたドライバー数}{レースに出走したドライバー数}
```

## 特徴量②：年間累積勝利数
同じドライバーが勝ち過ぎると、そのドライバーの熱烈なファンでも無い限りは、レースの展開に意外性がなくなり、ユーザ評価は下がると考えられます（例：2004年はMichael Schmacherが18レース中13勝したので、あんまり面白くありませんでした）。

そこでレースに優勝したドライバー年間の**累積勝利数(cum_wins)**を求めてみました。以下の2017年シーズンの例だと、１０戦目時点でLewis Hamiltonが４勝しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/7c46b8f3-d028-17e1-8a7d-e29f248e5c5d.png)


## 特徴量③：予選から決勝への合計順位変化
ドライバーの予選順位から、最終的な決勝での順位が大きく異なれば異なるほど、オーバーテイクが発生したり、順位の入れ替わりが激しいレースと言えるので、ユーザ評価が上がる可能性が考えられます。

そこで各ドライバーの予選順位と決勝順位の差分の絶対値を考え、それを全ドライバー分について足し合わせた**合計順位変化(delta_pos)**を以下のように求めました。なおリタイアした場合は、差分は０として取り扱います。

```math
合計順位変化 = \sum_{i=0}^N |予選順位(ドライバー_i) - 決勝順位(ドライバー_i)|
```

## 定義した特徴量とユーザ評価の関係
定義した特徴量とユーザ評価(rating)の関係を以下のとおり調べてみました。

| 特徴量  | ユーザ評価との関係 | 相関係数 | 
|---|---|---|
| **アクシデント率** |<img width="300" alt="accident rate" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/fe5bcddd-0219-ceec-f974-c769eda6a9f8.png"> | <img width="300" alt="accident rate" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/24e921b2-93bb-42f1-9e9f-20ced51e5438.png"> |
| **累計年間勝利数** | <img width="300" alt="cum wins" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/716bb854-2465-738d-17c2-146383dee84d.png"> | <img width="300" alt="cum wins" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/cb48ba8d-94f1-80b0-3f71-9cb5cba59113.png"> |
| **合計順位変化** | <img width="300" alt="delta pos" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/9ee1f51b-7603-5895-e79f-7ddc4e444d84.png"> |　<img width="300" alt="delta pos" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/61a1c29b-9e10-e8f4-bd5d-79dd69320dac.png"> |

アクシデント率と累計年間勝利数は、ユーザ評価との相関があまり高くなさそうです😓。

ただし累計年間勝利数は、意図したとおり負の相関（累計年間勝利数が上がるほど、ユーザ評価が下がる）となっています。

また合計順位変化は、全体的には右肩上がりの正の相関分布となっており、相関係数も0.47と比較的高めになっており、有望そうです。


# 実験

## 実験設定
2008年〜2017年シーズンのデータをランダムに分割して、7割を訓練データ、3割をテストデータとして、xgboostを使ってMSEを最小化するように学習しました。

以下の４つのケースを比較してみました。

- **①ベースライン**：学習データのユーザ評価平均(6.766)を予測値とする
- **②proposed**: 今回定義した特徴量で学習・予測を行う
- **③chrolss**: chrolss氏が[「Formula 1: What makes a good race?」](https://www.kaggle.com/christianolsson/formula-1-what-makes-a-good-race)で用いていた特徴量で学習・予測を行う
    - 追い抜きの数、リタイアの数、決勝順位top5ドライバーのレース中順位の分散
- **④chrolss + proposed**: chrolss氏＋今回定義した特徴量で学習・予測を行う

## 結果
テストデータに対する予測と実測値のMean Absolute Errorを上の４つのケースに対して求めてみたのが以下になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/b6a667e4-5e05-8c59-8a92-bf9d848efe14.png)

残念ながら今回定義した特徴量（②）は、ベースライン（①）よりは若干良かったものの、chrolss氏の特徴量（③）には敵いませんでした。ただ、chrolss氏の特徴量と今回のものを両方使うと（④）、若干エラーが改善しました！

④の場合の、最終的なユーザ評価の予測値（X軸）と実測値（Y軸）の関係は以下のとおりになります。結構当たっているように見えます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539520/00ea3874-3756-aade-9aab-9adef0aaeb4a.png)


# 感想
結果として今回定義した特徴量は単独ではあまり良い予測に寄与することはできませんでしたが、自分の好きなデータを眺めながら色々と特徴量を考えてみるのは楽しかったです。

また今回は時間の関係でできませんでしたが、各ドライバーの順位データの時系列データをLSTMに入れて、Deep Learning的なアプローチも試してみるのも面白そうだと思いました。

ツッコミどころあれば、ぜひよろしくお願いします。