贝叶斯实验报告(三)

一、实验目的

学会使用pymc3构建模型,解决短信数据推断行为以及A-B测试问题。

二、实验内容及步骤(包括问题,代码,结果和结论)

2.1 短信数据推断行为

题目:

在这里插入图片描述

代码:

数据读入和展示:

import pymc3 as pm
import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(12.5, 3.5))
count_data = np.loadtxt("./txtdata.csv")
n_count_data = len(count_data)
plt.bar(np.arange(n_count_data), count_data, color='#348ABD')
plt.xlabel("Time (days)")
plt.ylabel("Text messages received")
plt.title("Did the user's texting habits change over time?")
plt.xlim(0, n_count_data)

在这里插入图片描述

构建模型:

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)
    
    with model:
        idx = np.arange(n_count_data)
        lambda_ = pm.math.switch(tau >= idx, lambda_1, lambda_2)
        #print(tau>=idx)
    with model:
        observation = pm.Poisson("obs", lambda_, observed=count_data)
    with model:
        step = pm.Metropolis()
        trace = pm.sample(10000, tune=5000, step=step)
    
        lambda_1_samples = trace['lambda_1']
        lambda_2_samples = trace['lambda_2']
        tau_samples = trace['tau']
        print(lambda_1_samples)
        print(lambda_2_samples)

结果展示:

绘制三个参数的后验直方图:

plt.figure(figsize=(12.5, 10))

ax = plt.subplot(311)

ax.set_autoscaley_on(False)
plt.hist(lambda_1_samples, histtype='stepfilled', bins=30, alpha=0.85,
        label='posterior of $\lambda_1$', color='#A60628', density=True)

plt.legend(loc='upper left')
plt.title(r"""Posterior distributions of the varibles $\lambda_1,\;\lambda_2,\;\tau$""")
plt.xlim([15, 30])
plt.xlabel("$\lambda_1$ value")

ax = plt.subplot(312)
ax.set_autoscaley_on(False)
plt.hist(lambda_2_samples, histtype='stepfilled', bins=30, alpha=0.85,
        label='posterior of $\lambda_2$', color="#7A68A6", density=True)
plt.legend(loc='upper left')
plt.xlim([15,30])
plt.xlabel("$\lambda_2$ value")

plt.subplot(313)
w = 1.0 / tau_samples.shape[0] * np.ones_like(tau_samples)
plt.hist(tau_samples, bins=n_count_data, alpha=1, label=r"posterior of $\tau$",
        color='#467821', weights=w, rwidth=2)
plt.xticks(np.arange(n_count_data))

plt.legend(loc='upper left')
plt.ylim([0, .75])
plt.xlim([35, len(count_data) - 20])
plt.xlabel(r"$\tau$ (in days)")
plt.ylabel("probability")
plt.show()

在这里插入图片描述

结论:

1.λ1大概为18,λ2大概为23,这两个λ的后验分布有显著差异,表明用户接收短信的行为确实发生了变化。

2.λ的后验分布并不像指数分布,事实上后验分布并不是我们从原始模型中可以辨别的任何分布,用计算机可以很好展示出来。

3.τ是离散变量,后验分布有所不同,50%把握说明用户在44天行为改变。

结果展示:

绘制拟合的结果:

plt.figure(figsize=(12.5, 5))

N = tau_samples.shape[0]
excepted_texts_per_day = np.zeros(n_count_data)
for day in range(0, n_count_data):
    ix = day < tau_samples
    excepted_texts_per_day[day] = (lambda_1_samples[ix].sum()
                                  +lambda_2_samples[~ix].sum()) / N

plt.plot(range(n_count_data), excepted_texts_per_day, lw=4, color='#E24A33',
        label="expected number of text-messages received")
plt.xlim(0, n_count_data)
plt.xlabel("Day")
plt.ylabel("Excepted number of text-messages received")
plt.ylim(0, 60)
plt.bar(np.arange(len(count_data)), count_data, color="#348ABD", alpha=0.65,
       label='observed texts per day')
plt.legend(loc="upper left")

在这里插入图片描述

结论:

观察上图中的结果发现,分析的结果很符合之前的估计,用户的行为确 实发生了改变,而且变化是很突然的,所以可以推测情况产生的原因可能是:短信资费降低,或者逢年过节期间,或者天气提醒短信订阅等等。

2.2 短信数据推断行为(拓展)

题目:

在这里插入图片描述

代码:

