読者です 読者をやめる 読者になる 読者になる

Lean Baseball

Engineering/Baseball/Python/Agile/SABR and more...

MLBの選手情報データ「Sean Lahman Baseball Database」で野球ゲームのドラフト対策をPython+Excelでやってみた

Python 野球 オープンデータ セイバーメトリクス Fantasy Baseball PyDataTokyo

昨日のエントリーが思ったより盛り上がっててビックリしてる私ですこんばんは!*1

今日もPython + 野球ネタですが、今度は野球好き、特にセイバーメトリクスファンタジーベースボールが好きなキッズ達に刺さるネタを書こうと思います。

MLBの選手情報データ「Sean Lahman Baseball Database」で野球ゲームのドラフト対策をPython+Excelでやってみた

元ネタについて

こちらは先日のPython mini hack-a-thon #52(3/28)で作成、PyData.Tokyo Meetup #4(4/3)のLTで披露したネタです。スライドは公開していません。スライドよりコードを見せてブログを書いたほうが手っ取り早いと思い、こちらに記載することにしました。*2

使用したデータとコードの一部は昨年のPyCon JP 2014で発表した「Pythonではじめる野球プログラミング」で作ったデモおよびプロジェクトを活用した「応用編」でもあります。

なお、昨日のエントリーとの関連性はほぼゼロです!*3

おしながき

  • ファンタジーベースボールって何?
  • Live Draft for Fantasy Baseball~選手を獲得する方法
  • PythonでHackしてドラフト対策リストを作ってみた
  • 結果と学び
  • 【オマケ】PyData.Tokyo Meetup #4のLTで発表してみた

ファンタジーベースボールって何?

ファンタジーベースボール(Fantasy Baseball, ファンタジーベースボール - Wikipedia)は主にアメリカ、たまに日本などで遊ばれている、野球のソーシャルゲームで、一定のルールに従い自分のチームを作成、「現実の」現役選手の成績(ヒットを打つ、三振を奪う、エラーを犯すetc...)をポイント化して争うゲームです。

自分が選手を選んで(選ぶ方法は後述)、「ぼくが考えるさいきょうの野球チーム」を作成、同じく「ぼくがさいきょう!」という感じで作られたチームと対戦、ホンモノのMLBの試合で自軍(もしくは相手チーム)の選手成績に一喜一憂しながら、ポイントが出る画面を眺め、勝った負けたを争うゲームとなります。

f:id:shinyorke:20150407205816p:plain 【図】対戦画面

Live Draft for Fantasy Baseball~選手を獲得する方法

そんなファンタジーベースボール、プレーする選手は架空の選手、、、ではなくて、

現実にメジャー30球団に所属する選手もしくは、メジャーチームに昇格する(かもしれない)マイナーリーガーもしくは有望若手(トッププロスペクト)

が対象となります。対象となる選手は、

  • 各リーグで行われるドラフト会議(完全ウェーバー制)
  • ドラフト会議から漏れた選手をFAで獲得。マイナーから途中昇格する選手も対象
  • 相手チームとトレード交渉して獲得

ドラフト会議はある日ある時間(こちらはリーグのコミッショナーが指定)に「Live Draft」という、

ホンモノのドラフトさながらの方式で行います。

f:id:shinyorke:20150407210510j:plain 【図】Live Draftの画面。真ん中が獲得可能な選手リスト、右上に自軍の獲得予定リスト(Que)があります

ドラフトですべてが決まるわけではない、とはいえ、ここで大物選手や主力選手が決まるのが事実で、この日まで各オーナーはオープン戦や去年の成績、最近のニュース(故障してないか?調子落としてないか?とか)を漁って自分なりのドラフト戦略を立てて参加してきます。

要するにみんなガチです!

PythonでHackしてドラフト対策リストを作ってみた

そんなドラフトでは、ミゲル・カブレラ*4クレイトン・カーショウ*5といった誰しもが欲しがる大物選手、屈指の守備力とパワーを誇るジョシュ・ドナルドソン*6、長いイニングを投げてはキッチリ勝ち星をゲットするジェームス・シールズ*7といった主力選手は誰しもが欲しがるし、逆に薬物で出場が危ういジョシュ・ハミルトン、開幕前に故障して今季絶望となったダルさんといった、「優秀だけど試合に出られないor何かしらの問題がある」選手は誰も取りたくありません。

ドラフトでは自分の順番で考える時間が1分少しなので、効率よく各ポジションのほしい選手を獲得するため、私は以下の方針をとりました。

方針と打ち手

獲得したい選手を予めExcelに出力、並び替えたりデータを眺めたりする環境を作ることにしました。

  • ポジションごと(先発、中継、捕手、内野、外野)のドラフト獲得予定リストをExcelで作成
  • リストにポイント対象となる成績(打率、本塁打、打点、勝利、セーブ、奪三振、イニング数etc...)を出力
  • 選手をより客観的かつ効率よく評価するため、打者はRC(Run Created)*8、投手はWHIP(Walks plus Hits per Inning Pitched)*9を計算して出力セイバーメトリクスを駆使したドラフトを模索してみる*10

データは「Pythonではじめる野球プログラミング」で使ったデータベースの2014年版を新たに作成、このデータをサマリーしてExcelに出力するコードをPythonで書きました。

Sean Lahman Baseball Databaseを元にしたやきう選手DBを作る

