KMR (Kandori-Mailath-Rob)モデルのシミュレーション

ゲームの詳細

モジュール類のインポート


In [51]:
#!/usr/bin/python
#-*- encoding: utf-8 -*-
"""
KMR (Kandori-Mailath-Rob) Model
Copyright (c) 2015 @myuuuuun
https://github.com/myuuuuun/KMR

Released under the MIT license.
"""
# エラー処理の類はまた今度
# 無駄が多い部分があるものの、それもまた今度

%matplotlib inline
import numpy as np
import scipy as sc
import quantecon as qe
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from kmr import *

2×2対称行列ゲームの場合

利得表は

行動1 行動2
行動1 4, 4 0, 3
行動2 3, 0 2, 2

で与えられる。
以下、N=プレイヤーの総人数、ε=最適行動をとらない確率とする。

1. N=10, ε=0.1のとき

マルコフ連鎖の遷移行列は、


In [12]:
array = [[4, 0], [3, 2]]
kmr = KMR(array, 10, 0.1)

rst = ""
for v in kmr.transition_matrix:
    for j in v:
        rst += "{0:.3f} ".format(j)
    rst += "\n"
    
print(rst)


0.950 0.050 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
0.095 0.860 0.045 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
0.000 0.190 0.770 0.040 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
0.000 0.000 0.285 0.680 0.035 0.000 0.000 0.000 0.000 0.000 0.000 
0.000 0.000 0.000 0.380 0.590 0.030 0.000 0.000 0.000 0.000 0.000 
0.000 0.000 0.000 0.000 0.475 0.500 0.025 0.000 0.000 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.570 0.050 0.380 0.000 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.000 0.035 0.680 0.285 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.040 0.770 0.190 0.000 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.045 0.860 0.095 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.050 0.950 

※列: 遷移前の行動1をとるプレイヤー数, 行: 行動1をとるプレイヤー数

となる。

定常分布は、


In [52]:
state_players = kmr.state_players
stationary_distribution = kmr.compute_stationary_distribution()[0]
for p, d in zip(state_players, stationary_distribution):
    print("{0}: {1:.3f}".format(p, d))


[0, 10]: 0.597
[1, 9]: 0.314
[2, 8]: 0.074
[3, 7]: 0.010
[4, 6]: 0.001
[5, 5]: 0.000
[6, 4]: 0.000
[7, 3]: 0.000
[8, 2]: 0.000
[9, 1]: 0.001
[10, 0]: 0.002

※ [行動1をとっている人数, 行動2をとっている人数]: 確率

となる。パレート効率的でない方の純粋戦略ナッシュ均衡に収束しているのが面白いところ。

1000期でシミュレートしてみると、状態の遷移状況は、


In [48]:
simulated = kmr.from_stateindex_to_stateplayersnum(kmr.simulate(1000, 5, start_init=True))
print(simulated)


[[ 5  5]
 [ 5  5]
 [ 5  5]
 ..., 
 [ 0 10]
 [ 0 10]
 [ 0 10]]

となる。これをグラフにプロットしてみると、


In [26]:
kmr.plot_simulation(1000, 5)


となり、おおむね定常分布に一致していることがわかる。

他の初期状態の場合でも試してみると、


In [27]:
kmr.plot_simulation(1000, 0)
kmr.plot_simulation(1000, 2)
kmr.plot_simulation(1000, 4)
kmr.plot_simulation(1000, 6)
kmr.plot_simulation(1000, 8)
kmr.plot_simulation(1000, 10)


初期状態が0〜6の場合は定常分布通りになるが、初期状態が8や10だと(行動1, 行動1)のナッシュ均衡が実現しやすそう。

time seriesを1000期から増やしてみると、


In [54]:
kmr.plot_simulation(10000, 8)
kmr.plot_simulation(10000, 10)
kmr.plot_simulation(100000, 10)
kmr.plot_simulation(500000, 10)
kmr.plot_simulation(1000000, 10)


途中で偶然にも(行動2, 行動2)のナッシュ均衡の側に近づけば、それ以降は(ほぼ)ずっとそっちに張り付く。

2. N=10, ε= 0.2, 0.01のとき

εが大きかったり小さかったりすると、どういう状態推移をするだろうか。


In [35]:
array = [[4, 0], [3, 2]]
kmr2 = KMR(array, 10, 0.2)
kmr3 = KMR(array, 10, 0.01)

# ε=0.2の定常分布
rst = ""
for v in kmr2.transition_matrix:
    for j in v:
        rst += "{0:.3f} ".format(j)
    rst += "\n"
