首先杨蛋,介紹下什么是蒙特卡洛模擬(let's go)
蒙特卡羅(Monte Carlo)方法吆视,又稱隨機(jī)抽樣或統(tǒng)計(jì)試驗(yàn)方法念脯,當(dāng)所要求解的問(wèn)題是某種事件出現(xiàn)的概率,或者是某個(gè)隨機(jī)變量的期望值時(shí)窖维,它們可以通過(guò)某種“試驗(yàn)”的方法榆综,得到這種事件出現(xiàn)的頻率,或者這個(gè)隨機(jī)變數(shù)的平均值铸史,并用它們作為問(wèn)題的解鼻疮。這就是蒙特卡羅方法的基本思想。蒙特卡羅方法通過(guò)抓住事物運(yùn)動(dòng)的幾何數(shù)量和幾何特征琳轿,利用數(shù)學(xué)方法來(lái)加以模擬判沟,即進(jìn)行一種數(shù)字模擬實(shí)驗(yàn)。它是以一個(gè)概率模型為基礎(chǔ)崭篡,按照這個(gè)模型所描繪的過(guò)程挪哄,通過(guò)模擬實(shí)驗(yàn)的結(jié)果,作為問(wèn)題的近似解琉闪〖A叮可以把蒙特卡羅解題歸結(jié)為三個(gè)主要步驟:構(gòu)造或描述概率過(guò)程;實(shí)現(xiàn)從已知概率分布抽樣颠毙;建立各種估計(jì)量斯入。
簡(jiǎn)單來(lái)說(shuō),就是通過(guò)隨機(jī)數(shù)蛀蜜,對(duì)策略進(jìn)行模擬和評(píng)估
那么刻两,如何通過(guò)蒙特卡洛模擬對(duì)社會(huì)財(cái)富分配進(jìn)行預(yù)估呢,此處有個(gè)不成熟的小案例滴某,即:假設(shè)有100個(gè)人磅摹,每人的初始財(cái)富是100元,當(dāng)財(cái)富值大于0時(shí)壮池,需要隨機(jī)向其他一人支付1元偏瓤,當(dāng)財(cái)富值為0時(shí),無(wú)需支付椰憋,但仍有可能獲得其他人支付的金額,基于以上假設(shè)進(jìn)行需進(jìn)行如下四步操作:
1赔退、構(gòu)建函數(shù)模型
#注意:當(dāng)某人財(cái)富值為0時(shí)橙依,該輪無(wú)需拿錢出來(lái)证舟,但仍有機(jī)會(huì)獲得別人的財(cái)富
def game1(data,roundi):
if len(data[data[roundi-1]==0])>0:
round_i=pd.DataFrame({'pre_round':data[roundi-1],'lost':0})
con=round_i['pre_round']>0
round_i['lost'][con]=1
round_players_i=round_i[con]
choice_i=pd.Series(np.random.choice(person_n,len(round_players_i)))
gain_i=pd.DataFrame({'gain':choice_i.value_counts()})
round_i = round_i.join(gain_i)
round_i.fillna(0,inplace=True)
return round_i['pre_round']-round_i['lost']+round_i['gain']
else:
round_i=pd.DataFrame({'pre_round':data[roundi-1],'lost':1})
choice_i=pd.Series(np.random.choice(person_n,100))
gain_i=pd.DataFrame({'gain':choice_i.value_counts()})
round_i=round_i.join(gain_i)
round_i.fillna(0,inplace=True)
return round_i['pre_round']-round_i['lost']+round_i['gain']
運(yùn)行模型,模擬財(cái)富分配
import time
person_n=[x for x in range(1,101)]
fortune=pd.DataFrame([100 for i in range(100)],index=person_n)
fortune.index.name='id'
#設(shè)定初始參數(shù),游戲玩家100人窗骑,初始資金100元
starttime=time.time()
for round in range(1,17001)[:3000]:
print('正在進(jìn)行第%i次模擬'% round)
fortune[round] = game1(fortune,round)
#fortune[round] = game1(fortune,round)
game1_result=fortune.T
endtime=time.time()
print('模型總共用時(shí)%i秒' % (endtime - starttime))
game1_result
繪制柱狀圖
前100輪女责,按每10輪繪制一次,第100-1000輪创译,按照每100輪繪制1次抵知,第1000-17000輪,按每400輪繪制一次
查看財(cái)富變化狀況
def graph2(data,start,end,length):
for n in list(range(start,end,length)):
datai=data.iloc[n].sort_values().reset_index()[n]
plt.figure(figsize=(10,3))
plt.title('第%i輪'%n)
plt.bar(datai.index,datai.values,color='gray',alpha=0.8,width=0.5)
plt.xlabel('PlayerID')
plt.ylabel('Fortune')
plt.xlim(-10,110)
plt.ylim(0,400)
plt.grid(alpha=0.5,linestyle='--')
graph2(game1_result,0,100,10)
graph2(game1_result,100,1000,100)
graph2(game1_result,1000,17000,400)
得出結(jié)論
最后一輪中软族,最富有的人財(cái)富值為365元刷喜,相比于初始財(cái)富,翻了3.65倍
10%的人掌握著28%的財(cái)富立砸,20%的人掌握著51%的財(cái)富掖疮?
60%的人財(cái)富縮水至100元以下了
round_17000_1 = pd.DataFrame({'money':game1_result.iloc[-1]}).
sort_values(by = 'money',ascending = False).reset_index()
# 最后一輪數(shù)據(jù)匯總,并排序
round_17000_1['fortune_pre'] = round_17000_1['money'] / round_17000_1['money'].sum()
# 計(jì)算每個(gè)人的財(cái)富占比
round_17000_1['fortune_cumsum'] = round_17000_1['fortune_pre'].cumsum()
# 計(jì)算積累財(cái)富占比
round_17000_1.head()
fortune_sum = round_17000_1['money'].sum()
top10 = round_17000_1[round_17000_1['fortune_cumsum']<0.1]
top20 = round_17000_1[round_17000_1['fortune_cumsum']<0.2]
# 匯總出掌握前10%/20%財(cái)富的人群
lessthan100_num = len(round_17000_1[round_17000_1['money']<100])/100
print('最后一輪中颗祝,最富有的人財(cái)富值為%.1f元浊闪,相比于初始財(cái)富,翻了%.2f倍'
% (round_17000_1.iloc[0]['money'],round_17000_1.iloc[0]['money']/100))
print('10%%的人掌握著%.2f%%的財(cái)富螺戳,20%%的人掌握著%.2f%%的財(cái)富'
% (top10['money'].sum()/10000*100,top20['money'].sum()/10000*100))
print('%.2f%%的人財(cái)富縮水至100元以下了' % (lessthan100_num*100))
注意:用蒙特卡洛模擬需要滿足樣本可用隨機(jī)數(shù)試驗(yàn)的原則搁宾,樣本分布必須是隨機(jī)的,不能有偏好倔幼!
以上便是此次模擬過(guò)程~