构建模型:

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)
    lambda_3 = pm.Exponential("lambda_3", alpha)
    
    tau_1 = pm.DiscreteUniform("tau_1", lower=0, upper=n_count_data)
    tau_2 = pm.DiscreteUniform("tau_2", lower=0, upper=n_count_data)
    with model:
        idx = np.arange(n_count_data)
        #pm.math.switch(tau_2>=idx, lambda_2, lambda_3)
        lambda_ = pm.math.switch(tau_1>=idx, lambda_1, pm.math.switch(tau_2>=idx, lambda_2, lambda_3))
        #print(lambda_)
    with model:
        observation = pm.Poisson("obs", lambda_, observed=count_data)
    with model:
        step = pm.Metropolis()
        trace = pm.sample(10000, tune=5000, step=step)
    
        lambda_1_samples = trace['lambda_1']
        lambda_2_samples = trace['lambda_2']
        lambda_3_samples = trace['lambda_3']
        tau_1_samples = trace['tau_1']
        tau_2_samples = trace['tau_2']
        print(tau_1_samples)
        print(lambda_1_samples.sum())
        print(lambda_2_samples.sum())
        print(lambda_3_samples.sum())

结果展示:

绘制五个参数的后验直方图:

plt.figure(figsize=(12.5, 10))

ax = plt.subplot(511)
ax.set_autoscaley_on(False)
plt.hist(lambda_1_samples, histtype='stepfilled', bins=30, alpha=0.85,
        label='posterior of $\lambda_1$', color='#A60628', density=True)

plt.legend(loc='upper left')
plt.title(r"""Posterior distributions of the varibles $\lambda_1,\;\lambda_2,\;\tau$""")
plt.xlim([15, 30])
plt.xlabel("$\lambda_1$ value")

ax = plt.subplot(512)
ax.set_autoscaley_on(False)
plt.hist(lambda_2_samples, histtype='stepfilled', bins=30, alpha=0.85,
        label='posterior of $\lambda_2$', color="#7A68A6", density=True)
plt.legend(loc='upper left')
plt.xlim([5,20])
plt.xlabel("$\lambda_2$ value")

ax = plt.subplot(513)
ax.set_autoscaley_on(False)
plt.hist(lambda_3_samples, histtype='stepfilled', bins=30, alpha=0.85,
        label='posterior of $\lambda_3$', color='#467821', density=True)

plt.legend(loc='upper left')
plt.xlim([15, 30])
plt.xlabel("$\lambda_3$ value")

plt.subplot(514)
w = 1.0 / tau_1_samples.shape[0] * np.ones_like(tau_1_samples)
plt.hist(tau_1_samples, bins=n_count_data, alpha=1, label=r"posterior of $\tau$_1",
        color='#467821', weights=w, rwidth=2)
plt.xticks(np.arange(n_count_data))
plt.legend(loc='upper left')
plt.ylim([0, .75])
plt.xlim([35, len(count_data) - 20])
plt.xlabel(r"$\tau$_1 (in days)")
plt.ylabel("probability")

plt.subplot(515)
w = 1.0 / tau_2_samples.shape[0] * np.ones_like(tau_2_samples)
plt.hist(tau_2_samples, bins=n_count_data, alpha=1, label=r"posterior of $\tau$_2",
        color='#467821', weights=w, rwidth=2)
plt.xticks(np.arange(n_count_data))
plt.legend(loc='upper left')
plt.ylim([0, .75])
plt.xlim([35, len(count_data) - 20])
plt.xlabel(r"$\tau$_2 (in days)")
plt.ylabel("probability")

plt.show()

在这里插入图片描述

结论:

1.λ1大概为20,λ2大概为10,λ3大概为23,这三个λ的后验分布有显著差异,表明用户接收短信的行为确实发生了变化。

2.λ的后验分布并不像指数分布,事实上后验分布并不是我们从原始模型中可以辨别的任何分布,用计算机可以很好展示出来。

3.τ是离散变量,后验分布有所不同,40%把握说明用户在43天行为改变。

结果展示:

绘制拟合的结果:

plt.figure(figsize=(12.5, 5))

N = tau_1_samples.shape[0]
excepted_texts_per_day = np.zeros(n_count_data)
for day in range(0, n_count_data):
    ix = day<tau_1_samples
    iy = day>tau_2_samples
    iz = day>tau_1_samples
    if ix.sum()/len(ix) == 1:
        excepted_texts_per_day[day] = (lambda_1_samples.sum())/N
    elif iy.sum()/len(iy) == 1:
        excepted_texts_per_day[day] = (lambda_3_samples.sum())/N
    else:
        excepted_texts_per_day[day] = (lambda_2_samples.sum())/N
    
plt.plot(range(n_count_data), excepted_texts_per_day, lw=4, color='#E24A33',
        label="expected number of text-messages received")
