蒙特卡罗模拟财富分配

前言

随着学校网课的开始,这个博客其实是记录一下我的第一次作业,不过得到的结论还是有点意思的。我也不知道我最近干嘛天天更新,其实是今年这个形式我还在犹豫到底考不考研,我知道这个时候肯定有人会说现在还在犹豫已经是废了,我都一轮复习完了,题目刷了几遍……之类的,我只想说嗯,现在确实是你厉害,但是未来有太多不确定性,不要轻易否定一个人,不信来看看下面的内容。

正文

首先来看看这次的问题

在这里插入图片描述
简化一下,大致就是一共100人,每人初始资金100元,每天要给出1元,也会收到别人给的钱,每个人得到钱的概率相同。

情况一:有人情味的理想状态

这个状态下初始条件不变,只是有的人一旦财富为0,他就不再去给别人钱,只会得到别人给的钱,就好像政府的低保。

#初始化条件
person_id = [x for x in range(1,101)]
fortune = pd.DataFrame([100 for i in range(100)], index = person_id)
fortune.index.name = 'id'

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_player_i = round_i[con]
        choice_i = pd.Series(np.random.choice(person_id, len(round_player_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:
        # 对于不包含财富值为0 的状况
        round_i = pd.DataFrame({'pre_round':data[roundi-1],'lost':1})
        choice_i = pd.Series(np.random.choice(person_id, len(round_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']

#模拟10000次
for roundi in range(1, 10000):
    if roundi%1000==0:
        print('进行第%d次模拟' % roundi)
    fortune[roundi]  = game1(fortune, roundi)
    
game1_result = fortune.T
def draw(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,6))
        sns.barplot(datai.index, datai.values)
        plt.xlim((0,100))
        plt.ylim((0,400))
        plt.title('模拟的轮数%s' % n)
        plt.xlabel('ID') 
        plt.ylabel('拥有的财富')
        plt.grid(alpha=0.5, linestyle='--')

draw(game1_result, 0,10000,1000)

在这里插入图片描述
最后每个人的财富状况如上图。类似于正态分布的一半,因为也有可能是左高右低毕竟每个人获得钱的概率相同。在这种情况下,有的人会很富有,相对的有的人就会只能靠低保

情况二:更现实的情况

在这里插入图片描述
在这里,我就不考虑社会援助,并且将人分为不同的类型,有负债的、有努力工作的、投资的、也有技术进步的……他们每个人的初始资金不同,获得收益的概率也不一样。

# 初始化参数

#一共分配(游戏)2000次
N=2000


#投机者(负债但是仍然消费)20人
tj_id=[i for i in range(20)]
tj=pd.DataFrame([0 for i in range(20)],index=tj_id)

#努力工作者(可能现在财富并不多拥有60,但是获得利益的概率多1%)占大多数50人
nl_id=[i for i in range(20,70)]
nl=pd.DataFrame([60 for i in range(50)],index=nl_id)

#投资者(本身就很富有拥有100,而且很会投资,每次获得收益概率多3%)5人
tz_id=[i for i in range(70,75)]
tz=pd.DataFrame([100 for i in range(5)],index=tz_id)


#剩下就是知识进步(现在可能很不富有,拥有30,但是有知识有10%的概率获得利益)25人
zs_id=[i for i in range(75,100)]
zs=pd.DataFrame([30 for i in range(25)],index=zs_id)

# 将上面定义的人群合并起来
person=pd.concat([tj,nl,tz,zs])
person.head()

一开始的财富分布是这样的
在这里插入图片描述
然后我们根据上面给出的收益概率分配,去计算不同的人获得收益的概率。
比如收益概率多1%的努力者,他们的收益就是0.01+0.01*1%;类似这样计算后面三种类型的人的收益概率,最后剩下的概率分给负债者,开始模拟看看结果

#定义游戏(分配规则)

#得到钱的机会(也就是收益概率不同)
chance=np.concatenate((np.array([0.008425]*20),np.array([0.0101]*50),np.array([0.0103]*5),np.array([0.011]*25)))
#0.01*0.01+0.01
#得到失去钱的id
def get_fromid(id_from):
    id_to=np.random.choice(a=np.arange(100),size=1,replace=False,p=chance)
    #不能自己给自己钱
    if id_to==id_from:
        id_to=get_fromid(id_from)
    return id_to

def game2(data,time):
    for i in range(time):
        if i%500==0:
            print(f"正在模拟第{i}轮")
        for id_from in range(0,len(data)):
            id_to=get_fromid(id_from)
            data['money'][id_from]-=1
            data['money'][id_to]+=1
    return data

final=game2(person,N)
plt.figure(figsize=(10,6))
sns.barplot(final.index,final.money)
plt.title("模拟2000轮后的结果")
plt.xlabel("人群ID")
plt.xticks(np.arange(0,101,10),np.arange(0,101,10)) 
plt.ylabel("所拥有财富")
plt.show()

在这里插入图片描述
我们发现负债者负债情况会更严重,努力者虽然也有会出现负债情况,但是大多数还是比之前的财富多;投资者肯定是越来越富有的,但是看看学习者,像我们这样的人,一开始也许只是个穷小子,但是凭借自身的实力、运气等因素最后的财富赶上甚至超越了投资者们;
当然这个只是一个鸡汤,努力有没有用?答案是肯定是有用的,但是只凭努力,自身实力能让你的收益概率超过别人7%吗?很难,基本是不现实的,往往还和我们的运气以及对形式的把握有关。富有的人都是能顺应时代的人,2014年直播刚刚开始的时候也许无人问津,但是三年后2017年直播行业大火,当时有可能只是一个小主播,抱着一台电脑和寥寥无几观众聊天的主播,现在也许就是一个万人追捧的大主播。举个我自己的经历来说吧,当时在企鹅电竞我和张大仙基本上都是没几个观众的,当然他比我肯定还是好点的,后来因为没有观众、收益不理想、学业等等因素我放弃了,而现在呢尽管直播行业已经在走下坡路,但是他依然身价不菲,平台签约价大家应该也有个数。诸如此类很多,像孤影一开始在触手也是读书时期直播,只不过他坚持下来了。
再来看看近几年开始火起来的短视频,三,四分钟一个的视频让一个个普通人成了网红,用vlog分享生活也能慢慢变成百万up主,这个信息时代,变化很快,但是随之而来的是更多的机会。我记得之前看过一本书,讲人一生有三到四次改变命运的机会,抓住了就能改变人生,对于现在来说,机会往往会更多。说了这么多,回到我们的问题,再来看第三种情况。

情况三:负债者也会努力

这个模型,我抽出了10个负债者,让他们获益概率也增加1%,这也就意味着前十个负债者会更惨,来看看吧

#得到钱的机会(也就是收益概率不同)
chance2=np.concatenate((np.array([0.00675]*10),np.array([0.0101]*10),np.array([0.0101]*50),np.array([0.0103]*5),np.array([0.011]*25)))

#得到失去钱的id
def get_fromid2(id_from):
    id_to=np.random.choice(a=np.arange(100),size=1,replace=False,p=chance2)
    #不能自己给自己钱
    if id_to==id_from:
        id_to=get_fromid2(id_from)
    return id_to

def game3(data,time):
    for i in range(time):
        if i%500==0:
            print(f"正在模拟第{i}轮")
        for id_from in range(0,len(data)):
            id_to=get_fromid2(id_from)
            data['money'][id_from]-=1
            data['money'][id_to]+=1
    return data

final2=game3(person,N)
plt.figure(figsize=(10,6))
sns.barplot(final2.index,final2.money)
plt.title("模拟2000轮后的结果")
plt.xlabel("人群ID")
plt.xticks(np.arange(0,101,10),np.arange(0,101,10)) 
plt.ylabel("所拥有财富")
plt.show()

在这里插入图片描述
从上面的对比可以看出,当负债仍然努力的话,会减少负债的程度;当然如果足够努力(提高收钱的概率),也是有可能变成正资产的。
而且我们还可以看出来,负债者努力还有可能让相同努力的努力者也负债
在这里插入图片描述
在这里插入图片描述
对比可以看出来,即使初始情况不一样,但是同样努力的情况下,负债者一样有可能把努力者拉下水,更何况负债者往往为了改变会更努力。

用数据分析的流程去看待这次作业

  • 首先呢,数据分析第一步是数据的采集(爬虫、公开数据、任务数据……)
  • 拿到数据后先想清楚我们需要分析什么,明确大致的分析方向
  • 然后是数据清洗,数据预处理工作,为了保证数据的合理性以及有效性
  • 对于大多数情况下我们还会切分数据集,根据具体问题构建数学模型或者各种算法去分析(利用机器学习算法、深度学习网络、遗传算法……),最后得到一个既不欠拟合也不过拟合,具有良好鲁棒性的模型
  • 最后得到的结果我们会进行可视化,可以让人直观的看到分析的过程以及结果,得到相应的结论
  • 有的时候为了总结更清楚,还需要写分析报表、分析ppt

那就我们这次的作业来看,数据呢是自己定义的,所以也不用清洗。建模部分也没有用到什么其他的模型,主要就是蒙特卡罗方法,利用概率和大量实验去贴近现实情况。这个方法从简单的求pi值到之前B站其他up主模拟新冠病毒感染人的传播情况,几乎所有概率问题都能用它通过大量实验得到结果;当然最后每一种模型下由相应的可视化图都给出了自己的结论,至于报表之类的嘛老师没要求,所以我也不去做啦。(偷懒嘻嘻嘻)

总结

这个模型其实还没有完全贴近现实,比如投资者怎么可能一直获益,也会有亏损的时候;学习者的获益概率太高;当然也存在政府的援助……这些问题都会影响最后的模拟结果,但是大致的结论是一样的,只要你的获益概率大(实力、努力、运气、时代潮流的把握……),你就会富有

再来说说最开始说的,别轻易否定一个人。从上面的例子我们也看得出,即使初始情况不一样,但是相同的努力往往起点好的人也会被拉下水。而且上面的数值只是我自己定义的,也许起点好的人因为过早复习后期会太累而松懈,起点不好的人会更努力;我知道这时候肯定有人看了又会说,切说了一大堆不就是想安慰自己,还找那么多借口。对此,我只能说我很佩服那些已经下定决心考研,而且不受现在疫情影响还能认真复习的人。而我呢,首先没想好这种情况我到底能不能在家安心复习,并且我每天要操心的事太多,妈妈在前线救人,我一个人在家得想办法填饱自己的肚子(别问,我没爸爸,一个活着不如死了的人),家里没什么吃的,这段时间在湖北快递无法送(前几天买东西顺丰加运费都不送),外出买也不方便;每天还得上网课,做作业。也许你们早上起来,刷牙洗脸就可以吃上饭,而我就得从洗米煮饭洗菜开始,然后去上课,下午一点多吃一天的第一顿,晚上还要洗碗洗锅,所以我一直没有下定决心考研。不过,在我写下这段话的时候,我决定要考研了 ,不为别的,我想更充实我的生活,努力一次哪怕最后只是感动了自己也好,所有的经历只会让我的人生更有趣不是吗?

发布了85 篇原创文章 · 获赞 55 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/shelgi/article/details/104402466