野球シミュレーターを作ってみる(基本設計編)

シミュレーション

シミュレーター作りの動機

プロ野球を見ていて、チームがなかなか勝てないとき、「選手の打順をもっとうまく組み替えて!」だとか「打順はこのまま固定して我慢を続ければいい結果が生まれるはず!」だとか、色々な意見が出ますよね。

また他のチームの選手を見ては、「あの選手がうちにいたら」だとか「あの選手さえ敵打線にいなければ…」なんて思うこともありませんか?

そんな「たら」「れば」が実際に起こった時、チームの得点能力はどうなるのか、検証してみたい。

そんな思いから、野球シミュレーターを自作してみることにしました。

もちろん、シミュレーターというのは現実世界を模擬するものであって、100%その通りになるような代物は作れないのですが、納得できる範囲のリアリティがある結果を追い求めてみたいと思います。

野球というのはピッチャーが投げて、バッターが打つ、ダイヤモンドを一周して帰ってくれば得点。一見単純そうにも思えて、試合中に訪れる場面は様々であり、案外複雑なものです。その複雑さを全部まるごと表すのは容易でないので、まずはシミュレーター作りにおいて

  • 何のデータを元にするか
  • どのような仮定をおくか

ということについて考えていきましょう。

シミュレーターに使うデータを用意しよう。

基本となる選手成績

ベースとなるデータは以下のような野球好きの皆さんなら大体イメージが着くような選手成績。表にあるのは2019年のセ・リーグMVP坂本勇人選手の成績です。

ちなみに筆者はジャイアンツファンではありません(むしろ他チームを応援しがちです)が、そんな私から見ても、坂本選手の成績は素晴らしいですね。

アウトに占めるゴロ、フライ、併殺打の割合

次に選手ごとに、ゴロでアウトになる確率、フライでアウトになる確率を分けてみます。この点についてはデータを集めるのが簡単では無さそうなので、全選手で一様の数字を用いてみたいと思います。アメリカでは有名なメジャーリーグの統計サイトFANGRAPHS.COMさんにあるデータによると、2002~2020年の間のメジャーリーグでのアウトに占めるゴロとフライの割合は次の表のようになっています。

ここで、ゴロ+フライ+ライナーの合計は100%になっていることから、三振によるアウトは考慮されていないことが分かりますね。ライナーも含めてフライアウトに含めてしまうと、インフィールドでアウトになったケースのうちゴロが44%、フライが56%と想定することができます。この平均値を全バッターに当てはめることにしましょう。

併殺打の割合

インプレーでのアウトにもう一つ要素を上乗せしてみましょう。「併殺打」です。

こちらのサイトで併殺打率について考察してくださっており、「併殺打機会率」(=併殺打機会打席数÷打席数)は2010年シーズンにおいて各選手およそ15~25%程度であったと算出されています。なお、併殺打機会とは、0アウトまたは1アウトでランナーが少なくとも1塁にいる状況を指しますね。この数字を拝借させていただき、併殺打機会率は全選手20%と仮定してみます。そうすると、併殺打になる確率「併殺打率」は次のように計算される。

シミュレーターへの入力用データの整理

ヒットでどれだけ進塁できる?

この中でまず注目するのは、打席数・打数・安打・二塁打・三塁打・本塁打・四死球の7つの指標。「ヒットを確率」という意味では「打率」、「どれだけ進塁できるか」という意味では「長打率」がよく使われますよね。ここでは、次の5つの指標を導入します。

  • 単打率:(安打数-二塁打数-三塁打数-本塁打数)÷打席数
  • 二塁打率:二塁打数÷打席数
  • 三塁打率:三塁打数÷打席数
  • 本塁打率:本塁打数÷打席数
  • 四死球率:(四球数+死球数)÷打席数

アウトの内訳

前述の通り、アウトの内訳を細かく選手ごとに算出するのはなかなか難しいので、アウトに占めるフライ・ゴロの割合については全選手一貫性のある数字を用いたいと思います。

  • 三振率:三振数÷打席数
  • インプレーアウト率:(打数-安打数-三振数+犠打数※+犠飛数※)÷打席数
  • フライアウト率(ライナー含む):インプレーアウト率×56%

【併殺打機会※ではない場合】

  • ゴロアウト率:インプレーアウト率×44%

【併殺打機会である場合】

  • 併殺打率:併殺打数÷(打席数×20%) - ただし、併殺打機会※でのみ適用される割合
  • (併殺ではない)ゴロアウト率:インプレーアウト率×44%-併殺打率

※単純化のため、犠打は単純なゴロアウトに、犠飛はフライアウトに含めることにする

※併殺打機会:0アウトまたは1アウトでランナーが少なくとも1塁にいる状況

