クラッチタイムではミッドレンジシュートの方が効果的なのか検証した

こんにちは。

3Pとリム近くのシュートを増やす戦術の流行に異議を唱えようと下記のような記事を書いてきました。本記事はそのシリーズとなります。

具体的に何を検証するかというと、クラッチタイムでは3Pシュートを打つよりミッドレンジシュートを打ったほうが勝利に結びつきやすいかについてです。

昨今のNBAの潮流は得点期待値の高いシュートを目指し、その結果、得点期待値の高い3Pシュートとリム近くのシュートを増やし、その値が低いミッドレンジシュートを減らす方針になっています。

しかし、3Pシュートの得点期待値が高いのは、あくまで成功した時の得点が1.5倍になっているからで、成功率としてはミッドレンジシュートの方が高いわけです。

ここで考えていただきたいのですが、下記のシチュエーションを仮定した場合*1、あなたならミッドレンジシュートと3Pシュートのどちらを選択しますか。

・4Qで同点の残り10秒(自分たちのオフェンスで終わる)
・ミッドレンジシュートの成功率は40%
・3Pシュートの成功率は30%

たぶんなんですけど、ミッドレンジシュートを選択すると思うんですよ。

もう少し抽象的な言い方をすると、試行回数が多いときは得点期待値の高いシュートを増やすのが妥当なのは分かるけど、試行回数が少ないときは成功率が高いシュートを選択したほうが良いのでは?ということです。

そこで、本記事では上記の仮説について、シミュレーションをして検討していきたいと思います。

前提

さて、具体的にどのように検証するかですが、今回は下記の形で進めたいと思います

1.ミッドレンジシュートと3pシュートをそれぞれa回打った際に、どちらの方が最終的な得点が多いかを比べる
2.上記をx回繰り返し、ミッドレンジシュートの方が得点が多かった回数を調べる

1ではそれぞれのFG%を元に最終的な得点が確率的に決まるため、試行ごとに結果が変わります。
なので、その試行を大量に繰り返すことで、どちらの方が得点が上回りやすいかを検証します

上述のシミュレーションを行うにあたり、必要な数値を設定する必要があります。
今回は下記の条件でシミュレーションを行います。

・シュート回数:5回(上述のa回に該当)*2
・シミュレーション回数:10,000回(上述のx回に該当)
※シュート成功率は後述
※今回は、オフェンスリバウンドなどは考慮しません。

シミュレーションの実施方法ですが、さすがにサイコロを回して記録していくのは時間の浪費感が半端ないので、コンピュータに任せます。具体的には、Rというプログラミング言語でシミュレーション用のコードを書き、その結果を元に検討していくことにします。

次の項ではシミュレーションに利用したコードと、その結果を併記していきますので、興味のある方はコードもご覧ください。

結果だけ見たい方は、黒色の背景部分は飛ばしてお読みいただければと思います。

※シュート成功率のデータはNBAの2018-19レギュラーシーズンを利用します。
※コードの詳細やデータセットは下記URLに掲載していますので、興味のある方はご覧ください

シミュレーション結果

まずは諸々の下準備と、通常時のシュート成功率の算出です。

# 下準備
library(tidyverse)

data_byArea <- read_csv("../01_data/midrange_area.csv")  # エリアごとのシュート本数と成功数データ

data_byArea <- data_byArea %>% #対象シーズンの絞り込み
 filter(
   season == "2018-2019"
   ,type == "Regular"
 )
# 通常時のミッドレンジシュート成功率
> midrange_percent <- sum(data_byArea$MID_RANGE_FGM)/sum(data_byArea$MID_RANGE_FGA)
> print(midrange_percent)
[1] 0.4028249
# 通常時の3Pシュート成功率
> F3GA_percent <- sum(data_byArea$C3_FGM,data_byArea$AB3_FGM)/sum(data_byArea$C3_FGA,data_byArea$AB3_FGA)
> print(F3GA_percent)
[1] 0.356834

通常時のミッドレンジシュート成功率は40.3%で、3Pシュート成功率は35.7%となっています。

しかし、今回知りたいのは、接戦の終盤における成功率です。上述の数値には1Q~3Qの数値や、ガベージタイムの数値も含まれていますが、今回の目的は、接戦の終盤におけるミッドレンジシュートの価値を検討することなので、そういったシチュエーションでの数値を確認したほうが妥当です。

ということで、クラッチタイムの数値をチェックしてみましょう。

data_clutch_3point <- read_csv("../01_data/clutch_3point.csv") #接戦時の3P%算出
> F3GA_percent_clutch <- sum(data_clutch_3point$`3PM`)/sum(data_clutch_3point$`3PA`)
> print(F3GA_percent_clutch)
[1] 0.3139073

クラッチタイムの3P成功率は31.4%となっています。

あれ、ミッドレンジシュートの数値がないじゃないかと思ったあなた、その通りです。
実は、NBAの公式サイトでクラッチタイム時のミッドレンジシュートの成功率が見つからず、実数値が算出できない状態です。

