2014年7月18日金曜日

Point Distributionから見る今年の広島東洋カープ

総得点から勝率予想をすることは,セイバーメトリクスの世界では良く行われていることではあります.有名なところでは,ピタゴラス勝率と呼ばれているもので,得点数$a$,失点数$b$とした時に,チームの勝率Pが $$P=\frac{a}{\sqrt{a^2+b^2}}$$ であたえられるというものです.こんな簡単な式ですが案外うまくフィッティングするのでよく用いられているのですが,理論的な考察としてなぜこの式が有効なのかという議論をしているものはあまり見たことがありません.おそらく,野球の得点が入るという現象がrandomの結果として考察しづらいことが要因ではないかと考えています.
野球において得点が入る,とはどういうことかを考えてみます.当たり前ですが,点が入るということは3アウトになるまでにランナーが本塁まで進塁するというふうに考えることが出来ます.なので,ヒットが3本続いたとしても点が入らない場合もある一方で,本塁打が出れば確実に点が入り,また安打が一つの回に固まると,本塁打以上の大量得点が得られます.なので,打撃結果と得点が単純な比例ではありません.
実際,サッカーの得点や野球の一試合あたりの本塁打数の分布はポアソン分布に従いますが,野球の得点はポアソン分布よりも,高得点側の確率が高い分布になってる気がします.

Point Distribution (@2013 横浜ベイスターズ)

2013年カープの得点分布でも,ポアソン分布のピークがなだらかになり,高得点側に推移したような形となっています.他のチームに関してもまあ概ねこのような分布になっているので,得点がポアソン分布に従うということを仮定するのはマズイかなといえると思います.

で,やりたいのは今年去年よりだいぶ健闘しているカープの得点分布が去年と比べてどうなっているのか見てみましょうということです.結果は以下の様な感じ
Point Distribution(@広島東洋カープ 2012~2014)
縦軸は得点確率,横軸は得点数

去年と比べて低得点の割合が減少していることがわかります.まあそもそも平均得点が3.8→4.3になってるので右に寄ることは当たり前なのですが,得点分布自体が全体通して均一になっています.やっぱり今年奮起してるエルドレッドの長打(本塁打)のお陰で,得点が安定して取れるようになっているからなのかはたまた別の理由からなのか.失点分布はそれほど変わってない様子なので,安定して4,5点取るっていうのは勝率アップにつながるのかも.

チームの長打率とか出塁率とかとリンクさせて分布傾向を出したりすると,同じ平均得点のチームでも,強い弱いの評価が出来て面白そうっすね.

ちなみに巨人はこんな感じ どっかで今年の巨人はOPS.750~.800の打者ばかりで圧倒的に打てる打者がいないというのを見ましたが,そのせいで高得点側の確率が上がって,6,7点あたりの確率が低い事につながってるのかも.

2014年7月17日木曜日

数列の収束における有界単調数列の使い方

$$ a_{n+1}>a_n, a_n>1 \Rightarrow {a_n} は下に有界な単調数列 $$

定理:有界単調数列は収束する 単調増加で,上に有界な数列${a_n}$が集合$A=\left\{a_1,a_2,......\right\} $の上限$\alpha$に収束することを示せば良い. $\forall\varepsilon>0$に対して$\alpha-\varepsilon$は$A$の上界ではない. $${n>N_0 \Rightarrow \alpha-\varepsilon<{a_n}<\alphaなるn_0が存在する}$$ このとき $$|a_n-\alpha|<\varepsilon$$ であるから,a_n$rightarrow\alpha$が示された.

2014年5月29日木曜日

C#でWebからデータを取ってくる

C#でwebからデータを取ってくるってことはあまり考えたことがなかったのですが、ちょっとプロ野球の得点分布を知りたいなと思った時に、いちいちデータを手打ちで集めるのも面倒だから自動化出来ないかなぁと考えて色々さがしてみたところ、C#でもhtmlのDOMを自在に操れるHtmlAgilityPackなるものがあるらしいのでちょっとテスト。

