環境:
- OS: Mac OS X El Capitan (10.11)
- python: 2.7.10
- package install: Homebrew
- database: MySQL (SQLite, PostgreSQLも可)
- 参考: 最強の野球オープンデータ「Retrosheet」をPythonでHackしてゲームに勝つる何かを作ろう(序章)(今回とても参考にさせていただきました!!)
※なお今回はHomebrew、python、pipなどは導入済として話を進めていきます
#はじめに
この記事はセイバーメトリクスのような野球データの分析を自分でもやってみたい!と思ったときに、僕がやった必要なデータをもってきてデータベースに入れるところまでの流れをまとめたものです。
※なおMySQLを使ったのは今回が初めてなので、間違い等ありましたらご指摘いただけると喜びます。
#きっかけ
2015/10/29現在、日本ではソフトバンクが日本シリーズで優勝し、ワールドシリーズではロイヤルズが2連勝と非常に盛り上がっていて、野球好きの自分にとっては一番好きなシーズンです。
そんな僕がなぜセイバーに興味を持ったかというと、最初はデータ分析の勉強がしたいなーというのがきっかけでした。そうしてどんなデータをどうやって解析したら一番身につくかと考えたところ、辿り着いたのが自分の好きな野球のデータをとPythonでHackする、ということでした。
ですので同じようなことを考えている方にとってこの記事が少しでも参考になれば幸いです。
#Retrosheet
残念ながらNPBに関しては、MLBほど詳細なデータは公開されておらずダウンロードすることはできません(スクレイピングにより集めることは一応可能)。
そこで今回はMLBのデータをRetrosheet(他にもLahmanなどがある)からダウンロードして、データベースにぶちこんでみます。
#(1) py-retrosheet, Chadwick
Retrosheetのデータはそのままでは非常に読みにくく、データクリーニングが非常にめんどくさい。ただそんなデータを綺麗に整えてくれた方がいらっしゃるので、そちらのコードを使わせていただきます。
- Chadwick ← homebrew
- py-retrosheet ← レポジトリをクローン
$ brew update
$ brew install chadwick
$ git clone https://github.com/wellsoliver/py-retrosheet.git
また、py-retrosheetを使用するために必要なライブラリもダウンロードします。sqlalchemyおよび今回使用するMySQLに必要なmysql-pythonです。
$ pip install sqlalchemy mysql-python
(2) MySQL
py-retrosheetでデータダウンロード、SQLへのインポートもやってくれるので、あとはMySQLなどのデータベースを整備する。
$ brew install mysql
次にMySQLのいろいろな設定をします。(今回はテスト用のユーザを作成し使用)
$ mysql_secure_installation # パスワードなどのセキュリティ設定
$ mysql.server start
$ mysql -u root -p
Enter password: 設定したもの
mysql> CREATE DATABASE retrosheet # databaseの作成
mysql> CREATE USER test IDENTIFIED BY "*****(Your Password)" # testという名前のテストユーザを作成
mysql> GRANT ALL ON retrosheet.* TO test # テストユーザへのretrosheetデータベースアクセス権限を設定
あとは先ほど作成したテストユーザでschemaをインポートします
$ mysql -u test[USER_NAME] -p retrosheet[DB_NAME] < sql/schema.sql
これでMySQLのセッティングは完了。
※ なおSQLiteを用いる場合、Issuesにも書いてありますが以下のことに注意が必要のようです
(1) config.iniのdatabaseにはsqlファイルへのパスを記述
(2) そのままでは実行時にエラーが出るため、scripts/parse.py中の以下のような文(他にも多数あり)で%sを?に、results.rowcount()をlen(results.fetchall())に変更する(?)
sql = 'SELECT * FROM rosters WHERE year = %s AND player_id = %s AND team_tx = %s'
res = conn.execute(sql, [row[0], row[1], row[6]])
if results.rowcount() == 1:
sql = 'SELECT * FROM rosters WHERE year = ? AND player_id = ? AND team_tx = ?'
res = conn.execute(sql, [row[0], row[1], row[6]])
if len(results.fetchall()) == 1:
(3) config.iniの編集
最後に、confit.iniの編集し、先ほど作ったデータベースを設定します
$ cd scripts
$ cp config.ini.dist config.ini
$ vim config.ini # config.iniの編集
[database]
engine = mysql # or sqlite, postgresql
host = localhost
database = retrosheet
schema = retrosheet
user = test
password = ****** # your password
(4) 最後に
あとはdownload.pyでデータをダウンロード、parse.pyでSQLにインポート!
$ python download.py -y 2014 #ダウンロードする年を西暦で指定、オプション無しも可
$ python parse.py -y 2014 #SQLにインポート
これでSQLの中身を確認して、ちゃんとインポートできていれば終了。
あとはデータを自分の好きなように解析するだけですね!
※ 例えばチーム名はこんな感じ
mysql> select * from retrosheet.teams;
+---------+-------+---------------+--------------+
| TEAM_ID | LG_ID | LOC_TEAM_TX | NAME_TEAM_TX |
+---------+-------+---------------+--------------+
| ANA | A | Anaheim | Angels |
| BAL | A | Baltimore | Orioles |
| BOS | A | Boston | Red Sox |
| CHA | A | Chicago | White Sox |
| CLE | A | Cleveland | Indians |
| DET | A | Detroit | Tigers |
| HOU | A | Houston | Astros |
| KCA | A | Kansas City | Royals |
| MIN | A | Minnesota | Twins |
| NYA | A | New York | Yankees |
| OAK | A | Oakland | Athletics |
| SEA | A | Seattle | Mariners |
| TBA | A | Tampa Bay | Rays |
| TEX | A | Texas | Rangers |
| TOR | A | Toronto | Blue Jays |
| ARI | N | Arizona | Diamondbacks |
| ATL | N | Atlanta | Braves |
| CHN | N | Chicago | Cubs |
| CIN | N | Cincinnati | Reds |
| COL | N | Colorado | Rockies |
| LAN | N | Los Angeles | Dodgers |
| MIA | N | Miami | Marlins |
| MIL | N | Milwaukee | Brewers |
| NYN | N | New York | Mets |
| PHI | N | Philadelphia | Phillies |
| PIT | N | Pittsburgh | Pirates |
| SDN | N | San Diego | Padres |
| SFN | N | San Francisco | Giants |
| SLN | N | St. Louis | Cardinals |
| WAS | N | Washington | Nationals |
+---------+-------+---------------+--------------+