@@ -11,9 +11,9 @@ abstract type AbstractLikelihood end
1111# insupport(ℓ::AbstractLikelihood, p) = insupport(ℓ.k(p), ℓ.x)
1212
1313@doc raw """
14- Likelihood(k::AbstractTransitionKernel , x)
14+ Likelihood(k, x)
1515
16- "Observe" a value `x`, yielding a function from the parameters to ℝ .
16+ Default result of [`likelihoodof(k, x)`](@ref) .
1717
1818Likelihoods are most commonly used in conjunction with an existing _prior_
1919measure to yield a new measure, the _posterior_. In Bayes's Law, we have
@@ -91,34 +91,35 @@ Similarly to the above, we have
9191
9292Finally, let's return to the expression for Bayes's Law,
9393
94- ``P(θ|x) ∝ P(θ) P(x| θ)``
94+ ``P(θ|x) ∝ P(x| θ) P(θ)``
9595
96- The product on the right side is computed pointwise. To work with this in
97- MeasureBase, we have a "pointwise product" `⊙`, which takes a measure and a
98- likelihood, and returns a new measure, that is, the unnormalized posterior that
99- has density ``P(θ) P(x|θ)`` with respect to the base measure of the prior.
96+ In measure theory, the product on the right side is actually the Lebesgue integral,
97+ of the likelihood with respect to the prior.
10098
10199For example, say we have
102100
103101 μ ~ Normal()
104102 x ~ Normal(μ,σ)
105103 σ = 1
106104
107- and we observe `x=3`. We can compute the posterior measure on `μ` as
108-
109- julia> post = Normal() ⊙ Likelihood(Normal{(:μ, :σ)}, (σ=1,), 3)
110- Normal() ⊙ Likelihood(Normal{(:μ, :σ), T} where T, (σ = 1,), 3)
105+ and we observe `x=3`. We can compute the (non-normalized) posterior measure on
106+ `μ` as
111107
112- julia> logdensity_def(post, 2)
113- -2.5
108+ julia> prior = Normal()
109+ julia> likelihood = Likelihood(μ -> Normal(μ, 1), 3)
110+ julia> post = mintegrate(likelihood, prior)
111+ julia> post isa MeasureBase.DensityMeasure
112+ true
113+ julia> logdensity_rel(post, Lebesgue(), 2)
114+ -4.337877066409345
114115"""
115116struct Likelihood{K,X} <: AbstractLikelihood
116117 k:: K
117118 x:: X
118119
119- Likelihood (k:: K , x:: X ) where {K<: AbstractTransitionKernel ,X} = new {K,X} (k, x)
120- Likelihood (k :: K , x :: X ) where {K <: Function ,X} = new {K,X} (k, x)
121- Likelihood (μ , x) = Likelihood ( kernel (μ) , x)
120+ Likelihood (k:: K , x:: X ) where {K,X} = new {K,X} (k, x)
121+ # !!!!!!!!!!! # For type stability if `K isa UnionAll (e.g. a parameterized MeasureType)`
122+ Likelihood (:: Type{K} , x:: X ) where {K <: AbstractMeasure ,X} = new {K,X} (K , x)
122123end
123124
124125(lik:: AbstractLikelihood )(p) = exp (ULogarithmic, logdensityof (lik. k (p), lik. x))
@@ -150,58 +151,87 @@ end
150151
151152export likelihoodof
152153
153- """
154- likelihoodof(k::AbstractTransitionKernel, x; constraints...)
155- likelihoodof(k::AbstractTransitionKernel, x, constraints::NamedTuple)
154+ @doc raw """
155+ likelihoodof(k, x)
156156
157- A likelihood is *not* a measure. Rather, a likelihood acts on a measure, through
158- the "pointwise product" `⊙`, yielding another measure.
159- """
160- function likelihoodof end
157+ Returns the likelihood of observing `x` under a family of probability
158+ measures that is generated by a transition kernel `k(θ)`.
159+
160+ `k(θ)` maps points in the parameter space to measures (resp. objects that can
161+ be converted to measures) on a implicit set `Χ` that contains values like `x`.
162+
163+ `likelihoodof(k, x)` returns a likelihood object. A likelihhood is **not** a
164+ measure, it is a function from the parameter space to `ℝ₊`. Likelihood
165+ objects can also be interpreted as "generic densities" (but **not** as
166+ probability densities).
161167
162- likelihoodof (k, x, :: NamedTuple{()} ) = Likelihood (k, x)
168+ `likelihoodof(k, x)` implicitly chooses `ξ = rootmeasure(k(θ))` as the
169+ reference measure on the observation set `Χ`. Note that this implicit
170+ `ξ` **must** be independent of `θ`.
163171
164- likelihoodof (k, x; kwargs ... ) = likelihoodof (k, x, NamedTuple (kwargs))
172+ `ℒₓ = likelihoodof(k, x)` has the mathematical interpretation
165173
166- likelihoodof (k, x, pars:: NamedTuple ) = likelihoodof (kernel (k, pars), x)
174+ ```math
175+ \m athcal{L}_x(\t heta) = \f rac{\r m{d}\, k(\t heta)}{\r m{d}\, \c hi}(x)
176+ ```
167177
168- likelihoodof (k:: AbstractTransitionKernel , x) = Likelihood (k, x)
178+ `likelihoodof` must return an object that implements the
179+ [`DensityInterface`](https://github.com/JuliaMath/DensityInterface.jl)` API
180+ and `ℒₓ = likelihoodof(k, x)` must satisfy
169181
170- export log_likelihood_ratio
182+ ```julia
183+ log(ℒₓ(θ)) == logdensityof(ℒₓ, θ) ≈ logdensityof(k(θ), x)
171184
185+ DensityKind(ℒₓ) isa IsDensity
186+ ```
187+
188+ By default, an instance of [`MeasureBase.Likelihood`](@ref) is returned.
172189"""
173- log_likelihood_ratio(ℓ::Likelihood, p, q)
190+ function likelihoodof end
174191
175- Compute the log of the likelihood ratio, in order to compare two choices for
176- parameters. This is computed as
192+ likelihoodof (k, x) = Likelihood (k, x)
177193
178- logdensity_rel(ℓ.k(p), ℓ.k(q), ℓ.x)
179194
180- Since `logdensity_rel` can leave common base measure unevaluated, this can be
181- more efficient than
195+ # ##############################################################################
196+ # At the least, we need to think through in some more detail whether
197+ # (log-)likelihood ratios expressed in this way are correct and useful. For now
198+ # this code is commented out; we may remove it entirely in the future.
182199
183- logdensityof(ℓ.k(p), ℓ.x) - logdensityof(ℓ.k(q), ℓ.x)
184- """
185- log_likelihood_ratio (ℓ:: Likelihood , p, q) = logdensity_rel (ℓ. k (p), ℓ. k (q), ℓ. x)
200+ # export log_likelihood_ratio
186201
187- # likelihoodof(k, x; kwargs...) = likelihoodof(k, x, NamedTuple(kwargs))
202+ # """
203+ # log_likelihood_ratio(ℓ::Likelihood, p, q)
188204
189- export likelihood_ratio
205+ # Compute the log of the likelihood ratio, in order to compare two choices for
206+ # parameters. This is computed as
190207
191- """
192- likelihood_ratio(ℓ::Likelihood, p, q)
208+ # logdensity_rel(ℓ.k(p), ℓ.k(q), ℓ.x)
193209
194- Compute the log of the likelihood ratio, in order to compare two choices for
195- parameters. This is equal to
210+ # Since `logdensity_rel` can leave common base measure unevaluated, this can be
211+ # more efficient than
196212
197- density_rel(ℓ.k(p), ℓ.k(q), ℓ.x)
213+ # logdensityof(ℓ.k(p), ℓ.x) - logdensityof(ℓ.k(q), ℓ.x)
214+ # """
215+ # log_likelihood_ratio(ℓ::Likelihood, p, q) = logdensity_rel(ℓ.k(p), ℓ.k(q), ℓ.x)
198216
199- but is computed using LogarithmicNumbers.jl to avoid underflow and overflow.
200- Since `density_rel` can leave common base measure unevaluated, this can be
201- more efficient than
217+ # # likelihoodof(k, x; kwargs...) = likelihoodof(k, x, NamedTuple(kwargs))
202218
203- logdensityof(ℓ.k(p), ℓ.x) - logdensityof(ℓ.k(q), ℓ.x)
204- """
205- function likelihood_ratio (ℓ:: Likelihood , p, q)
206- exp (ULogarithmic, logdensity_rel (ℓ. k (p), ℓ. k (q), ℓ. x))
207- end
219+ # export likelihood_ratio
220+
221+ # """
222+ # likelihood_ratio(ℓ::Likelihood, p, q)
223+
224+ # Compute the log of the likelihood ratio, in order to compare two choices for
225+ # parameters. This is equal to
226+
227+ # density_rel(ℓ.k(p), ℓ.k(q), ℓ.x)
228+
229+ # but is computed using LogarithmicNumbers.jl to avoid underflow and overflow.
230+ # Since `density_rel` can leave common base measure unevaluated, this can be
231+ # more efficient than
232+
233+ # logdensityof(ℓ.k(p), ℓ.x) - logdensityof(ℓ.k(q), ℓ.x)
234+ # """
235+ # function likelihood_ratio(ℓ::Likelihood, p, q)
236+ # exp(ULogarithmic, logdensity_rel(ℓ.k(p), ℓ.k(q), ℓ.x))
237+ # end
0 commit comments