web-dev-qa-db-ja.com

最尤推定擬似コード

一部の玩具データの平均と分散を推定するには、最尤推定量をコーディングする必要があります。 numpy.random.randn(100)で作成された100個のサンプルを持つベクターがあります。データの平均と単位分散のガウス分布はゼロでなければなりません。

ウィキペディアといくつかの追加ソースを確認しましたが、統計の背景がないため、少し混乱しています。

最尤推定量の擬似コードはありますか? MLEの直感は得られますが、どこからコーディングを始めるべきかわかりません。

ウィキは、対数尤度のargmaxを採用すると言います。私が理解しているのは、異なるパラメーターを使用して対数尤度を計算する必要があり、最大確率を与えたパラメーターを使用することです。取得できないのは、最初の場所でパラメーターをどこで見つけることができるかということです。高い確率を得るために異なる平均と分散を無作為に試してみると、いつ試してみるのを止めるべきですか

25
user103021

最尤計算を行う場合、最初に行う必要がある手順は次のとおりです。一部のパラメーターに依存する分布を仮定します。データをgenerate(パラメータさえも知っている)しているので、ガウス分布を仮定するようにプログラムに「伝え」ます。ただし、プログラムにパラメーター(0および1)を伝えることはありませんが、事前にそれらを不明のままにして、後で計算します。

これで、サンプルベクトルができました(xと呼びましょう。その要素は_x[0]_から_x[100]_です)、処理する必要があります。そのためには、次を計算する必要があります(fガウス分布の確率密度関数 )。

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

私のリンクからわかるように、fは2つのパラメーター(ギリシャ文字µとσ)を使用します。 Youは、f(x[0]) * ... * f(x[100])が可能な最大値を取るように、µとσの値を計算する必要があります。

これを行った後、µは平均の最尤値であり、σは標準偏差の最尤値です。

Μとσの値を計算するようにhow明示的には教えていないことに注意してください。これは、手(そしておそらく私はそれを理解できないだろう);値を取得する手法を説明するだけで、他のどの分布にも適用できます。

元の用語を最大化するため、元の用語の対数を「単純に」最大化できます。これにより、これらすべての製品を扱う必要がなくなり、元の用語をいくつかの加数の合計に変換できます。

本当に計算したい場合は、次の用語につながるいくつかの単純化を行うことができます(私が何も台無しにしないことを望みます):

enter image description here

次に、上記の獣が最大になるように、µとσの値を見つける必要があります。これを行うことは、非線形最適化と呼ばれる非常に重要なタスクです。

試すことができる単純化の1つは次のとおりです。1つのパラメーターを修正し、他のパラメーターを計算してみます。これにより、2つの変数を同時に処理する必要がなくなります。

18
phimuemue

私はちょうどこれに出くわし、その古いことを知っていますが、他の誰かがこれから利益を得ることを望んでいます。これまでのコメントはML最適化とは何かについてかなり良い説明を提供しましたが、それを実装するための擬似コードを提供した人はいませんでした。 Pythonには、これを行うScipyの最小化機能があります。線形回帰の擬似コードを次に示します。

# 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

これは私にとってはうまくいきます。確かに、これは単なる基本です。パラメータ推定値のCIをプロファイルしたり提供したりはしませんが、開始点です。 here で説明しているように、MLテクニックを使用して、たとえばODEやその他のモデルの推定値を見つけることもできます。

私はこの質問が古いことを知っています、それからあなたがそれを理解したことを望みますが、うまくいけば他の誰かが利益を得るでしょう。

37
Nate

数値最適化手順が必要です。 Pythonで何かが実装されているかどうかはわかりませんが、実装されている場合は、numpyまたはscipyと友人になります。

「Nelder-Meadアルゴリズム」や「BFGS」などを探してください。他のすべてが失敗した場合は、Rpyを使用してR関数 'optim()'を呼び出します。

これらの関数は、関数空間を検索し、最大値がどこにあるかを見つけ出すことにより機能します。霧の中で丘の頂上を見つけようとすることを想像してください。常に最も急な方法で進んでみてください。または、ラジオやGPSユニットで友人を送り出し、少し調査することもできます。どちらの方法でも誤ったサミットにつながる可能性があるため、多くの場合、異なるポイントから始めて、これを数回行う必要があります。さもなければ、南の頂上は、それを覆い隠す大規模な北の頂上があるときに最高だと思うかもしれません。

4
Spacedman

Joranが言ったように、正規分布の最尤推定値は分析的に計算できます。答えは、パラメーターに関する対数尤度関数の偏導関数を見つけ、それぞれをゼロに設定してから、両方の方程式を同時に解くことによって見つかります。

正規分布の場合、平均(mu)に関して対数尤度を導出し、分散(sigma ^ 2)に関して導出して、両方がゼロに等しい2つの方程式を取得します。 muとsigma ^ 2の方程式を解いた後、回答としてサンプル平均とサンプル分散を取得します。

詳細については、 wikipediaページ を参照してください。

0
justinng1