質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1408閲覧

randam.choicesのKeyErrorの解決方法について

HGK

総合スコア29

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/10/07 07:32

編集2021/10/07 09:04

大学の卒業研究でマルチエージェントシミュレーションを用いて学級モデルを構築しています。
生徒は想像している人間関係、他の生徒への好感度、クラス内での影響力の3つの設定を持っています。
シミュレーションの流れは、
会話相手(1人)の選択→話題対象の選択→好感度の更新(2種類)→関係の構築
→影響力の更新→想像している人間関係の更新
以上の流れで行います

これを再現するために次のコードを組みました

python

1import numpy as np 2import random 3 4a = 0.4 5b = 0.4 6c = 0.2 7v1 = 0.3 8v2 = 0.3 9v3 = 0.6 10w1 = 0.2 11w2 = 0.2 12w3 = 0.6 13ap = 0.3 14rm = 0.25 15q = 0.3 16issues =10 17 18 19def sign(x,y): 20 if x*y>0: 21 sign = 1 22 if x*y == 0: 23 sign = 0 24 if x*y<0: 25 sign = -1 26 return sign 27 28def gij(x,y,z): 29 change = v1*(sign(x,y)*(abs(x*y)**0.5)-z) 30 return change 31 32 33class Agent: 34 def __init__(self,agent_id): 35 self.id = agent_id 36 self.talk = [] 37 self.topic = [] 38 self.f = np.random.uniform(low=0.0, high=0.1, size=None) #影響力 39 self.s = [0] #影響力更新で使用 40 self.frind_list = [] #友人リンク 41 self.hi_friend_list = [] #被友人リンク 42 self.exclusion_list = [] #排斥リンク 43 self.hi_exclusion_list = [] #被排斥リンク 44 self.bullying_list = [] #いじめリンク 45 self.hi_bullying_list = [] #被いじめリンク 46 self.lp = {} #自分からuへの好感度 47 self.lc = {} #実際の好感度 48 self.lagent = {} #自分が思うuからの好感度 49 self.lpi = {} #自分が思うuからjへの好感度 50 self.lx = {} #自分の話題xへの好感度 51 self.lxagent = {} #自分が思うuの話題xへの好感度 52 53 def First_set(self,agents): #初期設定 54 issues = 10 55 for agent in agents: 56 kari = {} 57 if agent is self: 58 continue 59 likability = np.random.uniform(low=-0.1, high=0.1, size=None) 60 self.lp[agent.id] = likability 61 self.lc[agent.id] = likability 62 like = np.random.uniform(low=-0.1, high=0.1, size=None) 63 self.lagent[agent.id] = like 64 for t in agents: 65 if t is agent: 66 continue 67 interested = np.random.uniform(low=-0.1, high=0.1, size=None) 68 kari[t.id] = interested 69 self.lpi[agent.id] = kari 70 71 for issue in range(issues): 72 instinct = np.random.uniform(low=-0.1, high=0.1, size=None) 73 self.lx[issue] = instinct 74 kari = {} 75 for agent in agents: 76 if issue is agent: 77 continue 78 instinct = np.random.uniform(low=-0.1, high=0.1, size=None) 79 kari[agent.id] = instinct 80 self.lxagent[issue] = kari 81 82 def decide_talk_man(self,agents): #会話相手の選択 83 agents_except_me = {} 84 weights_for_me = [] 85 z = 0 86 for agent in agents: 87 if agent is self: 88 continue 89 h = a*self.lp[agent.id]+b*self.lagent[agent.id]*(1-(self.f-agent.f))+c*(self.f-agent.f) 90 h = (h+0.8)/1.6 #正規化 91 z += h 92 for agent in agents: 93 if agent is self: 94 continue 95 h = a*self.lp[agent.id]+b*self.lagent[agent.id]*(1-(self.f-agent.f))+c*(self.f-agent.f) 96 h = (h+0.8)/1.6 #正規化 97 weight = h / z 98 agents_except_me[agent.id] = agent.id 99 weights_for_me.append(weight) 100 self.talk = random.choices(agents_except_me, weights=weights_for_me) 101 print(self.talk) 102 return self.talk 103 104 def decide_topic(self,agents,talk): #話題対象の選択 105 talks = self.talk[0] 106 topic_except_me = {} 107 weights_for_me = [] 108 zz = 0 109 110 for agent in agents: 111 if agent is self: 112 continue 113 if agent.id == talks: 114 for age in agents: 115 talk_f = agent.f 116 if age is agent or age is self: 117 continue 118 zz += abs(self.lp[age.id]*self.f+self.lpi[agent.id][age.id]*talk_f) 119 120 for issue in range(issues): 121 for agent in agents: 122 if agent is self: 123 continue 124 if agent.id ==talks: 125 zz += abs(self.lx[issue]*self.f+self.lxagent[issue][agent.id]*talk_f) 126 127 for agent in agents: 128 if agent is self: 129 continue 130 if agent.id == talks: 131 for age in agents: 132 if age is agent or age is self: 133 continue 134 r = abs(self.lp[age.id]*self.f+self.lpi[agent.id][age.id]*talk_f)/zz 135 topic_except_me[age.id] = age.id 136 weights_for_me.append(r) 137 138 for issue in range(issues): 139 for agent in agents: 140 if agent is self: 141 continue 142 if agent.id ==talks: 143 r = abs(self.lx[issue]*self.f+self.lxagent[issue][agent.id]*talk_f)/zz 144 issue += 31 145 topic_except_me[issue] = issue 146 weights_for_me.append(r) 147 148 self.topic = random.choices(topic_except_me, weights=weights_for_me) 149 print(self.topic) 150 return self.topic 151 152 def update_like1(self,agents,talk,topic): #好感度更新1 153 talks = talk[0] 154 topics = topic[0] 155 if topics <= 30: 156 x = self.lp[talks] 157 y = self.lp[topics] 158 z = self.lpi[talks][topics] 159 else: 160 topics -= 31 161 x = self.lx[topics] 162 y = self.lp[talks] 163 z = self.lxagent[topics][talks] 164 l = x*y*z 165 if l>=0: 166 dlu1 = gij(y,z,x) 167 dlx1 = gij(x,z,y) 168 else: 169 if x >= y: 170 dlu1 = gij(x,z,0) 171 dlx1 = 0 172 else: 173 dlu1 = 0 174 dlx1 = gij(y,z,0) 175 for agent in agents: 176 if agent.id is talks: 177 r = w1*self.lp[talks]+w2*self.lagent[talks]*(1-(self.f-agent.f))+w3*(self.f-agent.f) 178 r = (r+0.8)/1.6 179 break 180 weights_for_stra = {r,1-r} 181 kinds_of_stra = ["mini","same"] 182 stra = random.choices(kinds_of_stra, weights=weights_for_stra) 183 if stra is "mini": 184 dlu2 = v2*(self.lagent[talks]-self.lp[talks]) 185 else: 186 dlu2 = v3*sign(1,(self.lagent[talks]))*(abs(self.lagent[talks]+self.lp[talks])) 187 188 dlu = dlu1+dlu2 189 dlx = dlx1 190 return dlu,dlx 191 192 def update_like2(self,talk,topic,dlu,dlx): #好感度更新2 193 talks = self.talk[0] 194 topics = self.topic[0] 195 self.lp[talks] = self.lp[talks]+dlu 196 self.lc[talks] = self.lp[talks] 197 if topics <= 30: 198 self.lp[topics] += dlx 199 200 if self.lp[topics] > 1.0: 201 self.lp[topics] = 1.0 202 elif self.lp[topics] < -1.0: 203 self.lp[topics] = -1.0 204 else: 205 topics -= 31 206 self.lx[topics] += dlx 207 208 if self.lx[topics] > 1.0: 209 self.lx[topics] = 1.0 210 elif self.lx[topics] < -1.0: 211 self.lx[topics] = -1.0 212 213 214 def link(self,agents): #関係の構築 215 for agent in agents: 216 if agent is self: 217 continue 218 if self.lc[agent.id] >= 0.12: 219 self.frind_list.append(agent.id) 220 agent.hi_friend_list.append(self.id) 221 elif self.lc[agent.id] <= -0.04: 222 self.exclusion_list.append(agent.id) 223 agent.hi_exclusion_list.append(self.id) 224 else: 225 pass 226 227 228 def update_f(self,turn): #影響力の更新 229 self.s.append(len(self.hi_friend_list)-len(self.hi_exclusion_list)) 230 dr = rm*(self.s[turn+1]-self.s[turn]) 231 self.f += dr 232 233 if self.f > 1.0: 234 self.f = 1.0 235 elif self.f < 0: 236 self.f = 0 237 238 239 def updete_Pnet(self,agents): #自分が想像している人間関係の更新 240 for agent in agents: 241 for age in agents: 242 if agent is age or self is agent: 243 continue 244 E = np.random.uniform(low=-0.3, high=0.3, size=None) 245 dlp = ap*(agent.lc[age.id]-self.lpi[agent.id][age.id])+E 246 self.lpi[agent.id][age.id] += dlp 247 248 if self.lpi[agent.id][age.id] > 1.0: 249 self.lpi[agent.id][age.id] = 1.0 250 elif self.lpi[agent.id][age.id] < -1.0: 251 self.lpi[agent.id][age.id] = -1.0 252 253 254class Simulation: 255 def __init__(self): 256 self.agents = [] 257 258 def generate_agents(self, agents_num): 259 self.agents = [Agent(agent_id) for agent_id in range(agents_num)] 260 for agent in self.agents: 261 agent.First_set(self.agents) 262 263 def play_the_game(self,episode): 264 num_agents = 31 265 turns = 3000 266 self.generate_agents(num_agents) 267 for turn in range(turns): 268 print(turn,"ターン目") 269 for agent in self.agents: 270 print(agent) 271 self.talk = agent.decide_talk_man(self.agents) 272 self.topic = agent.decide_topic(self.agents,self.talk) 273 dlu,dlx = agent.update_like1(self.agents,self.talk,self.topic) 274 agent.update_like2(self.talk,self.topic,dlu,dlx) 275 agent.link(self.agents) 276 agent.update_f(turn) 277 agent.updete_Pnet(self.agents) 278 279 280 281 282simulation = Simulation() 283simulation.play_the_game(31) 284for agent in simulation.agents: 285 print("Likabilities for Agent", agent.id, ":") 286 for agent_id in agent.lc: 287 print(" agent", agent_id, ":", agent.lc[agent_id]) 288 for issue in range(issues): 289 print(" issue", issue, ":", agent.lx[issue]) 290 print(" frind", ":", agent.frlist) 291 print() 292