シミュレーションの「単純化」

シミュレーションにおける「仮定」

現実にある問題をシミュレーションによって模擬するとき、当然100%の精度で表すことはできません。ある程度の「仮定」をもって、扱うモデルを単純化してあげないと、コンピュータに求められる処理能力や、必要となる計算時間は延々長くなってしまいます。また、簡単に得られないデータがある場合、ある程度の考察を元に妥当と思われる「仮定」を持ってデータの代わりに推定値を置くことも、場合によっては必要となります。

このシミュレーターで行う「単純化」「仮定」についていくつか説明していきましょう。

ゴロアウトとフライアウトで塁上のランナーは進塁できる?

ランナーがいる状況でのアウトのなり方でもゴロでアウトになるのと、フライでアウトになるのは、結果に違いがあったりしますよね。実際に起こりえるケースを挙げていくと、場合分けにきりがないので、ここでは多少強引に次のように仮定してみます。

  • ランナーありの状況でのフライアウトはタッチアップはなし
  • ゴロの場合、ランナーは進塁

こうしてしまうと、ゴロを打つバッターの方がフライを打つバッターより優秀な結果になってしまいますが、前述の通りこのシミュレーター上では全選手のゴロ:フライの比率が同じなので、全選手にとって平等な条件とも言えるかと思います。

得点圏打率

このシミュレーターを作る上で、得点圏打率を組み込むかどうかというのは迷う点になりました。単純化する上では、「得点圏のとき」もシーズン通算の打率を適用することが可能です。また得点圏「じゃないとき」の打率というのがデータとして用意されていないのも手間ですよね(笑)

ただふと、このシミュレーションで考えることが「どれだけ選手の成績を元に得点力を算出できるか」という点であることを考えると、やはり考えてみる価値はありそうだなと思いました。

「得点圏のとき」「得点圏じゃないとき」に場合分けして、以下のように算出してみます。(四死球率には得点圏であることの影響はないものと考える)

「得点圏のとき」

  • 得点圏単打率:(得点圏安打数÷得点圏打数)÷(安打数÷打数)×単打率
  • 得点圏二塁打率:(得点圏安打数÷得点圏打数)÷(安打数÷打数)×二塁打率
  • 得点圏三塁打率:(得点圏安打数÷得点圏打数)÷(安打数÷打数)×三塁打率
  • 得点圏本塁打率:(得点圏安打数÷得点圏打数)÷(安打数÷打数)×本塁打率
  • 得点圏三振率:(1-得点圏安打数÷得点圏打数)÷(1-安打数÷打数)×三振率
  • 得点圏フライアウト率:(1-得点圏安打数÷得点圏打数)÷(1-安打数÷打数)×フライアウト率
  • 得点圏ゴロアウト率:(1-得点圏安打数÷得点圏打数)÷(1-安打数÷打数)×ゴロアウト率
  • 得点圏併殺打率:(1-得点圏安打数÷得点圏打数)÷(1-安打数÷打数)×併殺打率

「得点圏じゃない(非得点圏の)とき」

  • 非得点圏打数:打数-得点圏打数
  • 非得点圏安打数:安打数-得点圏安打数
  • 非得点圏単打率:(非得点圏安打数÷非得点圏打数)÷(安打数÷打数)×単打率
  • 非得点圏二塁打率:(非得点圏安打数÷非得点圏打数)÷(安打数÷打数)×二塁打率
  • 非得点圏三塁打率:(非得点圏安打数÷非得点圏打数)÷(安打数÷打数)×三塁打率
  • 非得点圏本塁打率:(非得点圏安打数÷非得点圏打数)÷(安打数÷打数)×本塁打率
  • 非得点圏三振率:(1-非得点圏安打数÷非得点圏打数)÷(1-安打数÷打数)×三振率
  • 非得点圏フライアウト率:(1-非得点圏安打数÷非得点圏打数)÷(1-安打数÷打数)×フライアウト率
  • 非得点圏ゴロアウト率:(1-非得点圏安打数÷非得点圏打数)÷(1-安打数÷打数)×ゴロアウト率
  • 非得点圏併殺打率:(1-非得点圏安打数÷非得点圏打数)÷(1-安打数÷打数)×併殺打率

見てすでにお分かりの方が多いかと思いますが、得点圏であろうと、非得点圏であろうと、安打に占める単打・二塁打・三塁打・本塁打の出現確率は同じものと仮定しています。

その程度の単純化を入れても、複雑になってきていますね。筆者が当初思っていたよりも多少複雑化してきていませんか?

実選手にあてはめる:坂本勇人選手の場合

ここまで整理できたので、坂本勇人選手の場合には、これらの数字がどれだけの確率で実現することになるのか、確認してみましょう。

