はじめに
こんにちは。
最近はJuliaについて勉強しています。PythonやRと比較して日本語の情報は少ないように感じますが、Juliaの思想にあるようにそれぞれの言語のいいとこ取りをしているような印象があります。実際、速度も早く面白いなと感じましたので、今後も継続して勉強したいなと思っている言語です。
そこで実際のデータを利用して、練習をしていこうと思っています。今回もいつものように野球のデータを利用して、データフレームの操作や可視化の練習をしていきます。
ただ、今回JuliaでWebスクレイピングやそこからテーブルを取得することが難しかったので(実際できるようですが、著者には困難でした。)、Pythonでcsvを作成して、Juliaで読み込むところからはじめています。
今回の流れ
- パ・リーグで2020年10月現在で打撃タイトル争いをしている柳田悠岐選手、吉田正尚選手、浅村栄斗選手、中田翔選手の4選手のここ5年の打撃成績を比較し、そのすごさを考える。
- 今回比較する打撃成績は以前内川聖一選手の際に算出したように、OPS、BB/K、wOBA、IsoP、IsoDとする。
- OPS:OPSは打席あたりで得点増加に有効な打撃をしているかどうかを表す指標。つまり打席での貢献度。平均は.730前後で、.1000を越えればリーグ最高レベルとのこと。
- BB/K:四球と三振の割合から打者の選球眼を見る指標。1前後が望ましく、理想は1.5〜2とのこと。
- wOBA:打者が打席あたりにどれだけチームの得点増に貢献する打撃をしているかを評価する指標。出塁の価値を全て均一とみなす出塁率よりも打撃の貢献を総合的に表し、加重が統計的な根拠に基づいていることからOPSよりも適切に打撃の価値を評価する。出塁率に合うように設計されているため、平均的な打者で.330程度になるようです。
- IsoP:打者が長打(二塁打以上)を放つ能力を測る指標。長打率から単打の要素を除くことでより純粋な長打力を測ることが可能。平均は.130程度。
- IsoD:四死球によってどの程度出塁したかを測るための指標。平均は.060程度。
- その中で少しJuliaにおけるデータフレーム操作や可視化について体験する。
ちなみに記事執筆当時のパ・リーグ打撃タイトル3傑は
打率 | 本塁打 | 打点 | |
---|---|---|---|
1 | 吉田正尚 .355 | 浅村栄斗 31 | 中田翔 102 |
2 | 柳田悠岐 .345 | 中田翔 30 | 浅村栄斗 99 |
3 | 近藤健介 .339 | 柳田悠岐 28 | 柳田悠岐 80 |
以下、今回の分析手順
- Pythonでスクレイピング、csvデータ作成
- Juliaでcsv読み込み
- JuliaでOPS、BB/K、wOBA、IsoP、IsoDを計算、データフレームに列追加
- Juliaで可視化
Pythonでスクレイピング、csvデータ作成
まずはpandasの準備。表示行列を増やします。
import pandas as pd
# 表示行・列を増やす(30列、10行)
pd.get_option("display.max_columns", 30)
pd.get_option("display.max_rows", 10)
おなじみNPB公式サイトから各選手のデータをスクレイピングしていきます。4選手全員分を行いますが、ここでは柳田悠岐選手に絞ってコードを記載します。
#柳田悠岐選手の個人年度別成績(npb.jp)
url = 'https://npb.jp/bis/players/31835133.html'
#Tableタグをスクレイピング。
yana = pd.read_html(url)
#不使用となるデータを捨てて、別のデータフレーム作成
yanagita = yana[1].drop([0, 1, 2, 3, 4, 10], axis=0)
# カラム名を付与する(野球英語の略称)
yanagita.columns = ['year', 'team', 'g', 'pa', 'ab', 'r', 'h', '_2b', '_3b', 'hr', 'tb',
'rbi', 'sb', 'cs', 'sh', 'sf', 'bb', 'hbp', 'so', 'dp', 'ba', 'slg', 'obp']
# 各カラムのデータ型を整える
import numpy as np
yanagita['year'] = yanagita['year'].astype(np.float64)
yanagita['g'] = yanagita['g'].astype(np.float64)
yanagita['pa'] = yanagita['pa'].astype(np.float64)
yanagita['ab'] = yanagita['ab'].astype(np.float64)
yanagita['r'] = yanagita['r'].astype(np.float64)
yanagita['h'] = yanagita['h'].astype(np.float64)
yanagita['_2b'] = yanagita['_2b'].astype(np.float64)
yanagita['_3b'] = yanagita['_3b'].astype(np.float64)
yanagita['hr'] = yanagita['hr'].astype(np.float64)
yanagita['tb'] = yanagita['tb'].astype(np.float64)
yanagita['rbi'] = yanagita['rbi'].astype(np.float64)
yanagita['sb'] = yanagita['sb'].astype(np.float64)
yanagita['cs'] = yanagita['cs'].astype(np.float64)
yanagita['sh'] = yanagita['tb'].astype(np.float64)
yanagita['sf'] = yanagita['sf'].astype(np.float64)
yanagita['bb'] = yanagita['bb'].astype(np.float64)
yanagita['hbp'] = yanagita['hbp'].astype(np.float64)
yanagita['so'] = yanagita['so'].astype(np.float64)
yanagita['dp'] = yanagita['dp'].astype(np.float64)
yanagita['ba'] = yanagita['ba'].astype(np.float64)
yanagita['slg'] = yanagita['slg'].astype(np.float64)
yanagita['obp'] = yanagita['obp'].astype(np.float64)
ここまで4選手分の処理をしたら、csvファイルに書き出します。
#データフレームの書き出し
yanagita.to_csv("yanagita.csv")
yoshida.to_csv("yoshida.csv")
asamura.to_csv("asamura.csv")
nakata.to_csv("nakata.csv")
Juliaでcsv読み込み
Pythonでcsvファイルを作成したら、Juliaでそのファイルを読み込みます。
#必要なパッケージの準備
import Pkg
Pkg.add("DataFrames")
Pkg.add("CSV")
using DataFrames
using CSV
#csvファイルの読み込み
ya = CSV.read("yanagita.csv")
yo = CSV.read("yoshida.csv")
asa = CSV.read("asamura.csv")
na = CSV.read("nakata.csv")
JuliaでOPS、BB/K、wOBA、IsoP、IsoDを計算、データフレームに列追加
csvファイルを読み込めたら、OPS、BB/K、wOBA、IsoP、IsoDを計算し、それぞれをデータフレームに追加します。
データフレームを計算するときにはDataFramesMeta
パッケージを利用します。DataFramesMeta
はR言語のdplyr
パッケージのようにデータフレームを操作できます。パイプ連結子|>
を利用して、複数の処理をつなぐことができます。具体的には以下の対応表を参考にしてください。
Julia | dplyr | |
---|---|---|
行の抽出 | @where | filter |
列の追加 | @transform | mutate |
グループ化+計算 | @by | |
グループ化 | @groupby | group_by |
要約 | @based_on | summarise |
並び替え | @orderby | arrange |
列の選択 | @select | Select |
実際の利用の際にははじめに@linq
を描くことで、以降は@
なく繋ぐことができます。
詳しくは公式のgithubを参照してください。
ではDataFramesMeta
を使って計算してみましょう。まずは柳田選手。
#必要なパッケージの準備
Pkg.add("DataFramesMeta")
using DataFramesMeta
#列の指定はsymbol型。:+列名で指定可能。
#除算、乗算のときは明示的に.が必要。
ya2 = @linq ya |>
transform(ops = :obp + :slg) |>
transform(bb_k = :bb./:so) |>
transform(woba = (0.7.*(:bb + :hbp) + 0.9.*:h + 1.3.*:_2b + 1.6.*:_3b + 2.0.*:hr )
./( :ab + :bb + :hbp + :sf )) |>
transform(isop = :slg - :ba) |>
transform(isod = :obp - :ba)
ya2[[:ops, :bb_k, :woba, :isop, :isod]]
同様に他の選手の成績を計算します。上のコードのya
をそれぞれyo
、asa
、na
に変えるだけです。
吉田選手
浅村選手
中田選手
4選手のOPS、BB/K、wOBA、IsoP、IsoDが計算できました。
ではこれを可視化して見やすくしましょう。
Juliaで可視化
Julia言語の可視化には様々な方法があるようですが、今回可視化にはPlots
パッケージを利用しました。バックエンドも色々種類があるようですが今回はGRを利用しています。
それぞれの選手のグラフを重ねましたが、重ねるときは!
をつけて破壊的にする必要があるようです。
では可視化していきます。まずはOPSから。
#必要なパッケージの準備
Pkg.add("Plots")
using Plots
gr()
#OPSの可視化。それぞれの結果を重ねる。
plot([2016:2020],ya2[:ops], xlabel="year", ylabel="OPS", title="OPS",
label="Yanagita", linecolor=:black)
plot!([2016:2020],yo2[:ops], label="Yoshida", linecolor=:blue)
plot!([2016:2020],asa2[:ops], label="Asamura", linecolor=:red)
plot!([2016:2020],na2[:ops], label="Nakata", linecolor=:orange)
savefig("ops.png")
同様にして、BB/K、wOBA、IsoP、IsoDも可視化していきます。
BB/K
wOBA
IsoP
IsoD
以上のような可視化ができました。これらのことから何がわかるか考察してみましょう。
考察
- どの指標を見ても毎年高水準の成績を残している柳田悠岐選手。年毎のムラが大きいのは気になりますが、すごい成績です。長打力も抜群。今年は2018年を超える成績を残すかもしれません。
- 今年の成績が特徴的な吉田正尚選手。長打の割合(IsoP)はガクンと減っていますが、三振が極端に少ない(BB/K)ことが見て取れます。単打が中心でも、打ちまくっているとOPSやwOBAは変わらないことがわかりました。
- 全体的に右肩上がりの成績の浅村栄斗選手。長打力(IsoP)も選球眼(IsoD)も年々向上していると推測できます。2019年に西武から楽天に移籍して、役割が変わったことも関係あるかもしれません。
- 全体的に浅村栄斗選手と似たグラフの中田翔選手。違いはIsoD(四球での出塁)の割合が少ないことかなと思います。なんとなくこの4人の中では、昔ながらのホームランバッターという印象です。
まとめ
以上、Julia言語を使ってパ・リーグの4打者の成績を分析してみました。全員高水準のバッターですが、それぞれの特徴が見られました。皆ほぼ同年代で、今後のさらなる活躍が楽しみです。
また、Juliaに関しては、後発の言語ということもあって色々使いやすく開発されたんだろうなということを感じました。さらなるパッケージの発展や、日本語でのドキュメントなどがたくさん増えることで、どんどん使いやすくなっていくのかなと感じました。今後も勉強していきます。
今回は以上です。
参考サイト・文献
- Julia: はじめてのプログラムは機械学習!, juno
- プログラミング/julia/グラフの書き方
- Julia ドキュメント
- Julia言語プログラミング入門
- Juliaで遊んでみた - データフレーム操作編
- 10 Minutes to DataFrames.jl
- JuliaTokyoTutorial/JuliaTokyo04.ipynb
- お気楽 Julia プログラミング超入門
- JuliaでCSV / DataFrameを扱う方法
- Juliaでグラフ作成
- juliaでよくつかうパッケージまとめ
- 統計分析をRからJuliaに~プロット
- DataFramesMeta, JuliaDB, Queryverseをそれぞれ触ってみた
- Julia&Juno: はじめ方3_データフレームの集計, DataFramesMeta ver. 2
- Juliaでの整数・浮動小数点数・文字列・文字間の型変換
- dataframe のとりあつかい
- Plots.jl+StatsPlots.jlでグラフを描画する
- JuliaでPlotsするよ
コメント