条件付きロジットモデル(尤度/勾配)の非常に単純な実装を書いています(hereを参照) - 尤度はうまく動作しますが、勾配は正しくありません。私の2つの質問は、私の勾配の派生は正しかったのですか?もしそうなら、私のPython実装は正しいのでしょうか?これが数学フォーラムでよりよく尋ねられる場合は、自由に移動してください。条件付きロジット勾配のこの実装が失敗するのはなぜですか?
ここで、iは、Cは、で選択された代替案であるjが観察内代替で、各観察であります観測iでは、Xijはiにおける選択jの特徴ベクトルであり、Bは対応する係数である。 尤度式は、特徴ベクトルに係数ベクトルを乗じたものでなければなりません。
尤:
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
勾配:ここ
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()
、coefsは、係数を含むnumpyの配列であるが、以下のように私のミス尤度とグラデーションの
私の実装であります、観測はデータフレームであり、各行は観測内の代替を表し、列は選択列インディケータ列内での選択については0/1、観測内のすべての選択肢は同じIDを持つobservation_id列、最後にconfigはフィーチャを含む観測値df内の列のリストであるメンバ 'フィーチャ'を含むdictである。 注記lassoパラメータを使用せずにテストしています。データがどのように見えるかの例を以下に示します。
私は可能性が正しいことを確認しました。 scipy.optimize.check_gradを使用すると、勾配の誤差が非常に大きくなります。 scipy.optimize.minimizeにグラデーションを渡さないと、私はBを解くこともできます。私が期待しているように勾配が評価されるので、この時点で私の派生が間違っているとしか思えませんが、私は理由は分かりません。
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