scipy ist nicht die Optimierung und liefert "die Gewünschten Fehler nicht unbedingt erreicht durch Präzision Verlust"
Habe ich den folgenden code versucht zu minimieren, eine log-likelihood-Funktion.
#!/usr/bin/python
import math
import random
import numpy as np
from scipy.optimize import minimize
def loglikelihood(params, data):
(mu, alpha, beta) = params
tlist = np.array(data)
r = np.zeros(len(tlist))
for i in xrange(1,len(tlist)):
r[i] = math.exp(-beta*(tlist[i]-tlist[i-1]))*(1+r[i-1])
loglik = -tlist[-1]*mu
loglik = loglik+alpha/beta*sum(np.exp(-beta*(tlist[-1]-tlist))-1)
loglik = loglik+np.sum(np.log(mu+alpha*r))
return -loglik
atimes = [ 148.98894201, 149.70253172, 151.13717804, 160.35968355,
160.98322609, 161.21331798, 163.60755544, 163.68994973,
164.26131871, 228.79436067]
a= 0.01
alpha = 0.5
beta = 0.6
print loglikelihood((a, alpha, beta), atimes)
res = minimize(loglikelihood, (0.01, 0.1,0.1), method = 'BFGS',args = (atimes,))
print res
Es gibt mir
28.3136498357
./test.py:17: RuntimeWarning: invalid value encountered in log
loglik = loglik+np.sum(np.log(mu+alpha*r))
status: 2
success: False
njev: 14
nfev: 72
hess_inv: array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
fun: 32.131359359964378
x: array([ 0.01, 0.1 , 0.1 ])
message: 'Desired error not necessarily achieved due to precision loss.'
jac: array([ -2.8051672 , 13.06962156, -48.97879982])
Beachten Sie, dass es noch nicht geschafft die Optimierung der Parameter und der minimierten Wert 32 ist größer als 28, die ist, was Sie erhalten mit a= 0,01, alpha = 0.5, beta = 0.6 . Es ist möglich, dieses problem könnte vermieden werden, indem die Auswahl der besseren ersten Vermutungen aber wenn es so ist, wie kann ich dies automatisch?
Ich würde denken, Sie wollen würde, um zu maximieren, LL, nicht minimieren. Wenn Sie die Minimierung einer Summe von Quadraten, du bist Maximierung LL.
Ja. Beachten Sie die Funktion gibt
Nur eine Bemerkung - ich hatte einmal ein problem, teilten die gleichen Symptome wie deiner, aber die Ursache war ganz anders. Es stellte sich heraus, dass ich hatte einen Fehler in meinem gradient-Funktion, so dass, wenn ich ging es in die routine über die
Ja. Beachten Sie die Funktion gibt
-loglik
welche diese verarbeitet.Nur eine Bemerkung - ich hatte einmal ein problem, teilten die gleichen Symptome wie deiner, aber die Ursache war ganz anders. Es stellte sich heraus, dass ich hatte einen Fehler in meinem gradient-Funktion, so dass, wenn ich ging es in die routine über die
jac
parameter, die routine konnte nicht arbeiten. Die Fehler waren kryptisch und es war nur bei der re-Inspektion mein code, den ich identifiziert den Fehler. Das heißt, die Antwort unten, die verwendet Nelder-Mead
wirklich geholfen, weil es könnte sich optimieren, ohne den Verlauf und gab die richtige Antwort für mich, hilft mir zu realisieren, dass das Problem mit dem bug in meinem gradient-Funktion.
InformationsquelleAutor felix | 2014-07-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kopierte ich Ihrem Beispiel und versuchte ein wenig. Sieht aus wie wenn du dich mit BFGS-solver, nach ein paar iteration der
mu+ alpha * r
haben einige negative zahlen, und das ist, wie man die RuntimeWarning.Der einfachste fix ich denken kann, ist die Umstellung auf Nelder Mead solver.
Und es wird Ihnen dieses Ergebnis:
InformationsquelleAutor JimmyK
Watch out für negative Werte der Funktion log (), beheben Sie und sagen Sie den Optimierer, dass Sie schlecht sind, indem Sie eine Strafe:
InformationsquelleAutor optimizer
In die gleiche Warnung, ich löste es durch umschreiben der log-likelihood-Funktion, um
log(params)
undlog(data)
als Argumente, anstatt params und Daten.So, ich vermeiden Sie die Verwendung
np.log()
in die likelihood-Funktion oder die Jacobi -, wenn möglich.InformationsquelleAutor Sahar
Andere Lösung (die für mich gearbeitet hat) ist, zu skalieren Ihre Funktion (und Gefälle) auf Werte näher an 0 ist. Zum Beispiel, mein problem kam, als ich zu bewerten hatte, eine log-likelihood-60k Punkte. Dies bedeutete, dass mein log-likelihood eine sehr große Zahl. Konzeptionell ist die log-likelihood-war ein sehr, sehr spikey-Funktion.
Den Gradienten begann der große (besteigen dieses zackigen Berg), und dann wurde mäßig klein, aber nie weniger als die Standard -
gtol
parameter in der BGFS-routine (das ist die Schwelle, dass alle Verläufe müssen unterhalb der für die Kündigung). Auch, in dieser Zeit hatte ich im wesentlichen kamen auf die richtigen Werte (ich war mit generierten Daten, so dass ich wusste, dass der wahre Werte).Was passierte war, dass meine Verläufe waren ca. 60k *
average individual gradient value
, und auch wenn dieaverage individual gradient value
klein war, sagen wir weniger als 1e-8, 60k * 1e-8 >gtol
. So war ich nie zufrieden die Schwelle, obwohl ich angekommen war an der Lösung.Konzeptionell, weil dieser sehr zackigen Berg, der Algorithmus wurde in kleinen Schritten, aber Schritt über das wahre minimum und nie erreicht
average individual gradient << 1e-8
was bedeutet mein Steigungen ging nie untergtol
.Zwei Lösungen:
1) Skalieren Sie Ihre log-likelihood und Gradienten um einen Faktor, wie
1/n
won
ist die Anzahl der Proben.2) Skalieren Sie Ihre
gtol
: zum Beispiel"gtol": 1e-7 * n
InformationsquelleAutor Cam.Davidson.Pilon