【バスケットボール】ボックススコアに残らないオフェンスへの貢献はどれくらいあるのか?(2)

↑の記事の続編になります。この記事を読んでくれた方からとても生産的なコメントを頂いたので、それを受けた分析について書きます。

 頂いたご指摘というのは、Point Per Possession(PPP)、True Shooting Percentage(TS%)、effective Field Goal Percentage(eFG%)のいずれもが攻撃の質(=攻撃効率)を測っているだけなので、攻撃の量も考慮すべきだろうというものです。さらに、ボックススコアにはリバウンドやアシスト、スティールが記録されているので、これらも使った方が「ボックススコアに残る貢献」をより反映しているのではないか、というものです。これらのコメントはそのとおりだと思いました。

 そこで、この記事ではO-PIPMを従属変数、PPP・(40分換算した)平均得点・アシスト・総リバウンド・スティール・ターンオーバー・ブロックショットの7つの変数を独立変数とした重回帰分析の結果を紹介します。本当はPERでO-PIPMを単回帰したほうが良いのかもしれませんが、PERは理解できていないので重回帰分析を使います。

 分析の結果を先に述べると、重回帰モデルの自由度調整済み決定係数は0.491となりました。つまり、PPP・(40分換算した)平均得点・アシスト・総リバウンド・スティール・ターンオーバー・ブロックショットの7つの変数のばらつきで、O-PIPMのばらつきを約50%説明できるということです。やはり、ボックススコアに残らない攻撃への貢献というのはかなり大きいという感想を持ちました。

データの準備