plt.xlim(0, n_count_data)
plt.xlabel("Day")
plt.ylabel("Excepted number of text-messages received")
plt.ylim(0, 60)
plt.bar(np.arange(len(count_data)), count_data, color="#348ABD", alpha=0.65,
       label='observed texts per day')
plt.legend(loc="upper left")

在这里插入图片描述

结论:

观察上图中的结果发现,分析的结果很符合之前的估计,用户的行为确 实发生了改变,而且变化是很突然的,所以可以推测情况产生的原因可能是:短信资费降低,或者逢年过节期间,或者天气提醒短信订阅等等。

2.3 A-B测试

题目:

在这里插入图片描述

2.3.1 方法一

先验分布取Beta分布是个好主意(转化率在0到1之间,刚好和Beta分布 值域一致)。而当样本是二项分布时,参数的共轭先验分布族是Beta分布,所以不需要进行MCMC采样。

代码:

导入需要的库:

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
import pymc3 as pm
from scipy.stats import beta
from IPython.core.pylabtools import figsize

导入需要的数据:

visitors_to_A=1300
visitors_to_B=1300
conversions_from_A=120
conversions_from_B=125
alpha_prior=1
beta_prior=1

得到后验分布,进行采样:

posterior_A=beta(alpha_prior+conversions_from_A,
                beta_prior+visitors_to_A-conversions_from_A)
posterior_B=beta(alpha_prior+conversions_from_B,
                beta_prior+visitors_to_B-conversions_from_B)
samples=2000
samples_posterior_A=posterior_A.rvs(samples)
samples_posterior_B=posterior_B.rvs(samples)

画出后验直方图,估计 p A p_A pA p B p_B pB:

plt.figure(figsize=(12.5,4))
plt.rcParams['savefig.dpi']=300
plt.rcParams['figure.dpi']=300
x=np.linspace(0,1,500)
plt.plot(x,posterior_A.pdf(x),label='posterior of A')
plt.plot(x,posterior_B.pdf(x),label='posterior of B')
plt.xlim(0.05,0.15)
plt.xlabel('value')

在这里插入图片描述

2.3.2 方法二

利用MCMC方法进行采样。

代码:

导入需要的库:

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
import pymc3 as pm
from scipy.stats import beta
from IPython.core.pylabtools import figsize

产生模拟数据:

p_true=0.05
N=1500
occurrences=stats.bernoulli.rvs(p_true,size=N)
print("What is the observed frequency in Group A?%.4f"%np.mean(occurrences))
print("Does this equal the true frequency?%s"%(np.mean(occurrences)==p_true))

构建模型,导入需要的数据:

with pm.Model() as model:
    p=pm.Uniform('p',lower=0,upper=1)
    obs=pm.Bernoulli('obs',p=p,observed=occurrences)
    step=pm.Metropolis()
    trace=pm.sample(12000,tune=1200,step=step,cores=2)
    burned_trace=trace[1000:]
    pm.traceplot(trace)

检查采样结果 :

 pm.traceplot(trace)

在这里插入图片描述

画出后验分布图:

plt.figure(figsize=(12.5,4))
plt.title("Posterior distribution of $p_A$,the true effectiveness of site A")
plt.vlines(p_true,0,90,linestyles="--",label='true $p_A$(unknown)')
plt.hist(burned_trace['p'],bins=25,histtype='stepfilled',density=True)
plt.legend()
plt.show()

在这里插入图片描述

2.4 A-B测试(拓展)

题目:

在这里插入图片描述

代码:

选取均匀分布为先验分布。

导入需要的库:

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
import pymc3 as pm
from scipy.stats import beta
from IPython.core.pylabtools import figsize

产生模拟数据:

true_p_A=0.05
true_p_B=0.04
N_A=1500
N_B=750
observations_A=stats.bernoulli.rvs(true_p_A,size=N_A)
observations_B=stats.bernoulli.rvs(true_p_B,size=N_B)

构建模型,导入需要的数据:

with pm.Model() as model:
    p_A=pm.Uniform('p_A',0,1)
    p_B=pm.Uniform('p_B',0,1)
    delta=pm.Deterministic('delta',p_A-p_B)
    obs_A=pm.Bernoulli('obs_A',p_A,observed=observations_A)    
    obs_B=pm.Bernoulli('obs_B',p_B,observed=observations_B)
    step=pm.Metropolis()
    trace=pm.sample(20000,step=step,cores=1)
    burned_trace=trace[1000:]

结果展示:

