Lean Baseball

No Engineering, No Baseball.

「PythonユーザのためのJupyter[実践]入門」の感想と野球版サンプルを作った #jupyterbook #mokupy

f:id:shinyorke:20171001170611p:plain

今年も野球は終わりですね*1...こんにちは,野球の人です.

このエントリーは,PyCon JP 2017で発表した内容の続きであり, 前回のエントリーの続きでもあります.*2

Scrapyでスクレイピング&SQLite3に保存したデータを,

  • Jupyter
  • pandas
  • matplotlib

で分析と可視化をしてみましょう.

3行でまとめると

  • Jupyter本(以下,jupyterbookと略す)はいいぞ!Pythonでデータを操る人すべての必読書やぞ!
  • pandasのread_sqlとwhere,groupbyで簡単な野球統計分析ができる
  • 率系の指標(打率・出塁率・長打率・OPS)のHistogramで大雑把な打撃の傾向がつかめる

対象の読者

  • Pythonでデータ分析・可視化をされたい方
  • 前回のエントリーの続きで野球データを使った分析をしたい方
  • jupyterbookの感想や実際の利用感を知りたい方

なお,機械学習や野球統計学(セイバーメトリクス)の理論については登場しません.*3

必要なPythonレベル

  • Pythonレベル初級〜中級くらい,好きなエディタでPythonの読み書きができればOK(割と初心者向き)
  • 本を読むor人に聞きながら手を動かして進められる
  • Jupyterが使えるとなお良い(本を片手にでOK)

おしながき

Jupyter + pandas + matplotlibを用いたPyData×野球サンプル

jupyterbookを片手に, なるべく簡略かつ優しいサンプルコードを作って公開しました.

こちらは本日(10/1)に参加した #mokupy の成果でもあります.

mokupy.connpass.com

SQUEEZEさん,素敵なオフィスでもくもくさせていただきありがとうございます!*4

コード

今回はJupyter notebookベースのコードです.

このサンプルでjupyterbook

  • 第1章「Jupyter notebookを導入しよう」
  • 第2章「Jupyter notebookの操作を学ぼう」
  • 第3章「pandasでデータを処理しよう」

のほぼ全ての内容と,やる気と使い方次第で,

  • 第4章「Matplotlibでグラフを描画しよう」
  • 第5章「Matplotlibを使いこなそう」
  • 第6章「Bokehでグラフを描画しよう」

の内容はなんとか試せると思います.

※4章以降の内容は未検証(だけど多分いける)

github.com

使い方

上記リポジトリのREADME.mdに記載していますがダイジェストで紹介.

事前準備

このサンプルコードは,以下のエントリーで公開した野球データセット(ScrapyでNPBデータをスクレイピング&SQLite3に保存)が必要です.

というわけで,ここのエントリーを参考にDBを作りましょう.

shinyorke.hatenablog.com

元のコードのリポジトリはこちら.

cloneしてPython3とscrapyを入れて動かせば割とすぐ取れると思います.

github.com

環境構築

  • jupyterbookの環境構築手順に従い,Anacondaをインストール
  • こんな感じで仮想環境を作る&ライブラリを入れる
$ conda create -n jupyter-sample-baseball python=3.6
$ source activate jupyter-sample-baseball
$ conda install -y jupyter pandas notebook matplotlib bokeh

今回,bokehは使いませんでしたがいずれ使うと思う&真似する方は是非bokeh版もやってみてください.

起動

ProjectのRootディレクトリ(cloneした場合はcloneしたディレクトリ配下)にbaseball.dbをコピー,Jupyter notebookを起動

$ cp {baseball.dbまでのパス}/baseball.db jupyter-sample-baseball/
$ jupyter notebook

勘どころの解説

DB(SQLite3)からデータセット(Table)を読み込む

pandasのread_sqlで読み取り可能です...ということが第3章に記載されています.

のと,ほんの少しだけこちらを参考にさせてもらいました.*5

SQLiteのDB情報をPythonで 可視化する - slideship.com

Pythonの標準ライブラリとして梱包されているsqlite3を活用して,クエリを書いてDataframeを取得します.

なお,今回はpandasのwhereやgroupbyで絞り込む前提で考えているため,全レコードを取得しています.*6

import pandas as pd
import sqlite3

# コネクションを作る, 引数はsqlite3ファイルまでのパス(相対でも絶対でもOK)
con = sqlite3.connect('baseball.db')

# (中略)

