読書・NBA・ポケモン

読書・ポケモン・NBA・統計学について書きます

Bリーグ2019-20シーズンMIP(Most Improved Player)を勝手に決める

はじめに

コロナウイルスのせいで2019-20年のBリーグが終わってしまいました。それに合わせて、各スタッツのリーダーズが確定しました。
www.bleague.jp
しかし、まだMVP(最優秀選手)やMIP(Most Improved Player:最も成長した選手)ベストファイブの発表はされていません。そこで、今回の記事ではスタッツの分析を通じて、独自にMIPを決めたいと思います。どうして、MVPではなくて、MIPなのかって? それはプレータイムの伸び具合や後述するOffensive Efficiency(OE)の伸び具合を使えば、選手の成長具合を評価できると考えたからです。
 今回の分析では、推測統計は使わず、OEの伸び具合・プレータイムの伸び具合・PPGの伸び具合を散布図にプロットして、選手の成長を可視化し、MIPに相応しい選手を探すことを目標としました。結論を先に書くと、大阪エヴェッサの橋本拓哉がMIPに相応しいと私は思います。

考慮するスタッツ

Offensive Efficiency (OE)の伸び

OEはShea & Baker(2013) で提案されたスタッツで「その選手が終わらせたポゼッションの内、得点またはアシストがついたポゼッションの割合」を意味します。OEの式は次の通りです。

OEは基本的には0~1の値を取り、大きければ大きいほど攻撃の効率が良いと解釈することができます。
 Shea & Baker(2013)では、OEがチームにとって重要であることを示すために、NBAのデータを用いて、チームのOEを算出し、それがチームの勝率と正の相関を示すことを報告しています。Bリーグにおいても、チームのOEがチームの勝率と正の相関を示すことが分かっています(チームのOffensive EfficiencyはBリーグの試合の勝ち試合数を予測するか?-2 - 読書・NBA・ポケモン)。MIPの選定にチームの勝率が加味したいので、チームのOEが勝率と正の相関を示すというのは、MIPを決める上で有用な特徴だと言えます。
 選手の攻撃の効率性が向上したかを調べるために、2019-20シーズンの選手個人のOEから、2018-19シーズンの選手個人のOEの差(つまりOEの伸び)を取ることにしました。このOEの伸びは大きければ大きいほど、前シーズンに比べて、今シーズンの攻撃の効率が良くなっていると解釈できます。

プレータイムの伸び

選手の成長を考える上でもう一つ重要となるのが、プレータイムの伸びです。プレータイムは選手がどれだけヘッドコーチから信頼されているかを示すと考えられます。ヘッドコーチからの信頼はオフェンスだけで決まるとは考えにくいです。ディフェンスやオフボールでの動きの上手さも反映されていると考えられます。これらはOEの伸びを見ているだけでは評価できないので、プレータイムの伸びを考慮することで、より適切にMIPを選ぶことができると思います。

1試合の平均得点(point per game: PPG)とPPGの伸び

PPGの伸びもMIPを決める上で必要だと考えます。OEは攻撃の効率性を評価してくれますが、オフェンスへの関与の大きさを評価しているわけではありません。そこで、オフェンスへの関与が大きくなったことの指標として、2019-20シーズンのPPGと2018−19シーズンのPPGの差を取ることにしました。また、参考に2019−20シーズンのPPGも示しました。

分析

使用するデータ

BリーグのHPから、2018-19シーズンと2019−20シーズンのスタッツをスクレイピングによって取得しました。また、2019-20シーズンに1試合平均で20分以上プレーしている選手のみを分析の対象としました。

散布図による成長の可視化

f:id:morry0371:20200328114312p:plain
縦軸に出場時間の伸びをとり、横軸にOEの伸びをとりました。また、選手が成長しているのか、つまり差が0より大きいのか否かをわかりやすくするために、縦軸・横軸が0のところに直線を追加しました。
 さらに、PPGの伸びを算出し、各データ点に色をつけました。色が明るくなればなるほど、PPGの伸びは大きいと読めます。2019−20シーズンのPPGに応じて、データ点の大きさを変更しました。データ点が大きくなればなるほど、PPGも大きくなると読むことができます。
 以上をまとめると、散布図の右上にあればあるほど攻撃の効率性とプレータイムの伸びが大きく、データ点の色が水色っぽく、またサイズが大きいほどオフェンスへの関与が大きくなっているあるいは大きいと読むことができます。
 この散布図の中で、右上にエリアにプロットされた目を引く選手としては、前田悟・橋本拓哉・松井啓十郎がいます。彼らはOEとプレータイムが伸びただけでなく、データ点が水色で大きいことからオフェンスへの関与も大きくなったと解釈することができます。
 この内、松井啓十郎は、本人の成長があることを否定できませんが、チームの移籍によってPPGやプレータイムが伸びたと考えられます。この解釈は、OEの向上が前田悟・橋本拓哉と比べて小さいからも裏付けることができます。具体的な数字を出すと、松井啓十郎のOEの伸びは0.075でした。以上のことから、松井啓十郎はスタッツはたしかに良くなったけれども、最も「成長した」選手とは言えないと判断します。
 前田悟と橋本拓哉は甲乙付けがたいです。どちらもOEが大きく向上しており、前田悟は0.146、橋本拓哉は0.196もOEが伸びています。PPGの伸びはどちらも8.5で、2019-20シーズンのPPGは前田が11.5、橋本が10.5となっており、ほぼ互角です。
 所属チームの成績は、前田の富山グラウジーズが17勝24敗、橋本の大阪エヴェッサが26勝15敗となっており、チーム勝率の面から言えば橋本に軍配が上がりそうです。よって、難しいところではありますが、私はMIPに橋本卓哉を選びたいと思います。

