Expectation, variance and likelihood
A random variable takes values with given probabilities. Its expectation is the probability-weighted average of its values; its variance is the expected squared distance from that average. A sample mean from many draws approaches the expectation.
import numpy as np
values = np.array([0.0, 1.0, 10.0])
probs = np.array([0.5, 0.4, 0.1])
mean = values @ probs
var = ((values - mean) ** 2) @ probs
print(mean, var) # 1.4 8.44
rng = np.random.default_rng(0)
draws = rng.choice(values, 10000, p=probs)
print(draws.mean().round(2))Likelihood
A model predicts a distribution, and training maximises the probability of the data it sees, the likelihood. In practice you minimise the negative log-likelihood. For a Gaussian with mean mu and spread sigma, it is 0.5 log(2 pi sigma ** 2) + (y - mu) ** 2 / (2 sigma ** 2). With sigma fixed, only the squared error depends on mu: mean squared error is Gaussian likelihood in disguise.
Your task
Write expectation(values, probs) and variance(values, probs), raising ValueError when the probabilities are negative or do not sum to 1 (within 1e-9). Write gaussian_nll(y, mu, sigma) returning the mean negative log-likelihood of the array y under a Gaussian, as a float.
The explanation opens here once every check passes.