# 続いてpandasで読み込む(全打撃データ)
df_batter = pd.read_sql('select * from batter', con)

打率ランキングを出す

pandasのDataframeを作った後は基本的に,

  • where
  • sort_values
  • head

の3つのメソッドでサマったり簡単なランキングを出せます.

これらもjupyterbookの解説を元にシンプルに書いてます.

ちなみに出しているカラムは左から

  • 選手名(name)
  • チーム(team)
  • 打席数(pa)
  • 打率(ba)
  • ホームラン(hr)
  • 打点(rbi)

です.

# セパ両リーグ合わせた打率ランキング(Best 30, 300打席以上)
df_batter[['name', 'team', 'pa', 'ba', 'hr', 'rbi']].where(df_batter['pa'] >= 300).sort_values('ba', ascending=False).head(30)

なおランキングはこんな感じです.

松山竜平(広島)が規定打数未満とはいえすごく優秀&秋山翔吾(西武)の成績が圧倒的ですね.*7

f:id:shinyorke:20171001224838p:plain

チームごとにgroupbyして基本統計量を出す

pandasでのgroupbyはたったこれだけでできます.

なおgroupbyの結果はpandas.core.groupby.DataFrameGroupByクラスのオブジェクトとして返ってきます.

df_batter_grouped = df_batter.groupby('team')

今回はチームごとの統計量をdescribe()で取ってみました.

f:id:shinyorke:20171001225640p:plain

このスクショには無いですが,巨人の本塁打数(hr)のmax値(=チーム本塁打王)が17本というところに辛みを感じました.*8

列(series)の追加とHistogramで可視化

列追加はたしかjupyterbookに無かった気がします...が必要だったので書きました.

出塁率(OBP)と長打率(SLG)の足し算で算出できるOPS(On Base Plus Slugging)を算出,Histogramで日本プロ野球全体の傾向を見てみました.

400打席以上で絞っています.

# 最後に,セイバーメトリクス指標で最も簡単なOPS(On Base Plus Slugging)を求める
df_batter['ops'] = df_batter['obp'] + df_batter['slg']

# OPSランキング
df_batter[['name', 'team', 'pa', 'ba', 'hr', 'rbi', 'obp', 'slg', 'ops']].where(df_batter['pa'] >= 400).sort_values('ops', ascending=False).head(30)

結果はこちら!ギータ強い...*9

f:id:shinyorke:20171001230645p:plain

OPSだけに絞ってHistogramはこちら.

これもjupyterbookの第3章に載っています.

pandasのDataFrameからそのままグラフに起こせますよと.

# OPSの分布
ax = df_batter['ops'].where(df_batter['pa'] > 400).hist(bins=20)
ax.set_title('histogram by OPS')
plt.show()

ボリュームゾーンがおおよそ.700〜.800台というのはだいたい合ってそうです.

f:id:shinyorke:20171001231953p:plain

コードの全容はこちらに記載していますので,ぜひぜひ参考に&自由に書き換えて遊んでもらえるとうれしいです.

https://github.com/Shinichi-Nakagawa/jupyter-sample-baseball/blob/master/baseball-sample-npb2017.ipynb

PythonユーザのためのJupyter[実践]入門の感想

著者の @iktakahiroさんはじめ,皆さまのご厚意により頂きました.

誠にありがとうございます!&Kindle版も買っちゃいました.

PythonユーザのためのJupyter[実践]入門

PythonユーザのためのJupyter[実践]入門

簡単にではございますが,感想と本の活かし方について触れたいと思います.

感想

PyDataの「困った」「知りたい」を解決してくれる「教科書」であり「辞書」である

PyDataが初めての方は勿論,ベテランの方にとっても大変ありがたい「教科書」であり「辞書」だなと思いました!

私自身は2014年ごろからPyDataなライブラリを使ってるのですが,

  • Jupyterのショートカット
  • pandasの「あれ,ソートどうやるんだったっけ?」「SQLで言う所のwhereってどう書くんだったっけ?」など,「やれるの知ってるけどやり方忘れる」やつ
  • matplotlibのsub plotがようわからん

みたいな困りごとや知りたいは結構あって...これは割と世の中のPyData勢もそんな感じなんじゃないかとも思っています.(きっと賛成を得られるはずw)

そんな時に,すぐに辞書として使える本が案外なかったりしてたのでやっと辞書であり,重要な勘所(DataFrameやSeries,sub plotなど)を説明してくれる教科書がようやっと出てきて感激を覚えました.