p_A_samples=burned_trace["p_A"]
p_B_samples=burned_trace["p_B"]
delta_samples=burned_trace["delta"]
plt.figure(figsize=(12.5,4))
plt.figure(1)
ax=plt.subplot(311)
plt.xlim(0,.1)
plt.hist(p_A_samples,histtype='stepfilled',bins=25,alpha=0.85,
        label="posterior of $p_A$",color="#A60628",density=True)
plt.vlines(true_p_A,0,80,linestyle="--",label="true $p_A$(unknown)")
plt.legend(loc="upper right")
plt.title("Poserior distributions of $p_A$,$_B$,and delta unknowns")

ax=plt.subplot(312)
plt.xlim(0,.1)
plt.hist(p_B_samples,histtype='stepfilled',bins=25,alpha=0.85,
        label="posterior of $p_B$",color="#467821",density=True)
plt.vlines(true_p_B,0,80,linestyle="--",label="true $p_B$(unknown)")
plt.legend(loc="upper right")
ax=plt.subplot(313)
plt.hist(delta_samples,histtype='stepfilled',bins=30,alpha=0.85,
        label="posterior of delta",color="#7A68A6",density=True)
plt.vlines(true_p_A-true_p_B,0,60,linestyle="--",label="true delta(unknown)")
plt.vlines(0,0,60,color="black",alpha=0.2)
plt.legend(loc="upper right")

在这里插入图片描述
在这里插入图片描述

plt.figure(2)
plt.xlim(0,.1)
plt.hist(p_A_samples,histtype='stepfilled',bins=30,alpha=0.80,
        label="posterior of $p_A$",color='#A60628',density=True)
plt.hist(p_B_samples,histtype='stepfilled',bins=30,alpha=0.80,
        label="posterior of $p_B$",color='#467821',density=True)
plt.legend(loc='upper right')
plt.xlabel("Value")
plt.ylabel("Density")
plt.title('Posterior distribution of $p_A$ and $p_B$')
plt.ylim(0,80)
plt.show()

在这里插入图片描述

比较 p A p_A pA, p B p_B pB大小

print("Probability site A is WRSE than site B:%.3f"%np.mean(delta_samples<0))
print("Probability site A is BETTER than site B:%.3f"%np.mean(delta_samples>0))

在这里插入图片描述

三、实验体会

通过本次实验,我对pymc3的使用更加熟悉,同时也对贝叶斯统计推断理解得更透彻。在实验过程中遇到困难要及时和老师同学们交流,以便实验的顺利进行,希望后续实验能对贝叶斯统计推断掌握得更好。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
实验报告: 一、实验目的 本次实验旨在掌握贝叶斯过滤算法的实现方法以及其在邮件垃圾分类中的应用。 二、实验内容 使用Java语言,设计实现一个基于贝叶斯过滤算法的邮件垃圾过滤器,对于一批已知的垃圾邮件和正常邮件分别提取出关键词,训练算法得到相应的概率分布。然后根据新邮件中的关键词,使用贝叶斯公式计算其属于垃圾邮件的概率。如果概率小于0.5,则判定该邮件为正常邮件,否则为垃圾邮件。 、问题分析 邮件垃圾分类是一个非常经典的二分类问题,通常使用朴素贝叶斯分类算法实现。核心思路就是先根据已知的垃圾邮件和正常邮件提取出关键词,然后根据这些关键词计算出在垃圾邮件和正常邮件中的出现概率和条件概率,从而得到模型的概率分布。在新邮件到来时,根据概率分布计算其属于垃圾邮件的概率,从而判定其分类。 四、算法设计 1.数据预处理 先对已有的垃圾邮件和正常邮件进行分词处理,得到每个邮件中出现的关键词,并统计出各个关键词在垃圾邮件和正常邮件中的出现次数,从而计算出在垃圾邮件和正常邮件中的出现概率。 2.贝叶斯分类算法 通过训练数据得到所有出现的关键词在垃圾邮件和正常邮件中的概率,并根据贝叶斯公式计算出新邮件属于垃圾邮件和正常邮件的概率。根据概率大小进行分类。 五、源程序 见附件 六、实验结果 输入邮件为:“最新, 产品,优惠,点击,链接”,根据算法得到分类结果为“垃圾邮件”。 七、实验总结 本次实验实现了一个基于贝叶斯过滤算法的邮件垃圾过滤器,并成功运用于邮件分类,准确率较高。在实现过程中,需要注意数据预处理的正确性和效率,以及贝叶斯分类算法的精度和效率。同时,应注意恶意邮件可能采用各种方法进行欺骗和伪装,需要多方面的数据处理和算法改进来提高准确度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值