@@ -11,9 +11,9 @@ abstract type AbstractLikelihood end
11
11
# insupport(ℓ::AbstractLikelihood, p) = insupport(ℓ.k(p), ℓ.x)
12
12
13
13
@doc raw """
14
- Likelihood(k::AbstractTransitionKernel , x)
14
+ Likelihood(k, x)
15
15
16
- "Observe" a value `x`, yielding a function from the parameters to ℝ .
16
+ Default result of [`likelihoodof(k, x)`](@ref) .
17
17
18
18
Likelihoods are most commonly used in conjunction with an existing _prior_
19
19
measure to yield a new measure, the _posterior_. In Bayes's Law, we have
@@ -91,34 +91,35 @@ Similarly to the above, we have
91
91
92
92
Finally, let's return to the expression for Bayes's Law,
93
93
94
- ``P(θ|x) ∝ P(θ) P(x| θ)``
94
+ ``P(θ|x) ∝ P(x| θ) P(θ)``
95
95
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.
100
98
101
99
For example, say we have
102
100
103
101
μ ~ Normal()
104
102
x ~ Normal(μ,σ)
105
103
σ = 1
106
104
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
111
107
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
114
115
"""
115
116
struct Likelihood{K,X} <: AbstractLikelihood
116
117
k:: K
117
118
x:: X
118
119
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)
122
123
end
123
124
124
125
(lik:: AbstractLikelihood )(p) = exp (ULogarithmic, logdensityof (lik. k (p), lik. x))
@@ -150,58 +151,87 @@ end
150
151
151
152
export likelihoodof
152
153
153
- """
154
- likelihoodof(k::AbstractTransitionKernel, x; constraints...)
155
- likelihoodof(k::AbstractTransitionKernel, x, constraints::NamedTuple)
154
+ @doc raw """
155
+ likelihoodof(k, x)
156
156
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).
161
167
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 `θ`.
163
171
164
- likelihoodof (k, x; kwargs ... ) = likelihoodof (k, x, NamedTuple (kwargs))
172
+ `ℒₓ = likelihoodof(k, x)` has the mathematical interpretation
165
173
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
+ ```
167
177
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
169
181
170
- export log_likelihood_ratio
182
+ ```julia
183
+ log(ℒₓ(θ)) == logdensityof(ℒₓ, θ) ≈ logdensityof(k(θ), x)
171
184
185
+ DensityKind(ℒₓ) isa IsDensity
186
+ ```
187
+
188
+ By default, an instance of [`MeasureBase.Likelihood`](@ref) is returned.
172
189
"""
173
- log_likelihood_ratio(ℓ::Likelihood, p, q)
190
+ function likelihoodof end
174
191
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)
177
193
178
- logdensity_rel(ℓ.k(p), ℓ.k(q), ℓ.x)
179
194
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.
182
199
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
186
201
187
- # likelihoodof(k, x; kwargs...) = likelihoodof(k, x, NamedTuple(kwargs))
202
+ # """
203
+ # log_likelihood_ratio(ℓ::Likelihood, p, q)
188
204
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
190
207
191
- """
192
- likelihood_ratio(ℓ::Likelihood, p, q)
208
+ # logdensity_rel(ℓ.k(p), ℓ.k(q), ℓ.x)
193
209
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
196
212
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)
198
216
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))
202
218
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