使い方としてはまず using System.Net でネットワーク関連のusingをもって来ておいて、HttpWebRequestとHttpWebResponseでデータを読み込みます。この時にもっと単純に取ってくるWebClientというクラスもあるのですが、それよりもrequestとresponseでストリーミングで読み込んだほうがUI(フォーム表示用)スレッドと読み込みスレッドを分離できるので、読み込み時にフォームが固まることを防げるのでよいらしいです。

WebClientよりHttpWebRequestを使った方がいい理由
http://d.hatena.ne.jp/kabakiyo/20120224/1330066622

あとはその読み込んだstringをHtmlAgilityPackにほり込んで、SelectNodesでjQuery的に検索してやれば勝手にほしいとこだけを検索して出してくれるという流れです。とってもシンプルでいいですね。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;

namespace web
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        string baseurl = "http://baseball.yahoo.co.jp/npb/game/";

        private void button1_Click(object sender, EventArgs e)
        {
            DateTime dt_now = DateTime.Now;
            string date = dt_now.ToShortDateString().Replace("/", "");

            // 今日の試合を読み込むためにurlを加工
            string url = baseurl + date + "01" + "/stats";
            //ex).url = http://baseball.yahoo.co.jp/npb/game/2014052801/stats

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "GET";
            HttpWebResponse res = (HttpWebResponse)req.GetResponse();
            Stream s = res.GetResponseStream();
            StreamReader sr = new StreamReader(s);
            string context = sr.ReadToEnd();
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(context);

            HtmlAgilityPack.HtmlNodeCollection _nodes = doc.DocumentNode.SelectNodes("/html[1]/body[1]/table[1]/tr");
            if (_nodes == null)
                break;
            foreach (var node in _nodes)
            {
                textBox1.Text += node.InnerText + "\r\n";
            }
        }
    }
}

2014年5月23日金曜日

久しぶりに

めっちゃ前に作ってた野球シミュレータの改良をやりました。

たまにはいじらないと自分で書いたコードが暗号に見えるようになりますね。すでに意味不明部分多数で手遅れ感満載ですが。

ほんとうはjavascriptかなにかweb上で動くもので作れればいろんな人に使ってもらえる可能性も増えて、いろいろと改良する点も意見としてもらえると思うのですがいかんせんC#しか使えないということと今現在新しい言語をいじくる余裕があまりないというので停滞中です。一応javascriptの本とか買ったんですけどね。ほとんど手付かず状態です。

とはいっても、C#でうまく設計さえできれば他の言語でかくのも結構楽にできるんではないかと(勝手に)予想してるので当分の目標はC#のWindowsWPFアプリケーションとして仕上げたいなぁともくろんでます。今のところ新しいやつでは

  • DHありなしの対戦
  • CSVで登録する選手を任意に決定できる
  • 先発ローテーション(最終的には抑えの登板とかも)実装
  • 天候、パークファクターの導入(まあこれは別にいいっちゃいいかな)

といった当たりをできるようにすることを目標にしてます。さっき見返してたら地味にもうこれ作り始めてから半年以上経ってるんですよねこれ。完成するのいつかな…

2014年5月21日水曜日

セイバーメトリクスな数字

打率、ホームラン、打点、勝ち星、得点圏打率というよく見る数字に比べて、出塁率や長打率、あるいはOPS(ここらへんは割りと浸透してるのかな?),XR,Fip,Dip,IsoD,IsoP,LOB%……とかいったセイバーメトリクス的な数字は市民権をまだまだ得れていない感じがあります。人によってはセイバーメトリクスの数字は実際の試合を見ていない数学オタクがでっち上げたもんでそんなのには意味が無いとかいう人もいたり。

じゃあそもそも、打率ってそんなに自然な数字なの?という話がでてきます。何気なく使っている打率ですが、あれの計算方法も全ての安打を無差別に足し算するという作業をしていますから、当然恣意的な指標です。しかもフォアボールはカウントされませんから、フォアボールを選ぶことは打率を上げると言う観点からいうと全く無意味です。ですから打率だけで打者の能力を図ろうとするときには、そういった消えた要素があることを考えていないと、間違った結論を導く可能性があります。

