torch_openreml.MarginalREML¶
- class torch_openreml.MarginalREML(v)[source]¶
Bases:
objectMarginal REML estimator for generalised least squares with a parametric marginal covariance matrix.
Fits covariance parameters \(\boldsymbol{\theta}\) by maximising the restricted log-likelihood
\[\ell_R(\boldsymbol{\theta}) = -\frac{1}{2} \left( \log |\symbf{V}(\boldsymbol{\theta})| + \log |\symbf{X}^\top \symbf{V}(\boldsymbol{\theta})^{-1} \symbf{X}| + \symbf{y}^\top \symbf{P} \symbf{y} \right)\]where \(\symbf{P} = \symbf{V}(\boldsymbol{\theta})^{-1} - \symbf{V}(\boldsymbol{\theta})^{-1}\symbf{X} (\symbf{X}^\top\symbf{V}(\boldsymbol{\theta})^{-1}\symbf{X})^{-1}\symbf{X}^\top\symbf{V}(\boldsymbol{\theta})^{-1}\) is the projection matrix and \(\symbf{V}(\boldsymbol{\theta})\) is the marginal covariance matrix of \(\symbf{y}\).
Optimisation uses the average information (AI) algorithm, which forms a quasi-Newton step \(\Delta = \symbf{AI}^{-1} \symbf{s}\) from the score vector \(\symbf{s}\) and the AI matrix at each iteration.
The covariance model \(\symbf{V}(\boldsymbol{\theta})\) is supplied as a
Matrixinstance viav. Gradients are handled internally by the matrix.Initialize a MarginalREML estimator.
- Parameters:
v (Matrix) – A
Matrixinstance that constructs \(\symbf{V}(\boldsymbol{\theta})\) and its Jacobian.- Raises:
TypeError – If
vis not aMatrixinstance.
Example:
import torch from torch_openreml import MarginalREML from torch_openreml.covariance import ScalarMatrix n, p = 50, 2 y = torch.randn(n) x = torch.randn(n, p) theta = torch.tensor([0.0]) mat = ScalarMatrix(n) reml = MarginalREML(mat) theta_hat, beta_hat, n_iter = reml.optimize(y, x, theta, verbose=1) theta_hat, beta_hat
[ 1] ∥∇∥: 9.9403, ∥Δ∥: 0.1306, η: 1.00, ∥Δᶜ∥: 0.1306, log 𝓛: -22.9222 [ 2] ∥∇∥: 1.4189, ∥Δ∥: 0.0144, η: 1.00, ∥Δᶜ∥: 0.0144, log 𝓛: -22.3336 (+0.5887) [ 3] ∥∇∥: 0.0202, ∥Δ∥: 0.0002, η: 1.00, ∥Δᶜ∥: 0.0002, log 𝓛: -22.3233 (+0.0103) [ 4] ∥∇∥: 0.0000, ∥Δ∥: 0.0000, η: 1.00, ∥Δᶜ∥: 0.0000, log 𝓛: -22.3233 (+0.0000) [∇: score, Δ: 𝐉⁻¹∇, η: learning rate, Δᶜ: clip(𝛉 + ηΔ, lb, ub) - 𝛉, 𝓛: restricted likelihood] ✓ Converged at iteration 4, total time: 0.00s
(tensor([-0.1160]), tensor([-0.0768, -0.1107]))
Methods
ai_step(y, x, theta[, require_loglik, ...])Perform a single average information (AI) algorithm step.
blue(y, x, theta)Compute the best linear unbiased estimator (BLUE) of \(\boldsymbol{\beta}\).
compute_v_dv(theta)Compute the covariance matrix and its Jacobian.
get_beta([select])Retrieve a coefficient estimate from the optimisation history.
get_theta([select])Retrieve a covariance parameter estimate from the optimisation history.
Check whether the optimisation has converged.
loglik(y, x, theta)Evaluate the REML log-likelihood.
optimize(y, x[, theta, max_iter, eta, ...])Run the AI-REML optimisation loop.
predict(y, x, theta)Compute fitted values.
residual(y, x, theta)Compute residuals.
update(theta, delta, eta[, lb, ub])Apply a damped AI step and clip covariance parameters to bounds.
- blue(y, x, theta)[source]¶
Compute the best linear unbiased estimator (BLUE) of \(\boldsymbol{\beta}\).
Solves for \(\hat{\boldsymbol{\beta}}\) via generalised least squares:
\[\hat{\boldsymbol{\beta}} = (\symbf{X}^\top \symbf{V}(\boldsymbol{\theta})^{-1} \symbf{X})^{-1} \symbf{X}^\top \symbf{V}(\boldsymbol{\theta})^{-1} \symbf{y}\]- Parameters:
y (torch.Tensor) – Response vector of shape
(n,).x (torch.Tensor) – Design matrix of shape
(n, p).theta (torch.Tensor) – Flat covariance parameter tensor.
- Returns:
Coefficient estimate \(\hat{\boldsymbol{\beta}}\) of shape
(p,).- Return type:
torch.Tensor
- predict(y, x, theta)[source]¶
Compute fitted values.
\[\hat{\symbf{y}} = \symbf{X} \hat{\boldsymbol{\beta}}\]- Parameters:
y (torch.Tensor) – Response vector of shape
(n,).x (torch.Tensor) – Design matrix of shape
(n, p).theta (torch.Tensor) – Flat covariance parameter tensor.
- Returns:
Fitted values of shape
(n,).- Return type:
torch.Tensor
- residual(y, x, theta)[source]¶
Compute residuals.
\[\hat{\symbf{e}} = \symbf{y} - \symbf{X}\hat{\boldsymbol{\beta}}\]- Parameters:
y (torch.Tensor) – Response vector of shape
(n,).x (torch.Tensor) – Design matrix of shape
(n, p).theta (torch.Tensor) – Flat covariance parameter tensor.
- Returns:
Residuals of shape
(n,).- Return type:
torch.Tensor
- loglik(y, x, theta)[source]¶
Evaluate the REML log-likelihood.
\[\ell_R(\boldsymbol{\theta}) = -\frac{1}{2} \left( \log |\symbf{V}(\boldsymbol{\theta})| + \log |\symbf{X}^\top \symbf{V}(\boldsymbol{\theta})^{-1} \symbf{X}| + \symbf{y}^\top \symbf{P} \symbf{y} \right)\]- Parameters:
y (torch.Tensor) – Response vector of shape
(n,).x (torch.Tensor) – Design matrix of shape
(n, p).theta (torch.Tensor) – Flat covariance parameter tensor.
- Returns:
Scalar REML log-likelihood value.
- Return type:
torch.Tensor
- compute_v_dv(theta)[source]¶
Compute the covariance matrix and its Jacobian.
Calls
vto build \(\symbf{V}(\boldsymbol{\theta})\) andgrad()for the Jacobian \(\partial\symbf{V}(\boldsymbol{\theta})/\partial\boldsymbol{\theta}\).- Parameters:
theta (torch.Tensor) – Flat covariance parameter tensor.
- Returns:
(v, dv), wherevis the covariance matrix of shape(n, n)anddvis the Jacobian of shape(num_free_params, n, n).- Return type:
tuple
- ai_step(y, x, theta, require_loglik=True, require_beta=True, trace_approx=False, subspace_fraction=0.01)[source]¶
Perform a single average information (AI) algorithm step.
Computes the score vector \(\symbf{s}\), AI matrix, and optionally the REML log-likelihood and coefficient estimate at the current \(\boldsymbol{\theta}\).
The score vector and AI matrix are:
\[\begin{split}s_k &= \frac{1}{2}\left( \symbf{y}^\top \symbf{P} \frac{\partial\symbf{V}(\boldsymbol{\theta})}{\partial\theta_k} \symbf{P} \symbf{y} - \mathrm{tr}\!\left(\symbf{P} \frac{\partial\symbf{V}(\boldsymbol{\theta})}{\partial\theta_k}\right) \right) \\ \mathrm{AI}_{kj} &= \frac{1}{2} \symbf{y}^\top \symbf{P} \frac{\partial\symbf{V}(\boldsymbol{\theta})}{\partial\theta_k} \symbf{P} \frac{\partial\symbf{V}(\boldsymbol{\theta})}{\partial\theta_j} \symbf{P} \symbf{y}\end{split}\]When
trace_approxisTrue, the trace term \(\mathrm{tr}(\symbf{P}\,\partial\symbf{V}/\partial\theta_k)\) is replaced by a stochastic probe estimate, which avoids forming \(\symbf{V}^{-1}\partial\symbf{V}\) in full. With\[\symbf{A}_k = \symbf{V}^{-1} \frac{\partial \symbf{V}}{\partial \theta_k}, \qquad \symbf{B}_k = \symbf{V}^{-1} \symbf{X} (\symbf{X}^\top \symbf{V}^{-1} \symbf{X})^{-1} \symbf{X}^\top \symbf{V}^{-1} \frac{\partial \symbf{V}}{\partial \theta_k},\]the trace splits as
\[\mathrm{tr}\!\left(\symbf{P} \frac{\partial \symbf{V}}{\partial \theta_k}\right) = \mathrm{tr}(\symbf{A}_k) - \mathrm{tr}(\symbf{B}_k),\]and each of the two terms is estimated on its own, so that neither \(\symbf{A}_k\) nor \(\symbf{B}_k\) is ever formed in full.
The estimator is Hutch++ (Meyer, Musco, Musco & Woodruff, Hutch++: Optimal stochastic trace estimation, SOSA 2021, pp. 142–155, doi:10.1137/1.9781611976496.16). For a matrix \(\symbf{C}\), two independent Rademacher probe matrices \(\symbf{S}, \symbf{G} \in \{\pm 1\}^{n \times m}\) are drawn once per call and shared across parameters, with \(m = \lfloor n f \rfloor + 1\) probes each and \(f\) the
subspace_fraction, and\[\begin{split}\symbf{Q} &= \mathrm{qr}(\symbf{C} \symbf{S}), \\ \hat{h}(\symbf{C}) &= \mathrm{tr}(\symbf{Q}^\top \symbf{C} \symbf{Q}) + \frac{1}{m} \mathrm{tr}\!\left( \symbf{G}^\top (\symbf{I} - \symbf{Q}\symbf{Q}^\top) \symbf{C} (\symbf{I} - \symbf{Q}\symbf{Q}^\top) \symbf{G} \right).\end{split}\]\(\symbf{Q}\) spans the dominant range of \(\symbf{C}\), so the first term is exact there; the second applies Hutchinson’s estimator to the deflated residual.
When
trace_approxisFalsethe traces are evaluated exactly. The average information matrix and the log-likelihood are computed exactly either way; only the trace term of the score is approximated.- Parameters:
y (torch.Tensor) – Response vector of shape
(n,).x (torch.Tensor) – Design matrix of shape
(n, p).theta (torch.Tensor) – Flat covariance parameter tensor.
require_loglik (bool, optional) – Whether to evaluate the REML log-likelihood. Defaults to
True.require_beta (bool, optional) – Whether to compute the coefficient estimate. Defaults to
True.trace_approx (bool, optional) – Whether to estimate the trace term of the score stochastically.
Falsecomputes the exact score, which is more expensive per call. This is a plain switch with no internal state:optimize()owns the decision of when to turn it off. Defaults toFalse.subspace_fraction (float, optional) – Fraction of the
nobservations used as the dimension of the random probe subspace in the stochastic trace estimate. Each of the two probe matrices holdsint(n * subspace_fraction) + 1vectors, so the total probe budget is about twice that. Must lie in[0, 1]; larger values trade time for accuracy of the approximate score. Only used whentrace_approxisTrue. Defaults to0.01.
- Raises:
ValueError – If
subspace_fractionis outside[0, 1].- Returns:
(beta, score, ai, loglik), wherebetais of shape(p,),scoreis of shape(num_free_params,),aiis of shape(num_free_params, num_free_params), andloglikis a scalar tensor.betaandloglikaretorch.nanif their respectiverequire_*flag isFalse.- Return type:
tuple
- get_theta(select='last')[source]¶
Retrieve a covariance parameter estimate from the optimisation history.
- Parameters:
select (str, optional) –
"last"returns the final iterate; any other value returns the iterate with the highest log-likelihood. Defaults to"last".- Returns:
Selected covariance parameter tensor \(\boldsymbol{\theta}\).
- Return type:
torch.Tensor
- get_beta(select='last')[source]¶
Retrieve a coefficient estimate from the optimisation history.
- Parameters:
select (str, optional) –
"last"returns the final iterate; any other value returns the iterate with the highest log-likelihood. Defaults to"last".- Returns:
Selected coefficient estimate \(\hat{\boldsymbol{\beta}}\).
- Return type:
torch.Tensor
- is_converged()[source]¶
Check whether the optimisation has converged.
Convergence is declared when all enabled criteria fall below their respective tolerances. At least two iterations must have completed before any criterion can be satisfied.
- Returns:
Trueif all enabled criteria are satisfied,Falseotherwise.- Return type:
bool
- update(theta, delta, eta, lb=-inf, ub=inf)[source]¶
Apply a damped AI step and clip covariance parameters to bounds.
\[\boldsymbol{\theta} \leftarrow \mathrm{clip}(\boldsymbol{\theta} + \eta \Delta,\, \text{lb},\, \text{ub})\]- Parameters:
theta (torch.Tensor) – Current covariance parameter tensor.
delta (torch.Tensor) – AI step \(\Delta = \symbf{AI}^{-1}\symbf{s}\).
eta (float) – Step size (learning rate).
lb (float, optional) – Lower bound for clipping. Defaults to
-inf.ub (float, optional) – Upper bound for clipping. Defaults to
inf.
- Returns:
(theta, update), wherethetais the updated covariance parameter tensor andupdateis the actual change after clipping.- Return type:
tuple
- optimize(y, x, theta=None, max_iter=200, eta=1.0, require_loglik=True, lb=-inf, ub=inf, verbose=0, check_score=True, check_delta=True, check_loglik=True, tol_score=0.0001, tol_delta=0.0001, tol_loglik=0.0001, trace_approx=False, subspace_fraction=0.01, exact_score_threshold=10.0)[source]¶
Run the AI-REML optimisation loop.
Iterates
ai_step()andupdate()until convergence ormax_iteris reached. Optimisation history is stored inhistoryand can be queried afterwards viaget_theta()andget_beta().- Parameters:
y (torch.Tensor) – Response vector of shape
(n,).x (torch.Tensor) – Design matrix of shape
(n, p).theta (torch.Tensor or dict) – Initial covariance parameter tensor, or a dictionary mapping free parameter names to value tensors. If omitted, default values are used. Defaults to
None.max_iter (int, optional) – Maximum number of iterations. Defaults to
200.eta (float, optional) – Step size applied to each AI update. Defaults to
1.0.require_loglik (bool, optional) – Whether to evaluate the REML log-likelihood at each iteration. Defaults to
True.lb (float, optional) – Lower bound for covariance parameter clipping. Defaults to
-inf.ub (float, optional) – Upper bound for covariance parameter clipping. Defaults to
inf.verbose (int, optional) – Verbosity level.
0suppresses all output;1prints per-iteration diagnostics, whether the optimisation converged or hitmax_iter, and the total optimisation time. Defaults to0.check_score (bool, optional) – Include score norm in convergence check. Defaults to
True.check_delta (bool, optional) – Include covariance parameter update norm in convergence check. Defaults to
True.check_loglik (bool, optional) – Include log-likelihood change in convergence check. Defaults to
True.tol_score (float, optional) – Score norm tolerance. Defaults to
1e-4.tol_delta (float, optional) – Covariance parameter update norm tolerance. Defaults to
1e-4.tol_loglik (float, optional) – Log-likelihood change tolerance. Defaults to
1e-4.trace_approx (bool, optional) –
Whether to start the optimisation with the stochastic probe estimate of
ai_step()for the score, which follows Hutch++ (Meyer, Musco, Musco & Woodruff, Hutch++: Optimal stochastic trace estimation, SOSA 2021, pp. 142–155, doi:10.1137/1.9781611976496.16). While it is on, the optimiser monitors the score norm, and once that norm drops belowexact_score_thresholdthe exact score is used for that and every remaining iteration. The probe estimate has a noise floor that does not decay, so an optimisation left on the approximation cannot satisfytol_scoreand will run tomax_iter; the switch is what makes the approximation usable. Defaults toFalse, which runs the whole optimisation with the exact score.subspace_fraction (float, optional) – Fraction of the
nobservations used as the dimension of the random probe subspace in the stochastic trace estimate ofai_step(). Must lie in[0, 1]; larger values trade time for accuracy of the score on iterations that are still far from the optimum. Defaults to0.01.exact_score_threshold (float, optional) – Score norm below which the stochastic probe estimate is switched off for the remainder of the optimisation. Since the first score is always computed with the current setting,
infswitches off after the first iteration while0.0keeps the approximation on throughout. Defaults to10.0.
- Returns:
(theta, beta, n_iter), wherethetais the final covariance parameter estimate,betais the corresponding coefficient estimate, andn_iteris the number of iterations completed.- Return type:
tuple