しかし、このままでは話が進まないので、3Pシュート成功率の減少率をクラッチタイムの影響と仮定し、その減少率を通常時のミッドレンジシュート成功率と掛け合わせて推定の数値を算出します。

> midrange_percent_clutch <- midrange_percent*(F3GA_percent_clutch/F3GA_percent)
> print(midrange_percent_clutch)
[1] 0.3543656

計算すると、クラッチタイムのミッドレンジシュートの推定成功率は35.4%となりました。

これで、シミュレーションに必要な素材は揃いました。

それではRに10000回働いてもらいましょう。

set.seed(1031) #乱数固定
N = 10000 #シミュレーション回数
freq = 5 #シュート本数
df_2point <- data.frame(sim_2point = rep(0, length = N)) #格納用のデータフレーム作成
x <- c(2, 0) #得点
for (i in 1:N){
 a <-  sum(sample(x, size = freq, replace = TRUE, prob = c(midrange_percent_clutch, 1 - midrange_percent_clutch))) #1シミュレーションごとの得点算出
 df_2point[i,] = a
 i = i + 1
}
df_3point <- data.frame(sim_3point = rep(0, length = N)) #格納用のデータフレーム作成
y <- c(3, 0) #得点
for (i in 1:N){
 a <-  sum(sample(y, size = freq, replace = TRUE, prob = c(F3GA_percent_clutch, 1 - F3GA_percent_clutch))) #1シミュレーションごとの得点算出
 df_3point[i,] = a
 i = i + 1
}
df <- df_2point %>%
 bind_cols(df_3point) %>%
 mutate(
   over3point_flag = if_else(
     sim_2point >= sim_3point
     ,1
     ,0
   )
 )
sum(df$over3point_flag)/nrow(df)
[1] 0.4327

終盤の接戦時に、シュート回数が5回のとき、すべてミッドレンジシュートを打ったケースがすべて3Pシュートを打ったケースより得点数を上回る確率は約43.3%となりました。

これはつまり、5回という比較的少ない本数でも、3Pシュートを打ったほうが良いということを示唆しています。

しかし、ここで諦めたくない!
そこで、このような説を考えました。

「ミッドレンジシュートの方が終盤の接戦の時でも成功率が落ちにくい説」

先程のシミュレーションでは、推定でクラッチタイム時のミッドレンジシュート成功率を算出しましたが、そもそもクラッチタイムでミッドレンジシュートの成功率が落ちるという前提がおかしいという考えですね。

この説の妥当性は分かりませんが、説が正しいとした時のシミュレーションは行なえますので、やってみましょう。

set.seed(1031) #乱数固定
N = 10000 #シミュレーション回数
freq = 5 #シュート本数
df_2point <- data.frame(sim_2point = rep(0, length = N)) #格納用のデータフレーム作成
x <- c(2, 0) #得点
for (i in 1:N){
 a <-  sum(sample(x, size = freq, replace = TRUE, prob = c(midrange_percent, 1 - midrange_percent))) #1シミュレーションごとの得点算出
 df_2point[i,] = a
 i = i + 1
}
df_3point <- data.frame(sim_3point = rep(0, length = N)) #格納用のデータフレーム作成
y <- c(3, 0) #得点
for (i in 1:N){
 a <-  sum(sample(y, size = freq, replace = TRUE, prob = c(F3GA_percent_clutch, 1 - F3GA_percent_clutch))) #1シミュレーションごとの得点算出
 df_3point[i,] = a
 i = i + 1
}
df <- df_2point %>%
 bind_cols(df_3point) %>%
 mutate(
   over3point_flag = if_else(
     sim_2point >= sim_3point
     ,1
     ,0
   )
 )
sum(df$over3point_flag)/nrow(df)
[1] 0.487

ミッドレンジシュートが3Pシュートを上回る確率は48.7%となりました。

さっきよりましな数値にはなりましたけど、まだ50%を下回っています。

うーん、渋い。

結論としては、クラッチタイムではミッドレンジシュートの方が効果的ということは言えないということになりました。

ただ、チームごとに状況が異なりますので、ミッドレンジシュートの名手がいるなどの場合は効果的かもしれません。

本文は以上です。
ご質問・ご指摘などありましたらコメントいただければと思います。


*1
本来なら色々な要素を検討するべきなのです。
(終盤はファウルが吹かれにくそうだから、ファウルされにくい3Pシュートにする、3Pシュートなら決まれば逆転されることはほぼないetc)
今回は話をシンプルにするために。条件の少ない仮定にしています。

*2
この数値は感覚です。本来なら4Q終盤における1ポゼッションあたりのshot clock平均などから算出するべきなのですが、データが見つからなかったので、このようにアテで設定しています。


サポートしていただけるとありがたいですが、 SNS等で広めていただけるともっとありがたいです。 一緒にバスケを盛り上げていきましょう!