{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Agent-based model のチュートリアル\n", "\n", "このノートブックでは Boltzmann money modelを例にAgent-based Modelのコードの書き方を解説する.\n", "コードはPythonで実装し,最小限のコードでクラスオブジェクトを使った計算の例を示す." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Boltzmann money model\n", "\n", "Dragulescu と Yakovenko は所得不平等の生成プロセスを説明するシンプルなモデルを提唱した.\n", "仮定は以下の通り([Yakovenkoさんのwebsite](http://physics.umd.edu/~yakovenk/econophysics/))\n", "\n", "1. エージェントは等しい初期資産1を持ち,ランダムに出会う\n", "2. エージェントは出会った他者に自分の資産を1単位わたす.ただし自分の資産が0以下の場合は何もしない\n", "\n", "この仮定の下でエージェントがランダムに出会って交換を繰り返すと,資産の分布はBoltzmann-Gibbs法則に従う.\n", "\n", "このモデルをPythonで計算してみよう.なおこの単純な計算のために,わざわざAgentクラスを定義する必要はない.\n", "しかしこのチュートリアルでは,オブジェクトの考え方に慣れるために,あえてクラスを使ったコードで計算する.\n", "\n", "コード作成にあたり[Mesa](https://github.com/projectmesa)のサンプルコードを参照した.\n", "Mesaは包括的なAgent-based Model用のライブラリである.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "はじめに計算に必要なライブラリを導入する.以下のコードは上から順番に入力していくことを前提にしている." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# ライブラリの導入\n", "import random\n", "import matplotlib.pyplot as plt\n", "import numpy.random as rd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "次にAgentのクラスを定義する" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# define class of Agent\n", "class Agent:\n", " def __init__(self, unique_id):\n", " self.unique_id = unique_id #agentのid番号を記録する\n", " self.wealth = 1 #初期資産の定義" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "このクラスは初期化メソッドだけを含み,クラス固有のメソッドは持っていない.インスタンス化する際の引数はunique_idだけである(selfはpythonの仕様で必ず書く).例えばx = Agent(2)のようにインスタンス化する.するとこの「2」がunique_idの値として保存される.\n", "実際にやってみよう." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = Agent(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "このようにインスタンス化すると,オブジェクトxのインスタンス変数unique_idに値2が代入される.\n", "確認してみよう" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.unique_id" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "次にAgentクラスをn個まとめてインスタンス化する." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# define No.of agents\n", "n = 10 \n", "\n", "# define agents (instance of Agent)\n", "agents = [Agent(i) for i in range(n)] " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ここでは配列agentsにfor文を使ってn=10個のAgentクラスのオブジェクトを代入している.\n", "\n", "配列の中にfor文を書けるところが,ちょっとおもしろい.可読性も高いし,短くて済む.\n", "\n", "(こういう点がPythonの特徴のひとつだろう)\n", "\n", "agentsの中身を確認してみよう." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[<__main__.Agent at 0x78e2940>,\n", " <__main__.Agent at 0x78e29b0>,\n", " <__main__.Agent at 0x78e29e8>,\n", " <__main__.Agent at 0x78e2a20>,\n", " <__main__.Agent at 0x78e2a58>,\n", " <__main__.Agent at 0x78e2a90>,\n", " <__main__.Agent at 0x78e2ac8>,\n", " <__main__.Agent at 0x78e2b00>,\n", " <__main__.Agent at 0x78e2b38>,\n", " <__main__.Agent at 0x78e2b70>]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agents" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "__main__.Agent という表示でオブジェクトがat以下のメモリ上のアドレスに格納されたことが分かる.\n", "\n", "例えば0番目のAgentのメモリ上のアドレスを調べるにはid関数を使い,hexで16進数表示すると\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'0x78e2940'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hex(id(agents[0]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "さきほど表示した配列agentsの中身と一致することが分かる.\n", "\n", "慣れないうちはagentsという配列の中には抽象的なAgentクラスのオブジェクトが入っていることがイメージしにくいかもしれない.\n", "そのような場合は個々のAgentを呼び出して属性を確認してやればよい." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agents[3].unique_id" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ちゃんと配列の位置に対応したunique_idをAgentオブジェクトが持つことが示された.\n", "\n", "次にランダムマッチングしたAgentがお金のやりとりをする関数giving_moneyを定義する.\n", "\n", "(この部分をAgentクラスの固有メソッドとして定義してもいいのだが,無駄にややこしくなるので単純な関数として定義した)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# define functions\n", "def giving_money():\n", " agent1 = random.choice(agents)# 1人ランダムに選ぶ\n", " agent2 = random.choice(agents)# 1人ランダムに選ぶ\n", " if agent1.wealth > 0:\n", " agent2.wealth +=1 # 2の資産を1単位増やす\n", " agent1.wealth -=1 # 1の資産が1減る" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "この関数の動作は以下の通りである.\n", "\n", "1. まず,関数`random.choice`を使ってAgentを2人選び出す.\n", "2. 次にagent1の資産が1以上なら相手に渡す.\n", "\n", "まれに自分自身が相手になってしまうが,自分で自分に与えるので問題はない.\n", "\n", "ほかの言語の感覚からするとagentsを関数の引数にしなくていいのか?という気もするが\n", "さきほど確認したとおり,agentsをグローバルに定義しているので,参照できるようだ.\n", "\n", "これで準備完了.あとは繰り返し回数timeを指定して,関数`giving_money()`を\n", "for文で繰り返し実行すればよい" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "time = 10 # define No. of interaction \n", " \n", "# compute interactions \n", "for i in range(time):\n", " giving_money()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "以上で終了.\n", "計算の結果を確認してみよう." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(array([ 3., 0., 0., 5., 0., 0., 1., 0., 0., 1.]),\n", " array([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3. ]),\n", " )" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nABoRfgBoRPgBoBHhB4BGhB8AGhF+AGhE+AGgEeEHgEaEHwAaEX4AaET4AaAR4QeARoQfABoRfgBo\nRPgBoBHhB4BGhB8AGhF+AGhE+AGgEeEHgEaEHwAaEX4AaET4AaAR4QeARoQfABoRfgBoRPgBoBHh\nB4BGhB8AGhF+AGhE+AGgEeEHgEaEHwAaEX4AaET4AaAR4QeARoQfABoRfgBoRPgBoBHhB4BGhB8A\nGhH+09T6+vp2j7ADWbNl2GvLsGbLsNdOD0uFv6p+r6qurqofVtXHq+phUw/Wnb8gy7Bmy7DXlmHN\nlmGvnR4WDn9VPSPJ65K8IskvJflckg9U1XkTzwYATGyZM/5Lk7x5jPHOMcYXk7wgyQ+SPHfSyQCA\nyS0U/qo6J8neJP98w3VjjJHkQ0keOe1oAMDUzl7w+POS3CLJtzZd/60kDzjG8efO/vP+JN9Y8K62\n19Gj38zBg7fKu971rm25/69//etL3/dZZ52Vo0ePTjzR6l199dXz/7syyf4lPsPXk2zHn9ds7iuv\nvDL79y8z9/Y6ePDgtu3zZW19r2zVVvbazt0vW/3aspWva1ux/ftlWf92w/+cO+VnrdkJ+0keXHXX\nJAeTPHKM8YkN178myYVjjEduOv5Z2Z6vxABwprhkjPHuqT7Zomf8h5L8JMmdN11/5yTfPMbxH0hy\nSZKvJjmy6HAA0Ni5Se6dWUsns9AZf5JU1ceTfGKM8eL5ryvJgSR/OcZ47ZTDAQDTWvSMP0len+Tt\nVfXpJJ/M7Fn+t07y9gnnAgBWYOHwjzH+bv6a/T/P7CH+zyZ5whjjO1MPBwBMa+GH+gGAnct79QNA\nI8IPAI1sOfyL/sCeqnp0VX26qo5U1Zer6re2OsNOtMi6VdVFVXV00+UnVXWnUznzdqqqC6rqfVV1\ncP77v/gkbtN6ry26ZvZZUlUvq6pPVtW1VfWtqnpPVd3/JG7Xfa8tvG7d91tVvaCqPldVh+eXj1bV\nE2/mNpPssy2Ff9Ef2FNV907yD5m95e+Dk7wxyVur6te2MsdOs+QPOhpJ7pfkLvPLXccY3171rKeR\n22T2RNIXZbYWJ2SvJVlwzea677MLkrwpycOTPC7JOUk+WFW3Ot4N7LUkS6zbXOf99rUkL0myJ7O3\nwr8qyXuravexDp50n40xlr4k+XiSN274dWX2XpZ/fJzjX5Pk85uuW09y5Vbm2GmXJdbtoszeOOl2\n2z376XBJcjTJxTdzjL22+JrZZzddk/Pma/crJzjGXltu3ey3m67Jd5P8znE+Ntk+W/qMf8kf2POI\n+cc3+sAJjj/jbOEHHVWSz1bVN6rqg1X1qNVOuuO132tLss9u7PaZnZV+7wTH2Gs3dTLrlthvSZKq\nOquqnpnZe+J87DiHTbbPtvJQ/4l+YM9djnObuxzn+NtV1S23MMtOssy6XZPk+Ul+I8mvZ/YQ0Yer\n6iGrGvIMYK8tzj7bYP6upG9I8pExxhdOcKi9tsEC69Z+v1XVg6rq+0l+lOTyJE8dsx93fyyT7bNl\n3rmPU2yM8eUkX95w1cer6j6ZvWtiqycRsTr22U1cnuSBSc7f7kF2mJNaN/stSfLFzL5fvyvJ05K8\ns6ouPEH8J7GVM/5Ff2BP5tcf6/hrxxg/2sIsO8ky63Ysn0xy36mGOgPZa9Nouc+q6q+SPCnJo8cY\n19zM4fba3ILrdiyt9tsY4/oxxlfGGJ8ZY/xJZk/0fvFxDp9sny0d/jHGj5N8Osljb7hu/hDPY5N8\n9Dg3+9jG4+cen+N/T+OMs+S6HctDMnuojGNrv9cm0m6fzeP1lCS/OsY4cBI3sdey1LodS7v9tslZ\nSY73sP10+2yLz0B8epIfJHlOkp9P8ubMnpV4x/nHX53kHRuOv3eS72f27MQHZPYyo/9N8rjtfjbl\nKX7m5qLr9uIkFye5T5JfyOz7Zz/O7F/V2/77OUVrdpvMHhJ7SGbPFv6D+a/vYa9Ntmb22exh6v/O\n7OVpd95wOXfDMa+y1yZZt9b7bb4eFyS5V5IHzf8+Xp/kMfOPr+xr2hTDvyjJV5P8MLN/eTx0w8fe\nluSqTcdfmNkZ7w+T/EeS39zuP4Bt+kM/6XVL8kfztbouyXcye0XAhdv9ezjF63XRPF4/2XT5G3tt\nmjWzz376ssfN6/WTJM/ZcIy9NsG6dd9vSd6a5CvzPfPNJB+8Ifqr3md+SA8ANOK9+gGgEeEHgEaE\nHwAaEX4AaET4AaAR4QeARoQfABoRfgBoRPgBoBHhB4BGhB8AGvk/+tu00ErFIZMAAAAASUVORK5C\nYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# analyze statistics \n", "agent_wealth = [x.wealth for x in agents]# 各自の資産を取り出す.\n", "%matplotlib inline\n", "#jupyterでplotをインライン表示するための命令\n", "# 交換後の資産分布\n", "plt.hist(agent_wealth)#plot a histogram\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "agent_wealth = [x.wealth for x in agents]\n", "\n", "は,各Agentの属性wealthだけを取り出した配列を作っている.\n", "\n", "## まとめ\n", "\n", "では最初からコードをまとめて,計算後の資産分布をplotするまで実行してみよう\n", "\n", "n=50, time=500と仮定する." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(array([ 23., 16., 6., 0., 2., 1., 0., 1., 0., 1.]),\n", " array([ 0. , 0.7, 1.4, 2.1, 2.8, 3.5, 4.2, 4.9, 5.6, 6.3, 7. ]),\n", " )" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# ライブラリの導入\n", "import random\n", "import matplotlib.pyplot as plt\n", "import numpy.random as rd\n", "\n", "# define class of Agent\n", "class Agent:\n", " def __init__(self, unique_id):\n", " self.unique_id = unique_id #agentのid番号を記録する\n", " self.wealth = 1 #初期資産の定義\n", "\n", "# define functions\n", "def giving_money():\n", " agent1 = random.choice(agents)# 1人ランダムに選ぶ\n", " agent2 = random.choice(agents)# 1人ランダムに選ぶ\n", " if agent1.wealth > 0:\n", " agent2.wealth +=1 # 2の資産を1単位増やす\n", " agent1.wealth -=1 # 1の資産が1減る\n", "\n", "n = 50 # define No.of agents\n", "time = 500 # define No. of interaction \n", "\n", "# define agents (instance of Agent)\n", "agents = [Agent(i) for i in range(n)] \n", "\n", "# compute interactions \n", "for i in range(time):\n", " giving_money()\n", " \n", "# analyze statistics \n", "agent_wealth = [x.wealth for x in agents]# 各自の資産を取り出す.\n", "%matplotlib inline\n", "plt.hist(agent_wealth)#plot a histogram" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "計算の結果,現実の所得分布の特徴(中低層が多く,高層が少ない)を再現した分布が生成された" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ちなみにクラスを使わず関数だけで書くと,さらにコードはシンプルになる.\n", "以下はMathematicaで作った例." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```mathematica\n", "moneymodel[n_, k_] := Module[{money, id, give},\n", " id = Range[n];\n", " money = Table[1, {n}];(* 初期資産の設定 *)\n", " (* interaction 用の関数定義*)\n", " give[] := Module[{self, other},\n", " self = RandomInteger[{1, n}];\n", " other = RandomInteger[{1, n}];\n", " If[money[[self]] > 0,\n", " money[[other]] = money[[other]] + 1;\n", " money[[self]] = money[[self]] - 1]];\n", " Do[give[], {k}];\n", " Histogram[money]]\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "この関数 moneymodel[n, k] の引数は`n`がエージェントの数で`k`が試行回数(ランダムマッチの回数)である." ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.1" } }, "nbformat": 4, "nbformat_minor": 2 }