일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Statistics
- MongoDB
- 김양재
- WebGL
- 데이터 과학
- 빅데이터
- 몽고디비
- 빅데이타
- 빅 데이터
- 주일설교
- 빅 데이타
- 김양재 목사님
- node.js
- probability
- Machine Learning
- nodeJS
- 김양재 목사
- Big Data
- openCV
- R
- 우리들교회
- data science
- 딥러닝
- No SQL
- 통계
- Artificial Intelligence
- c++
- Deep learning
- 인공지능
- 확률
- Today
- Total
Scientific Computing & Data Science
[Data Science / Baseball] 온라인 야구 데이터를 MongoDB에 저장하기 본문
[Data Science / Baseball] 온라인 야구 데이터를 MongoDB에 저장하기
cinema4dr12 2017. 3. 23. 23:01Retrosheet는 메이저리그 야구의 play-by-play Game Logs를 .zip 압축 파일 형태로 제공한다.
Game Logs를 분석하기 위해 Retrosheet 웹사이트에서 일일이 .zip 파일들을 다운받아 압축을 풀어 불러올 수 있겠지만 여간 번거로운 것이 아닐 것이다.
이번 포스팅에서는 Retrosheet 웹사이트가 제공하는 Game Logs 파일들을 다운받아 CSV 형식으로 Data Frame에 저장하고 이를 MongoDB에 저장하고 또한 DB로부터 데이터를 불러오는 방법에 대하여 설명하도록 하겠다.
우선 Retrosheet 웹사이트를 방문하면 상단에 Data downloads > Game logs를 클릭한다.
Game logs 페이지에 보면 1871년부터 2016년까지의 Game Logs 파일에 대한 링크들을 볼 수 있을 것이다.
이 중 하나를 클릭해 보자. 가령, 2016년도 Game Log를 클릭하면, gl2016.zip 파일이 다운로드 될 것이다.
이들 각각의 파일 링크 주소는 다음과 같은 형식이다:
http://www.retrosheet.org/gamelogs/gl{YEAR}.zip
결국 이 경로에 연도만 바꿔주면 이들 모두를 일괄 처리할 수 있는 것이다.
이제 MongoDB를 실행한다:
$ mongod --dbpath {YOUR_MONGODB_DATA_PATH}
이제 R에서 mongolite 라이브러리 패키지를 불러오고,
R CODE:
## intall packages & load them if (! ("mongolite" %in% rownames(installed.packages()))) { install.packages("mongolite") } base::library(mongolite)
MongoDB의 Document Collection을 입력받아 connection을 수립하는 함수를 작성한다:
R CODE:
################################################################################################ ## MongoDB connection Connect <- function(colName) { con <- mongolite::mongo(collection = colName, db = "baseball", url = "mongodb://localhost", verbose = TRUE, options = ssl_options()) return(con) }
Document Collection 이름과 Data Frame을 입력받아 이 Data Frame을 MongoDB의 해당 Document Collection에 저장하는 함수를 작성한다:
R CODE:
################################################################################################ ## MongoDB insert InsertDataFrameToDB <- function(colName, df) { con <- Connect(colName); ## drop DB if any if(con$count() > 0) con$drop(); ## insert document as data frame con$insert(df); ## disconnect base::rm(con); }
이제 다운받을 Game Logs 연도 시퀀스를 정의한다 (1871~2016년까지로 정하였다):
R CODE:
seq_range <- base::seq(from = 1871, to = 2016, by = 1)
Retrosheet의 Game Logs의 .zip 파일들을 임시로 저장할 임시 경로를 생성한다:
R CODE:
temp <- base::tempfile()
R의 빌트-인(Built-in) 함수인 utils::download.file()를 각 경로의 파일들을 임시 경로에 다운받는다:
R CODE:
filePath <- base::sprintf("http://www.retrosheet.org/gamelogs/gl%d.zip", year) utils::download.file(filePath, temp)
year는 seq_range로부터 차례로 불러오는 1871년부터 2016년까지의 연도이다.
Document Collection의 이름과 파일이름을 해당년도에 따라 순차적으로 정한다:
R CODE:
collectionName <- base::sprintf("GameLog%04d", year) fileName <- base::sprintf("GL%04d.TXT", year)
R의 base::unz() 함수를 이용하여 해당 .zip 파일의 압축을 풀고, 이를 read.csv() 파일을 이용하여 Data Frame 형식으로 저장한다:
R CODE:
data <- utils::read.csv(base::unz(temp, fileName))
한 가지 고려해야 할 사항은, 변수 data가 Data Frame임에도 열 이름(Column Names)가 정해져 있지 않다는 것이다. 열 이름이 정해져 있지 않으면 데이터 처리에 오류를 가져올 수 있으므로 열의 개수(곧, Features 수) 만큼 X1, X2, X3, ... 형식으로 적당한 이름을 붙인다 - 구체적인 이름을 붙이기에는 열의 개수가 매우 많다.
R CODE:
for(i in 1:base::ncol(df)) { names(df)[i] <- base::sprintf("X%d", i) }
이를 앞서 정의한 InsertDataFrameToDB() 함수를 이용하여 MongoDB에 저장한다:
R CODE:
InsertDataFrameToDB(colName = collectionName, df = data)
Loop가 모두 완료되면, 파일을 다운로드하기 위해 임시로 생성한 경로의 링크를 해제한다:
R CODE:
base::unlink(temp)
지금까지 언급한 일련의 과정에 대한 전체 R Code는 다음과 같다:
R Code:
코드를 실행하여 1871년부터 2016년까지 MongoDB에 저장하는데 걸린 시간은 5분 정도였다.
Robomongo를 이용하여 데이터가 잘 들어왔는지 확인해 보자:
데이터가 모두 잘 들어왔음을 알 수 있다.
마지막으로 DB에 저장된 데이터를 Data Frame으로 불러오는 코드를 작성해 본다:
R CODE:
## intall packages & load them if (! ("mongolite" %in% rownames(installed.packages()))) { install.packages("mongolite") } base::library(mongolite) ################################################################################################ ## MongoDB connection Connect <- function(colName) { con <- mongolite::mongo(collection = colName, db = "baseball", url = "mongodb://localhost", verbose = TRUE, options = ssl_options()) return(con) } ################################################################################################ ## Import document collection from MongoDB ImportCollection <- function(colName) { con <- Connect(colName); df <- con$find(query = '{}'); rm(con); return(df); } df <- ImportCollection("GameLog2016")
df에 이를 데이터가 잘 불러와졌는지 확인한다:
> head(df)
X20160403 X0 Sun NYN NL X1 KCA AL X1_1 X3 X4 X51 N X X_2 KAN06 X40030 X193 X000000030 X10010200x X33 X7 X1_2 X0_1
1 20160403 0 Sun TOR AL 1 TBA AL 1 5 3 54 D STP01 31042 171 200100020 001000002 35 7 1 0
2 20160403 0 Sun SLN NL 1 PIT NL 1 1 4 51 D PIT08 39500 182 000000001 02000101x 32 5 0 0
3 20160404 0 Mon CHN NL 1 ANA AL 1 9 0 54 N ANA01 44020 188 100202103 000000000 37 11 3 0
4 20160404 0 Mon MIN AL 1 BAL AL 1 2 3 53 D BAL12 45785 168 000000200 000020001 33 7 3 0
5 20160404 0 Mon CHA AL 1 OAK AL 1 4 3 54 N OAK01 35067 176 004000000 003000000 33 7 1 1
6 20160404 0 Mon TOR AL 2 TBA AL 2 5 3 54 N STP01 15116 178 001310000 010011000 33 7 1 0
X0_2 X3_1 X0_3 X0_4 X0_5 X6 X0_6 X9 X0_7 X1_3 X0_8 X0_9 X9_1 X3_2 X3_3 X3_4 X0_10 X0_11 X24 X15 X1_4 X1_5 X3_5
1 1 5 0 0 0 3 0 16 0 0 0 0 6 2 3 3 1 0 27 15 2 0 0
2 0 1 0 0 1 5 0 14 0 0 1 0 10 3 4 4 0 0 24 11 0 0 2
3 1 9 0 0 0 7 1 12 0 0 1 0 8 3 0 0 0 0 27 9 0 0 1
4 0 2 0 1 1 0 0 10 0 0 0 0 6 6 3 3 1 0 26 5 0 0 0
5 0 2 0 0 2 1 0 6 0 2 0 0 5 5 3 3 0 0 27 9 1 0 0
6 3 5 0 1 0 2 0 9 0 0 0 0 4 5 3 3 1 0 27 8 1 0 0
X0_12 X30 X9_2 X0_13 X0_14 X0_15 X4_1 X0_16 X1_6 X0_17 X2 X0_18 X3_6 X1_7 X0_19 X3_7 X0_20 X5 X5_1 X3_8 X3_9
1 0 35 7 1 0 1 3 0 0 0 1 0 7 0 1 0 0 6 4 4 4
2 0 28 9 2 1 0 4 1 1 1 5 0 5 0 1 1 0 8 4 1 1
3 0 29 3 1 0 0 0 0 0 0 1 0 7 0 0 0 0 3 5 9 9
4 0 36 10 3 0 0 3 0 0 0 5 0 10 1 0 0 0 12 6 2 2
5 0 33 7 2 0 0 3 0 0 0 3 0 10 0 0 0 0 6 6 2 2
6 0 35 8 1 0 1 2 0 0 0 4 0 9 1 0 0 0 9 4 5 5
X0_21 X0_22 X27 X13 X0_23 X0_24 X0_25 X0_26 davig901 Gerry_Davis holbs901 Sam_Holbrook drakr901
1 1 0 27 8 1 0 0 0 everm901 Mike Everitt emmep901 Paul Emmel timmt901
2 0 0 27 8 1 0 1 0 laynj901 Jerry Layne wendh902 Hunter Wendelstedt gibsh902
3 0 0 27 8 1 0 1 0 barrt901 Ted Barrett herna901 Angel Hernandez barkl901
4 0 0 27 6 0 0 0 0 wintm901 Mike Winters wegnm901 Mark Wegner fostm901
5 0 0 27 12 2 0 0 0 hallt901 Tom Hallion cuzzp901 Phil Cuzzi belld901
6 1 0 27 6 0 0 0 0 emmep901 Paul Emmel timmt901 Tim Timmons diazl901
Rob_Drake torrc901 Carlos_Torres X_none_ X_none__1 collt801 Terry_Collins yoste001 Ned_Yost
1 Tim Timmons diazl901 Laz Diaz (none) (none) gibbj001 John Gibbons cashk001 Kevin Cash
2 Tripp Gibson fagac901 Clint Fagan (none) (none) mathm001 Mike Matheny hurdc001 Clint Hurdle
3 Lance Barksdale littw901 Will Little (none) (none) maddj801 Joe Maddon sciom001 Mike Scioscia
4 Marty Foster muchm901 Mike Muchlinski (none) (none) molip001 Paul Molitor showb801 Buck Showalter
5 Dan Bellino morag901 Gabe Morales (none) (none) ventr001 Robin Ventura melvb001 Bob Melvin
6 Laz Diaz everm901 Mike Everitt (none) (none) gibbj001 John Gibbons cashk001 Kevin Cash
volqe001 Edinson_Volquez harvm001 Matt_Harvey daviw001 Wade_Davis hosme001 Eric_Hosmer
1 strom001 Marcus Stroman archc001 Chris Archer osunr001 Roberto Osuna encae001 Edwin Encarnacion
2 lirif001 Francisco Liriano waina001 Adam Wainwright (none) lirif001 Francisco Liriano
3 arrij001 Jake Arrieta richg002 Garrett Richards (none) rizza001 Anthony Rizzo
4 britz001 Zach Britton jepsk001 Kevin Jepsen (none) wietm001 Matt Wieters
5 salec001 Chris Sale hillr001 Rich Hill robed002 David Robertson eatoa002 Adam Eaton
6 dickr001 R.A. Dickey smyld001 Drew Smyly osunr001 Roberto Osuna tulot001 Troy Tulowitzki
harvm001_1 Matt_Harvey_1 volqe001_1 Edinson_Volquez_1 granc001 Curtis_Granderson X9_3 wrigd002 David_Wright
1 strom001 Marcus Stroman archc001 Chris Archer pillk001 Kevin Pillar 8 donaj001 Josh Donaldson
2 waina001 Adam Wainwright lirif001 Francisco Liriano carpm002 Matt Carpenter 5 phamt001 Tommy Pham
3 arrij001 Jake Arrieta richg002 Garrett Richards fowld001 Dexter Fowler 8 heywj001 Jason Heyward
4 sante001 Ervin Santana tillc001 Chris Tillman dozib001 Brian Dozier 4 mauej001 Joe Mauer
5 salec001 Chris Sale hillr001 Rich Hill eatoa002 Adam Eaton 9 rollj001 Jimmy Rollins
6 dickr001 R.A. Dickey smyld001 Drew Smyly pillk001 Kevin Pillar 8 donaj001 Josh Donaldson
X5_2 cespy001 Yoenis_Cespedes X7_1 dudal001 Lucas_Duda X3_10 walkn001 Neil_Walker X4_2 confm001
1 5 bautj002 Jose Bautista 9 encae001 Edwin Encarnacion 10 tulot001 Troy Tulowitzki 6 colac001
2 7 hollm001 Matt Holliday 3 gricr001 Randal Grichuk 8 piscs001 Stephen Piscotty 9 moliy001
3 9 zobrb001 Ben Zobrist 4 rizza001 Anthony Rizzo 3 bryak001 Kris Bryant 5 schwk001
4 3 sanom001 Miguel Sano 9 plout001 Trevor Plouffe 5 rosae001 Eddie Rosario 7 parkb002
5 6 abrej003 Jose Abreu 3 frazt001 Todd Frazier 5 cabrm002 Melky Cabrera 7 garca003
6 5 bautj002 Jose Bautista 9 encae001 Edwin Encarnacion 10 tulot001 Troy Tulowitzki 6 colac001
Michael_Conforto X10 cabra002 Asdrubal_Cabrera X6_1 darnt001 Travis_d_Arnaud X2_1 lagaj001 Juan_Lagares X8
1 Chris Colabello 3 saunm001 Michael Saunders 7 martr004 Russell Martin 2 goinr001 Ryan Goins 4
2 Yadier Molina 2 wongk001 Kolten Wong 4 gyorj001 Jedd Gyorko 6 waina001 Adam Wainwright 1
3 Kyle Schwarber 7 solej001 Jorge Soler 10 montm001 Miguel Montero 2 russa002 Addison Russell 6
4 Byung Ho Park 10 escoe001 Eduardo Escobar 6 suzuk001 Kurt Suzuki 2 buxtb001 Byron Buxton 8
5 Avisail Garcia 10 lawrb002 Brett Lawrie 4 navad001 Dioner Navarro 2 jacka001 Austin Jackson 8
6 Chris Colabello 3 saunm001 Michael Saunders 7 goinr001 Ryan Goins 4 tholj001 Josh Thole 2
escoa003 Alcides_Escobar X6_2 mousm001 Mike_Moustakas X5_3 cainl001 Lorenzo_Cain X8_1 hosme001_1
1 forsl001 Logan Forsythe 4 morrl001 Logan Morrison 3 longe001 Evan Longoria 5 dickc002
2 jasoj001 John Jaso 3 mccua001 Andrew McCutchen 8 freed001 David Freese 5 marts002
3 escoy001 Yunel Escobar 5 navad002 Daniel Nava 7 troum001 Mike Trout 8 pujoa001
4 machm001 Manny Machado 5 jonea003 Adam Jones 8 davic003 Chris Davis 3 trumm001
5 burnb002 Billy Burns 8 lowrj001 Jed Lowrie 4 reddj001 Josh Reddick 9 valed001
6 forsl001 Logan Forsythe 4 morrl001 Logan Morrison 3 longe001 Evan Longoria 5 dickc002
Eric_Hosmer_1 X3_11 morak001 Kendrys_Morales X10_1 gorda001 Alex_Gordon X7_2 peres002 Salvador_Perez
1 Corey Dickerson 10 jennd002 Desmond Jennings 7 millb002 Brad Miller 6 souzs001 Steven Souza
2 Starling Marte 7 cervf001 Francisco Cervelli 2 polag001 Gregory Polanco 9 harrj002 Josh Harrison
3 Albert Pujols 10 calhk001 Kole Calhoun 9 cronc002 C.J. Cron 3 simma001 Andrelton Simmons
4 Mark Trumbo 9 wietm001 Matt Wieters 2 alvap001 Pedro Alvarez 10 hardj003 J.J. Hardy
5 Danny Valencia 5 davik003 Khris Davis 7 butlb003 Billy Butler 10 canhm001 Mark Canha
6 Corey Dickerson 10 jennd002 Desmond Jennings 7 millb002 Brad Miller 6 souzs001 Steven Souza
X2_2 infao001 Omar_Infante X4_3 fuenr001 Reymond_Fuentes X9_4 X_5 Y
1 9 kierk001 Kevin Kiermaier 8 congh001 Hank Conger 2 Y
2 4 mercj002 Jordy Mercer 6 lirif001 Francisco Liriano 1 Y
3 6 perec003 Carlos Perez 2 giavj001 Johnny Giavotella 4 Y
4 6 schoj001 Jonathan Schoop 4 rickj001 Joey Rickard 7 Y
5 3 vogts001 Stephen Vogt 2 semim001 Marcus Semien 6 Y
6 9 kierk001 Kevin Kiermaier 8 casac001 Curt Casali 2 Y
이로써 이번 포스팅을 마친다.
by Geol Choi |
'Data Science > Baseball Data Analysis' 카테고리의 다른 글
[Data Science / Baseball] rvest 패키지를 이용하여 웹페이지로부터 야구 데이터 가져오기 (0) | 2017.05.09 |
---|---|
[Data Science / Baseball] Retrosheet의 Game Log 데이터로부터 MLB 역대 관중수 알아보기 (1) | 2017.04.05 |
[Data Science / Baseball] Lahman 데이터를 이용한 야구 데이터 분석 Part 3. (0) | 2017.03.09 |
[Data Science / Baseball] Lahman 데이터를 이용한 야구 데이터 분석 Part 2. (0) | 2017.03.04 |
[Data Science / Baseball] Lahman 데이터를 이용한 야구 데이터 분석 Part 1. - 데이터 준비 (2) | 2017.03.02 |