print("ε=0.2の定常分布")
print(rst)

# ε=0.01の定常分布
rst = ""
for v in kmr3.transition_matrix:
    for j in v:
        rst += "{0:.3f} ".format(j)
    rst += "\n"
print("\nε=0.01の定常分布")
print(rst)


ε=0.2の定常分布
0.900 0.100 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
0.090 0.820 0.090 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
0.000 0.180 0.740 0.080 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
0.000 0.000 0.270 0.660 0.070 0.000 0.000 0.000 0.000 0.000 0.000 
0.000 0.000 0.000 0.360 0.580 0.060 0.000 0.000 0.000 0.000 0.000 
0.000 0.000 0.000 0.000 0.450 0.500 0.050 0.000 0.000 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.540 0.100 0.360 0.000 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.000 0.070 0.660 0.270 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.080 0.740 0.180 0.000 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.090 0.820 0.090 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.100 0.900 


ε=0.01の定常分布
0.995 0.005 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
0.100 0.896 0.005 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
0.000 0.199 0.797 0.004 0.000 0.000 0.000 0.000 0.000 0.000 0.000 
0.000 0.000 0.298 0.698 0.003 0.000 0.000 0.000 0.000 0.000 0.000 
0.000 0.000 0.000 0.398 0.599 0.003 0.000 0.000 0.000 0.000 0.000 
0.000 0.000 0.000 0.000 0.497 0.500 0.003 0.000 0.000 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.597 0.005 0.398 0.000 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.000 0.003 0.698 0.298 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.004 0.797 0.199 0.000 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.005 0.896 0.100 
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.005 0.995 

ε=0.2のときの状態推移をplot


In [34]:
kmr2.plot_simulation(1000, 0)
kmr2.plot_simulation(1000, 2)
kmr2.plot_simulation(1000, 4)
kmr2.plot_simulation(1000, 6)
kmr2.plot_simulation(1000, 8)
kmr2.plot_simulation(1000, 10)


「実験」をする確率が上がると、2つの(純粋戦略)ナッシュ均衡をいったり来たりする


In [55]:
kmr2.plot_simulation(10000, 10)
kmr2.plot_simulation(50000, 10)
kmr2.plot_simulation(100000, 10)
kmr2.plot_simulation(500000, 10)
kmr2.plot_simulation(1000000, 10)


ε=0.01のときの状態推移をplot


In [36]:
kmr3.plot_simulation(1000, 0)
kmr3.plot_simulation(1000, 2)
kmr3.plot_simulation(1000, 4)
kmr3.plot_simulation(1000, 6)
kmr3.plot_simulation(1000, 8)
kmr3.plot_simulation(1000, 10)


「実験」をする確率が下がると、1つの純粋戦略ナッシュ均衡に張り付いたら、離れづらい。


In [53]:
kmr3.plot_simulation(10000, 10)
kmr3.plot_simulation(50000, 10)
kmr3.plot_simulation(100000, 10)
kmr3.plot_simulation(500000, 10)
kmr3.plot_simulation(1000000, 10)


離れづらい。

3×3対称行列ゲームの場合

利得表は

行動1 行動2 行動3
行動1 6, 6 0, 5 0, 0
行動2 5, 0 7, 7 5, 5
行動3 0, 0 5, 5 8, 8

で与えられる。
以下、N=プレイヤーの総人数、ε=最適行動をとらない確率とする。

1. N=10, ε=0.1のとき

定常分布は、


In [59]:
array = [[6, 0, 0],
             [5, 7, 5],
             [0, 5, 8]]
kmr = KMR(array, 10, 0.1)

state_players = kmr.state_players
stationary_distribution = kmr.compute_stationary_distribution()[0]
for p, d in zip(state_players, stationary_distribution):
    print("{0}: {1:.3f}".format(p, d))


