ConjugateAR
Overview
ConjugateAR is the likelihood of AR with the coefficients θ and the noise precision γ joint on one edge w = (θ, γ). With a normal-gamma prior on w the parameter update is conjugate: the posterior q(w) is the normal-gamma posterior of a Bayesian linear regression with unknown noise precision, with the states' expected sufficient statistics in place of the data. Use it where θ and γ should stay coupled, rather than factorised as q(θ) q(γ).
Here q(w) is the marginal of w, the approximate posterior that message passing computes. As for AR, the node's rules are those of variational message passing.
Definition
For the state xₜ = (yₜ₋₁, …, yₜ₋ₚ) and w = (θ, γ):
\[p(y \mid x, w) = \mathcal{N}\big(y_1 \mid \theta^\top x, \, \gamma^{-1}\big),\]
with y = A(θ) x + ε in companion form, noise on the first component only, as for AR. Averaged over q(y, x), the node is a normal-gamma factor in w with statistics
\[C = \langle x x^\top \rangle, \qquad b = \langle x\, y_1 \rangle, \qquad a = \langle y_1^2 \rangle,\]
that is Λ = C, μ = C⁻¹ b, shape (3 - p)/2 and rate (a - bᵀ C⁻¹ b)/2. These are the parameters of the message towards w.
Interfaces
using AutoregressiveMessagePassingRules, MessagePassingRulesBase, BayesBase, ExponentialFamily
MessagePassingRulesBase.nodespec(ConjugateAR)| interface | aliases | |
|---|---|---|
y | out | |
x | ||
w |
| default algorithm | MessagePassingRulesBase.DefaultAlgorithm() |
|---|---|
| static inputs | none |
| defined | src/conjugate_autoregressive.jl:49 |
The node has three interfaces; y also answers to out.
| name | aliases | meaning | messages and marginals its rules take |
|---|---|---|---|
y | out | the current state | a normal message, multivariate unless the form is Univariate; q(y) with a mean and covariance |
x | the previous state | a normal message of the same dimension; q(x) with a mean and covariance | |
w | the coefficients and the precision | q(w), an MvNormalGamma of dimension p |
The joint marginal q(y, x) is a multivariate normal of dimension 2p, y first.
Algorithm
The node shares AR's algorithm, ARVMP(form, order, stype), which the model must name, with every argument required. form is Univariate for an AR(1) on scalars, whose rules read q(w)'s one coefficient as a scalar θ, or Multivariate for an AR of any order on state vectors. stype is ARsafe() or ARunsafe(), as for AR. The node declares no dependencies, so each rule takes the inputs of the default scheme.
Supported rules
MessagePassingRulesBase.rule_coverage(ConjugateAR)| DefaultAlgorithm | ARVMP{<:VariateForm, _} | |
|---|---|---|
| → y | ✓×2 | |
| → x | ✓×2 | |
| → w | ✓ | |
| q(y, x) | ✓ | |
| average energy | ✓ |
Every rule is under ARVMP. The rules towards y and x exist for the structured factorisation q(y, x) q(w), as belief propagation between them, and for the mean field. They and the joint marginal q(y, x) are AR's, computed from the marginals of θ and γ that q(w) implies. The rule towards w and the average energy need the structured factorisation q(y, x) q(w).
Example
The message towards w of an AR(1) from the joint marginal of the states:
@call_message_update_rule(
node = ConjugateAR, target = :w, algorithm = ARVMP(Multivariate, 1, ARsafe()),
clusters = ((:y, :x) => MvNormalMeanCovariance([1.0, 0.5], [1.0 0.0; 0.0 1.0]),),
)Result
| value | ExponentialFamily.MvNormalGamma{Float64, Vector{Float64}, Matrix{Float64}, Float64, Float64}( μ: [0.4] Λ: [1.25;;] α: 1.0 β: 0.9 ) |
|---|---|
| type | ExponentialFamily.MvNormalGamma{Float64, Vector{Float64}, Matrix{Float64}, Float64, Float64} |
| log scale | undefined: the message rule for ConjugateAR towards :w under ARVMP declares no `logscale` |
Inputs
| edge | value | |
|---|---|---|
| y | q | MvNormalMeanCovariance( μ: [1.0, 0.5] Σ: [1.0 0.0; 0.0 1.0] ) q[:y, :x] |
| x | q | q[:y, :x] |
Rule
| declared inputs | q[:y, :x]::Union{ExponentialFamily.MultivariateNormalDistributionsFamily{T}, ExponentialFamily.MultivariateGaussianDistributionsFamily{T}} where T |
|---|---|
| algorithm | ARVMP{Multivariate, ARsafe}(1, ARsafe()) |
| log scale | none |
| defined | src/conjugate_autoregressive.jl:98 |
| body | (algo, args)->begin
order = getorder(algo)
(myx, Vyx) = mean_cov(args.q[:y, :x])
x_range = order + 1:2order
mx = myx[x_range]
my1 = first(myx)
Vx = Vyx[x_range, x_range]
Vy1 = Vyx[1, 1]
cov_x_y1 = Vyx[x_range, 1]
C = Vx + mx * transpose(mx)
b = cov_x_y1 + mx * my1
a = Vy1 + my1 ^ 2
μ = cholinv(C) * b
α = convert(eltype(μ), (3 - order) / 2)
β = (a - dot(b, μ)) / 2
MvNormalGamma(μ, C, α, β)
end |
@call_message_update_rule runs the rule and draws the joint marginal it read. With C = 1.25, b = 0.5 and a = 2, the getresult of the call is the normal-gamma of the definition:
julia> result = @call_message_update_rule(
node = ConjugateAR, target = :w, algorithm = ARVMP(Multivariate, 1, ARsafe()),
clusters = ((:y, :x) => MvNormalMeanCovariance([1.0, 0.5], [1.0 0.0; 0.0 1.0]),),
);
julia> μ, Λ, α, β = params(getresult(result));
julia> μ ≈ [0.4] && Λ ≈ fill(1.25, 1, 1) && α ≈ 1.0 && β ≈ 0.9
trueLimitations
- A model must give
ARVMP; without it the node has no rule. - The rule towards
wand the average energy need the structured factorisationq(y, x) q(w): under the mean fieldq(y) q(x) q(w)there is no message towardswand no average energy. - The message towards
wis improper forp ≥ 3, its shape(3 - p)/2being non-positive; its product with a proper normal-gamma prior is proper.q(w)therefore needs a prior, and an initial marginal where the schedule reads it first.
API
AutoregressiveMessagePassingRules.ConjugateAR — Type
ConjugateARThe autoregressive node with its parameters on one edge: the likelihood of AR, but with the coefficients and the precision joint on the edge w = (θ, γ), a normal-gamma:
\[p(y \mid x, w) = \mathcal{N}\big(y_1 \mid \theta^\top x, \, \gamma^{-1}\big), \qquad w = (\theta, \gamma).\]
For p > 1 the edges y and x carry the whole state: x = (yₜ₋₁, …, yₜ₋ₚ) and y = (yₜ, …, yₜ₋ₚ₊₁), related by the companion matrix A(θ), whose first row is θᵀ and whose sub-diagonal is ones, under noise on the first component only:
\[y = A(\theta)\, x + \varepsilon, \qquad \varepsilon \sim \mathcal{N}(0, \operatorname{diag}(\gamma^{-1}, 0, \dots, 0)).\]
Keeping (θ, γ) joint makes the parameter update conjugate: under q(y, x) q(w) the message towards w is a normal-gamma, and so is q(w) for a normal-gamma prior, the posterior of a Bayesian linear regression with unknown noise precision.
Interfaces
y(aliasout): the current state, a normal, multivariate unless the form isUnivariate;x: the previous state, a normal of the same dimension;w: the coefficients and the precision, anMvNormalGammaof dimensionp.
Its rules run under ARVMP, which the model must give, since the variate form and the order are properties of the model rather than of the node. The node declares no algorithm of its own: under DefaultAlgorithm no rule exists, and a model that names none gets a "no message rule" error. Under Univariate, an AR(1) with scalar y and x, the rules read the one coefficient of q(w) as a scalar θ; the message towards w is an MvNormalGamma of dimension 1 either way.
The rules towards y and x and the joint marginal q(y, x) are AR's, computed from the marginals of θ and γ that q(w) implies. The message towards w needs the structured factorisation q(y, x) q(w); it is improper for p ≥ 3, its shape (3 - p)/2 being non-positive, and becomes proper in its product with the prior. There is an average energy under q(y, x) q(w) only.
Examples
julia> result = @call_message_update_rule(
node = ConjugateAR, target = :w, algorithm = ARVMP(Multivariate, 1, ARsafe()),
clusters = ((:y, :x) => MvNormalMeanCovariance([1.0, 0.5], [1.0 0.0; 0.0 1.0]),),
);
julia> getresult(result) isa MvNormalGamma
true