Is this function the right implementation to compute the likelihood of a normal distribution at a point?

This post give this code

normalF <- function(parvec) {
  # Log of likelihood of a normal distribution
  # parvec[1] - mean
  # parvec[2] - standard deviation
  # x - set of observations. Should be initialized before MLE
  sum ( -0.5* log(parvec[2]) - 0.5*(x - parvec[1])^2/parvec[2] )
}

x = c(1,2,3,4) # set of observations
normalF(c(1,1)) # log likelihood function value for given x and mu=sd=1 

to compute the log of a likelihood function of a Normal Distribution. This video computes this object with \mu = 32, \sigma = 2.5 at x=34, which is approximately equal to 0.12.

I plug the params into function normalF,

x = c(34) # set of observations
normalF(c(32,2.5)) # log likelihood function value for given x and mu=sd=1

and I got -1.258145.

Is the function normalF the right implementation to compute the likelihood of a normal distribution at a point?

Neither is correct.

Likelihood is a probability, and hence it is a proper fraction. So, its log-likelihood cannot possibly be positive, and hence it cannot be 0.12. I haven't seen the video, but almost certainly it is not the log likelihood, rather the density of the \mathbb{N}(32,2.5^2) at the point x=34.

The normalF function doesn't calculate the exact log-likelihood. While finding the maximum likelihood estimators of \mu and \sigma^2, you don't need the constant part involving \pi. Hence, it removes that part and returns only what is necessary. So, it's output is not the exact log-likelihood.

And, a short note is that the function is rather misleading, as though the comments say it expects parvec[2] to be standard deviation, it actually needs variance. That's why the -0.5 part is present and the denominator of the 2^{nd} term is not squared. If you want to verify this, do the derivation yourself, or see the last equation of the post.

If you want the exact likelihood, I'll say this is a far easier way:

get_normal_log_likelihood <- function(observations, mean_parameter, sd_parameter)
{
    log(x = prod(dnorm(x = observations,
                       mean = mean_parameter,
                       sd = sd_parameter)))
}

get_normal_log_likelihood(observations = 34,
                          mean_parameter = 32,
                          sd_parameter = 2.5)
#> [1] -2.155229

Created on 2019-10-12 by the reprex package (v0.3.0)

1 Like

Hi @shiqangpan,

Is this what you're looking for?

> dnorm(x = 34, mean = 32, sd = 2.5)
[1] 0.1158766
> log(dnorm(x = 34, mean = 32, sd = 2.5))
[1] -2.155229

(Hint, it is :wink:)

Ps. the video you link to, nicely explains probability versus likelihood - Please note that these are not the same. They are used interchangeably in every day talk, but in statistics they represent different entities.

1 Like

Thank you so much. The likelihood "0.12" is in that video is an approximate of "0.1158766" which is the probability density of \mathbb{N}(32,2.5^2) at the point x=34, Is my understanding right?

Yup - Right you are!