主要内容

基于哈密顿蒙特卡罗的贝叶斯线性回归

此示例显示如何使用Hamiltonian Monte Carlo(HMC)采样器对线性回归模型执行贝叶斯推断。

在贝叶斯参数推理中,目标是结合模型参数的先验知识来分析统计模型。自由参数的后验分布\θ美元结合似然函数P (y | \θ)美元与先前分配$ p(\ theta)$,使用贝叶斯定理:

$ $ P(\θ| y) = \压裂{P (y | \θ)(\θ)}{P (y)} $ $

通常,总结后部分布的最佳方法是使用Monte Carlo方法获得来自该分布的样品。使用这些样本,您可以估计边缘后分布和衍生统计,例如后平均值,中值和标准偏差。HMC是一种基于梯度的马尔可夫链蒙特卡罗采样器,可以比标准采样器更有效,尤其是中维和高维问题。

线性回归模型

通过截距分析线性回归模型$ \ Alpha $,线性系数β\美元(列向量),以及噪声方差$ \ sigma ^ 2 $数据分布为自由参数。假设每个数据点都有一个独立的高斯分布:

$$ y_i | \ theta \ sim \ mathcal {n}(\ mu_i(\ theta),\ sigma ^ 2)。$$

模型意思\ mu_i美元高斯分布作为预测因子的函数x_i美元和模型参数为

$$ mu_i = + x_i^T, $$

在贝叶斯分析中,您还必须将先前的分布分配给所有免费参数。在拦截和线性系数上分配独立的高斯前瞻:

美元\α\ sim \ mathcal {N} (\ alpha_0 \ sigma_ \α^ 2)美元

美元\ beta_i \ sim \ mathcal {N} (\ beta_ {0}, \ sigma_{\β}^ 2)美元

要使用HMC,所有采样变量必须是无疑的,这意味着后密度及其梯度必须为所有真实参数值定义。如果您有一个受限于间隔的参数,则必须将此参数转换为无限的一个。为了节省概率,必须将先前的分布乘以相应的雅各主义因子。此外,在计算后后的梯度时,将此因素考虑在内。

噪声方差是一个(平方)尺度参数,只能是正的。这样就可以更容易、更自然地将它的对数视为自由参数,它是无界的。在噪声方差的对数之前指定一个正态分布:

$ \ log \ sigma ^ 2 \ sim \ mathcal {n}(\ kappa,\ omega ^ 2)$

写出自由参数的后验密度的对数$ \θ=(\α;\β;日志\ \σ^ 2)美元作为

$$ logp (\theta | y) = mathrm{const。} + log P(y | \theta) + log
P(\theta).$$

忽略常数项,取最后两项的和g(\θ)美元.要使用HMC,请创建评估的函数句柄g(\θ)美元及其渐变${\部分g} /{\部分\θ}$对于任意值\θ美元.用于计算的功能g(\θ)美元位于脚本的末尾。

创建数据集

定义截距的真实参数值,即线性系数β,噪声标准差。知道真实的参数值可以与HMC采样器的输出进行比较。只有第一个预测因子会影响反应。

NumPredictors = 2;trueIntercept = 2;trueBeta = (3; 0);trueNoiseSigma = 1;

使用这些参数值以在两个预测器的随机值中创建正常分布的样本数据。

numdata = 100;RNG(“默认”%的再现性X =兰特(NumData NumPredictors);= X*trueBeta + trueIntercept;y = normrnd(μ,trueNoiseSigma);

定义后验概率密度

选择高斯先验的均值和标准差。

InterceptPriorMean = 0;InterceptPriorSigma = 10;BetaPriorMean = 0;BetaPriorSigma = 10;LogNoiseVarianceMean = 0;LogNoiseVarianceSigma = 2;

保存功能logPosterior在MATLAB®路径上返回先验和似然乘积的对数,以及这个对数的梯度。的logPosterior函数在本例的最后定义。然后,调用带参数的函数来定义logpdf的输入参数hmcSampler功能。

logpdf = @(参数)logposterior(参数,x,y,...拦截Proormean,拦截产品,...BetaPriorMean BetaPriorSigma,...lognoisevariarcememean,lognoisevariaresigma);

创建HMC取样器

定义初始点以开始采样,然后调用hmcSampler函数创建Hamiltonian采样器作为一个汉密尔顿人寻找者目的。显示采样器属性。

拦截= randn;Beta = Randn(NumPredictors,1);lognoisevariance = Randn;startpoint = [拦截; beta; lognoisevariance];SMP = HMCSampler(logpdf,startpoint,'numsteps', 50);
smp
smp = HamiltonianSampler with properties: StepSize: 0.1000 NumSteps: 50 MassVector: [4x1 double] JitterMethod: 'jitter-both' StepSizeTuningMethod: 'dual-averaging' MassVectorTuningMethod: ' iter- sampling' LogPDF: [function_handle] VariableNames: {4x1 cell} StartPoint: [4x1 double]

估计地图点

估算后密度的地图(最大-A-Bouthiori)点。您可以从任何点开始采样,但估计地图点通常更有效,然后将其用作调整采样器和绘图样本的起点。估计并显示地图点。通过设置,您可以在优化期间显示更多信息“VerbosityLevel”值为1。

[MAPpars, fitInfo] = estimateMAP (smp,“VerbosityLevel”, 0);MAPIntercept = mapservers (1) MAPBeta = mapservers (2:end-1) mapservers (2:end-1)
MAPIntercept = 2.3857 MAPBeta = 2.5495 -0.4508 mapplognoise variance = -0.1007

要检查优化是否融合到本地最佳,请绘制fitInfo。客观的场地。此字段包含函数优化的每次迭代时的负日志密度的值。最终值都是相似的,因此优化融合了。

情节(fitInfo.Iteration fitInfo.Objective,“ro - - - - - -”);包含('迭代');ylabel (“负对数密度”);

调整取样器

为获得有效的采样,选择合适的采样参数值是非常重要的。找到好的值的最好方法是自动调优MassVectorStepSize,NumSteps参数使用tuneSampler方法。使用该方法:

1.托儿MassVector取样器。

2.调优StepSizeNumSteps对于固定的模拟长度达到一定的接受比。在大多数情况下,0.65的默认目标接受率是好的。

从估计的MAP点开始调优,以获得更有效的调优。

[SMP,TuneInfo] = TuneSampler(SMP,“开始”, MAPpars);

绘制调优过程中步长的演变,以确保步长调优已经收敛。显示达到的合格率。

图;情节(tuneinfo.StepSizeTuningInfo.StepSizeProfile);包含('迭代');ylabel (“步长”);accratio = tuneinfo.StepSizeTuningInfo.AcceptanceRatio
accratio = 0.6700

画出样本

从后验密度中抽取样本,使用几个独立的链。为链选择不同的初始点,随机分布在估计的MAP点周围。指定从马尔可夫链开始丢弃的老化样本数量和老化后生成的样本数量。

设定“VerbosityLevel”值打印第一个链采样期间的详细信息。

NumChains = 4;链=细胞(NumChains, 1);燃烧= 500;NumSamples = 1000;为了c = 1: NumChains如果(c == 1) = 1;别的级别= 0;结尾链{c} = drawSamples (smp,“开始”MAPpars + randn(大小(MAPpars)),...“燃烧”燃烧,“NumSamples”NumSamples,...“VerbosityLevel”水平,'numprint',300);结尾
|==================================================================================| | ITER日志PDF | |步长| NUM | | ACC比例不同的步骤  | |==================================================================================| | 300 e + 02 | -1.490356 | 2.617 e-01 | 11 | 9.467 e-01 | 0 | | 600 | -1.493478 e + 02 | 2.199 e-02 | 3 | 9.367 e-01 | 0 || 900 | -1.509868e+02 | 2.244e-01 | 5 | 9.422e-01 | 0 | | 1200 | -1.493611e+02 | 1.166e-01 | 15 | 9.300e-01 | 0 | 1500 | -1.488397e+02 | 2.617e-01 | 11 | 9.320e-01 | 0 |

检查融合诊断

使用诊断方法来计算标准MCMC诊断。对于每个抽样参数,该方法使用所有链来计算这些统计数据:

  • 后验均值估计(的意思是

  • 蒙特卡罗标准误差估计(MCSE),即后验均值估计值的标准差

  • 后验标准差的估计(SD

  • 后缘分布的第5和95分位数的估计(Q5Q95

  • 后验均值估计的有效样本量(ESS

  • Gelman-Rubin收敛统计(罗阿).根据经验,值罗阿不到1.1是链已经收敛到期望分布的标志。如果罗阿对于任何变量大于1.1,然后尝试用drawSamples方法。

显示诊断表和示例开始定义的采样参数的真实值。由于先前分发对于此数据集是非信息,因此True值在第5和第95分钟之间介于(或接近)。

Diags =诊断(SMP,链)Truepars = [TrueIntercept; TrueBeta; log(Truenoisesigma ^ 2)]
诊断接头= 4×8表名的意思是MCSE SD Q5 Q95 ESS小红帽  ______ _________ _________ _______ ________ _______ ______ ______ {' x1} 2.3792 0.0055101 0.27821 1.9116 2.8372 2549.3 1.0009{“x2”}2.5533 0.0062076 0.32836 2.0223 3.0959 2798.1 1.0004 {x3的}-0.43983 0.0065001 0.34398 -1.0192 0.12916 2800.5 1.0001{“x4”}-0.063367 0.0028645 0.14159 -0.288530.1838 2443.3 1.0004 truePars = 2 3 00

可视化样本

研究收敛和混合等问题,以确定抽取的样本是否代表了目标分布的一组合理的随机实现。要检查输出,请使用第一个链绘制样本的跟踪图。

drawSamples方法从马尔可夫链的开始就丢弃老化样本,以减少抽样起点的影响。此外,轨迹图看起来像高频噪声,样本之间没有任何可见的长期相关性。这一行为表明该链混合良好。

图;次要情节(2 2 1);情节(链{1}(:1));标题(sprintf ('拦截,连锁1'));为了p = 2:1+NumPredictors subplot(2,2,p);情节(链{1}(:p));标题(sprintf ('beta(%d),链1',p-1));结尾次要情节(2、2、4);情节(链{1}(:,结束));标题(sprintf ('lognoisevariance,链1'));

将这些链组合成一个矩阵,并创建散点图和直方图来可视化1-D和2-D的边缘后验分布。

连锁concatenatedSamples = vertcat ({});图;plotmatrix (concatenatedSamples);标题(“所有连锁店的总和”);

计算后验分布的函数

logPosterior函数返回线性模型的正态似然和正态先验乘积的对数。输入参数参数格式[拦截;β;LogNoiseVariance]XY分别包含预测器和响应的值。

normalPrior函数返回具有均值的多元正态概率密度的对数μ和标准偏差西格玛,指定为长度相同的标量或列向量P.第二个输出参数是相应的梯度。

函数[logpdf,gradlogpdf] = logposter(参数,x,y,...拦截Proormean,拦截产品,...BetaPriorMean BetaPriorSigma,...LogNoiseVarianceMean LogNoiseVarianceSigma)%解包参数向量拦截=参数(1);β=参数(2:end-1);LogNoiseVariance =参数(结束);%计算对数似然及其梯度σ=√exp (LogNoiseVariance));= X* +截距;Z = (Y - Mu)/;loglik =总和(日志(σ)- 5 *日志(2 *π)- 5 * z ^ 2);gradIntercept1 =总和(Z /σ);gradBeta1 = X ' * Z /σ;gradLogNoiseVariance1 =(-求和。5 + 5 * (z ^ 2));%计算日志优先级和梯度[LPIntercept, gradIntercept2] = normalPrior(Intercept,InterceptPriorMean,InterceptPriorSigma);[LPBeta, gradBeta2] = normalPrior(Beta,BetaPriorMean,BetaPriorSigma);[LPLogNoiseVar, gradLogNoiseVariance2] = normalPrior(LogNoiseVariance,LogNoiseVarianceMean,LogNoiseVarianceSigma);logprior = LPIntercept + LPBeta + LPLogNoiseVar;%返回日志后部及其渐变Logpdf = loglik + logprior;gradIntercept = gradIntercept1 + gradIntercept2;gradBeta = gradBeta1 + gradBeta2;gradLogNoiseVariance = gradLogNoiseVariance1 + gradlognoisvariance2;gradlogpdf = [gradIntercept; gradBeta gradLogNoiseVariance];结尾函数[logpdf,gradlogpdf] = normalPrior(P,Mu,Sigma) Z = (P - Mu)./Sigma;logpdf =总和(日志(σ)- 5 *日志(2 *π)- 5 * (z ^ 2));gradlogpdf = z /σ;结尾

也可以看看

功能