【机器学习实验】概率编程及贝叶斯方法

引言

贝叶斯方法是天生用来做推断的方法,然而它常隐藏在课本的数学分析的背后。 随着近年来贝叶斯方法在机器学习竞赛中成功应用,其重要性又引起了学习者的兴趣,但是其难点在于贝叶斯数学和概率编程之间的衔接。《Probabilistic Programming and Bayesian Methods for Hackers》一书试图弥补以上的遗憾。 有关概率编程和贝叶斯方法的实验,我将以该在线书籍作为学习资料,希望从中能将理论知识和编程实践想结合,以加深对理论的理解,以提高解决具体问题和数学建模的能力。

我们期望使用贝叶斯推断来进行统计分析,利用计算机的计算能力通过概率编程来解决问题。该方法去除了原本数学分析的干预。PyMC是一个马尔可夫链蒙特卡罗采样(Markov chain Monte Carlo Sampling)Python工具包,它实现了Metropolis-Hastings算法,包含了画图、拟合优度(goodness-of-fit)和聚合诊断(convergence diagnostics)的方法。

贝叶斯思想

比如测试一个算法的正确性,我们通过一个个测试用例来验证算法的正确性,每次测试都让我们对算法的准确性更加有信心,但是我们无法保证算法是没有bug的,除非测试了所有可能的问题,但这常常是不实际的。 贝叶斯推断是同样的一个道理,通过成功的结果来更新信任度,在没有验证所有可能的结果之前,我们无法绝对肯定。

现在,我们来对比一下贝叶斯和频率派对于概率的解释。 从贝叶斯的世界观中,概率是一个事件发生的可信度(believability)的度量,也就是说,我们对一件事情发生是多么有信心。 而频率派的观点,他们设定概率是事件的长期频率。比如飞机发生事故的概率,频率派解释为飞机事故的长期频率。这在很多事件的概率问题上看上去确实有逻辑合理性,但当一个事件不会经常出现,无法统计长期的发生频率的话,就很难解释通了。比如总统选举的概率,因为该选举只发生一次。 贝叶斯观点认为,概率是事件发生的可信度或者信心的测度。对于一个事件的发生,如果将这种可信度设为0,那么说明我们对该事件发生没有信心;相反,如果将这种可信度设为1,那么说明我们十分肯定该事件一定会发生。0到1之间的可信度是对结果发生的权重的考虑。这样的定义与飞机发生事故的概率的解释是一致的:通过观测了飞机事故的发生频率,在没有附加信息的情况下,飞机事故的可信度应该等于该频率。

我们设定可信度的测量是针对一个个体的,而不是对于自然而言的。这是因为,不同的个体具有不同的信息,所以其对于事件发生的信任程度也不同。 将可信度认为是一种概率的哲学观点对人类是很自然的,我们持续不断地与世界万物互动接触,总是看到一部分真相,,却收集了一些证据来构成这种可信度。 贝叶斯派通过观察到更多的证据和现象来更正自己的信任度,尤其是当证据与初始认为的一致时,该证据就更不能被忽视了。我们将更新的可信度设为P(A|X),解释为在给定证据X时,事件A发生的概率。这被称作后验概率。

先验概率P(A):硬币有50%的机会向上;后验概率P(A|X):你看到了硬币落到地上时正面朝上,这就是信息X,于是我们就将硬币朝上的概率设为1.0,硬币朝下的概率设为0.0。 先验概率P(A):大型复杂的程序代码可能bug;后验概率P(A|X):如果代码通过了所有的测试用例X,尽管仍然有bug存在的可能性,但是该可能性已经减小了。 贝叶斯推断实战

如果是频率派和贝叶斯派编写一个函数,输入一个统计问题,而返回的结果是不同的。频率派的推断方程会返回一个数来表示一个估计,而贝叶斯派的方程将返回一个概率。 以之前代码调试问题为例,当询问“代码通过了所有测试,那么该代码是不是没有bug了”,频率派的方程会返回“是”;而贝叶斯派的方程将返回“是”和“否”的概率。

