-
Notifications
You must be signed in to change notification settings - Fork 3
/
BayesMixedLogit.do
157 lines (118 loc) · 3.51 KB
/
BayesMixedLogit.do
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
clear all
set more off
use http://fmwww.bc.edu/repec/bocode/t/traindata.dta
set seed 90210
capture ssc install mixlogit
mixlogit y, rand(price contract local wknown tod seasonal) group(gid) id(pid)
mata:
real matrix drawb_betaW(beta, W) {
return( mean(beta) + rnormal(1, cols(beta) ,0 ,1 ) * cholesky(W)' )
}
end
mata:
real matrix drawW_bbeta(beta, b) {
v = rnormal( cols(b) + rows(beta), cols(b), 0, 1)
S1 = variance(beta :- b)
S=invsym((cols(b)*I(cols(b)) + rows(beta)*S1)/(cols(b) + rows(beta)))
L = cholesky(S)
R = (L*v')*(L*v')' / (cols(b) + rows(beta))
return(invsym(R))
}
end
mata:
real scalar lncp(real rowvector beta_rn,
real rowvector b,
real matrix Winv,
real matrix ldetW,
real matrix y,
real matrix Xr,
real matrix cid)
{
real scalar i, lnp, lnprior
real matrix z, Xrp, yp, mus
z = panelsetup(cid, 1)
lnp = 0
for (i=1; i<=rows(z); i++) {
Xrp = panelsubmatrix(Xr, i, z)
yp = panelsubmatrix(y, i, z)
mus = rowsum(Xrp:*beta_rn)
max = max(mus)
sum = max + ln(colsum(exp(mus :- max)))
lnp = lnp + colsum(yp:*mus) - sum
}
lnprior= -1/2*(beta_rn - b)*Winv*(beta_rn - b)' - 1/2*ldetW - cols(b)/2*ln(2*pi())
return(lnp + lnprior)
}
end
mata:
st_view(y=., ., "y")
st_view(X=., ., "price contract local wknown tod seasonal")
st_view(pid=., ., "pid") // Individual identifier
st_view(gid=., ., "gid") // choice occasions
end
mata:
m = panelsetup(pid, 1)
b = J(1, 6, 0)
W = I(6)*6
beta = b :+ sqrt(diagonal(W))':*rnormal(rows(m), cols(b), 0, 1)
end
mata:
its = 20000
burn = 10000
nb = cols(beta)
bvals = J(0, cols(beta), .)
Wvals = J(0, cols(rowshape(W, 1)), .)
propVs = J(rows(m), 1, rowshape(W, 1))
propms = J(rows(m), 1, b)
accept = J(rows(m), 1, 0)
atarg = .25
lam = J(rows(m), 1, 2.38^2/nb)
damper = 1
for (i=1; i<=its; i++) {
b = drawb_betaW(beta, W/rows(m))
W = drawW_bbeta(beta, b)
bvals = bvals \ b
Wvals = Wvals \ rowshape(W, 1)
beta_old = beta
Winv = invsym(W)
ldetW = ln(det(W))
for (j=1; j<=rows(m); j++) {
yi = panelsubmatrix(y, j,m)
Xi = panelsubmatrix(X, j, m)
gidi = panelsubmatrix(gid, j, m)
propV = rowshape(propVs[j, ], nb)
beta_old = beta[j, ]
beta_hat = beta[j, ] + lam[j]*rnormal(1,nb,0,1)*cholesky(propV)'
old = lncp(beta_old, b, Winv, ldetW, yi, Xi, gidi)
pro = lncp(beta_hat, b, Winv, ldetW, yi, Xi, gidi)
if (pro == . ) alpha = 0
else if (pro > old) alpha = 1
else alpha = exp(pro - old)
if (runiform(1, 1) < alpha) {
beta[j, ] = beta_hat
accept[j] = accept[j] + 1
}
lam[j] = lam[j]*exp(1/(i+1)^damper*(alpha - atarg))
propms[j, ] = propms[j, ] + 1/(i + 1)^damper*(beta[j, ] - propms[j, ])
propV = propV + 1/(i + 1)^damper*((beta[j, ] - propms[j, ])'(beta[j, ] - propms[j, ]) - propV)
_makesymmetric(propV)
propVs[j, ] = rowshape(propV, 1)
}
}
arates = accept/its
end
preserve
clear
getmata (b*) = bvals
sum b*
gen t = _n
tsset t
forvalues i=1/6 {
quietly tsline b`i', saving(bg`i'.gph, replace)
local glist `glist' "bg`i'.gph"
}
graph combine `glist'
clear
getmata arates lam
hist arates
hist lam