メジャーリーグのデータ解析をしたい (ダルビッシュがすごい)
序論
Rを使ってメジャーリーグのデータ解析がしたいです.
全ての試合結果データが公開されています.
retrosheetという名前で, 無料で使えます.
http://www.retrosheet.org/game.htm
せっかくなので使います.
データの内容と整形
全試合の出場選手とその全打席結果データがダウンロードできます.
http://www.retrosheet.org/game.htm
2013年のデータを見てみます.
Regular Season のEvent Fileを落とします. 2013eve.zipです.
zipを展開すると, たくさんのファイルが
gghatano:2013eve taku$ ls 2013ANA.EVA 2013LAN.EVN 2013TBA.EVA COL2013.ROS SDN2013.ROS 2013ARI.EVN 2013MIA.EVN 2013TEX.EVA DET2013.ROS SEA2013.ROS 2013ATL.EVN 2013MIL.EVN 2013TOR.EVA HOU2013.ROS SFN2013.ROS 2013BAL.EVA 2013MIN.EVA 2013WAS.EVN KCA2013.ROS SLN2013.ROS 2013BOS.EVA 2013NYA.EVA ANA2013.ROS LAN2013.ROS TBA2013.ROS 2013CHA.EVA 2013NYN.EVN ARI2013.ROS MIA2013.ROS TEAM2013 2013CHN.EVN 2013OAK.EVA ATL2013.ROS MIL2013.ROS TEX2013.ROS 2013CIN.EVN 2013PHI.EVN BAL2013.ROS MIN2013.ROS TOR2013.ROS 2013CLE.EVA 2013PIT.EVN BOS2013.ROS NYA2013.ROS WAS2013.ROS 2013COL.EVN 2013SDN.EVN CHA2013.ROS NYN2013.ROS 2013DET.EVA 2013SEA.EVA CHN2013.ROS OAK2013.ROS 2013HOU.EVA 2013SFN.EVN CIN2013.ROS PHI2013.ROS 2013KCA.EVA 2013SLN.EVN CLE2013.ROS PIT2013.ROS
行われた試合の動きが各チームごとに記録されています.
Rで扱いやすい形にしたいです.
csvファイルにして整理します.
Analysing Baseball Data with Rで提供されるコードを改変して, 整形用スクリプトを作って適用します.
整形の手法は後日詳しく説明します.
使用結果です. 整形したデータファイルはgithubにあります.
> data2013 <- read.csv("all2013.csv") > names(data2013) <- read.csv("fields.csv")[,"Header"] > dim(data2013) [1] 190907 97 > > head(data2013)[,1:10] GAME_ID AWAY_TEAM_ID INN_CT BAT_HOME_ID OUTS_CT BALLS_CT STRIKES_CT PITCH_SEQ_TX AWAY_SCORE_CT HOME_SCORE_CT 1 ANA201304090 OAK 1 0 0 0 1 CX 0 0 2 ANA201304090 OAK 1 0 1 2 2 CBCFBX 0 0 3 ANA201304090 OAK 1 0 2 3 1 BBCBB 0 0 4 ANA201304090 OAK 1 0 2 3 1 BBCBB 0 0 5 ANA201304090 OAK 1 0 2 3 1 BCBBX 0 0 6 ANA201304090 OAK 1 0 2 0 0 X 1 0
97変数で1つの打席の状態と結果を表しています.
全打席は190,907回あったみたいです.
...変数が多すぎて分かりません.
説明はここに書いてあります.
http://www.retrosheet.org/eventfile.htm
よくわかりました.
試合の動きを少しだけ確認します.
試合開始直後から, アウトカウントと得点, 打席の内容とその結果の様子を抜き出しました.
> head(data2013)[c("OUTS_CT", "AWAY_SCORE_CT","PITCH_SEQ_TX","EVENT_TX")] OUTS_CT AWAY_SCORE_CT PITCH_SEQ_TX EVENT_TX 1 0 0 CX 53/G 2 1 0 CBCFBX 63/G 3 2 0 BBCBB W 4 2 0 BBCBB W.1-2 5 2 0 BCBBX S8/G.2-H;1-2 6 2 1 X S56/L+.2-3;1-2
暗号解読です.
PITCH_SEQ_TXは投球結果です. 以下の通りらしいです.
この表を使って解読します.
+ following pickoff throw by the catcher
* indicates the following pitch was blocked by the catcher
. marker for play not involving the batter
1 pickoff throw to first
2 pickoff throw to second
3 pickoff throw to third
> Indicates a runner going on the pitch
B ball
C called strike
F foul
H hit batter
I intentional ball
K strike (unknown type)
L foul bunt
M missed bunt attempt
N no pitch (on balks and interference calls)
O foul tip on bunt
P pitchout
Q swinging on pitchout
R foul ball on pitchout
S swinging strike
T foul tip
U unknown or missed pitch
V called ball because pitcher went to his mouth
X ball put into play by batter
Y ball put into play on pitchout
めんどくさい.
暗号解読. 再掲. 試合開始からの動き.
> head(data2013)[c("OUTS_CT", "AWAY_SCORE_CT","PITCH_SEQ_TX","EVENT_TX")] OUTS_CT AWAY_SCORE_CT PITCH_SEQ_TX EVENT_TX 1 0 0 CX 53/G 2 1 0 CBCFBX 63/G 3 2 0 BBCBB W 4 2 0 BBCBB W.1-2 5 2 0 BCBBX S8/G.2-H;1-2 6 2 1 X S56/L+.2-3;1-2
先頭打者から見ていきます.
投球結果はCX.
CXはcalled strike からの ball put into play by batterです.
つまり, 初球は見逃しストライク.
2球目がバットにあたってインフィールドに飛んだ, ということでしょうね.
その結果は. EVENT_TX.
53/Gはサードからファーストに送球されたゴロ, ということです.
つまり, サードゴロで1アウト.
2人目.
CBCFBXは
見逃し, ボール, 見逃し, ファウルボール, ヒッティング.
打ったボールは63/G. 6はショート. 3はファースト. Gはゴロ
つまりショートゴロでファースト送球で2アウト.
3人目はBBCBBで四球.
4人目はBBCBBで四球. ランナーは1塁から2塁へ.
5人目は5球目を当てました. S8はセンターへのSingleヒットです.
ランナーは2塁からホーム(Home)へ, 1塁ランナーは2塁へ.
アウェイチームが1点とったのでAWAY_SCOREが増えています.
細かいですが, ほとんど全ての試合進行が把握できますね.
試合と選手でデータを統合すれば, 各選手の試合ごとの成績が得られます.
これでなんでもできますね!
ダルビッシュの成績推移を知りたい.
試合ごとの結果がわかるので, 成績の変化もわかります.
今回は2013年のダルビッシュの各種成績の推移を視覚化します.
タイトルを取った奪三振から.
結論
ダルビッシュすごい
この成績でどうして13勝9敗なんですかね
ソースコード
扱うcsvファイルは2種類です.
2013年の試合結果が詰まったデータファイルがall2013.csv
変数のラベルつけ用のcsvファイルがfields.csvです.
偉いからgithubにまとめました.
https://github.com/gghatano/AnalyzingBaseballData
グラフ描画のためのRソースコードです.
csvファイルが有る場所で実行すればOKです.
library(plyr) # setwd("csvファイルがある場所") # 2013年の整形済みデータを利用 data2013 <- read.csv("all2013.csv", header= FALSE) fields <- read.csv("fields.csv") names(data2013) <- fields[, "Header"] # playerIDをつけます dar.id <- "darvy001" iwakuma.id <- "iwakh001" verland.id <- "verlj001" # 選手ごとにデータを抽出 dar.data <- subset(data2013, PIT_ID ==dar.id) iwakuma.data <- subset(data2013, PIT_ID ==iwakuma.id) verland.data <- subset(data2013, PIT_ID ==verland.id) # データをまとめる関数 createdata <- function(d){ # 試合の日にちを抽出 d$Date <- as.Date(substr(d$GAME_ID, 4, 11), format = "%Y%m%d") d <- arrange(d, Date) # 三振のデータが欲しいなら EVENT_CD は3です d$SO <- ifelse(d$EVENT_CD == 3, 1, 0) d$cumSO <- cumsum(d$SO) d[, c("Date", "cumSO")] } dar.SOdata <- createdata(dar.data) iwakuma.SOdata <- createdata(iwakuma.data) verland.SOdata <- createdata(verland.data) # 適当にプロット plot(dar.SOdata, type ="l", lwd =2,xlab = "Date(Month)", ylab = "SO") lines(iwakuma.SOdata, lwd = 2, col = "grey") lines(verland.SOdata, lwd = 2, col = "red") legend("topleft", legend = c(paste("Darvish (", max(dar.SOdata$cumSO), ")", sep=""), paste("Iwakuma (", max(iwakuma.SOdata$cumSO), ")", sep=""), paste("Verlander (", max(verland.SOdata$cumSO), ")", sep="")), lwd = 2, col = c("black", "grey", "red"))
EVENT_CDの対応表.
Unknown event
1 No event
2 Generic out
3 Strikeout
4 Stolen base
5 Defensive indifference
6 Caught stealing
7 Pickoff error
8 Pickoff
9 Wild pitch
10 Passed ball
11 Balk
12 Other advance
13 Foul error
14 Walk
15 Intentional walk
16 Hit by pitch
17 Interference
18 Error
19 Fielder's choice
20 Single
21 Double
22 Triple
23 Home run
24 Missing play
なので, さっきのコードで
# 三振のデータが欲しいなら EVENT_CD は3です d$SO <- ifelse(d$EVENT_CD == 23, 1, 0) # 3 を 23にするとホームランになります.
被本塁打数もすぐに分かります.
参考文献
Analyzing Baseball Data with R (Chapman & Hall/CRC The R Series)
- 作者: Max Marchi
- 出版社/メーカー: Chapman and Hall/CRC
- 発売日: 2013/10/30
- メディア: Kindle版
- この商品を含むブログを見る