令N为我们手上数据证据的数量,当我们收集了无限多个证据,即N→∞,贝叶斯的结果和频率派的结果是一致的。所以,对于很大的N,统计推断或多或少有一定客观性;而对于较小的N,该推断就不太稳定了:频率派估计就有较大的方差和较大的置信区间(confidence intervals)。这却是贝叶斯分析擅长的,贝叶斯派引入了先验概率,返回一个概率,这样就保有了对于小数据集情况下统计推断所反映出来的不确定性(uncertainty)。

有人会认为,当N很大的时候,人们会不太在意这两种技术的区别,因为此时它们提供了类似的推断,甚至更倾向于计算简单的频率派方法。 而有专家[Andrew Gelman (2005)]认为,样本数量永远不会很大。如果N很小,为了得到一个足够精确的推论,你需要获得更多的数据。但是一旦N足够大,你便开始细分数据以学习更多(比如,在一个公开的民意投票中,一旦你对于全国的情况有一个很好的估计,你便会划分不同的人群来进行更多的估计,比如按照性别,不同的年龄,不同的地域等)。N不会很充足,因为一旦你认为有充足的数据,你便转向更加细致的问题,这样你便需要更多的数据。

频率派方法是错误的吗?

频率派方法依然很有用,并且在很多领域都是先进水平(state-of-the-art)。像最小二乘线性回归、LASSO回归、期望最大算法都很有用、很快速。贝叶斯方法补充了这些技术的不足,或者用弹性建模(flexible modeling)来阐述潜在的系统。

关于大数据

反常的是,大数据的预测分析问题常常使用相对简单的算法,因此,我们辩解大数据预测的困难点不在于算法的使用,而是存储和使用大数据的难度。 更多的难以分析的问题包含中数据(medium data)以至于小数据(small data)。

贝叶斯框架

入门实验抛硬币实验

假设你不知道抛硬币正面朝上的的概率,你定义该真实比率为p,但是并没有关于p的任何先验知识。 于是,我们尝试抛硬币并记录其观测结果。有趣的问题来了,随着我们观察到越来越多的数据,我们的推断是如何发生变化的?

%matplotlib inlinefrom IPython.core.pylabtools import figsizeimport numpy as npfrom matplotlib import pyplot as pltfigsize(11, 9)import scipy.stats as statsdist = stats.beta#多次试验n_trials = [0, 1, 2, 3, 4, 5, 8, 15, 50, 500]#构造500个符合伯努利分布的随机抽样data = stats.bernoulli.rvs(0.5, size=n_trials[-1])x = np.linspace(0, 1, 100)#使用伯努利分布的共轭先验——Beta分布for k, N in enumerate(n_trials):sx = plt.subplot(len(n_trials) / 2, 2, k + 1)plt.xlabel(“$p$, probability of heads”) \if k in [0, len(n_trials) – 1] else Noneplt.setp(sx.get_yticklabels(), visible=False)#不显示y轴刻度heads = data[:N].sum()#统计1的个数y = dist.pdf(x, 1 + heads, 1 + N – heads)#构造Beta分布plt.plot(x, y, label=”observe %d tosses,\n %d heads” % (N, heads))plt.fill_between(x, 0, y, color=”#FF99CC”, alpha=0.4)#填充色彩到曲线下区域plt.vlines(0.5, 0, 4, color=”k”, linestyles=”–“, lw=1)#在0.5处画虚线leg = plt.legend()leg.get_frame().set_alpha(0.4)plt.autoscale(tight=True)plt.suptitle(“Bayesian updating of posterior probabilities”,y=1.02,fontsize=14)plt.tight_layout()去旅行不在于记忆,而在于当时的那份心情。

【机器学习实验】概率编程及贝叶斯方法

相关文章:

你感兴趣的文章:

标签云: