【入門】変動係数を使って『ガチャ感』のある選手を探そう!(R編)【バスケのデータ分析】

こんにちは、らんそうるい(@rnsr0371)です。この記事では、バスケのデータ分析をやってみたい! という人向けに、一緒にコード(Rを使います)を書きながら、バスケのデータ分析を行ってみます。データハンドリング〜分析結果の出力までお付き合いください。テーマは変動係数という統計的な指標を使って『ガチャ感』のある選手を探そう! です。
この記事は【入門】変動係数を使って『ガチャ感』のある選手を探そう!(Python編)【バスケのデータ分析】のR版です。分析結果は当然同じですので、Python使いの方はPython編をご覧ください。
想定している読者は次のような感じです。
  • Rで四則演算ができる
  • RStudioを導入済み
  • tidyverseチョットワカル (パイプ処理を多用します)
  • バスケに限らず、データ分析が初めて
分析に用いたコードはGitHub上にアップされています。

『ガチャ感』と変動係数――日常用語を統計的な用語に落とし込もう!

まず『ガチャ感』という日常用語を統計的な用語に翻訳するために『ガチャ感』について考えます。次の2選手の試合ごとの得点について『ガチャ感』を感じるのはどちらでしょうか?
  • 選手A:20,20,20,20,20(一試合平均20点)
  • 選手B:10,30,10,30,20(一試合平均20点)
おそらく選手Bの方がAより『ガチャ感』が強いと感じるのではないかと思います。でも、この2選手で平均得点は同じです。つまり『ガチャ感』は平均得点ではない何かです。 ここで分散という統計的な指標について考えてみます。分散$s^2$はデータ(ここでは一試合ごとの得点)のばらつきを表す指標で、次のように定義されます。$$s^2=\frac{1}{n}\sum_{i=1}^{n}(x_i-\bar{x})^2$$ここで、$\bar{x}$は平均、$i$はデータの番号、$n$はデータの個数です。つまり「各データの平均からの距離の2乗」の平均値です。です。選手Aと選手Bの分散を計算すると、選手Aは分散0、選手Bは分散80となります。選手AとBでは平均得点は同じですが、得点の分散は選手Bの方が大きいことが分かりました。分散の意味――ばらつきを数値化したものからも『ガチャ感』――試合ごとに出来に当たり外れがあると対応があるように私は感じます。
統計学の世界ではばらつきを表す指標は分散以外にもあります。分散の一つの難しさとして、計算結果が測定単位の2乗になってしまうということが挙げられます。つまり、分散の平方根をとってあげれば、測定単位が元に戻ります。分散の平方根のことを標準偏差といいます。
標準偏差を使っても、まだ問題は残ります。バスケの世界ではスター選手が平均20得点以上を記録するのに対して、ロールプレイヤーは平均10得点未満のこともしばしばです。平均が大きく異なるデータ同士の散らばりの比較は標準偏差では不適切です。スター選手のほうが標準偏差が大きくなりやすいからです。そこで、標準偏差を平均で割ってあげた指標、変動係数を算出してあげると良さげだと思います。変動係数(CV, coefficient of variation)の定義を書くと、$$CV=\frac{s}{\bar{x}}$$です。
以上の話をまとめると『ガチャ感』はデータの散らばりによって感じられる。統計学の世界ではデータの散らばりを評価する指標がいくつかあるが、バスケの特性(スター選手とロールプレイヤーでは平均得点にかなり差がある)を踏まえると変動係数を使ってばらつきを評価すると良さそう。となります。あとは、データを準備し、Pythonを走らせて、各選手の得点の変動係数を算出し、ランキングを表示させてあげれば『ガチャ感』のある選手を見つけられそうです。

データを用意しよう!

データ分析をするためにはデータが必要です。これはとても幸運なことだと思うのですが、バスケのデータ分析界隈には増田林太郎様という神がおられて、GitHub上にBリーグの各試合のボックススコアなどを公開されています。このデータはとても綺麗で前処理が必要ないので、このデータを生データとして使うことにします。teams.csvとgames_boxscore_202021.csvをダウンロードしてください。そして、列名を確認しておいてください。

分析しよう!

データの整形

では、まず必要なライブラリをインポートします。ここではtidyverseというライブラリを使います。tidyverseは便利なライブラリを集めたものだと思っていただければ大丈夫です。
library(tidyverse)
次に先程ダウンロードした.csvファイルをインポートします。「相対パス」「絶対パス」などで検索すれば、書き方は分かると思います。
teams=read_csv("../data/teams.csv")
boxscore=read_csv("../data/games_boxscore_202021.csv")
teamsとboxscoreを整形していきます。まず、teamsからB1 2020-21シーズンのTeamIdを取り出します。この作業はboxscoreからB1の選手のデータだけを取り出すために必要です。
teams=teams %>% filter(.,League=="B1") %>% filter(.,Season=="2020-21")
次にteamsとboxscoreをTeamIdで連結して、B1の選手だけを抜き出します。
boxscore=teams %>% left_join(boxscore,by="TeamId")
続いて、シーズンの平均スタッツと標準偏差を得るために、Playerごとに平均・標準偏差を集計します。
data=boxscore %>% group_by(.,Player) %>% summarise(avg=mean(PTS),std=sd(PTS),MIN=mean(MIN))
これでお目当てのデータセットが得られたはずです。

変動係数の計算

変動係数(CV)を計算しましょう!
data=data %>% mutate(CV=std/avg)

ランキングの表示

では、ランキングの表示させましょう! 平均20分以上出場している選手の中で、変動係数が高い選手TOP10を表示してみます。
data %>% filter(MIN>=20) %>% arrange(desc(CV)) %>% head(10)
どうでしょうか? ガチャ感強い選手が挙がっているでしょうか? 絞り込みの条件を変えてランキングを作ってみましょう! 平均得点が10点以上の選手で変動係数が高い選手TOP10を表示させてみます。
data %>% filter(avg>=10) %>% arrange(desc(CV)) %>% head(10)
もちろん、変動係数が小さい選手(試合ごとのムラが小さい選手)のランキングを作ることもできます。自分でコードを変えて試してみてください。

終わりに

お付き合いいただきありがとうございました。推測統計や機械学習の高度な手法を使わなくても、意外と面白いことができるというのが実感していただけると嬉しいです。
Rは独特なプログラミング言語だと言われているらしいのですが、私はプログラミングをRから入門したのであまり違和感を感じずに済んでいます。tidyverseのパイプ(%>%)を書くのは楽しいです。
もしPython編も合わせて、この記事が好評だったら、単純な可視化(データの見える化)でも面白いことができる! という記事を書きたいと思っています。よろしければTwitterなどで拡散していただけると嬉しいです。

Follow me!

コメントを残す

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

CAPTCHA