{ "cells": [ { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end", "slide_type": "subslide" }, "slide_helper": "slide_end", "slideshow": { "slide_type": "slide" } }, "source": [ "# モデル化" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_type": "subslide" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## 構想" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end" }, "slide_helper": "slide_end", "slideshow": { "slide_type": "-" } }, "source": [ "シチュエーション:\n", "\n", "- はじめに議題が与えられる\n", "- 参加者はそれまでに提出された意見に関連して自分の意見を述べる\n", "- 沈黙も考慮\n", "\n", "仮定:\n", "\n", "- 一度に発言できるのは一人まで\n", "- 参加者の意見の引き出しは有限(人が多いほど多様性が確保される)\n", "- 結論は議題やある一定数以上の意見に関連した意見である(たとえば参加者の数の2倍程度)。\n", "- 結論が出るまでにかかる時間が長いほど評価は低くなる。\n" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_type": "subslide" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## 定式化" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end" }, "slide_helper": "subslide_end", "slideshow": { "slide_type": "-" } }, "source": [ "評価関数について:\n", "\n", "評価関数は参加者の人数$n$に対して\n", "\n", "$L(n)$:結論までに張られたリンクの数\n", "\n", "$T(n)$:結論までにかかった時間\n", "\n", "として、\n", "\n", "$$f(n) = f_L(n) - f_T(n)$$\n", "\n", "とできるだろう。$f_{L},f_{T}$は正値関数\n" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end", "slide_type": "subslide" }, "slide_helper": "subslide_end", "slideshow": { "slide_type": "subslide" } }, "source": [ "発言が、それを特徴づけるパラメータ(発言者、思想、賛成反対、重要度など)$a$個で表現できるとした時、各離散時刻$t_{k}$(全体で$k$番目の発言の開始された時刻)になされる発言$x_{k}$は$R^{a}$上の有界集合$X\\subset R^{a}$における1点とみなすことができる。\n", "\n", "発言者の人数を$n$人とすると、$x$のパラメータの一つである発言者は、アルファベット$N = \\{1, 2, \\dots n\\}$に、沈黙を意味する\\{0\\}を加えて表すことができる(これを$N'$とする)。\n", "\n", "ここで、$i$の持っている意見すべての集合は$X_{i}$と表し、その要素数は$I_{i}$と表すことにする。\n", "\n", "すなわち\n", "\n", "$$X_{i} = \\{\\text{person}(x)=i | x \\in X\\}$$\n", "\n", "\n", "また、定義より\n", "\n", "$$X_{i} \\cap X_{j} = \\emptyset,\\ \\ \\,\\ ^{\\forall} i, j \\in \\{i\\neq j | i, j \\in N'\\}$$\n", "\n", "\n", "$$ \\bigcup_{i=0}^{n} X_{i} = X$$\n", "\n", "である。\n" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end", "slide_type": "subslide" }, "slide_helper": "subslide_end", "slideshow": { "slide_type": "subslide" } }, "source": [ "次に、時刻$k$に$i$が発言した後、時刻$k+1$に$j$が発言する条件付き確率$P(x_{k+1}^{j}|x_{k}^{i})$は、以下のように書けるだろう。\n", "\n", "$$P(x_{k+1}^{j}|x_{k}^{i}) = p_{i}(k,j)q(x_{k+1}^{j},X_{j}(k)),\\ \\ \\ \\ ^{\\forall} i, j \\in N'$$\n", "\n", "ここで、$p_{i}(k,j)$は発言者$i$のあとに$j$が発言する確率であり、$q(x_{k+1}^{j},X_{j}(k))$は、$j$の発言のうち、$k$番目までに出現していない発言を選ぶ確率である。条件付き確率の定義から、$X_{j}(k) = \\emptyset$の時、$p_{i}(k,j)$は再定義される必要がある。$p$と$q$の具体的な形については後で述べることとする。" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end", "slide_type": "subslide" }, "slide_helper": "subslide_end", "slideshow": { "slide_type": "subslide" } }, "source": [ "時間発展は以下のようなプロセスで進展する。\n", "\n", "初期条件としての意見$x_{0}$は議題であり、このときの発言者は$0$であるとする。\n", "\n", "時刻$t_{1}$で確率$P(x_{1}^{i}|x_{0}^{0})$のもと点$x_{1}^{i}$が選ばれ、このとき議題$x_{o}^{0}$との間の関係があれば(すなわち適当に定めた距離において、ある閾値$r$より小さければ)、この二つの要素の間にリンクを張ることにする。一度選ばれた点は、再び選ばれることはない。\n", "\n", "以後同様に確率的に点を選んでいき、それまでに発言された点で距離が近い点はすべてリンクで結んでゆく。\n", "\n", "シミュレーションの終了条件は、ある発言がなされた時、その発言がある閾値より大きいリンク数を持つような場合と、すべての参加者が発言し尽くしてしまった場合である。\n" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_type": "subslide" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### $p,q$の具体例" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end" }, "slide_helper": "subslide_end", "slideshow": { "slide_type": "-" } }, "source": [ "$p$は、ある人$i$の発言が$j$に向けられることによる効果や、声の大きさ、立場、実際の物理的距離、親密度、関心などの要素を含んでいる。\n", "\n", "一番簡単な定式化は、すべての人に関して等確率で話すことを促進するというものである。\n", "\n", "$$p_{i}(k,j) = \\frac{1}{m}$$\n", "\n", "ここで$m$は、時刻$t_{k}$の終わった時点で発言することのできる人(発言のストックがある人)の数+(沈黙)である。" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end", "slide_type": "subslide" }, "slide_helper": "subslide_end", "slideshow": { "slide_type": "subslide" } }, "source": [ "次に現実的な定式化として、各参加者の実際の位置を用いて、その距離に応じて重みを付けるというものが考えられる。\n", "\n", "すなわち、$i$から$j$の実際の物理的距離が$d_{ij}$で書けるとすると、\n", "\n", "$$p_{i}(k,j) = \\frac{g(d_{ij})}{\\sum_{v \\in N'} g(d_{iv})}$$\n", "\n", "のようにできる。このとき関数$g$は$[0, +\\infty)$の領域で連続で有界な正値単調減少関数と考えていいだろう。また、この場合には$d_{i0}$には正の有界値を任意に与える必要があるだろう(他の値との相対的な大小は、声の大きさ、場所の声の通りやすさなどを表すことになる)。\n", "\n", "ex1)$$ g(x) = \\frac{1}{x+1}$$\n", "\n", "ex2)$$\\displaystyle g(x) = e^{-x}$$\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end", "slide_type": "subslide" }, "slide_helper": "subslide_end", "slideshow": { "slide_type": "subslide" } }, "source": [ "$q$は、発言者が定まった上で、その中から一つ発言を選ぶ確率である。これも最も簡単な式としては\n", "\n", "$$ q(x_{k+1}^{j}, X_{j}(k)) = \\frac{1}{\\#X_{j}(k)}$$\n", "\n", "が考えられる。ここで$\\#$は集合内の要素数である。また、先程も述べたように$\\#X_{j}(k)=0$のときはこれは定義できない。" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_type": "subslide" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "次に考えられるのは、それまでの意見をできるだけ反映するように発言するような場合で、このとき、\n", "\n", "$$\\# \\{d(x_{l}^{s}, x_{k+1}^{j}) < r \\ |\\ ^{\\forall} l \\le k, s \\in N\\}$$\n", "\n", "を最大にするような$x_{k+1}^{j}$が選ばれる。" ] }, { "cell_type": "markdown", "metadata": { "internals": {}, "slideshow": { "slide_type": "-" } }, "source": [ "もしくは、直前の意見のみに関連するように発言するとすれば、\n", "\n", "$x_{k+1}^{j}$の選び方は、$d(x_{k}^{i}-x_{k+1}^{j})$を最小とするように選べば良い。\n" ] }, { "cell_type": "markdown", "metadata": { "internals": {}, "slideshow": { "slide_type": "skip" } }, "source": [ "## シミュレーション" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true, "internals": {}, "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "internals": {}, "slideshow": { "slide_type": "skip" } }, "outputs": [ { "ename": "SyntaxError", "evalue": "invalid syntax (, line 21)", "output_type": "error", "traceback": [ "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m21\u001b[0m\n\u001b[1;33m self.place = place\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" ] } ], "source": [ "N = 6\n", "radius = 3\n", "\n", "def accumulate(iterable):\n", " 'Return running totals'\n", " # accumulate([1,2,3,4,5]) --> 1 3 6 10 15\n", " # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120\n", " it = iter(iterable)\n", " total = next(it)\n", " yield total\n", " for element in it:\n", " total += element\n", " yield total\n", "\n", "class Person(object):\n", " \n", " def __init__(self, ideas_num=10, place=(0., 0.), **kwargs):\n", " # 意見は0~1の間の値を一様に取りうる\n", " self.ideas = list(np.random.random(ideas_num)\n", " # 発言者の実際の位置が2次元の座標として表せる\n", " self.place = place\n", " # その他の特徴量\n", " for (k, v) in kwargs.items():\n", " setattr(self, k, v)\n", " \n", " def distance(self, p):\n", " # 人pと自分との間の距離(ユークリッド距離)\n", " d = np.sqrt((self.place[0]-p.place[0])**2 + (self.place[1]-p.place[1])**2)\n", " return d\n", " \n", "class meeting(object):\n", " \n", " def __init__(self):\n", " # 意見の時系列(今の場合0〜1の乱数の値そのもの)\n", " self.ideas = []\n", " # 発言者の時系列\n", " self.speaker = []\n", " # 時刻\n", " self.k = 0\n", " # 張られたリンク(時刻, 時刻)のタプルで表現する\n", " self.links = []\n", " # はじめの意見(議題)\n", " x0 = 0.\n", " self.ideas.append(x0)\n", " # 議題は沈黙の意見だとする\n", " self.speaker.append(0)\n", " # 会議のメンバーとして沈黙を加える\n", " self.members = {0: Person(place=(0., 0.)),}\n", " # 沈黙を中心とした円周上に等間隔で参加者が存在する\n", " deg = np.linspace(0., 360., N, endpoint=False)\n", " for n in range(1, N+1):\n", " rad = np.radians(deg[n-1])\n", " self.members[n] = Person(place=(radius*np.cos(rad), radius*np.sin(rad)))\n", " \n", " def p(self, i):\n", " \n", " # 発言者の物理的距離に対する関数\n", " def g(x):\n", " return 1./(1.+x)\n", " \n", " # 参加者の中で話せる人のみを対象に\n", " _N = []\n", " for k, v in self.members.items():\n", " if len(v.ideas):\n", " _N.append(k)\n", " \n", " # それらの人たちに対し、重み付けの確率を付与\n", " w = []\n", " for n in _N:\n", " d = self.members[n].distance(i)\n", " w.append(g(d))\n", " w = np.array(w)\n", " sum_ = np.sum(w)\n", " _p = list(w/sum_)\n", " p = accumulate(_p)\n", " rn = np.random.rand()\n", " nm = 0\n", " while True:\n", " if p[nm] > rn:\n", " break\n", " else:\n", " nm += 1\n", " # その確率で選ばれた人の名前を返す\n", " return _N[nm]\n", " \n", " def q(self, j):\n", " # 発言者jが選ばれた時、持っている意見から等確率で意見を取り出す\n", " x_j = self.members[j]\n", " return x_j.ideas.pop()\n", " \n", " def distance(self, x, y):\n", " d = np.abs(x - y)\n", " return d\n", " \n", " def connect(self, idea):\n", " for i, v in enumerate(self.ideas):\n", " if self.distance(v, idea) < radius:\n", " \n", " \n", " \n", " def progress(self): \n", " j = self.p(self.members[self.speaker[-1]])\n", " self.ideas.append(self.q(j))\n", " \n", " \n", " def test_plot(self):\n", " x = [0,]\n", " y = [0,]\n", " for n in range(N+1):\n", " x.append(self.members[n].place[0])\n", " y.append(self.members[n].place[1])\n", " return x,y" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "internals": {}, "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "a = meeting()\n", "a.progress()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "internals": { "slide_helper": "subslide_end" }, "slide_helper": "slide_end", "slideshow": { "slide_type": "skip" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0]\n", "[0.0, 0.25575792014749998]\n" ] } ], "source": [ "print a.speaker\n", "print a.ideas\n" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_type": "subslide" }, "slideshow": { "slide_type": "slide" } }, "source": [ "# 今後の課題" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end" }, "slide_helper": "slide_end", "slideshow": { "slide_type": "-" } }, "source": [ "- シミュレーションの実行と解析\n", "\n", " - 様々な状況を再現し、現実の現象と対応しているかどうか\n", " \n", " \n", " \n", "- 他の現象(代謝ネットワーク等)との関連付け" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_type": "subslide" }, "slideshow": { "slide_type": "slide" } }, "source": [ "# 参考文献" ] }, { "cell_type": "markdown", "metadata": { "internals": { "slide_helper": "subslide_end" }, "slide_helper": "slide_end", "slideshow": { "slide_type": "-" } }, "source": [ "- 石川 正純・足立 にれか・岡本 浩一, 会議分析のための数値シミュレーション技法-組織内集団に見られる意思決定モデルの開発-, 社会技術研究論文集, 2004.\n", "- 城 綾実・細馬 宏通, 多人数会話における自発的ジェスチャーの同期, Congnitive Studies, __16__(1), 103-119, 2009.\n", "- 藤本 学・大坊 郁夫, 小集団の会話の展開に及ぼす会話者の発話行動傾向の影響, The Japanese Journal of Experimental Social Psychology, __47__(1), 51-60, 2007.\n", "- 高良 美樹, 集団討議の参加者の人数が集団決定および個人決定に及ぼす影響について, 人間科学, __1__, 67-84, 1998.\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 0 }