NBAジャパンゲームに向けてロケッツ、ラプターズの両チームが日本入りしましたね。NBAも2019-20シーズン開始に向けて盛り上がってきました。
この記事は以下の記事の続きみたいなものですが、NBAのデータAPIを使って昨シーズンの渡邊雄太の全シュート(フリースローは除く)51本のデータを見てみたいと思います。
渡邊雄太のデータは昨シーズンのものですが、NBAって過去のゲームも含めてすごいデータがたくさん揃っているんですよね。かなり感心してます。
2003年10月29日、CLE vs SACでデビューしたレブロン・ジェームス。彼がNBAで初めて放ったシュートは1Q残り8分56秒時点、リングの右側0度15フィートの所からのジャンプショットで、見事に決まりました。
— 増田林太郎 / Rintaro Masuda (@rintaromasuda) October 4, 2019
……みたいなデータが記録されていていつでも取得できるのすごくないですか?さすがNBA!
ちなみにこの記事は分析するのが目的ではなく、APIを使ったデータ取得方法を解説するのが主な目的です。コード中のIDを変更すれば、もちろん他の選手のデータも取得できます。
IDはNBAのスタッツのサイトに行くと取得できます。渡邊雄太とメンフィス・グリズリーズのIDは以下のURLの一部となっていることが分かると思います。
https://stats.nba.com/player/1629139/
https://stats.nba.com/team/1610612763/
以下がデータ取得用にRで書いたコードです。データは取得後にCSVファイルとなって保存されるはずです。その後はExcelなりなんなりで分析できるはずです*1。
if(!require(httr)) { install.packages("httr") library(httr) } if(!require(jsonlite)) { install.packages("jsonlite") library(jsonlite) } player_id <- "1629139" # Yuta Watanabe team_id <- "1610612763" # Memphis Grizzlies season <- "2018-19" # Empty ifyou want all seasons url <- paste0("https://stats.nba.com/stats/shotchartdetail", "?PlayerID=", player_id, "&Season=", season, "&SeasonType=Regular+Season", "&TeamID=", team_id, "&ContextMeasure=", "FGA", "&AheadBehind=&ClutchTime=&ContextFilter=", "&DateFrom=&DateTo=&EndPeriod=&EndRange=", "&GameID=&GameSegment=&LastNGames=0&LeagueID=00", "&Location=&Month=0&OpponentTeamID=0&Outcome=", "&Period=0&PlayerPosition=&PointDiff=&Position=&RangeType=", "&RookieYear=&Season=&SeasonSegment=&StartPeriod=&StartRange=", "&VsConference=&VsDivision=") httpResponse = GET(url, add_headers(Referer = "http://stats.nba.com"), accept_json()) res <- content(httpResponse) col_names <- res$resultSets[[1]]$headers num_rows <- length(res$resultSets[[1]]$rowSet) df_shots <- data.frame() for (i in 1:num_rows) { arrayRow <- as.character(res$resultSets[[1]]$rowSet[[i]]) df <- as.data.frame(matrix(arrayRow, nrow = 1), stringsAsFactors = FALSE) colnames(df) <- col_names df_shots <- rbind(df_shots, df) } file_name <- paste0(paste("NBA_Shots", player_id, team_id, season, "_"), ".csv") write.csv(df_shots, file = file_name, row.names = FALSE)
せっかくなんで少しだけデータを見てみましょう。ちなみに同ファイルを以下にアップロードしておきましたので、生データを見たい人はそちらを参照して下さい。
2P vs 3P
2Pシュートを35本、3Pシュートを16本打ちました。決まった3Pシュートはわずか2本でした。
SHOT_TYPE | Attempt | Made | Pct |
---|---|---|---|
2PT Field Goal | 35 | 13 | 0.37 |
3PT Field Goal | 16 | 2 | 0.12 |
シュートエリア
左側から放った17本のシュートの内、決まったのは1本だけでした。この本数で左側が苦手と結論はできないと思いますが、確かに渡邉のハイライトを思い出してみるとセンターか右側が多い気はします。
SHOT_ZONE_AREA | Attempt | Made | Pct |
---|---|---|---|
Center(C) | 27 | 11 | 0.41 |
Left Side Center(LC) | 8 | 0 | 0.00 |
Left Side(L) | 9 | 1 | 0.11 |
Right Side Center(RC) | 3 | 2 | 0.67 |
Right Side(R) | 4 | 1 | 0.25 |
こちらは以下のショットチャートからも明らかです。ちなみにこのチャートはballrという素晴らしいツールを使って得たものです。こちらのツールも同じAPIを利用していると思います。
シュートの種類
NBAのデータではかなり細かくシュートの種類がカテゴライズされているようです。Pullup Jump ShotとJump Shot両方があるということは、Jump Shotはキャッチアンドシュートであることが想像できます。
SHOT_TYPE | ACTION_TYPE | Attempt | Made | Pct |
---|---|---|---|---|
2PT Field Goal | Cutting Finger Roll Layup Shot | 1 | 1 | 1.00 |
2PT Field Goal | Driving Dunk Shot | 1 | 1 | 1.00 |
2PT Field Goal | Driving Finger Roll Layup Shot | 1 | 1 | 1.00 |
2PT Field Goal | Driving Floating Bank Jump Shot | 1 | 0 | 0.00 |
2PT Field Goal | Driving Floating Jump Shot | 2 | 1 | 0.50 |
2PT Field Goal | Driving Hook Shot | 2 | 0 | 0.00 |
2PT Field Goal | Driving Layup Shot | 2 | 1 | 0.50 |
2PT Field Goal | Dunk Shot | 1 | 1 | 1.00 |
2PT Field Goal | Fadeaway Jump Shot | 1 | 0 | 0.00 |
2PT Field Goal | Floating Jump shot | 1 | 0 | 0.00 |
2PT Field Goal | Jump Shot | 5 | 1 | 0.20 |
2PT Field Goal | Pullup Jump shot | 5 | 2 | 0.40 |
2PT Field Goal | Running Alley Oop Layup Shot | 1 | 1 | 1.00 |
2PT Field Goal | Running Jump Shot | 1 | 0 | 0.00 |
2PT Field Goal | Running Layup Shot | 3 | 1 | 0.33 |
2PT Field Goal | Tip Layup Shot | 1 | 0 | 0.00 |
2PT Field Goal | Turnaround Fadeaway Bank Jump Shot | 1 | 1 | 1.00 |
2PT Field Goal | Turnaround Fadeaway shot | 1 | 0 | 0.00 |
2PT Field Goal | Turnaround Jump Shot | 4 | 1 | 0.25 |
3PT Field Goal | Jump Shot | 12 | 2 | 0.17 |
3PT Field Goal | Pullup Jump shot | 1 | 0 | 0.00 |
3PT Field Goal | Running Jump Shot | 2 | 0 | 0.00 |
3PT Field Goal | Running Pull-Up Jump Shot | 1 | 0 | 0.00 |
渡邉のプレースタイルと役割を思えば当然ですが、キャッチアンドシュートの本数が一番多いですね。そして一番苦労しているのもここ。2019-20シーズンは向上した数値が見られると良いですね。
シュートの距離
上のチャートで明らかではありますが、ミドルレンジ、それより長い距離はかなり苦戦していますね。
SHOT_DISTANCE (ft) | Attempt | Made | Pct |
---|---|---|---|
0 | 4 | 3 | 0.75 |
1 | 3 | 3 | 1.00 |
2 | 4 | 1 | 0.25 |
4 | 1 | 0 | 0.00 |
5 | 1 | 1 | 1.00 |
6 | 2 | 1 | 0.50 |
7 | 1 | 0 | 0.00 |
8 | 3 | 1 | 0.33 |
10 | 1 | 0 | 0.00 |
11 | 2 | 1 | 0.50 |
12 | 2 | 1 | 0.50 |
13 | 2 | 0 | 0.00 |
14 | 3 | 0 | 0.00 |
15 | 1 | 0 | 0.00 |
17 | 2 | 0 | 0.00 |
18 | 3 | 1 | 0.33 |
22 | 3 | 0 | 0.00 |
23 | 3 | 1 | 0.33 |
24 | 2 | 0 | 0.00 |
25 | 4 | 0 | 0.00 |
26 | 2 | 1 | 0.50 |
27 | 2 | 0 | 0.00 |
まとめ
あまり試していないのですが、APIをコールするときのパラメータをいじればもっと面白い情報が返ってくるかもしれません*2。
NBAで活躍する日本人選手も増えてきて、こういったデータを触りたい人も増えるかと思って記事を書いてみました。いや、増えろ。
こういう情報がBリーグでも利用できるようになるのはいつかなー。
追記 (2019.12.13)
NBA APIの仕様変更に併せてRのコードを変更しました。
*1:stats.nba.comのサイトはAPIのアクセスやサイトのスクレイピングを防ぐ為の施策が施されているようで、環境によってはアクセスが妨げられレスポンスが返ってこない場合があります。User-AgentヘッダーやAcceptヘッダーの追加などで回避できる場合もあるようですが、詳細は不明です。
*2:ここのドキュメント群を見ると、他のAPIも併せて多少パラメータ調整の参考になります。