# GPLikelihoods

`GPLikelihoods.jl`

provides a practical interface to connect Gaussian and non-conjugate likelihoods to Gaussian Processes. The API is very basic: Every `AbstractLikelihood`

object is a functor taking a `Real`

or an `AbstractVector`

as an input and returning a `Distribution`

from `Distributions.jl`

.

### Single-latent vs multi-latent likelihoods

Most likelihoods, like the `GaussianLikelihood`

, only require one latent Gaussian process. Passing a `Real`

will therefore return a `UnivariateDistribution`

, and passing an `AbstractVector{<:Real}`

will return a multivariate product of distributions.

`julia> f = 2.0;`

`julia> GaussianLikelihood()(f) == Normal(2.0, 1e-3)`

`true`

`julia> fs = [2.0, 3.0, 1.5];`

`julia> GaussianLikelihood()(fs) isa AbstractMvNormal`

`true`

Some likelihoods, like the `CategoricalLikelihood`

, require multiple latent Gaussian processes, and an `AbstractVector{<:Real}`

needs to be passed. To obtain a product of distributions an `AbstractVector{<:AbstractVector{<:Real}}`

has to be passed (we recommend using `ColVecs`

and `RowVecs`

from KernelFunctions.jl if you need to transform an `AbstractMatrix`

).

`julia> fs = [2.0, 3.0, 4.5];`

`julia> CategoricalLikelihood()(fs) isa Categorical`

`true`

`julia> Fs = [rand(3) for _ in 1:4];`

`julia> CategoricalLikelihood()(Fs) isa Product{<:Any,<:Categorical}`

`true`

### Constrained parameters

The function values `f`

of the latent Gaussian process live in the real domain $\mathbb{R}$. For some likelihoods, the domain of the distribution parameter `p`

that is modulated by the latent Gaussian process is constrained to some subset of $\mathbb{R}$, e.g. only positive values or values in an interval.

To connect these two domains, a transformation from `f`

to `p`

is required. For this, we provide the `Link`

type, which can be passed to the likelihood constructors. (Alternatively, `function`

s can also directly be passed and will be wrapped in a `Link`

.)

We typically call this passed transformation the `invlink`

. This comes from the statistics literature, where the "link" is defined as `f = link(p)`

, whereas here we need `p = invlink(f)`

.

For more details about which likelihoods require a `Link`

check out their docs.

A classical example is the `BernoulliLikelihood`

for classification, with the probability parameter $p \in [0, 1]$. The default is to use a `logistic`

transformation, but one could also use the inverse of the `probit`

link:

`julia> f = 2.0;`

`julia> BernoulliLikelihood()(f) == Bernoulli(logistic(f))`

`true`

`julia> BernoulliLikelihood(NormalCDFLink())(f) == Bernoulli(normcdf(f))`

`true`

Note that we passed the *inverse* of the `probit`

function which is the `normcdf`

function.