web-dev-qa-db-fra.com

Pseudocode d'estimation de vraisemblance maximale

Je dois coder un estimateur de vraisemblance maximale pour estimer la moyenne et la variance de certaines données relatives aux jouets. J'ai un vecteur avec 100 échantillons, créé avec numpy.random.randn(100). Les données doivent avoir une distribution gaussienne de moyenne et unité de variance nulle.

J'ai consulté Wikipedia et quelques sources supplémentaires, mais je suis un peu confus car je n'ai pas de statistiques de base.

Existe-t-il un pseudo-code pour un estimateur du maximum de vraisemblance? Je comprends l’intuition de MLE mais je ne sais pas par où commencer à coder.

Le wiki dit prendre l'argmax de log-vraisemblance. Ce que je comprends, c’est: j’ai besoin de calculer log-vraisemblance en utilisant différents paramètres, puis je prendrai ceux qui ont donné la probabilité maximale. Ce que je ne comprends pas, c'est: où vais-je trouver les paramètres en premier lieu? Si j'essaie au hasard différentes moyennes et variances pour obtenir une probabilité élevée, quand devrais-je arrêter d'essayer?

24
user103021

Si vous effectuez des calculs de probabilité maximale, la première étape à suivre est la suivante: Supposons une distribution qui dépend de certains paramètres. Puisque vous generate vos données (vous connaissez même vos paramètres), vous "dites" à votre programme d'assumer la distribution gaussienne. Cependant, vous ne communiquez pas vos paramètres à votre programme (0 et 1), mais vous les laissez inconnus a priori et vous les calculez par la suite.

Maintenant, vous avez votre échantillon de vecteur (appelons-le x, ses éléments sont de x[0] à x[100]) et vous devez le traiter. Pour ce faire, vous devez calculer ce qui suit (f désigne la fonction de densité de probabilité de la distribution gaussienne ):

f(x[0]) * ... * f(x[100])

Comme vous pouvez le voir dans mon lien, f utilise deux paramètres (les lettres grecques µ et σ). Vous devez maintenant calculer les valeurs pour µ et σ de manière à ce que f(x[0]) * ... * f(x[100]) prenne la valeur maximale possible.

Lorsque vous avez terminé, µ est votre valeur de probabilité maximale pour la moyenne et σ est la valeur de probabilité maximale pour l'écart type.

Notez que je ne vous dis pas explicitement comment calculer les valeurs pour µ et σ, puisqu'il s'agit d'une procédure assez mathématique que je n'ai pas sous la main (et que je ne comprendrais probablement pas); Je viens de vous dire la technique pour obtenir les valeurs, qui peuvent également être appliquées à d’autres distributions.

Puisque vous voulez maximiser le terme d'origine, vous pouvez "simplement" maximiser le logarithme du terme d'origine - cela vous évite de traiter avec tous ces produits et transforme le terme d'origine en une somme avec quelques summands.

Si vous voulez vraiment le calculer, vous pouvez faire quelques simplifications qui mènent au terme suivant (espérons que je n'ai rien gâché):

 enter image description here

Maintenant, vous devez trouver des valeurs pour µ et σ telles que la bête ci-dessus soit maximale. Faire cela est une tâche très non triviale appelée optimisation non linéaire.

Une simplification que vous pouvez essayer est la suivante: Corrigez un paramètre et essayez de calculer l’autre. Cela vous évite de traiter deux variables en même temps.

18
phimuemue

Je viens de découvrir ceci, et je connais son âge, mais j'espère que quelqu'un d'autre en tirera profit. Bien que les commentaires précédents décrivent assez bien ce qu'est l'optimisation de ML, personne n'a donné de pseudo-code pour l'implémenter. Python a un minimiseur dans Scipy qui le fera. Voici un pseudo-code pour une régression linéaire.

# import the packages
import numpy as np
from scipy.optimize import minimize
import scipy.stats as stats
import time

# Set up your x values
x = np.linspace(0, 100, num=100)

# Set up your observed y values with a known slope (2.4), intercept (5), and sd (4)
yObs = 5 + 2.4*x + np.random.normal(0, 4, 100)

# Define the likelihood function where params is a list of initial parameter estimates
def regressLL(params):
    # Resave the initial parameter guesses
    b0 = params[0]
    b1 = params[1]
    sd = params[2]

    # Calculate the predicted values from the initial parameter guesses
    yPred = b0 + b1*x

    # Calculate the negative log-likelihood as the negative sum of the log of a normal
    # PDF where the observed values are normally distributed around the mean (yPred)
    # with a standard deviation of sd
    logLik = -np.sum( stats.norm.logpdf(yObs, loc=yPred, scale=sd) )

    # Tell the function to return the NLL (this is what will be minimized)
    return(logLik)

# Make a list of initial parameter guesses (b0, b1, sd)    
initParams = [1, 1, 1]

# Run the minimizer
results = minimize(regressLL, initParams, method='nelder-mead')

# Print the results. They should be really close to your actual values
print results.x

Cela fonctionne très bien pour moi. Certes, ce ne sont que les bases. Il ne donne pas de profil ni ne donne de CI sur les estimations de paramètres, mais c’est un début. Vous pouvez également utiliser les techniques de ML pour trouver des estimations pour, par exemple, les ODE et d’autres modèles, comme je l’ai décrit ici .

Je sais que cette question était ancienne, j'espère que vous l'aurez comprise depuis, mais j'espère que quelqu'un d'autre en profitera.

36
Nate

Vous avez besoin d'une procédure d'optimisation numérique. Je ne sais pas si quelque chose est implémenté en Python, mais si c'est le cas, ce sera en numpy ou scipy et amis.

Recherchez des éléments tels que «l'algorithme de Nelder-Mead» ou «BFGS». Si tout échoue, utilisez Rpy et appelez la fonction R 'optim ()'.

Ces fonctions fonctionnent en recherchant l’espace des fonctions et en essayant de déterminer le maximum. Imaginez que vous essayez de trouver le sommet d'une colline dans le brouillard. Vous pouvez simplement essayer de toujours vous diriger le plus raide. Vous pouvez aussi envoyer des amis avec des radios et des unités GPS et effectuer des levés. L'une ou l'autre méthode peut vous conduire à un faux sommet, vous devez donc souvent le faire plusieurs fois, en partant de différents points. Sinon, vous pensez peut-être que le sommet sud est le plus élevé lorsqu'un sommet nord gigantesque le recouvre.

4
Spacedman

Comme Joran l’a dit, les estimations du maximum de vraisemblance pour la distribution normale peuvent être calculées de manière analytique. Les réponses sont trouvées en recherchant les dérivées partielles de la fonction log-vraisemblance par rapport aux paramètres, en réglant chaque valeur à zéro, puis en résolvant les deux équations simultanément. 

Dans le cas de la distribution normale, vous obtiendrez la log-vraisemblance par rapport à la moyenne (mu), puis par rapport à la variance (sigma ^ 2) pour obtenir deux équations égales à zéro. Après avoir résolu les équations pour mu et sigma ^ 2, vous obtiendrez la moyenne et la variance de l'échantillon comme réponses.

Voir la page wikipedia pour plus de détails.

0
justinng1