これを実行したところ動かすことはできるように見えるののですが、
self.talk = random.choices(agents_except_me, weights=weights_for_me)
self.topic = random.choices(topic_except_me, weights=weights_for_me)
この二つの箇所で毎回違う種類のエラーがでます。
そのエラーはKeyError: 13というようにKeyError: (数字)がでます。
このエラーを出さないようにするためにはどのようにコードを修正すればいいでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2021/10/07 07:41

提示コードをそのまま実行すると 「AttributeError: 'Agent' object has no attribute 'hi_frind_list'」エラーが発生します。 コードは正しいでしょうか?
HGK

2021/10/07 09:03

スペルミスをしていました
guest

回答1

0

ベストアンサー

原因はrandom.choicesの選択対象として辞書を渡しているからです。
たとえばランダム選択の結果2番目の値を返そうとしますが、キー値が2である要素がない場合に提示エラーが発生します。
対応策としては、以下のように欲しいもの(キーか値か両方か)をリスト化して渡せばよいです。
参考:Getting key error from random.choice()

Python

1import random 2 3d = {1:2, 3:4, 5:6} 4w = [0.1,0.2,9999.9] # 2番目の要素が選択されるように重みづけ 5#print(random.choices(d, weights=w)) # KeyError: 2 6 7print(random.choices(list(d.keys()), weights=w)) # キー[5] 8print(random.choices(list(d.values()), weights=w))# 値 [6] 9print(random.choices(list(d.items()), weights=w)) # キーと値 [(5, 6)]

投稿2021/10/07 08:02

can110

総合スコア38266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HGK

2021/10/07 09:58

解答ありがとうございます おかげで研究が進めることができます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問