美文网首页
使用pymc3进行贝叶斯推断的简单示例

使用pymc3进行贝叶斯推断的简单示例

作者: 社交达人叔本华 | 来源:发表于2021-12-30 22:53 被阅读0次

    本文是学习《贝叶斯方法 概率编程与贝叶斯推断》重点参考了这个教程

    import numpy as np
    import pymc3 as pm
    import matplotlib.pyplot as plt
    import os
    
    # 加载数据并且展示
    count_data=np.loadtxt("data/txtdata.csv")
    plt.figure(figsize=(12.5,3.5))
    n_count_data=len(count_data)
    plt.bar(np.arange(n_count_data),count_data,color="#348ABD")
    plt.xlabel("days")
    plt.ylabel("number of messages")
    plt.title("did the model change?")
    plt.xlim(0,n_count_data)
    plt.show()
    
    bayesian_opitimization_2_0.png

    初步假设,在时间\tau之前短信数量C_i服从泊松分布Poi(\lambda_1),在时间\tau之后短信数量C_i服从泊松分布Poi(\lambda_2).这样就有了三个参数\tau\lambda_1\lambda_2,我们的目标呢就是根据证据给出这三个参数的概率分布。(注意!是参数的概率分布!!这是贝叶斯推断的核心!!
    为了进行推断呢,我们首先给这三个参数一个初始的先验分布,因为先验分布是要根据证据不断更新的,相当于一个初始值,会在后续的调整中不断地接近真实值,所以我们先验可以给的随意一些。\tau是个离散值,最常见是用一个离散的均匀分布就完事了,\lambda_1\lambda_2是连续值,我们用一个指数分布Exp(\alpha)。有人就说啦,凭啥呀?为啥用这些做先验呢?没有凭啥,我们只是想给一个先验分布而已,你要是想用别的分布完全也可以,甚至,你可以不用已知的分布,直接一个个值的指定,也没毛病,自创一个分布。都行。

    接下来的东西呢,为了方便编程,我们用到了Pymc3这个库,这是一个专门针对概率相关问题进行编程的库。还是那句话,用了方便,不用也行

    # 先验分布
    with pm.Model() as model:
        alpha=1.0/count_data.mean() 
        lambda_1=pm.Exponential("lambda_1",alpha)
        lambda_2=pm.Exponential("lambda_2",alpha)
        tau=pm.DiscreteUniform("tau",lower=0,upper=n_count_data)
        # get likelihood
        lbds=np.zeros(n_count_data)
        lbds[:tau]=lambda_1
        lbds[tau:]=lambda_2
        target=pm.Poisson("target",observed=lbds)
    
    # 学习方法1: MAP。返回的是一个参数的数值,而不是分布! 这玩意就是极大似然求导吧(不是,要区分MLE和MAP),但是这个tau是怎么求出来的,不可导吧。 参考这篇文章https://zhuanlan.zhihu.com/p/40024110
    map_estimate=pm.find_MAP(model=model)
    print(map_estimate)
    
    {'lambda_1_log__': array(-9.1772865), 'lambda_2_log__': array(-9.1772865), 'tau': array(37), 'lambda_1': array(0.00010336), 'lambda_2': array(0.00010336)}
    
    # 学习方法2:MCMC
    import arviz as az
    with model:
        trace=pm.sample(500,return_inferencedata=False)
        az.plot_trace(trace)
        display(az.summary(trace,round_to=2))
    
    Multiprocess sampling (4 chains in 4 jobs)
    CompoundStep
    >NUTS: [lambda_2, lambda_1]
    >Metropolis: [tau]
    
    
    
    
    
    
    
    Sampling 4 chains for 1_000 tune and 500 draw iterations (4_000 + 2_000 draws total) took 10 seconds.
    There was 1 divergence after tuning. Increase `target_accept` or reparameterize.
    The number of effective samples is smaller than 25% for some parameters.
    
    bayesian_opitimization_6_4.png

    相关文章

      网友评论

          本文标题:使用pymc3进行贝叶斯推断的简单示例

          本文链接:https://www.haomeiwen.com/subject/hvvwqrtx.html