システムとモデリング

modelica, Julia, Design Structure Matrix, SysML, 他モデリング全般について。

プロ野球のチームの順位をマルコフモデルから考える(Matlab)

久々の更新になります。2020年も最後になりますが、11月に『多モデル思考』という素晴らしい本が出版されました。数理モデルを分野横断的に網羅する辞書的な本になります。
今回この書籍にありましたマルコフモデルの考え方を日本野球のペナントレースに適用してみます。

マルコフモデルについて

マルコフモデルは確率モデルの1種で『状態』と『遷移確率』からなるモデルです。
 
s = [1 1 1 2 2 3];
t = [2 3 1 1 2 1] ;
G = digraph(s,t);
nLabels = {'1' '2' '3'};
eLabels = {'1/3','1/3','1/3','0.7','0.3','1.0'};
plot(G,'Layout','force','EdgeLabel',eLabels,'NodeLabel',nLabels)
 
xlim([-1.30 1.00])
ylim([-1.35 0.94])
title('マルコフモデルの例')
上記のように状態1,2,3とそれぞれの状態への遷移確率(1/3, 0.7……)が記述されたモデルになります。このモデルの解釈ですが
今の状態が状態1とすると、次のステップには『1/3の確率に状態2に、1/3の確率で状態3に、1/3の確率で状態1のままになる』。
また今の状態が2とすると次のステップには『0.7の確率で状態1に、0.3の確率で状態2のままになる』。
今の状態が3だとすると、次のステップには『1.0の確率で状態1になる』。
と読むことができます。
このマルコフモデルは一定の条件を満たすと、何ステップも繰り返すうちにそれぞれの状態に存在する確率は収束するようになります。

プロ野球のチームの強さをマルコフモデルで考える

このマルコフモデルを使ってプロ野球ペナントレースの順位を考えてみます。
プロ野球のチーム毎の順位は一般的に勝利数の多さで決められますが、勝利数で決められた順位とマルコフモデルで決められた順位とに相違があるか確認してみます。
 

セ・リーグマルコフモデルの作成

 
対戦成績表は日刊スポーツより
マルコフモデルを作成する以上、この場合の『状態』と『遷移確率』を定義しなくてはなりません。

『状態』

今回、「巨人」「阪神」「中日」「DeNA」「広島」「ヤクルト」の6状態を作成します。
この状態の解釈は、例えば今の状態が状態『巨人』だとすると、『巨人が優勝している状態』ということにします。
 
A = zeros(6) ;
G = digraph(A);
nLabels = {'巨人','阪神','中日','DeNA','広島','ヤクルト'};
plot(G,'Layout','force','NodeLabel',nLabels)

『遷移確率』

例えば、巨人と阪神の対戦成績は16勝8敗です。また巨人はこのリーグ中120試合行い、そのうち8試合は引き分けだったので有効試合数は112試合です。
このとき、状態「巨人」から状態「阪神」への遷移確率は8/112=0.0714とします。巨人が優勝状態から、確率0.071429で阪神に敗北して、阪神が優勝状態になるイメージです。
A = zeros(6) ;
A(1,2) = 8/112;
G = digraph(A);
nLabels = {'巨人','阪神','中日','DeNA','広島','ヤクルト'};
elabels = G.Edges.Weight;
plot(G,'Layout','force','NodeLabel',nLabels,'EdgeLabel',elabels)
この要領で、巨人の遷移確率をすべて作成していきます。
A = zeros(6) ;
A(1,:) =[67/112 8/112 10/112 12/112 9/112 6/112] ;
G = digraph(A);
nLabels = {'巨人','阪神','中日','DeNA','広島','ヤクルト'};
elabels = G.Edges.Weight;
plot(G,'Layout','force','NodeLabel',nLabels,'EdgeLabel',elabels)
上記のように所与の遷移確率で各チームに敗北し状態が移行しますが、逆に敗北しなかった場合(確率0.59821で)状態「巨人」のままです。
ではセ・リーグ全体のマルコフモデルを作成します。
 
セ・リーグの確率の行列は以下になります。
 
B = [67/112 8/112 10/112 12/112 9/112 6/112;
16/113 60/113 10/113 9/113 8/113 10/113;
12/115 14/115 60/115 9/115 13/115 7/115;
12/114 12/114 15/114 56/114 8/114 11/114;
12/108 13/108 10/108 14/108 52/108 7/108;
15/110 13/110 15/110 12/110 14/110 41/110]
B = 6×6
0.5982 0.0714 0.0893 0.1071 0.0804 0.0536 0.1416 0.5310 0.0885 0.0796 0.0708 0.0885 0.1043 0.1217 0.5217 0.0783 0.1130 0.0609 0.1053 0.1053 0.1316 0.4912 0.0702 0.0965 0.1111 0.1204 0.0926 0.1296 0.4815 0.0648 0.1364 0.1182 0.1364 0.1091 0.1273 0.3727
G = digraph(B);
nLabels = {'巨人','阪神','中日','DeNA','広島','ヤクルト'};
elabels = G.Edges.Weight;
plot(G,'Layout','force','NodeLabel',nLabels,'EdgeLabel',elabels)
 