まずは一旦得点圏・非得点圏の区別なく、基準データを算出してみます。

ここで計算が軽くチェック。単打・二塁打・三塁打・本塁打・四死球・三振・インプレーアウトはこのシミュレーターで考える打者の打撃内容として全ケースを網羅しているはずです。そのためこれらの率の総和は1.000になるかどうか。ちゃんと1.000になっていますね。

また、フライアウト率+ゴロアウト室はインプレーアウト率の内訳に相当するので、ここも一致するはず。こちらも0.413で一致していますね。

最後に併殺機会時のゴロアウト率+併殺打率は非併殺機会時のゴロアウト率と一致するはず。こちらも0.182で一致しています。

いい感じですね。

ここまで正しく計算が進められていそうなので、次に、「得点圏のとき」と「得点圏じゃないとき」に分けて、それぞれでの率を見ていきます。

「得点圏のとき」の率

「得点圏じゃないとき」の率

単純化する要素まとめ

実際の野球はもちろんより複雑なわけですが、シミュレーションを単純化するため、また、データとして容易に手に入らないことも考慮して、以下の要素を今回のシミュレーターからは単純化することにしました。(細かいところまで書き出すときりがないため、目立つ点だけのまとめです)

  • 盗塁、エラーによる出塁・進塁、暴投・パスボールによる進塁は考慮しない
  • 塁打以上に次の塁を狙った走塁(1塁のランナーが、単打で3塁に進むなど)は考慮しない
  • ゴロアウト(併殺打は除く)は常時進塁打扱い、フライアウトは進塁・タッチアップなし
  • 犠打はゴロアウトに、犠飛はフライアウトに含める
  • アウトカウント別の打撃成績は考慮しない
  • トリプルプレーは起こらないと仮定
  • 選手交代はなし(チームは同じオーダーでひたすら戦い続ける)
  • 振り逃げはなし
  • 球場別の成績(パークファクター)は考慮しない

難しいと想定していたデータの入手が容易になったり、複雑さを計算に悪影響を及ぼさない範囲でうまく盛り込むアイデアが思いつけば、今後改良していきたいと思っています。

状況別の結果場合分け

ここではアウトカウントや塁上のランナーの状況から、打者の結果によってランナーがどれだけ進めるのかという考察を進めていきましょう。

アウト数・塁上状況 全通り

まずそもそも、アウトカウントや塁上にランナーがいる状況には全部で何通りあるでしょうか。(この場合分けにランナーの足の速さなどの選手の特性は含みません)

「アウト数」はシンプルですね。

0死、1死、2死 ⇒ 3通り あります。

「塁上のランナーの状況」は組み合わせは少し多くなります。

ランナーなし、ランナー1塁、ランナー2塁、ランナー3塁、ランナー1・2塁、ランナー1・3塁、ランナー2・3塁、満塁 ⇒ 8通り ありますね。
(数学的に表すと、3つのベースそれぞれにランナーがいる・いないの二通りの可能性があるので2の3乗=8通りと計算で出すこともできます)

つまりアウト数・塁上状況全通りには全部で 3×8=24通りの組み合わせがあることになります。ちょっと場合分けが大変そうな気がしてきましたね (^_^;;)

表:アウト数・塁上状況 場合分け 全通り

打席後の状況:打者出塁編

アウトカウントや打席前の塁上のランナーの各状況において、まずは打者が出塁するケースについて考えてみましょう。

打者が出塁する場合、アウトカウントは増えません。

そのため、アウトカウントによらず塁上のランナーの状況が打席前と打席後にどう変わるか、について考えればよいことになります。

表:打席後の得点・塁上状況(打者出塁編)

打席後の状況:0死から打者凡退編

次に0死から打者が凡退するケースについて。

0死からは打者がどんな凡退をしようと、チェンジになることはありません(トリプルプレーは起こらないものと仮定しています)

表:打席後の得点・塁上状況(0死から打者凡退編)

打席後の状況:1死から打者凡退編

次に1死から打者が凡退するケースについて。

おおむね0死の場合と同じですが、併殺打の際にはイニングが終了してしまいます。

表:打席後の得点・塁上状況(1死から打者凡退編)

打席後の状況:2死から打者凡退編

次に2死から打者が凡退するケースについて。

2死の場合は、凡退の形が何であろうとイニングが終わってしまいますね。また、併殺打は2死から起こらないので、考慮する必要がありません。

表:打席後の得点・塁上状況(2死から打者凡退編)

以上でシミュレーター作りに必要な、データ(選手成績)や場合分けの整理が完了しましたね。デザインの完成です。

というわけでいよいよ次回からは実際にこれをプログラムとして完成させていきましょう。

コメント

タイトルとURLをコピーしました