Ich habe eine sehr einfache Implementierung der Wahrscheinlichkeit/Gradienten für das bedingte Logit-Modell geschrieben (erklärt here) - die Wahrscheinlichkeit funktioniert gut, aber der Farbverlauf ist nicht korrekt. Meine zwei Fragen sind: Ist meine Ableitung des Gradienten korrekt, und wenn ja, ist meine Implementierung in Python korrekt? Wenn dies im Math Forum besser gestellt wird, können Sie sich bewegen.Warum schlägt diese Implementierung des bedingten Logit-Gradienten fehl?
Schließlich wird der Gradient:
Hier i jede Beobachtung ist, j eine Alternative innerhalb Beobachtung i, c ist die gewählte Alternative Beobachtung i, Xij ist der Merkmalsvektor zur Auswahl j in i und B sind die entsprechenden Koeffizienten. In der Wahrscheinlichkeitsformel sollte der Merkmalsvektor mit dem Koeffizientenvektor multipliziert werden. Mein Fehler
My Implementierung für die Wahrscheinlichkeit und Steigungen sind wie folgt:
Likelihood:
def log_likelihood(coefs, observations, config, lasso):
def func(grp):
mtrx = grp.as_matrix(config.features)
dp = np.dot(mtrx, coefs)
sub = np.log(np.exp(dp).sum())
inc = (dp * grp['choice']).sum()
return inc - sub
ll = observations.groupby(['observation_id']).apply(func).sum()
if lasso is not None:
ll -= (np.abs(coefs).sum() * lasso)
neg_log = ll * -1
return neg_log
Gradient:
def gradient(coefs, observations, config, lasso):
def func(grp):
mtrx = grp.as_matrix([config.features])
tmtrx = mtrx.transpose()
tmp = np.exp(tmtrx * coefs[:, np.newaxis])
sub = (tmp * tmtrx).sum(1)/tmp.sum(1)
inc = (mtrx * grp['choice'][:, np.newaxis]).sum(0)
ret = inc - sub
return ret
return -1 * observations.groupby(['observation_id']).apply(func).sum()
Hier coefs ist ein numpy Array mit den Koeffizienten , Beobachtungen ist ein Datenrahmen, wobei jede Reihe eine Alternative innerhalb einer Beobachtung darstellt und die Spalten eine Auswahlspaltenindica sind Ting 0/1 für die Wahl innerhalb einer Spalte und eine Beobachtung_id Spalte, wo alle Alternativen innerhalb einer Beobachtung die gleiche ID haben, und schließlich ist Config ein Diktat, das ein Mitglied 'Eigenschaften' enthält, das ist die Liste der Spalten in den Beobachtungen df, die die Merkmale enthalten . Hinweis Ich teste ohne den Lasso-Parameter. Beispiel unten, wie die Daten aussehen.
Ich habe überprüft, die Wahrscheinlichkeit ist richtig; Der Fehler für den Farbverlauf ist jedoch sehr groß, wenn scipy.optimize.check_grad verwendet wird. Ich bin auch in der Lage, nach B zu lösen, wenn ich den Gradienten nicht an scipy.optimize.minimize übergebe. Der Gradient wird so ausgewertet, wie ich es erwarte, daher kann ich an dieser Stelle nur denken, dass meine Herleitung falsch ist, aber ich bin mir nicht sicher warum.
In [27]: df.head(14)
Out[27]:
x1 x2 x3 observation_id choice
0 0.187785 0.435922 -0.475349 211 1
1 -0.935956 -0.405833 -1.753128 211 0
2 0.210424 0.141579 0.415933 211 0
3 0.507025 0.307965 -0.198089 211 0
4 0.080658 -0.125473 -0.592301 211 0
5 0.605302 0.239491 0.287094 293 1
6 0.259580 0.415388 -0.396969 293 0
7 -0.637267 -0.984442 -1.376066 293 0
8 0.241874 0.435922 0.855742 293 0
9 0.831534 0.650425 0.930592 293 0
10 -1.682565 0.435922 -2.517229 293 0
11 -0.149186 0.300299 0.494513 293 0
12 -1.918179 -9.967421 -2.774450 293 0
13 -1.185817 0.295601 -1.974923 293 0