おまけ:分析に使ったコード(R)

library(rvest)
library(dplyr)
library(ggplot2)
library(ggrepel)
library(stringr)

#スクレイピングによってデータを取得する

url="https://www.bleague.jp/stats/?tab=1&year=2018"
page=read_html(url, encoding = "utf-8")
tables=html_table(page)#pageから表を取得する
players2018=tables[[1]]#選手のシーズン平均のスタッツをplayersに格納

url2="https://www.bleague.jp/stats/?tab=1&year=2019"
page2=read_html(url2,encoding = "utf-8")
tables2=html_table(page2)
players2019=tables2[[1]]

#players2018のデータを整形する
str(players2018)
players2018=players2018[-269,]#行の名前が重複しているので消す

players2018$PTS=as.numeric(players2018$PTS)

players2018$AS=as.numeric(players2018$AS)
players2018$FGM=as.numeric(players2018$FGM)

players2018$FGA=as.numeric(players2018$FGA)
players2018$OR=as.numeric(players2018$OR)
players2018$TO=as.numeric(players2018$TO)

MINPG2018=str_split(players2018$MINPG,pattern = ":",simplify = T)
players2018$MINPG2018=as.numeric(MINPG2018[,1])#秒を切り捨ててプレイタイムとする
players2018$PPG2018=as.numeric(players2018$PPG)



#players2018からOEを計算する
players2018$OE2018=(players2018$FGM+players2018$AS)/
  (players2018$FGA+players2018$TO+players2018$AS-players2018$OR)


#players2019のデータを整形する
str(players2019)
players2019=players2019[-282,]#行の名前が重複しているので消す

players2019$PTS=as.numeric(players2019$PTS)

players2019$AS=as.numeric(players2019$AS)
players2019$FGM=as.numeric(players2019$FGM)

players2019$FGA=as.numeric(players2019$FGA)
players2019$OR=as.numeric(players2019$OR)
players2019$TO=as.numeric(players2019$TO)
players2019$PPG2019=as.numeric(players2019$PPG)

#players2019からOEを計算する
players2019$OE2019=(players2019$FGM+players2019$AS)/
  (players2019$FGA+players2019$TO+players2019$AS-players2019$OR)

MINPG2019=str_split(players2019$MINPG,pattern = ":",simplify = T)
players2019$MINPG2019=as.numeric(MINPG2019[,1])#秒を切り捨ててプレイタイムとする


#players2018とplayers2019を結合する
players2018 %>% select(.,PLAYER,OE2018,MINPG2018,PPG2018)->data_2018
players2019 %>% select(.,PLAYER,OE2019,MINPG2019,PPG2019)->data_2019

data=full_join(data_2018,data_2019,by="PLAYER")

data=na.omit(data)
data %>% mutate(.,OE_diff=OE2019-OE2018) ->data
data %>% mutate(.,MINPG_diff=MINPG2019-MINPG2018)->data
data %>% mutate(.,PPG_diff=PPG2019-PPG2018)->data

#2020年のプレータイムが20分未満の選手を除く
data %>% filter(MINPG2019>20)->data

#散布図を書く
data %>% ggplot(.,aes(x=OE_diff,y=MINPG_diff,color=PPG_diff,size=PPG2019))+
  geom_point()+
  geom_vline(xintercept=0,colour="black")+
  geom_hline(yintercept = 0,colour="black")+
  xlim(c(-0.5,0.5))+
  ylim(c(-25,25))+
  theme_classic(base_family = "HiraKakuPro-W3")+
  xlab("OEの伸び")+
  ylab("プレータイムの伸び")+
  labs(color="PPGの伸び",
       size="19-20シーズンのPPG")+
  ggtitle("選手の成長具合を示した散布図")+
  geom_text_repel(aes(label=ifelse(OE_diff>0.05&MINPG_diff>10,PLAYER,""),
                      family = "HiraKakuPro-W3"))