たとえば、ノースリーから毎回打ちに行ってフォアボールは選ばないし打っても毎回単打の3割バッターと、打てばほとんどホームラン、フォアボールも選びまくる3割バッター、この二人が同じになってしまうのが打率です。ここまで酷いことは無いと思いますが、そのような可能性があることは頭の何処かに考えて置く必要があります。

打点とか勝ち星とかいったものに関してはもっと不条理で、ヒットは打つものの毎回運悪くランナー無しで回ってくる弱小チームの四番よりも、周りが打ちまくるせいで毎回ランナーがいる状態で回ってくる打者の方が明らかに有利ですし、勝ち星なんてのは自分が打たれまくっても打線がバカバカ打てば増えるし、去年のいつかのDeNAの高崎投手みたいに、自責点0失点2で尚且つ自分がヒットを打って1点とって8回まで投げたとしても打線が打てずに負けてしまえば負けになるというある意味論理的でない無茶苦茶な数字です。

このように、指標の妥当性という面からセイバーメトリクスな数字を批判するのは無理があります。結局は、打率とOPSなにがちがうのかっていうのは、見慣れているのかそうではないのか、ただその違いに尽きると思います。

例えば今一般によく用いられる指標としてセーブとかHP(ホールドポイント)がありますが、あれはつい最近まで日本球界には存在しませんでした。しかし先発完投型の試合構成であったのが、先発→中継ぎ→抑えという分業制へと移行していく段階で、途中で登板する投手の地位向上が図られ、中継ぎを評価する指標として導入されたのがセーブといった概念です。では、セーブが無い時代の抑えで活躍した選手に価値がないかというとそんなことは無いですよね。今の時代の人と同じようにチームの勝利に貢献しているはずですから、同じように評価されるべきです。しかし、その選手がいた当時にはそんな概念がありませんから、おそらくは先発投手に比べてかなり選手としての価値が低いとみなされていたでしょう。

このセーブやホールドポイントと同じように、今一般に普及している指標だけが万能で十分である、とは必ずしも言い切れないはずです。そのためいろいろな側面から選手を見てやる方法として、セイバーメトリクスがあるんだと思っています。打者指標のIsoDを見れば、どれだけフォアボールを選ぶ傾向があるバッターであるかが、投手指標の一つであるFipを見れば、守備の影響から独立してどの程度その投手が抑えることが出来るのかといったことをある程度客観的に判断できます。

従来指標が絶対だ!という立場を頑なに守ろうとすると、結果として現実を見ることができなくなる恐ろしさがあります。

この記事は http://www.fangraphs.com/blogs/a-response-to-bob-ryan/を読んで思ったことをつらつら書いた(というか多分に影響を受けてい書いた)のですが、あらためて物事を認知する難しさや主観の危うさを感じれた気がします。

さきほどの内容も、セイバーメトリクスの指標を使う時にそれが絶対だという立場にたてば結局おなじことになるわけで、そこは常に注意して行かないといけないところです。

I think telling an accurate story is more important than telling a comfortable one, and the reality is that the numbers that are commonly used generate stories that are factually incorrect. ........
We’re not replacing the “Holy Trinity” of baseball statistics because we can’t enjoy the game. We’re pointing out that these statistics breed false narratives, and we value the truth.
A Response to Bob Ryan http://www.fangraphs.com/blogs/a-response-to-bob-ryan/

2014年5月15日木曜日

ランナー二塁でのチームバッティング

今日の巨人対ヤクルト戦、5回ノーアウトランナー二塁、バッター比屋根の場面。このような場面で間違いなく実況が言うのが、「バッターは最低でもファーストもしくはセカンドゴロを打てるように流し打ちを心がけて欲しいですね」というコメントです。今日も解説の江川がそのようなことを話していました。

確かにライト方向へのゴロならば2塁ランナーはサードへ進めますし、もしサードやショートへの強烈な当たりであればランナーは動けず流れが悪くなるというのも一理あります。

