落車数の確率分布

あるレースにおいて落車した選手の数を落車数とする。落車数は0から9の整数をとる確率変数となり、この確率分布を与えるモデルを考える。

2008年の落車数

2008年に実施された32994個レースで、落車が発生したレースは2116個レースでありレース単位の落車率は2116/32994=6.41%である。落車した選手ののべ人数は3954人で、平均落車数は3954/32994=0.120(人/レース)である。また、落車が発生したレースに限ると平均落車数は3954/2116=1.87(人/レース)となる*1

2008年のデータによる落車数の確率分布は下表のようになる。

落車数 0 1 2 3 4 5 6 7 8 9
確率(%) 93.6 3.07 1.89 0.94 0.36 0.10 0.045 0.0091 0.0 0.0030

プロットすると以下になる。

落車数>0の領域を詳しく見るためy軸の範囲を変えると、


2項分布に当てはめる

まずは単純なモデルをやってみる。ひとりの選手があるレースで落車する確率を一定値pとすると、ある9車立てのレースでk人が落車する確率は

C(9,k) * p^k * (1-p)^(9-k)  ... (1)

になる*2。この分布が2008年のデータに合うように母数pを決める。ここでは落車数=0のときの確率が一致するようにpを決めよう。落車がない確率を実データの値に等しいとして、(1-p)^9=93.6%を得る。これより、p=0.732%となる。

このpを(1)式に入れて、kを振ると以下の確率分布が得られる。

落車数 0 1 2 3 4 5 6 7 8 9
確率(%) 93.6 6.21 0.183 0.0031 0.000035 ~0 ~0 ~0 ~0 ~0

これを先の実データと合わせてプロットすると、

このグラフを見ると、実データとかなりずれがある。2項分布では落車数が大きくなると急速に確率が0に落ちるのに対し、実データはその変化が緩やかで裾が長い曲線を描く。

このモデルでは個々の落車は全く関係なく発生するものとしているが、実際は1人が落車するとそれが原因となって次の落車が引き起こされることがよくある。この点が考慮されていないので、複数の選手が落車する確率を低く見積もってしまうことになる。

高次落車モデル

上の欠点を修正したモデルを考える。以下のように、あるレースの落車数を手続きとして定義する。

あるレースで1人の選手が他の選手と関係なく独立に落車する確率をp1とする。最初、そのレースに参加している全ての選手について確率p1で落車が発生する(これを1次落車と呼ぶ)。ここで誰も落車しなかったら落車数=0で終了する。もし誰かが落車した場合、さらに確率p2で1人が落車する(これを2次落車と呼ぶ)。ここで落車しなければ終了し、落車すればまた確率p2で落車を判定する。これを繰り返す(同様にn次落車が定義される)。

Rubyで書けば次のような関数になる。

def rand_fall(p1, p2)
  # あるレースの落車数を返す
  n = 0
  9.times{n += 1 if rand <= p1}
  return(0) if n == 0
  loop do
    if n < 9 && rand <= p2
      n += 1
    else
      break
    end
  end
  return(n)
end

上で、randは0から1.0までの浮動小数点数の疑似乱数を返す関数である。母数p1、p2を与えてrand_fall()を多数回呼んで結果を集計すると確率分布が得られる。

次に、2008年のデータに合うようにp1、p2を決める。p1は2項分布のときと同様に、落車数=0のときの確率が実データと一致するように決める。値は2項分布のpと同じでp1=0.732%になる。p2は最尤法により数値計算で決める。対数尤度は、

Σ(i=0〜9) [dist_data(i) * log(dist_fall(p1, p2, i))] ... (2)

となる。ここで、dist_data(i)は実データによる確率分布関数で落車数=iの確率を与える。dist_fall(p1, p2, i)はこのモデルの確率分布関数であり、p1、p2を具体的に与えればrand_fall()により数値的に求められる。

p1はすでに決めているので(2)式はp2のみの関数になり、(2)式の最大値を与えるp2を数値計算で求めれば良い。2008年のデータで実際にやってみると、p2=45.5%となる。

このようにして求めたp1、p2から数値的に確率分布を得ると下の表になる。

落車数 0 1 2 3 4 5 6 7 8 9
確率(%) 93.6 3.41 1.62 0.75 0.34 0.16 0.068 0.032 0.012 0.013

実データとともにプロットすると、

2項分布に比べれば良く合っている。悪くないモデルと言えるだろう。ただし、細かく見ると、実データに比べて裾が長い曲線になっていて、実際よりも大量落車の確率が若干高くなっている。これは、2次以降の落車を全て同じ確率p2で発生するとしていることによると思われる。選手は1次落車を見た時点で回避行動を取るから、2次落車より時間的に後で起こる3次落車は起こりにくい。したがって、p2>p3であるはずだ。同様に高次の落車程その発生確率は低いと推測される。新たにp3、p4などを母数に入れればより実データと合う確率分布が得られるが、そこまでは止めておこう。

S級とA級を比べる

2008年のデータをS、A級別に2つに分けてそれぞれでパラメタp1、p2を求めてみる。対象となるレース数、レース単位での落車率とともに、結果を下に示す。

レース数 落車率(%) p1(%) p2(%)
A級 25107 5.38 0.613 44.9
S級 7884 9.72 1.13 46.1

A級とS級では落車率に大きな違いがあって、S級はA級の9.72/5.38=1.81倍もある。p1は、これがほぼ同じように反映され、1.13/0.613=1.84倍とはやり大きな差になっている*3。しかし、p2は46.1/44.9=1.027倍でA、S級でほとんど差がない。

S級選手は明らかに落車が多くなるような走りをしているが、それはp1を大きくするだけで、p2に変化はほとんどない。前方で落車があったとき、どの選手もまず全力で追突を避けようとし、その成功率はA、S級でほとんど同じであるということだろう。

あるレースにおいて落車が発生するかしないかは選手の意図により大きく変化するが、落車が発生してしまったレースにおいてその落車数の多い少ないは、ほとんど偶然に支配されると考えてよいと思う。少なくとも、選手が意図的に大量落車を防ぐことは非常に困難であろう。

*1:競輪見太郎データの集計による。データの信頼性については落車、失格の発生頻度の時間的推移を参照されたい。

*2:C(n,k)=n!/((n-k)!*k!)で、n個からk個取る組合せの数を表す。

*3:p1とレース単位の落車率p_rには、(1-p1)^9=1-p_rの関係がある。