xlim([-2.92 3.03])
ylim([-2.76 2.63])
案の定複雑でわけがわかりませんが、とりあえず完成しました。

順位の計算

チームの順位はマルコフモデルのステップを収束するまで繰り返した後、「優勝状態にいる確率が高い順」としてみます。
まず初期値を各チーム均等に1/6ずつ割り振ります。その状態から、1ステップ遷移したあとのそれぞれの状態にいる確率を計算してみます。
team = ["巨人" "阪神" "中日" "DeNA" "広島" "ヤクルト" ];
u = [1/6 1/6 1/6 1/6 1/6 1/6];%%初期状態
u1 = [team;u*B] %1ステップ後の確率
u1 = 2×6 の string 配列
"巨人" "阪神" "中日" "DeNA" "広島" "ヤクルト"
"0.19948" "0.17799" "0.17668" "0.16583" "0.15719" "0.12283"
さらに1ステップ経過した状態での確率は以下になります。
u2 = [team;u*B^2] %2ステップ後の確率
u22×6 の string 配列
"巨人" "阪神" "中日" "DeNA" "広島" "ヤクルト"
"0.21464" "0.18116" "0.17887" "0.16461" "0.15156" "0.10916"
まだ収束はしていないようですね。100ステップと101ステップの遷移確率を見てみます。
u100 = [team;u*B^100] %100ステップ後の確率
u100 = 2×6 の string 配列
"巨人" "阪神" "中日" "DeNA" "広島" "ヤクルト"
"0.22823" "0.18113" "0.17859" "0.16316" "0.1463" "0.10259"
u101 = [team;u*B^101] %101ステップ後の確率
u101 = 2×6 の string 配列
"巨人" "阪神" "中日" "DeNA" "広島" "ヤクルト"
"0.22823" "0.18113" "0.17859" "0.16316" "0.1463" "0.10259"
100ステップ後と101ステップ後の遷移確率は同じで、収束している事がわかります。
またこの結果からマルコフモデルによるセ・リーグの順位は以下のようになります。
1位:巨人
2位:阪神
3位:中日
4位:DeNA
5位:広島
6位:ヤクルト
実際の順位を再掲しますが、全く同じでした。(日刊スポーツより)

なぜ同じだったのか

実際の順位は「勝利数が多い順」に決まりますので、どのチームに勝っても、その価値は等しくなります。一方マルコフモデルでは「強いチームに勝った場合、弱いチームに勝つよりも価値がある」と見做されると考えています(あまり検証はできていませんが、ページランクと同様の考え方だとするとそのように類推できるように思います)。
なので両者の順位付けには違いがでてしかるべきですが、今回はたまたま同じになったと考えるしかないかと考えています。
 

パ・リーグではどうか。

 
セ・リーグで実施した手順を、同様にパ・リーグでも実施してみます。
C = [73/115 12/115 10/115 9/115 6/115 5/115;
11/117 60/117 15/117 15/117 11/117 5/117;
13/116 9/116 58/116 10/116 14/116 12/116;
15/112 8/112 12/112 55/112 10/112 12/112;
17/115 13/115 10/115 11/115 53/115 11/115;
17/113 18/113 11/113 10/113 12/113 45/113]
C = 6×6
0.6348 0.1043 0.0870 0.0783 0.0522 0.0435 0.0940 0.5128 0.1282 0.1282 0.0940 0.0427 0.1121 0.0776 0.5000 0.0862 0.1207 0.1034 0.1339 0.0714 0.1071 0.4911 0.0893 0.1071 0.1478 0.1130 0.0870 0.0957 0.4609 0.0957 0.1504 0.1593 0.0973 0.0885 0.1062 0.3982
G = digraph(C);
nLabels = {'ソフトバンク','ロッテ','西武','楽天','日本ハム','オリックス'};
elabels = G.Edges.Weight;
plot(G,'Layout','force','NodeLabel',nLabels,'EdgeLabel',elabels)
 
xlim([-2.92 3.03])
ylim([-2.76 2.63])
 
team = ["ソフトバンク" "ロッテ" "西武" "楽天" "日本ハム" "オリックス" ];
u100 = [team;u*C^100] %100ステップ後の確率
u100 = 2×6 の string 配列
"ソフトバンク" "ロッテ" "西武" "楽天" "日本ハム" "オリックス"
"0.25471" "0.17235" "0.16757" "0.15625" "0.13966" "0.10947"
u101 = [team;u*C^101] %100ステップ後の確率
u101 = 2×6 の string 配列
"ソフトバンク" "ロッテ" "西武" "楽天" "日本ハム" "オリックス"
"0.25471" "0.17235" "0.16757" "0.15625" "0.13966" "0.10947"
パ・リーグでも実際の順位とマルコフモデルでの順位は一致しました。
今回はここまでにします。