Pythonではじめる野球プログラミング」で活用したコードを自分で公開していたので、今回はこちらを利用、2014年データを扱うのは初めてかつ、ちょっとしたバグもあったので手直ししました。

Shinichi-Nakagawa/no-ball-db-server · GitHub

なお、データはこちらから獲得しました。

Sean Lahman | Database Journalist

データの位置づけ、説明はPyCon JP 2014発表資料を参照ください。

一言でいうと、「野球選手のオープンデータでたいていの成績は獲得可能なCSVもしくはSQLデータ」です。

PythonでHackする

Sean Lahman Baseball Databaseのデータに対してクエリーを発行、サマリーしたり重複データをchunkしたり整形したりするPythonスクリプトを書きました。

Shinichi-Nakagawa/tsubuyaki_league_draft_list_script · GitHub

使い方はREADME.mdを御覧ください。本体のスクリプトはあんまり綺麗なコードじゃないですが(汗)、ちゃんと動いてくれました。

ちなみに、一番自慢したいのはstats.pyというセイバーメトリクス計算のコードで、

セイバーメトリクス計算クラス(抜粋)

とまあわりかし真面目に書きました&ちゃんと使える感じにはなりました。

ちなみにテストコードも書きましたがこちらをpushするの忘れてましたので後で上げようと思います。 ※テストコードpushしました!

そんでもって、出来上がったExcelリストはこちら!

f:id:shinyorke:20150407214218p:plain

ドラフトの実用に耐える、十分過ぎるリストができました。

結果と学び

そんな

  • ドラフトは90%成功!取りたい選手をほぼ取れた
  • ドラ一でアルチューベ*11を躊躇なく取れたのはこの対策のおかげ
  • 一方、詰めが甘くてショートで欲しかったマーカス・セミエン*12を取り逃したのは痛かった。
  • 来年は相手チームの競合分析*13、ドラフト指名予測あたりにチャレンジしたい。

【オマケ】PyData.Tokyo Meetup #4のLTで発表してみた

f:id:shinyorke:20150407214802j:plain

このドラフト対策は3/28に実装、29に実践しました。

で、その経緯とか結果をPyData.Tokyo Meetup #4の(飲みながら)LTで披露しました。

pydatatokyo.connpass.com

本編テーマとは関係ないLT(それ自体は問題ない)でしたが、そこそこ盛り上がった感があります。

このLT中に、オーガナイザーのシバタさんから、

中川さん、Pythonの野球クラスタって今何人いるの???*14

って聞かれましたのでこう答えました。

「(先日のBPStudy #91で)2人増えて3人になりましたよ!!!!」

なお、当日の模様を知りたい方はこちらを御覧ください。

togetter.com

相変わらずアツい勉強会でした!自分もいずれ野球ネタで登壇したいなあ。

最後になりましたが、オークランド・アスレチックス開幕戦勝利おめでとうございます!!!

今年も優勝するぞ!

*1:職場で突っ込まれました

*2:自分のスライドシェアが似たようなスライドで埋まるのを防ぐ意味合いもあります(小声)

*3:あとの解説でもありますが、データは別、コードもVagrantの構成を引きずっている以外あんまり共通点はありません。ちなみにこっちではAnsibleではなくChef soloを使っています

*4:デトロイト・タイガース内野手。2012年ア・リーグ打撃三冠王。おそらく現役メジャー最強の打者で、守備と走塁はアレだが打撃は全く穴がない

*5:去年のナ・リーグMVPおよびサイ・ヤング賞左腕。ドジャースのエース左腕で向かう所敵なし。広島の黒田とはドジャース時代から仲良しで、キャッチボールの相手をしていたことで有名

*6:トロント・ブルージェイズ三塁手。去年まではアスレチックスの三塁手として活躍していたが、マネーボールで有名なビーンGMと喧嘩、トレードで放出された。三塁守備が超絶に上手い元捕手で打撃もかなりいい

*7:サンディエゴパドレスの先発右腕。去年まではロイヤルズ、メジャーデビューからしばらくはレイズでプレー。完投が多く、勝ち運も恵まれているが被本塁打が多い

*8:RC (野球) - Wikipedia計算式はいくつか形式あり、本来は打席数による揺らぎを防ぐRC27を使うべきなのですが、ゲームの特性上打席にたくさん立ってる選手を優先したかったのでRCで評価しました。

*9:WHIP - Wikipedia 1イニングあたりに許したランナーの数の平均を表す。1.2を切れば先発エース級、1未満は神レベル

*10:他にもOPSや BB/9、HR/9やSO/9あたりも出しました。あまり使わなかったけどw

*11:ヒューストン・アストロズの快速セカンド。昨年のア・リーグ首位打者&盗塁王で足が速く打撃が上手い。なお、守備は意外とザルで、メジャーリーグで一番小さい選手(160cmちょい)としても有名

*12:アスレチックスのショート。昨秋にホワイトソックスからトレードで獲得。守備はアレだがショートとしては十分なパワー&選球眼を誇る。メジャー実績はまだまだだが今季伸びると予想されている選手の一人

*13:今年もチャレンジしましたが、Fantasy Baseballの昨年サイトにデータがなく、断念しましたorz今年はリーグ終了後にデータを抜こう。うん。

*14:Pythonとコミュニティーと野球(と少しだけLean)の2015年- #CROSS2015 で喋ってきました - Lean Baseball