ボックススコアのデータはrintaromasuda様(https://github.com/rintaromasuda/bleaguer/tree/master/inst/extdata)のデータを用いました。O-PIPMはB League Impact Metrics様(https://twitter.com/B_ImpactMetrics)からいただきました。

従属変数・独立変数の記述的特徴・加工

独立変数の内、得点・アシスト・リバウンド・スティール・ターンオーバー・ブロックショットについては40分換算したものを用いました。これは、これら6つの変数の背後に出場時間という共通の因子があると考えられるためです。つまり、出場時間が長いほど、これら6つの指標も高くなりやすいということです。重回帰分析では、独立変数どうしの相関係数が高すぎると多重共線性という問題が起こるので、6つの指標どうしの相関係数を低くするために、40分換算した数値を用いることにしました。実際、この処理によって相関係数は減少しました。相関行列を示します。

 O-PIPM、PPP、40分換算した得点(PTS_40)、アシスト(AS_40)、リバウンド(TR_40)、スティール(ST_40)、ターンオーバー(TO_40)、ブロックショット(BS_40)の要約統計量とヒストグラムを示します。アシストとリバウンド、ターンオーバーには外れ値の選手がいるので確認したところ、アシストの外れ値(18.16)は米須玲音選手で、リバウンドの外れ値(22.25)はエリック・ニッセン選手であることが分かりました。ターンオーバーの外れ値(5以上)は7名の選手がいました。これらの選手を分析から外すかどうかですが、外さずに分析することにします。

 重回帰分析の結果を見やすくするために、従属変数と7つの独立変数を平均が0、標準偏差が1になるように変換しました(標準化)。

分析

O-PIPMを従属変数、PPP・得点・アシスト・リバウンド・スティール・ターンオーバー・ブロックショットを独立変数に重回帰分析を行いました。その結果、有意なモデルが得られました(F(7, 286)=41.36, p<0.05)。重回帰モデルの自由度調整済み決定係数は0.491でした。つまり、7つの変数によってO-PIPMのばらつきの49.1%を説明することができるということが分かりました。逆に説明できない分の約50%が「ボックススコアに残らない攻撃への貢献」だと捉えることができます。

 本稿は重回帰モデルの自由度調整済み決定係数に関心があったのですが、参考になるかもしれないので、独立変数の係数とその有意性をまとめたテーブルも載せておきます(constというのは切片のことです。気にしなくて大丈夫です)。5%水準ではリバウンドとターンオーバーが有意ではないという結果が得られました。

終わりに

この記事ではO-PIPMを従属変数、PPP・(40分換算した)平均得点・アシスト・総リバウンド・スティール・ターンオーバー・ブロックショットの7つの変数を独立変数とした重回帰分析を行いました。その結果、自由度調整済み決定係数は0.491となりました。つまり、O-PIPMの分散の内、約50%は説明できませんでした。この説明できなかった分散が「ボックススコアに残らない攻撃への貢献」を少なくとも部分的には反映していると考えられます。

 PPPだけを使って回帰した場合と比べて、重回帰モデルでは決定係数は向上したものの、その向上は私が予想していたよりは小さかったです。ボックススコアに残らない攻撃への貢献はやはり大きかったです。

【著者のTwitter:https://twitter.com/rnsr0371

分析に用いたコード(Python)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm
import scipy.stats

pd.set_option("display.max_columns",100)
pd.set_option("display.max_rows",1000)

pipm=pd.read_csv("B1_20-21_PIPM 2_no_space.csv")
o_pipm=pipm[["選手名","O-PIPM"]]
o_pipm=o_pipm.rename(columns={"選手名":"Player"})

box=pd.read_csv("games_boxscore_202021.csv")

#PPPを計算する
ppp=[]
for pts,fga,fta,to in zip(box["PTS"],box["FGA"],box["FTA"],box["TO"]):
    if fga+(0.44*fta)+to==0:
        ppp.append(np.nan)
    else:
        ppp.append(pts/(fga+(0.44*fta)+to))
        
box["PPP"]=ppp

box_ad=box[["Player","PPP","PTS","TR","AS","ST","TO","BS","EFF","MIN"]]
box_ad=box_ad.groupby("Player").mean()
data=box_ad.merge(o_pipm,on="Player")

data[data["PPP"]==0]
data=data[data["PPP"]>0]

#PTS,PPP,AS,TR,ST,TO,BSを用いた重回帰
#相関係数の確認
data.loc[:,["O-PIPM","PPP","PTS","AS","TR","ST","TO","BS","MIN"]].corr()

#40分換算
PTS_40=[]
AS_40=[]
TR_40=[]
ST_40=[]
TO_40=[]
BS_40=[]

for PTS,AS,TR,ST,TO,BS,MIN in zip(data["PTS"],data["AS"],data["TR"],data["ST"],data["TO"],data["BS"],data["MIN"]):
    PTS_40.append(PTS/MIN*40)
    AS_40.append(AS/MIN*40)
    TR_40.append(TR/MIN*40)
    ST_40.append(ST/MIN*40)
    TO_40.append(TO/MIN*40)
    BS_40.append(BS/MIN*40)
    
data["PTS_40"]=PTS_40
data["AS_40"]=AS_40
data["TR_40"]=TR_40
data["ST_40"]=ST_40
data["TO_40"]=TO_40
data["BS_40"]=BS_40

#相関係数の確認
data.loc[:,["O-PIPM","PPP","PTS_40","AS_40","TR_40","ST_40","TO_40","BS_40"]].corr()
#40分換算のスタッツのほうが独立変数どうしの相関係数は低くなる

#記述的指標の確認
data3=data.loc[:,["Player","O-PIPM","PPP","PTS_40","AS_40","TR_40","ST_40","TO_40","BS_40"]]
data3.describe()

#各変数のヒストグラムを書く
fig=plt.figure(figsize=(15,10))

fig.add_subplot(3, 3, 1)
plt.hist(data3["O-PIPM"])
plt.title("histgram of O-PIPM")

fig.add_subplot(3, 3, 2)
plt.hist(data3["PPP"])
plt.title("histgram of PPP")

fig.add_subplot(3, 3, 3)
plt.hist(data3["PTS_40"])
plt.title("histgram of PTS_40")

fig.add_subplot(3, 3, 4)
plt.hist(data3["AS_40"])
plt.title("histgram of AS_40")

fig.add_subplot(3, 3, 5)
plt.hist(data3["TR_40"])
plt.title("histgram of TR_40")

fig.add_subplot(3, 3, 6)
plt.hist(data3["ST_40"])
plt.title("histgram of ST_40")

fig.add_subplot(3, 3, 7)
plt.hist(data3["TO_40"])
plt.title("histgram of TO_40")

fig.add_subplot(3, 3, 8)
plt.hist(data3["BS_40"])
plt.title("histgram of BS_40")

plt.show()

#独立変数・従属変数を標準化する
data3=pd.DataFrame(scipy.stats.zscore(data3.drop("Player",axis=1)))
data3=data3.rename(columns={0:"O-PIPM",1:"PPP",2:"PTS_40",3:"AS_40",4:"TR_40",5:"ST_40",6:"TO_40",7:"BS_40"})
data3

X=data3.loc[:,["PPP","PTS_40","AS_40","TR_40","ST_40","TO_40","BS_40"]]
y=data3.loc[:,["O-PIPM"]]

model = sm.OLS(y, sm.add_constant(X))
result = model.fit()

result.summary()

 

 

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA