使用python进行贝叶斯统计分析

血红的双手。 提交于 2019-12-01 10:07:11

原文链接:http://tecdat.cn/?p=7637

 

本文讲解了使用PyMC3进行基本的贝叶斯统计分析过程. 

  •  
# Imports  import pymc3 as pm # python的概率编程包  import numpy.random as npr # numpy是用来做科学计算的  import numpy as np  import matplotlib.pyplot as plt # matplotlib是用来画图的  import matplotlib as mpl    from collections import Counter # ?   import seaborn as sns # ?   # import missingno as msno # 用来应对缺失的数据    # Set plotting style  # plt.style.use('fivethirtyeight')  sns.set_style('white')  sns.set_context('poster')    %load_ext autoreload  %autoreload 2  %matplotlib inline  %config InlineBackend.figure_format = 'retina'    import warnings  warnings.filterwarnings('ignore')  

使用python进行贝叶斯统计分析

  

 

贝叶斯公式

 

 

贝叶斯主义者的思维方式

根据证据不断更新信念

pymc3

​ 

常见的统计分析问题

  • 参数估计: "真实值是否等于X"
  • 比较两组实验数据: "实验组是否与对照组不同? "

问题1: 参数估计

"真实值是否等于X?"

或者说

"给定数据,对于感兴趣的参数,可能值的概率分布是多少?"

例 1: 抛硬币问题

我把我的硬币抛了 n次,正面是 h次。 这枚硬币是有偏的吗?

参数估计问题parameterized problem

 

先验假设

  • 对参数预先的假设分布:  p∼Uniform(0,1)
  • likelihood function(似然函数, 翻译这词还不如英文原文呢): data∼Bernoulli(p)
# 产生所需要的数据  from random import shuffle  total = 30  n_heads = 11  n_tails = total - n_heads  tosses = [1] * n_heads + [0] * n_tails  shuffle(tosses)  

数据

 

fig = plot_coins()  plt.show()      

  

MCMC Inference Button (TM)

 

100%|██████████| 2500/2500 [00:00<00:00, 3382.23it/s]  

结果

 

pm.traceplot(coin_trace)  plt.show()  


In [10]:

   plt.show()  

  • 95% highest posterior density (HPD, 大概类似于置信区间) 包含了 region of practical equivalence (ROPE, 实际等同区间).
  •  

 

例 2: 药品活性问题

我有一个新开发的分子X; X在阻止流感病毒复制方面有多好?

实验

  • 测试X的浓度范围, 测量流感活性

  • 计算 IC50: 能够抑制病毒复制活性50%的X浓度.

data

import pandas as pd    chem_df = pd.DataFrame(chem_data)  chem_df.columns = ['concentration', 'activity']  chem_df['concentration_log'] = chem_df['concentration'].apply(lambda x:np.log10(x))  # df.set_index('concentration', inplace=True)  

参数化问题parameterized problem

给定数据, 求出化学物质的IC50值是多少, 并且求出置信区间( 原文中the uncertainty surrounding it, 后面看类似置信区间的含义)?

先验知识

  • 由药学知识已知测量函数(measurement function):  m=β1+ex−IC50
  • 测量函数中的参数估计, 来自先验知识: β∼HalfNormal(1002)
  • 关于感兴趣参数的先验知识: log(IC50)∼ImproperFlat
  • likelihood function: data∼N(m,1)

 

数据

  

In [13]:

fig = plot_chemical_data(log=True)  plt.show()  


  

MCMC Inference Button (TM)

  

In [16]:

pm.traceplot(ic50_trace[2000:], varnames=['IC50_log10', 'IC50'])  # live: sample from step 2000 onwards.  plt.show()  

结果

In [17]:

pm.plot_posterior(ic50_trace[4000:], varnames=['IC50'],                     color='#87ceeb', point_estimate='mean')  plt.show()  

该化学物质的 IC50 大约在[2 mM, 2.4 mM] (95% HPD). 这不是个好的药物候选者. 在这个问提上不确定性影响不大, 看看单位数量级就知道IC50在毫摩的物质没什么用...

第二类问题: 实验组之间的比较

"实验组和对照组之间是否有差别? "

例 1: 药品对IQ的影响问题

药品治疗是否影响(提高)IQ分数?

  def ECDF(data):      x = np.sort(data)      y = np.cumsum(x) / np.sum(x)            return x, y    def plot_drug():      fig = plt.figure()      ax = fig.add_subplot(1,1,1)      x_drug, y_drug = ECDF(drug)      ax.plot(x_drug, y_drug, label='drug, n={0}'.format(len(drug)))      x_placebo, y_placebo = ECDF(placebo)      ax.plot(x_placebo, y_placebo, label='placebo, n={0}'.format(len(placebo)))      ax.legend()      ax.set_xlabel('IQ Score')      ax.set_ylabel('Cumulative Frequency')      ax.hlines(0.5, ax.get_xlim()[0], ax.get_xlim()[1], linestyle='--')            return fig  

In [19]:

# Eric Ma自己很好奇, 从频率主义的观点, 差别是否已经是具有"具有统计学意义"    from scipy.stats import ttest_ind    ttest_ind(drug, placebo) # (非配对) t检验. P=0.025, 已经<0.05了  

Out[19]:

Ttest_indResult(statistic=2.2806701634329549, pvalue=0.025011500508647616)

实验

  • 参与者被随机分为两组:
    • 给药组 vs. 安慰剂组
  • 测量参与者的IQ分数

先验知识

  • 被测数据符合t分布:  data∼StudentsT(μ,σ,ν)

以下为t分布的几个参数:

  • 均值符合正态分布:  μ∼N(0,1002)
  • 自由度(degrees of freedom)符合指数分布:  ν∼Exp(30)
  • 方差是positively-distributed:  σ∼HalfCauchy(1002)

数据

In [20]:

fig = plot_drug()  plt.show()  

代码

In [21]:

y_vals = np.concatenate([drug, placebo])  labels = ['drug'] * len(drug) + ['placebo'] * len(placebo)    data = pd.DataFrame([y_vals, labels]).T  data.columns = ['IQ', 'treatment']  
  

MCMC Inference Button (TM)

 

结果

In [24]:

pm.traceplot(kruschke_trace[2000:],                varnames=['mu_drug', 'mu_placebo'])  plt.show()  

In [25]:

pm.plot_posterior(kruschke_trace[2000:], color='#87ceeb',              varnames=['mu_drug', 'mu_placebo', 'diff_means'])  plt.show()  

  • IQ均值的差距为: [0.5, 4.6]
  • 频率主义的 p-value: 0.02 (!!!!!!!!)

注: IQ的差异在10以上才有点意义. p-value=0.02说明组间有差异, 但没说差异有多大. 这个故事说的是虽然有差异, 但是差异太小了, 也没啥意思.

  

In [27]:

   ax = adjust_forestplot_for_slides(ax)  plt.show()  

森林图:在同一轴上的95%HPD(细线),IQR(粗线)和后验分布的中位数(点),使我们能够直接比较治疗组和对照组。

  

In [29]:

ax = pm.plot_posterior(kruschke_trace[2000:],                          varnames=['effect_size'],                         color='#87ceeb')  overlay_effect_size(ax)  

  • 效果大小(Cohen's d, 效果微小, 效果中等, 效果很大)可以从微小到很大(95%HPD [0.0,0.77])。
  •  这种药很可能是无关紧要的。
  • 没有生物学意义的证据。

例 2: 手机消毒问题

比较两种常用的消毒方法, 和我的fancy方法, 哪种消毒方法更好

实验设计

  • 将手机随机分到6组: 4 "fancy" 方法 + 2 "control" 方法.
  • 处理前后对手机表面进行拭子菌培养
  • count 菌落数量, 比较处理前后的菌落计数
    

Out[30]:

sample_id                 int32  treatment                 int32  colonies_pre              int32  colonies_post             int32  morphologies_pre          int32  morphologies_post         int32  year                    float32  month                   float32  day                     float32  perc_reduction morph    float32  site                      int32  phone ID                float32  no case                 float32  frac_change_colonies    float64  dtype: object

数据

  

In [32]:

fig = plot_colonies_data()  plt.show()  

先验知识

菌落计数符合泊松Poisson分布. 因此...

  • 菌落计数符合泊松分布:  dataij∼Poisson(μij),j∈[pre,post],i∈[1,2,3...]
  • 泊松分布的参数是离散均匀分布:  μij∼DiscreteUniform(0,104),j∈[pre,post],i∈[1,2,3...]
  • 灭菌效力通过百分比变化测量,定义如下:  mupre−mupostmupre

 

  

MCMC Inference Button (TM)

In [34]:

with poisson_estimation:      poisson_trace = pm.sample(200000)  
Assigned Metropolis to pre_mus  Assigned Metropolis to post_mus  100%|██████████| 200500/200500 [01:15<00:00, 2671.98it/s]  

In [35]:

pm.traceplot(poisson_trace[50000:], varnames=['pre_mus', 'post_mus'])  plt.show()  

结果

In [39]:

pm.forestplot(poisson_trace[50000:], varnames=['perc_change'],                 ylabels=treatment_order) #, xrange=[0, 110])  plt.xlabel('Percentage Reduction')    ax = plt.gca()  ax = adjust_forestplot_for_slides(ax)  

 

 

 如果您有任何疑问,请在下面发表评论。 

 

 

  

大数据部落 -中国专业的第三方数据服务提供商,提供定制化的一站式数据挖掘和统计分析咨询服务

统计分析和数据挖掘咨询服务:y0.cn/teradat(咨询服务请联系官网客服

QQ:3025393450

 

​QQ交流群:186388004 

【服务场景】  

科研项目; 公司项目外包;线上线下一对一培训;数据爬虫采集;学术研究;报告撰写;市场调查。

【大数据部落】提供定制化的一站式数据挖掘和统计分析咨询

欢迎选修我们的R语言数据分析挖掘必知必会课程!

 

 

  

大数据部落 -中国专业的第三方数据服务提供商,提供定制化的一站式数据挖掘和统计分析咨询服务

统计分析和数据挖掘咨询服务:y0.cn/teradat(咨询服务请联系官网客服

QQ:3025393450

 

​QQ交流群:186388004 

【服务场景】  

科研项目; 公司项目外包;线上线下一对一培训;数据爬虫采集;学术研究;报告撰写;市场调查。

【大数据部落】提供定制化的一站式数据挖掘和统计分析咨询

欢迎选修我们的R语言数据分析挖掘必知必会课程!

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!