2016-09-17 5 views
0

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?

Modell: enter image description here

Log Likelihood: enter image description here

Schließlich wird der Gradient: enter image description here

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 

Antwort

0

Die Ableitung war falsch. Bei der Exponentiation habe ich nur das Merkmal und den Koeffizienten für die partielle Ableitung des gegebenen Koeffizienten berücksichtigt. Es hätte vielmehr das Skalarprodukt aller Merkmale und Koeffizienten sein sollen.

Verwandte Themen