[0, 0, 10]: 0.111
[0, 1, 9]: 0.040
[0, 2, 8]: 0.007
[0, 3, 7]: 0.001
[0, 4, 6]: 0.000
[0, 5, 5]: 0.000
[0, 6, 4]: 0.000
[0, 7, 3]: 0.002
[0, 8, 2]: 0.022
[0, 9, 1]: 0.139
[0, 10, 0]: 0.391
[1, 0, 9]: 0.039
[1, 1, 8]: 0.013
[1, 2, 7]: 0.002
[1, 3, 6]: 0.000
[1, 4, 5]: 0.000
[1, 5, 4]: 0.000
[1, 6, 3]: 0.001
[1, 7, 2]: 0.006
[1, 8, 1]: 0.045
[1, 9, 0]: 0.140
[2, 0, 8]: 0.006
[2, 1, 7]: 0.002
[2, 2, 6]: 0.000
[2, 3, 5]: 0.000
[2, 4, 4]: 0.000
[2, 5, 3]: 0.000
[2, 6, 2]: 0.001
[2, 7, 1]: 0.006
[2, 8, 0]: 0.022
[3, 0, 7]: 0.001
[3, 1, 6]: 0.000
[3, 2, 5]: 0.000
[3, 3, 4]: 0.000
[3, 4, 3]: 0.000
[3, 5, 2]: 0.000
[3, 6, 1]: 0.001
[3, 7, 0]: 0.002
[4, 0, 6]: 0.000
[4, 1, 5]: 0.000
[4, 2, 4]: 0.000
[4, 3, 3]: 0.000
[4, 4, 2]: 0.000
[4, 5, 1]: 0.000
[4, 6, 0]: 0.000
[5, 0, 5]: 0.000
[5, 1, 4]: 0.000
[5, 2, 3]: 0.000
[5, 3, 2]: 0.000
[5, 4, 1]: 0.000
[5, 5, 0]: 0.000
[6, 0, 4]: 0.000
[6, 1, 3]: 0.000
[6, 2, 2]: 0.000
[6, 3, 1]: 0.000
[6, 4, 0]: 0.000
[7, 0, 3]: 0.000
[7, 1, 2]: 0.000
[7, 2, 1]: 0.000
[7, 3, 0]: 0.000
[8, 0, 2]: 0.000
[8, 1, 1]: 0.000
[8, 2, 0]: 0.000
[9, 0, 1]: 0.000
[9, 1, 0]: 0.000
[10, 0, 0]: 0.000

となる((行動2, 行動2)のナッシュ均衡に落ち着く確率が高そう)。

time_series=1000でsimulateしてみると、


In [68]:
kmr.plot_simulation(1000, kmr.from_stateplayersnum_to_stateindex([0, 0, 10]))
kmr.plot_simulation(1000, kmr.from_stateplayersnum_to_stateindex([0, 5, 5]))
kmr.plot_simulation(1000, kmr.from_stateplayersnum_to_stateindex([0, 10, 0]))
kmr.plot_simulation(1000, kmr.from_stateplayersnum_to_stateindex([5, 0, 5]))
kmr.plot_simulation(1000, kmr.from_stateplayersnum_to_stateindex([5, 5, 0]))
kmr.plot_simulation(1000, kmr.from_stateplayersnum_to_stateindex([10, 0, 0]))


(行動1, 行動1)の均衡は長続きしない。

time_series=50000だと、


In [69]:
kmr.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([0, 0, 10]))
kmr.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([0, 5, 5]))
kmr.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([0, 10, 0]))
kmr.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([5, 0, 5]))
kmr.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([5, 5, 0]))
kmr.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([10, 0, 0]))


(行動2, 行動2)や(行動3, 行動3)の均衡がよく起こる。

2. N=10, ε=0.2, 0.01のとき

ε=0.2


In [70]:
array = [[6, 0, 0],
             [5, 7, 5],
             [0, 5, 8]]
kmr2 = KMR(array, 10, 0.2)

kmr2.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([0, 0, 10]))
kmr2.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([0, 5, 5]))
kmr2.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([0, 10, 0]))
kmr2.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([5, 0, 5]))
kmr2.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([5, 5, 0]))
kmr2.plot_simulation(50000, kmr.from_stateplayersnum_to_stateindex([10, 0, 0]))


ε=0.01


In [73]:
array = [[6, 0, 0],
             [5, 7, 5],
             [0, 5, 8]]
kmr3 = KMR(array, 10, 0.01)

kmr3.plot_simulation(500000, kmr.from_stateplayersnum_to_stateindex([0, 0, 10]))
kmr3.plot_simulation(500000, kmr.from_stateplayersnum_to_stateindex([0, 5, 5]))
kmr3.plot_simulation(500000, kmr.from_stateplayersnum_to_stateindex([0, 10, 0]))
kmr3.plot_simulation(500000, kmr.from_stateplayersnum_to_stateindex([5, 0, 5]))
kmr3.plot_simulation(500000, kmr.from_stateplayersnum_to_stateindex([5, 5, 0]))
kmr3.plot_simulation(500000, kmr.from_stateplayersnum_to_stateindex([10, 0, 0]))



In [ ]: