此示例显示如何使用Hamiltonian Monte Carlo(HMC)采样器对线性回归模型执行贝叶斯推断。
在贝叶斯参数推理中,目标是结合模型参数的先验知识来分析统计模型。自由参数的后验分布结合似然函数与先前分配,使用贝叶斯定理:
通常,总结后部分布的最佳方法是使用Monte Carlo方法获得来自该分布的样品。使用这些样本,您可以估计边缘后分布和衍生统计,例如后平均值,中值和标准偏差。HMC是一种基于梯度的马尔可夫链蒙特卡罗采样器,可以比标准采样器更有效,尤其是中维和高维问题。
通过截距分析线性回归模型,线性系数(列向量),以及噪声方差数据分布为自由参数。假设每个数据点都有一个独立的高斯分布:
模型意思高斯分布作为预测因子的函数和模型参数为
在贝叶斯分析中,您还必须将先前的分布分配给所有免费参数。在拦截和线性系数上分配独立的高斯前瞻:
,
.
要使用HMC,所有采样变量必须是无疑的,这意味着后密度及其梯度必须为所有真实参数值定义。如果您有一个受限于间隔的参数,则必须将此参数转换为无限的一个。为了节省概率,必须将先前的分布乘以相应的雅各主义因子。此外,在计算后后的梯度时,将此因素考虑在内。
噪声方差是一个(平方)尺度参数,只能是正的。这样就可以更容易、更自然地将它的对数视为自由参数,它是无界的。在噪声方差的对数之前指定一个正态分布:
.
写出自由参数的后验密度的对数作为
忽略常数项,取最后两项的和.要使用HMC,请创建评估的函数句柄及其渐变对于任意值.用于计算的功能位于脚本的末尾。
定义截距的真实参数值,即线性系数β
,噪声标准差。知道真实的参数值可以与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);
定义初始点以开始采样,然后调用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 (“负对数密度”);
为获得有效的采样,选择合适的采样参数值是非常重要的。找到好的值的最好方法是自动调优MassVector
,StepSize
,NumSteps
参数使用tuneSampler
方法。使用该方法:
1.托儿MassVector
取样器。
2.调优StepSize
和NumSteps
对于固定的模拟长度达到一定的接受比。在大多数情况下,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分位数的估计(Q5
和Q95
)
后验均值估计的有效样本量(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]
.X
和Y
分别包含预测器和响应的值。
的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 /σ;结尾