しかし、当然それを見越してピッチャーも左バッターならばアウトコースへのストレート、右打者へならインコースへのチェンジアップなどを軸に流し打ちをさせない投球をしてくるでしょう。そのような流し打ちをしてヒットを打つことが難しい場面において、監督は無理に流し打ちを意識させる必要があるのでしょうか。

まず、ノーアウトランナー二塁と言う状況では平均的にどの程度の点数を得ることが出来るのかを確認します。以下の表は2013年のNPB全試合においてノーアウトランナー二塁の状況が発生した後得られた点数の平均値を表しています。

situation アウトカウント 得点期待値
2 0 1.022
これを見るとノーアウトランナー二塁は平均的に見れば1点取ったことと同義であると言えます。では次にこの状況から起こりうる状況変化を考えます。

ノーアウトランナー二塁で起こりうるものとして、四死球、シングルヒット、ツーベース、スリーベース、フライもしくは2,3塁へのゴロアウト、1,2塁へのゴロがありますが、今回は簡単のためスリーベースとホームランは考えないこととします。

バッターの結果による次の状況の得点期待値が次の表です

situation アウトカウント 得点期待値 差分
2 1 0.713 -0.309
3 1 0.873 -0.149
1-2 0 1.41 0.388
1-3 0 1.736 0.714
これを見ると思ったより1アウトランナー3塁の得点期待値がよろしくないです。ノーアウト2塁時よりも得点期待値はだいたい0.15点ほど減少します。当然1アウトランナー2塁のほうが低いのですが、くらべても0.2点以下の差しかありません。

一方もし打者がヒット、もしくはフォアボールを選べば得点期待値はぐっと上がります。フォアボールでも0.4点、ヒットなら0.7点分の価値です。ここには載せていませんが、ノーアウトランナー1塁での得点期待値が0.44であることを考えると、このシチュエーションでヒットを一本追加することは、ノーアウトでランナー無しの時に単打もしくはフォアボールを選ぶときに得られる得点期待値よりも1.7倍ほどの価値があることがわかります。

しかも、ランナー二塁で強打が成功しツーベースを放てば、1点獲得した上にその後の得点期待値は1.022のままですし、ホームランを打つ可能性も当然含まれますから、強打策は更に大きな得点寄与となることが予想できます。

以上のことから、長打が見込まれるバッターや、ライト方向への打球を打とうとすると打率や長打率の下がってしまう選手は、普通に打たせるべきだということが言えるでしょう。

今日の試合の場面ではバッターは比屋根ですから、長打は少ないし次の川端バレンティンで点を取れば良いと考えて右打ちを指示することは、それほど間違った選択ではないですし、むしろセオリー通りです。

しかし続く打者が川端、バレンティン、雄平ということは、裏を返せば打撃能力が高く大量得点が見込める場面であるとも言えます。また比屋根は右打者で、尚且つ今シーズン3割近い打率を誇り、打球方向は主に左に寄っています(http://baseballdata.jp/playerB/1100052.htmlによると33打席中ライトへ飛んだ打球はわずか4球です)から、比屋根はそこまで右打ちが得意であるようには見受けられません。したがって、右打ちを指示した時の打率が下がってしまう可能性は十分考えられます。

加えてヤクルトは現在救援陣の防御率が極端に悪く3点差程度であれば試合後半にひっくり返されてしまうというリクスがあります。以上のことを鑑みると、確実に1点を取るよりも強打で大量点を取ってトドメを指すという指示もありではないのか、と思ったりもします。

2014年5月9日金曜日

本を買いました

一冊280円という安さにつられてついつい買ってしまいました。技術系の本を読んでると、一冊1000円ぐらいまで安く感じてしまうのは病気だと思います。

今回もまたAmazonで。立ち読みしなくても欲しいなと思う本は殆どAmazonかもしくはhontoで買うようになりました。

特にhontoは定期的に200円~500円offのクーポンを配ってくれるので貧乏学生にはとても助かります。まわしもんではないですが結構オススメです。欠点は発送がちょっと遅いことですかね。

与謝野晶子とか読んだこと一切なかったのでちょっとチャレンジですね。青空文庫でざっと見た感じ古文の授業を受けてないに等しい僕には厳しい気もしますが頑張ります。