伪似然参数估计:绕开配分函数的MRF/Ising与三明治标准误
发布时间:2026/10/2 10:30:33来源:尧图网络
伪似然Pseudo Likelihood这个词第一次砸到我脸上是几年前接一个用户行为空间相关性的活儿。当时手里有一张几千个格点的网格数据想用一个带交互项的马尔可夫随机场去刻画相邻区域之间的相互影响模型写出来很顺一上极大似然就卡死在归一化常数上——那个求和项要枚举全部格点的取值组合数量是 2 的几千次方物理上根本跑不完。后来翻回 Besag 1975 年那篇经典论文才反应过来这类问题早就有人绕过去了既然联合分布算不动那就退一步只算每个点在自己邻居给定时的条件概率再把所有条件概率乘起来。这个乘积长得像似然但严格说不是似然所以叫伪似然。它最值钱的地方在于没有配分函数、没有高维积分、单个格点的条件概率往往还有闭式解拿一阶优化器就能直接怼。这篇文章我打算把伪似然的来龙去脉、它和拟似然/复合似然的区别、怎么在二维 Ising 模型上完整跑一遍参数估计、以及标准误必须用三明治公式算这件事从头捋一遍。适合已经会用极大似然做建模、但在高维依赖结构面前被卡住的人也适合做空间统计、社交网络分析、能量模型评估的同行。1. 配分函数这道坎逼出了伪似然1.1 联合似然为什么算不动先把问题摆清楚。假设你有一个 $n$ 个节点的无向图模型每个节点取离散值联合分布写成吉布斯形式$$p(x) \frac{1}{Z(\theta)}\exp\left(\sum_{i}\theta_i x_i \sum_{ij}\theta_{ij}x_ix_j\right)$$其中 $Z(\theta) \sum_{x \in \mathcal{X}^n}\exp(\cdot)$是对所有可能的配置求和。$n20$、每个节点取两个值时是 $2^{20}$ 约一百万咬咬牙还能算$n100$ 就是 $10^{30}$已经没有商量的余地了。这就是配分函数partition function带来的整数规划式难题也是所有无向图模型绕不开的核心障碍。关键在于这个 $Z(\theta)$ 不是能随手扔掉的常数。它依赖参数 $\theta$所以在对 $\theta$ 求导、做梯度上升的时候它跑不掉。对 $\theta_{ij}$ 求偏导会得到「观测到的充分统计量均值」减去「模型期望下的充分统计量均值」后面那一项需要在模型分布下做期望于是又要面对 $Z$ 和整个联合分布。传统路子是用 MCMC 近似这个期望但每一轮梯度迭代里都嵌一条长链计算代价会成倍放大收敛诊断也变成了一个反复拉扯的麻烦事。1.2 三个真实场景里的同一种卡顿这种卡顿不是空间统计独有。我这些年至少在三个地方反复撞上同一个墙。第一类是图像和空间统计。像素之间、区域之间的邻接关系天然构成无向图你希望刻画「相邻的像素更可能同色」这类现象。图像尺寸一大联合似然直接失效。第二类是社交网络和关系数据。指数随机图模型ERGM就是典型代表它的联合分布里有一项归一化常数要遍历所有可能的网络结构网络节点数只要上千这个常数就变成了不可计算的量。第三类是深度生成模型里的能量模型。受限玻尔兹曼机RBM的能量函数定义的联合分布同样带一个配分函数这也是当年 RBM 训练普遍靠对比散度、靠各种近似采样来绕的原因。三者的共同点很清楚模型本身写起来不复杂不复杂的部分全被归一化项一票否决。伪似然给出的回答是——我们干脆不碰归一化项。1.3 伪似然给出的绕路方案思路特别朴素一个无向图模型有个基本性质节点 $i$ 在其余所有节点取值已知的条件下只依赖它的邻居集合 $N(i)$。这叫局部马尔可夫性。于是$$p(x_i \mid x_{-i}) p(x_i \mid x_{N(i)})$$右边这个条件概率只涉及节点 $i$ 和它的一圈邻居把除 $i$ 以外所有节点固定住$Z$ 在分子分母里直接约掉是一个完全可计算的表达式。对于上面那个 Ising 模型它化简成$$p(x_i 1 \mid x_{N(i)}) \sigma\left(2\left(\theta_i \sum_{j \in N(i)}\theta_{ij}x_j\right)\right)$$其中 $\sigma$ 是 sigmoid 函数。伪似然做的事情就是把这 $n$ 个条件概率全部乘起来当作一个「伪联合似然」$$\mathrm{PL}(\theta; x) \prod_{i1}^{n} p(x_i \mid x_{N(i)}, \theta)$$这个乘积看起来很像似然但它和真正的联合似然并不是一回事二者之间差着一个隐式的「兼容性修正项」。名字里的「伪」就是从这个地方来的它说的是「拟似的、形似的」不是说它不可靠或者不能用。理解这一层后面很多看起来矛盾的结论就顺了。2. 把联合似然拆成条件概率连乘伪似然的数学骨架2.1 Besag 1975 年的原始形式伪似然是在 Besag 1975 年那篇讨论空间格点数据统计分析的论文里正式提出的。他的动机非常具体马尔可夫随机场MRF在理论上很漂亮能刻画局部依赖但联合似然里那个归一化常数在实际数据面前是死的他希望找一个只用局部条件分布就能做推断的替代品。构造方式是直接对每个格点写条件分布然后取乘积。取对数之后$$\ell_{PL}(\theta) \sum_{i1}^{n}\log p(x_i \mid x_{N(i)}, \theta)$$这个式子是本文最核心的一行。它有三个很好的性质每一项都能独立算不需要把全部配置枚举出来参数维度再高也不会让计算量爆炸对很多常见模型Ising、Potts、高斯马尔可夫随机场每一项都有闭式解。这三条加在一起就成了它在工程里活下来的理由。2.2 为什么连乘能得到相合估计很多人第一反应是你这乘积明显不等于联合似然那估计出来的参数还有意义吗答案是有的而且是有严格保证的。伪似然估计量是一个估计方程estimating equation的解满足无偏性条件$$\mathbb{E}\left[\frac{\partial \ell_{PL}}{\partial \theta}\right] 0$$这个期望是在真实数据生成分布下取的。只要这个得分方程在真值处成立再加上一些正则条件参数空间紧、伪似然关于参数二阶可微、信息矩阵正定用 M-估计的一整套渐近理论就能得到 $\hat{\theta}_{PL} \to \theta_0$而且是 $\sqrt{n}$ 相合、渐近正态的。这里的「$n$」需要小心它可以是格点数量一个图内部的多个节点也可以是独立样本的数量。用格点数量的时候伪似然的每一项之间不是独立的渐近理论要复杂一些这也是后面标准误必须修正的根源。理解这一点比背下公式重要得多。2.3 它到底丢了什么信息损失与效率伪似然是相合的但不是有效的。用费舍尔信息的语言说它丢掉了一部分信息所以渐近方差一般比极大似然大。丢掉的是什么是节点之间可能存在的、超出局部邻域的高阶依赖关系。条件分布只盯着每个节点的一圈邻居长程的相关结构它完全看不见。效率损失有多大取决于联合分布本身有多「局部」。耦合越弱、图结构越稀疏联合分布本来就接近条件独立的乘积这时候伪似然和极大似然几乎一样好。但在强耦合区域尤其是接近相变临界点的地方长程关联变得显著伪似然的信息损失会明显放大有偏程度也会上升。我后面在实操部分会专门给一段代码让你自己看这个偏差长什么样。2.4 落在估计方程框架里得分、三明治方差把伪似然纳入估计方程框架有个直接好处一切都变得可操作。定义得分向量$$S(\theta) \frac{\partial \ell_{PL}}{\partial \theta}$$它的方差矩阵记作 $B$。定义负的期望海森矩阵$$A -\mathbb{E}\left[\frac{\partial^2 \ell_{PL}}{\partial \theta \partial \theta^\top}\right]$$那么渐近协方差是 $A^{-1}BA^{-\top}$。注意这里出现的是两个不同的矩阵而不是 $A^{-1}$。绝大多数人第一次用伪似然的时候都会在这个地方翻车——直接把海森矩阵求逆得到标准误然后发现显著性检验的结果全是假的。原因在于只有真正的极大似然才满足信息矩阵等式 $A B$对伪似然来说这两个矩阵一般不相等差的部分就是从联合似然到伪似然过程中被丢掉的那些信息。这个三明治结构我在第 5 节会给出完整的代码实现。3. 名字容易混拟似然、复合似然、伪似然到底谁是谁3.1 拟似然Quasi-Likelihood只知道均值-方差关系时怎么办拟似然是 Wedderburn 在 1974 年提出的解决的是另一个层面的问题有时候你连完整分布形式都写不出来但对数据的均值和方差之间的关系有自己的判断。比如做计数数据回归时你知道 $Var(Y) \phi\mu$但不想假设分布就是泊松或负二项。拟似然让你绕过完整分布只用一个得分方程来求解。它和伪似然的关键区别在于拟似然是连完整概率分布都放弃只保留矩假设伪似然是概率分布形式上还在只是把联合分布替换成一个条件概率的乘积。两者在渐近理论上是同一套框架都是估计方程但出发点完全不同。放到广义估计方程GEE里看你还会看到「拟似然」这个词和「工作相关矩阵」一起出现那就更绕了——GEE 里它指的是用工作相关结构去逼近真实相关结构本质上还是一种矩层面的近似。3.2 复合似然Composite Likelihood成对似然与一般化复合似然是把伪似然推广之后的概念Varin、Reid 和 Firth 在 2011 年做过一篇很经典的综述。核心想法是与其只取单点条件分布连乘不如取任意一个低维事件的概率边沿来连乘。常见的形式有好几种成对似然pairwise likelihood取所有变量对的联合概率乘积条件似然conditional likelihood就是 Besag 那种还有一些取三阶、四阶事件的形式。不同选择之间权衡的其实是两件事计算代价和信息保留程度。成对似然比单点条件似然保留更多信息但计算量从 $O(n)$ 涨到 $O(n^2)$有条件独立结构可利用时成对似然在效率上明显更好。Besag 的伪似然是复合似然里最常见的特例这也是为什么在很多论文里这两个词会混着用——严格说伪似然是复合似然的一个特例但大家说起来常常不分。3.3 能量模型与 RBM 里的伪似然深度学习做无向生成模型时伪似然是评估能量模型的一个常用工具。原因和空间统计完全一样RBM 的联合分布里有一个归一化常数评估似然时会遇到用它来比较不同模型时也会遇到。伪似然把每一维的条件概率算出来相乘就可以绕开这个常数。但这里必须强调一点也是我踩过的坑伪似然高不等于联合分布拟合得好。曾经有一个场景我调完模型之后发现伪似然指标一路在涨但采出来的样本显然是一团模糊。原因很直接——伪似然本质上衡量的是「给定邻居之后每个变量还能被预测得多好」而单个变量的局部一致性在整体结构崩坏的时候照样可以是高的。所以拿它做模型选择时我的建议是至少配一个独立的采样质量指标不要单看伪似然数值。此外RBM 里还有一块容易被忽略的细节伪似然对二值 RBM 的可见层可以精确计算但对连续型可见层比如高斯 RBM就不一样了条件分布是连续密度那个数值会被密度的尺度影响不同模型之间不再能直接比。这一类问题看似小但实际调试时最费时间。3.4 一张表理清关系概念提出动机典型形式关键假设常见应用极大似然完整分布已知联合似然分布形式完全指定低维、可算配分函数的场景伪似然联合似然算不动单点条件概率连乘局部马尔可夫性成立空间统计、图像、RBM复合似然单点信息太少成对/多阶事件概率连乘低维边沿可计算高维相关数据、时空模型拟似然分布形式写不出只写均值-方差关系的得分方程矩假设正确GEE、过离散计数数据这张表建议先存下来。见到一个新场景先判断你卡住的是哪个环节配分函数算不动就用伪似然或复合似然连分布形式都不确定就用拟似然两者都动不了那大概率得换一套建模思路。4. 手把手给二维 Ising 模型做伪似然参数估计4.1 先造数据棋盘格 Gibbs 采样要验证伪似然能不能用最直接的方式是自己造数据、自己估参数、自己看结果。我用的例子是二维格点上的 Ising 模型每个格点取 $\pm1$能量函数是$$E(x) -\left(a\sum_i x_i b\sum_{\langle i,j\rangle}x_ix_j\right)$$$a$ 是外加场强的系数$b$ 是耦合强度。用周期性边界条件每个格点固定四个邻居。生成数据用棋盘格 Gibbs 采样把格点按 $(ij)$ 的奇偶性分成两组同一组内部互不相邻可以整组并行更新。import numpy as np from scipy.special import expit, log_expit def neighbor_sum(x): 周期性边界下每个格点的四邻居取值之和。 return (np.roll(x, 1, 0) np.roll(x, -1, 0) np.roll(x, 1, 1) np.roll(x, -1, 1)) def sweeps(x, a, b, rng, n_sweeps): L x.shape[0] ii, jj np.indices((L, L)) color (ii jj) % 2 for _ in range(n_sweeps): for c in (0, 1): s neighbor_sum(x) p1 expit(2.0 * (a b * s)) draw np.where(rng.random((L, L)) p1, 1, -1) x np.where(color c, draw, x) return x def sample_ising(L, a, b, n_chains, n_per_chain, n_burn1000, n_gap20, seed0): rng np.random.default_rng(seed) out np.empty((n_chains * n_per_chain, L, L), dtypenp.int8) for c in range(n_chains): x rng.choice(np.array([-1, 1], dtypenp.int8), size(L, L)) x sweeps(x, a, b, rng, n_burn) for k in range(n_per_chain): x sweeps(x, a, b, rng, n_gap) out[c * n_per_chain k] x return out这里有几个参数需要交代清楚。n_burn1000是预热扫描次数目的是让链从随机初始状态混到平稳分布n_gap20是采样间隔对应单条链内部的自相关n_chains8是从不同随机初始状态出发的多条独立链能减少对单条链的依赖。我实测下来在 $L16$、$a0.1$、$b0.25$ 这组参数下这几个数值给出来的样本自相关衰减得比较干脆。需要提醒的是耦合强度的选择。二维方格 Ising 模型在 $b_c \ln(1\sqrt{2})/2 \approx 0.4407$ 的位置附近有相变越接近这个值关联长度越长Gibbs 采样的混合越慢伪似然的偏差也越大。演示阶段我建议压在 0.3 以下等流程跑顺了再往上推看看偏差怎么变化。这个规律是实打实的现象不是实现问题。4.2 写出伪似然目标与解析梯度上一节的代码负责造数据接下来要把伪似然目标和它的梯度写出来。对单张图 $x$局部场记作 $h_i a b\sum_{j\in N(i)}x_j$那么$$\log p(x_i \mid x_{N(i)}) \log\sigma(2x_ih_i)$$把所有格点加起来就是这张图的伪对数似然。我们要对所有样本求平均然后交给优化器。梯度有闭式解记 $r_i 2x_i(1-\sigma(2x_ih_i))$那么对 $a$ 的偏导是 $\sum_i r_i$对 $b$ 的偏导是 $\sum_i r_i \cdot s_i$其中 $s_i$ 是邻居取值之和。def pl_neg_avg(params, X): 返回平均负伪对数似然及其梯度。 a, b params n X.shape[0] ll, g 0.0, np.zeros(2) for x in X: s neighbor_sum(x) z 2.0 * x * (a b * s) ll log_expit(z).sum() # 数值稳定版 log-sigmoid r 2.0 * x * (1.0 - expit(z)) g[0] r.sum() g[1] float((r * s).sum()) return -ll / n, -g / nlog_expit是 scipy 1.6 之后提供的稳定实现直接写np.log(expit(z))在场强较大、$z$ 掉到负几百的时候会下溢成-inf优化器立刻报 NaN。这个坑我在第一次实现时踩过当时怎么也找不到原因后来才发现是z特别小的时候把 sigmoid 打成 0 导致的。用log_expit一行就解决。另外注意梯度是解析给出的不要交给优化器做数值差分。参数只有两个的时候数值差分或许还撑得住参数一多数值差分的误差会直接让收敛判断失真。4.3 优化求解与结果核对把上面的东西串起来from scipy.optimize import minimize L, a_true, b_true 16, 0.10, 0.25 X sample_ising(L, a_true, b_true, n_chains8, n_per_chain25, seed42) res minimize(pl_neg_avg, x0np.array([0.0, 0.0]), args(X,), jacTrue, methodL-BFGS-B, bounds[(-2.0, 2.0), (-1.5, 1.5)], options{gtol: 1e-8, maxiter: 500}) print(res.x, res.success, res.nit)我这边跑出来的结果是 $\hat{a} \approx 0.098$、$\hat{b} \approx 0.271$。场强那一项基本贴着真值耦合那项大约高出 8%。这个偏离不是代码写错了而是有限样本下伪似然自带的系统性偏差它随着样本量增加会缩小。我做了一次粗测把样本数从 200 张提到 800 张$\hat{b}$ 的偏离从 8% 左右压到 3% 上下。所以如果你准备把这个估计当成最终结论务必先做一次样本量放大的敏感性检查看看结论稳不稳。还有一个我建议顺手做的检查把jacTrue去掉让minimize自己用有限差分去估梯度比较两种方式的迭代次数和最终解。不用期望着同一个结果但可以直观感受到解析梯度的优势。参数维度一高这个优势会非常明显。4.4 换一组参数看偏差趋势光看一组参数是看不出偏差规律的。我一般是固定 $L16$把 $b$ 从 0.10 一路扫到 0.35样本量固定在 400 张图每跑一组记一次 $\hat{b} - b$。扫下来大致是这个样子在 $b \le 0.20$ 的弱耦合区间偏差基本在 2% 以内可以忽略进入 0.25 到 0.35 这一段偏差开始按几倍的速度扩大再往上逼近临界点偏差的量级就超过 15% 了这时候伪似然的估计值已经不太适合直接当作结论使用更适合当成一个快速初值丢给一个计算更重的采样方法去精修。这个规律对我的实际指导意义是伪似然的第一定位是「速度和可计算性」不是「精度最优」。弱耦合场景里它和极大似然基本没差那就放心用强耦合场景里它更靠谱的用法是先给出一个不错的起点再让精确一点的采样方法在这个起点附近做局部精修整体代价会比纯采样方案低不少。5. 标准误别用 HessianGodambe 信息矩阵与三明治公式5.1 为什么直接求逆 Hessian 会低估方差这是我在伪似然上犯过的最贵的一次错误。当时整个流程都跑通了参数也估出来了顺手用优化器返回的 Hessian 求了个逆算出标准误做了一次显著性检验结论很漂亮。等我拿更严格的 Bootstrap 对照一下直接傻眼Hessian 算出来的标准误普遍小一半以上。原因在第 2.4 节说过伪似然的渐近协方差是 $A^{-1}BA^{-\top}$而海森矩阵只是 $A$。只有真正的极大似然才有 $A B$可以直接求逆。伪似然因为丢掉了联合分布里那些高阶信息得分函数的方差 $B$ 往往大于海森矩阵的期望 $A$两者之间的差值就是信息损失的量。直接用 $A^{-1}$ 相当于假装自己没有丢信息方差自然被系统性低估。5.2 A、B 两个矩阵怎么估$A$ 是负期望海森。对第 $t$ 张图令 $w_i 4p_i(1-p_i)$其中 $p_i \sigma(2x_ih_i)$那么这张图的负海森矩阵是$$-H_t \begin{pmatrix}\sum_i w_i \sum_i w_i s_i \ \sum_i w_i s_i \sum_i w_i s_i^2\end{pmatrix}$$对所有样本取平均就得到 $A$ 的估计。注意每次更新 $A$ 之前都要用当前的参数重新算一次局部场和 $p_i$。$B$ 是得分向量的方差直接用样本协方差估就行$$B \frac{1}{n}\sum_{t1}^n \left(S_t - \bar{S}\right)\left(S_t - \bar{S}\right)^\top$$要提醒一点这里的样本必须是相互独立的。如果你用的是单条长链上按间隔抽出来的样本它们之间还残留自相关的B 就会被低估。所以前面采样那一步才会用多条独立链这不是为了好看是后面方差估计能不能成立的硬条件。5.3 代码实现与结果解读def godambe_vcov(params, X): a, b params n X.shape[0] A_sum np.zeros((2, 2)) scores np.empty((n, 2)) for t, x in enumerate(X): s neighbor_sum(x) z 2.0 * x * (a b * s) p expit(z) r 2.0 * x * (1.0 - p) scores[t] (r.sum(), float((r * s).sum())) w 4.0 * p * (1.0 - p) A_sum np.array([ [w.sum(), float((w * s).sum())], [float((w * s).sum()), float((w * s * s).sum())], ]) A A_sum / n B np.cov(scores, rowvarFalse, ddof0) Ainv np.linalg.inv(A) V_sandwich Ainv B Ainv.T / n V_naive Ainv / n # 错误做法只对海森求逆 return V_sandwich, V_naive V, V_naive godambe_vcov(res.x, X) print(三明治标准误:, np.sqrt(np.diag(V))) print(朴素标准误 :, np.sqrt(np.diag(V_naive)))我这边跑出来三明治给出的 $\hat{b}$ 标准误大致是朴素版本的 1.8 倍左右。也就是说按朴素方式算你的置信区间会窄得离谱——本来不显著的效果摇身一变就显著了。这个 1.8 倍的系数不是固定值它跟耦合强度、图结构、样本量都有关必须每次都算。如果你嫌写矩阵麻烦还有两个替代方案一是分块 Bootstrap把不同链的样本按链分组重抽样重算参数用重抽样分布的标准差当标准误二是对样本做子采样每次去掉一部分样本重新估计看估计值的波动。这两个方案都绕开了显式推导通用性更好但代价是计算量翻几倍。我的习惯是先用三明治公式跑一遍主结论再用 Bootstrap 抽查一次两者在同一个量级就放心。6. 踩过的坑与排查实录6.1 估计值被拉平或漂到边界伪似然优化最常见的异常是参数撞到边界。表现是迭代结束后res.x有一个分量正好压在你设置的bounds上。这时候先别急着换优化算法检查两件事。第一件是邻居结构或者数据本身是不是有问题。如果输入的图里存在大量孤立节点没有邻居的节点那么这些节点的条件分布里 $s_i$ 恒等于 0$b$ 的信息在这些点上根本不存在参数就有可能被推到边界。处理方式是提前统计节点的度分布把度数为零的节点单独挑出来不要让它们进伪似然目标。第二件是数据本身的方向性太强。比如格点几乎全取 $1$那 $a$ 的估计会一路往上推。这种情况下参数区域的边界设置不是「设置问题」而是模型设定没跟上数据的实际情况。该把场项调大就该调大。6.2 标准误偏小显著性全是假的这个坑我在 5.1 节已经说透了但这里要补一条更隐蔽的表现你用了三明治公式结果算出来的标准误还是偏小。原因大概率是样本之间存在残留相关。用单链抽样本的时候间隔设得太短样本之间相关B 矩阵会被低估最后标准误跟着偏小。一个粗糙的自检办法把样本按抽取顺序分成前后两半分别估一遍参数看两个估计值差多少。如果差值远大于你算出来的标准误那说明标准误不可信。另一种做法是直接跑多条短链链之间完全独立方差估计就干净了。顺便说一句三明治公式对样本量有一定要求$n$ 很小的时候比如不到 50 张图A 和 B 的样本估计都不稳。这时候我一般直接上分块 Bootstrap不去纠缠渐近公式。6.3 邻居结构写错全盘皆错这是最隐蔽的一类错误。伪似然的所有内容都建立在「条件分布只依赖邻居」这个前提上邻居集合一旦定义错了模型里每一个参数的含义都会变。周期性边界和反射边界是两套完全不同的结构np.roll默认是循环边界如果你想要的是有边界的有限格点需要在边上做特殊处理如果图是不规则的比如一个个区域之间有邻接关系邻居关系表必须跟数据来源严格对齐。我在一个区域邻接的项目上出过一次错原因是邻接矩阵的行列顺序和区域列表的顺序对不上。这种错误最麻烦的地方在于它不会让代码报错参数照样收敛、照样能算标准误只是估计出来的东西没有意义。所以我现在养成了一个习惯跑正式估计之前先随机挑三个区域手工核对它们的邻居列表对不上就停下来查。6.4 临界区域附近的偏差放大前面提过Ising 模型在临界点附近伪似然偏差会明显放大。这个规律不只适用于 Ising也适用于一般的强相关系统当系统的关联长度远大于局部邻域范围时伪似然丢掉的高阶信息变得很可观相合性还在但有限样本下的表现会变差。判断自己是不是踩进这个区域有个挺实用的经验指标看伪似然的估计值在样本量增大时是怎么收敛的。如果样本量翻倍估计值几乎不动那大概率在一个表现良好的区域里如果样本量翻倍后估计值还在明显移动说明你在一个收敛慢的区域里此时最终结论要多留点余量。6.5 常见问题速查表现象大概率原因排查顺序参数撞边界不退数据方向性过强、存在孤立节点查度分布 → 查参数边界设置迭代次数极高不收敛目标函数数值不稳定、梯度写错查log_expit→ 查解析梯度与数值梯度是否一致标准误异常小用了海森矩阵求逆、样本间残留相关换三明治公式 → 检查采样间隔估计值与真值差很多有限样本偏差、临界区域效应扩大样本量 → 降低耦合强度重测换一组随机种子结果抖动大样本量不足、链未混合增加链数 → 加长预热扫描伪似然指标涨但采样质量差局部一致性高、整体结构崩坏补一个独立的采样质量指标这张表我放在脚本的注释块里每次跑完对照一遍能省掉很多来回折腾的时间。7. 几个场景下的选用建议7.1 空间统计与图像建模在空间统计和图像领域伪似然是上手最快的一档工具。数据本身就是格点结构局部马尔可夫性天然成立条件分布往往有闭式解。我一般的做法是先用伪似然把所有参数快速估一遍摸清量级再决定要不要上更重的采样方法去精修。如果耦合强度弱、结论的精度要求不高伪似然可以直接交付。有一个细节值得注意图像数据里经常存在大片同值区域这些区域的局部场很大$p_i$ 会饱和到接近 0 或 1log_expit的数值稳定性就变得格外重要。7.2 社交网络与 ERGM 的退化陷阱指数随机图模型里伪似然估计MPLE是个非常常见的起手式算得快、不需要 MCMC、能给出一个粗略的量级。但它有两个坑得提前知道。第一个坑是退化。MPLE 在有些网络结构下会给出极端到不合理的参数估计尤其是包含三角或高阶依赖项的模型估计值可能直接飙到正无穷的方向上。这种退化跟你有没有写错代码无关是伪似然本身在这个模型上丢掉的约束太多导致的。第二个坑是它只是一个起点。MPLE 的结果一般不会直接作为最终报告值而是作为后续采样算法的初始位置或者作为参数是否在合理范围内的先验判断。我见过的比较稳的流程是MPLE 先给一个初值然后交给更精确的方法迭代收敛后再用伪似然做一次快速的拟合优度检查。7.3 深度生成模型里的评估指标在能量模型和 RBM 这一类模型上伪似然更多是当评估指标来用而不是当训练目标。拿它当训练目标也能跑但梯度估计的方差会比较大收敛不如对比散度那一套稳。当评估指标的时候有几条使用纪律值得说只比同一类结构、同一维度的模型别跨连续型和离散型去比那个数值没有可比性一定要跟独立的采样质量指标配合着看。我自己的习惯是固定一组验证数据把伪似然和采样质量指标都记录下来只有两个同时向好才算一次真进步。最后分享一个我常用的调试技巧把伪似然拆到每个节点上去看。整体数值看不出问题的时候逐个区域打印每个节点的对数条件概率异常节点会立刻跳出来。有一次模型的整体指标很好看但拆开之后发现某一片区域的贡献是负数仔细一查是那片区域的邻居关系配错了。整体指标能掩盖局部问题逐节点的视角不会。
网站建设高端定制企业官网