使う順番やハマる・困る勘所を抑えている

データを扱う際は,

  1. データの取得(スクレイピングしてデータセットを作る,SQLなどで塊をとる)
  2. データのクレンジング・前処理(行列を整える,欠損値を解決する,型を指定する)
  3. 分析
  4. 可視化

というような手順を取るのが普通かなと思っていますが,その時に必要な順序

  • 環境を作る・使う(Jupyter)
  • データを習得する&クレンジング・前処理(pandas)
  • 可視化する(matplotlib・bokeh)

の順にライブラリの解説や勘所が載ってるのはとても優しい構成だなと思いました.

この本自体,スクレイピングや分析の一部(例えば機械学習そのもの)はスコープ外で,そこの部分は自分たちでなんとかしろ!って感じかと思いますが,

だいたいハマる箇所は前処理だったり可視化だったりっていう印象もあるので(やることにもよります&異論は認める),これを順番に解決できる構成はほんといいなと思いました.

環境作りに対する細かい配慮

写経する時にだいたいハマる環境作りですが,こちらについても配慮がされていてホントにプロの本だな!と感心しました.

  • 有無を言わさずanaconda
  • conda installするライブラリのバージョンを固定

このエントリーをやるため,私も本に合わせてanacondaを使いましたが,特に困ることも無く円滑に進みました.*10

また,ライブラリバージョンの固定はとても良くて,下手に最新いれて動かないリスクを避ける,冪等性を保つ意味でもいいなと思いました.

Python以外にも優しい網羅性

Ruby(iRuby)やRを使った方法も紹介しています.

手前味噌で恐縮ですが,以前私がTokyuRuby会議'11でやったネタと同じ話が載ってました.

shinyorke.hatenablog.com

私自身が思ったこと

細かい話ですが,pandasのDataFrameの行選択でqueryじゃなくてwhereを使う理由をしりたいと思いました.

理由「個人的にはqueryをよく使う」*11

活かし方

jupyter,pandas,matplolib,bokehおよび周辺技術(RubyやR,Jupyterlabなど)にサービス(Cloud DatalabやAzure Notebooks)と,幅広いことが網羅的に載っている&すぐ試せるサンプルなどで構成されているので,

  • 困ったときの辞書として使う
  • 覚えたいことを写経する

といった使い方に強いと思いました.

前者(辞書)は紙でも電子でもOK,後者(写経)は紙で持ってるとベストかな...

個人的には辞書利用が増えそうなのでKindle版でも買いました.*12

なお,ハッシュタグ「#jupyterbook」で感想ブログや書評や著者の皆様の活動などが見えるのでオススメです.

まとめ

PythonとJupyter,pandasとmatplotlibをちょっと覚えることにより,大抵のセイバーメトリクスが出来るようになりますよ!というのがこの記事で言いたいポイントです.

そのお供としてのjupyterbookはかなりオススメなので,データ分析をする方や野球データで遊びたい方は是非試してみるといいと思います!

プロ野球もMLBももうすぐ終わり,CS・プレーオフを楽しみつつ,Pythonで野球データの秋を味わえたらと思います!

フィードバック&提案とかご意見などなどお待ちしております(._.)

素敵なPyDataライフを!

【Appendix】参考文献

繰り返しになりますが,今回はJupyter[実践]入門が大活躍でした!

PythonユーザのためのJupyter[実践]入門

PythonユーザのためのJupyter[実践]入門

【Appendix】コードの全容

Jupyter notebook 日本プロ野球分析のサンプル

*1:DeNAベイスターズCS進出おめでとうございます&読売さんは残念でした

*2:PyCon JPの続きシリーズは今回で一旦最後

*3:なぜならそんなテクノロジーを使わなくても十分証明できちゃうからです

*4:ソファーの座り心地が最高でした

*5:このスライドでSQLite3でread_sql出来ることを初めて知った

*6:全部読んでも647レコード.これぐらいならオンメモリで問題ない

*7:松山はエルドレッドと鈴木誠也が両翼にいる関係で機会損失してる感あってもったいない.誠也の故障でチームは大ダメージだけど出場機会を得られたのは皮肉&秋山翔吾は何が変わったのかすごく知りたい.

*8:1位はマギーでした,流石チーム三冠王

*9:益々強くなっててほんと怖い

*10:PyDataやるならやっぱanacondaか...と改宗しつつある自分がいる

*11:queryの方がSQLチックで好きだったりする

*12:毎日持ち歩きたいってことです.