Skip to content

Commit 936e8fd

Browse files
committed
Update kalman_2.md
1 parent 0184d5e commit 936e8fd

File tree

1 file changed

+71
-39
lines changed

1 file changed

+71
-39
lines changed

lectures/kalman_2.md

Lines changed: 71 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ kernelspec:
3030
```
3131

3232
In this quantecon lecture {doc}`A First Look at the Kalman filter <kalman>`, we used
33-
a Kalman filter to estimate locations of a rocket.
33+
a Kalman filter to estimate locations of a rocket.
3434

3535
In this lecture, we'll use the Kalman filter to
3636
infer a worker's human capital and the effort that the worker devotes to accumulating
3737
human capital, neither of which the firm observes directly.
3838

3939
The firm learns about those things only by observing a history of the output that the worker generates for the firm, and from understanding how that output depends on the worker's human capital and how human capital evolves as a function of the worker's effort.
4040

41-
We'll posit a rule that expresses how the much firm pays the worker each period as a function of the firm's information each period.
41+
We'll posit a rule that expresses how much the firm pays the worker each period as a function of the firm's information each period.
4242

4343
In addition to what's in Anaconda, this lecture will need the following libraries:
4444

@@ -53,8 +53,11 @@ To conduct simulations, we bring in these imports, as in {doc}`A First Look at t
5353
```{code-cell} ipython3
5454
import matplotlib.pyplot as plt
5555
import numpy as np
56+
import jax
57+
import jax.numpy as jnp
5658
from quantecon import Kalman, LinearStateSpace
5759
from collections import namedtuple
60+
from typing import NamedTuple
5861
from scipy.stats import multivariate_normal
5962
import matplotlib as mpl
6063
mpl.rcParams['text.usetex'] = True
@@ -71,7 +74,7 @@ The workers' output is described by the following dynamic process:
7174
:label: worker_model
7275
7376
\begin{aligned}
74-
h_{t+1} &= \alpha h_t + \beta u_t + c w_{t+1}, \quad c_{t+1} \sim {\mathcal N}(0,1) \\
77+
h_{t+1} &= \alpha h_t + \beta u_t + c w_{t+1}, \quad w_{t+1} \sim {\mathcal N}(0,1) \\
7578
u_{t+1} & = u_t \\
7679
y_t & = g h_t + v_t , \quad v_t \sim {\mathcal N} (0, R)
7780
\end{aligned}
@@ -85,7 +88,7 @@ Here
8588
* $h_0 \sim {\mathcal N}(\hat h_0, \sigma_{h,0})$
8689
* $u_0 \sim {\mathcal N}(\hat u_0, \sigma_{u,0})$
8790

88-
Parameters of the model are $\alpha, \beta, c, R, g, \hat h_0, \hat u_0, \sigma_h, \sigma_u$.
91+
Parameters of the model are $\alpha, \beta, c, R, g, \hat h_0, \hat u_0, \sigma_{h,0}, \sigma_{u,0}$.
8992

9093
At time $0$, a firm has hired the worker.
9194

@@ -129,8 +132,17 @@ Write system [](worker_model) in the state-space form
129132

130133
```{math}
131134
\begin{aligned}
132-
\begin{bmatrix} h_{t+1} \cr u_{t+1} \end{bmatrix} &= \begin{bmatrix} \alpha & \beta \cr 0 & 1 \end{bmatrix}\begin{bmatrix} h_{t} \cr u_{t} \end{bmatrix} + \begin{bmatrix} c \cr 0 \end{bmatrix} w_{t+1} \cr
133-
y_t & = \begin{bmatrix} g & 0 \end{bmatrix} \begin{bmatrix} h_{t} \cr u_{t} \end{bmatrix} + v_t
135+
\begin{bmatrix} h_{t+1} \cr u_{t+1} \end{bmatrix}
136+
&=
137+
\begin{bmatrix} \alpha & \beta \cr 0 & 1 \end{bmatrix}
138+
\begin{bmatrix} h_{t} \cr u_{t} \end{bmatrix}
139+
+
140+
\begin{bmatrix} c \cr 0 \end{bmatrix}
141+
w_{t+1} \cr
142+
y_t & =
143+
\begin{bmatrix} g & 0 \end{bmatrix}
144+
\begin{bmatrix} h_{t} \cr u_{t} \end{bmatrix}
145+
+ v_t
134146
\end{aligned}
135147
```
136148

@@ -151,67 +163,87 @@ where
151163
x_t = \begin{bmatrix} h_{t} \cr u_{t} \end{bmatrix} , \quad
152164
\hat x_0 = \begin{bmatrix} \hat h_0 \cr \hat u_0 \end{bmatrix} , \quad
153165
\Sigma_0 = \begin{bmatrix} \sigma_{h,0} & 0 \cr
154-
0 & \sigma_{u,0} \end{bmatrix}
166+
0 & \sigma_{u,0} \end{bmatrix}
155167
```
156168

157-
To compute the firm's wage setting policy, we first we create a `namedtuple` to store the parameters of the model
169+
To compute the firm's wage setting policy, we first we create a `NamedTuple` to store the parameters of the model
158170

159171
```{code-cell} ipython3
160-
WorkerModel = namedtuple("WorkerModel",
161-
('A', 'C', 'G', 'R', 'xhat_0', 'Σ_0'))
172+
class WorkerModel(NamedTuple):
173+
"""
174+
Parameters for the worker model state-space representation.
175+
176+
A : jax.Array
177+
Transition matrix of state variables
178+
C : jax.Array
179+
Parameter of the state shock
180+
G : jax.Array
181+
Parameter of state variables in observation equation
182+
R : jax.Array
183+
Coefficient of observation shock
184+
xhat_0 : jax.Array
185+
Initial state estimate
186+
Σ_0 : jax.Array
187+
Initial covariance matrix
188+
"""
189+
A: jax.Array
190+
C: jax.Array
191+
G: jax.Array
192+
R: jax.Array
193+
xhat_0: jax.Array
194+
Σ_0: jax.Array
162195
163196
def create_worker(α=.8, β=.2, c=.2,
164197
R=.5, g=1.0, hhat_0=4, uhat_0=4,
165198
σ_h=4, σ_u=4):
166199
167-
A = np.array([[α, β],
200+
A = jnp.array([[α, β],
168201
[0, 1]])
169-
C = np.array([[c],
202+
C = jnp.array([[c],
170203
[0]])
171-
G = np.array([g, 1])
204+
G = jnp.array([g, 0])
205+
R = jnp.array(R)
172206
173207
# Define initial state and covariance matrix
174-
xhat_0 = np.array([[hhat_0],
208+
xhat_0 = jnp.array([[hhat_0],
175209
[uhat_0]])
176210
177-
Σ_0 = np.array([[σ_h, 0],
211+
Σ_0 = jnp.array([[σ_h, 0],
178212
[0, σ_u]])
179213
180214
return WorkerModel(A=A, C=C, G=G, R=R, xhat_0=xhat_0, Σ_0=Σ_0)
181215
```
182216

183-
Please note how the `WorkerModel` namedtuple creates all of the objects required to compute an associated
184-
state-space representation {eq}`ssrepresent`.
217+
Please note how the `WorkerModel` namedtuple creates all of the objects required to compute an associated state-space representation {eq}`ssrepresent`.
185218

186-
This is handy, because in order to simulate a history $\{y_t, h_t\}$ for a worker, we'll want to form
187-
state space system for him/her by using the [`LinearStateSpace`](https://quanteconpy.readthedocs.io/en/latest/tools/lss.html) class.
219+
This is handy, because in order to simulate a history $\{y_t, h_t\}$ for a worker, we'll want to form state space system for him/her by using the [`LinearStateSpace`](https://quanteconpy.readthedocs.io/en/latest/tools/lss.html) class.
188220

189221
```{code-cell} ipython3
222+
# TODO write it into a function
190223
# Define A, C, G, R, xhat_0, Σ_0
191224
worker = create_worker()
192225
A, C, G, R = worker.A, worker.C, worker.G, worker.R
193226
xhat_0, Σ_0 = worker.xhat_0, worker.Σ_0
194227
195228
# Create a LinearStateSpace object
196-
ss = LinearStateSpace(A, C, G, np.sqrt(R),
197-
mu_0=xhat_0, Sigma_0=np.zeros((2,2)))
229+
ss = LinearStateSpace(A, C, G, jnp.sqrt(R),
230+
mu_0=xhat_0, Sigma_0=Σ_0)
198231
199232
T = 100
200-
x, y = ss.simulate(T)
233+
seed = 1234
234+
x, y = ss.simulate(T, seed)
201235
y = y.flatten()
202236
203237
h_0, u_0 = x[0, 0], x[1, 0]
204238
```
205239

206-
Next, to compute the firm's policy for setting the log wage based on the information it has about the worker,
207-
we use the Kalman filter described in this quantecon lecture {doc}`A First Look at the Kalman filter <kalman>`.
240+
Next, to compute the firm's policy for setting the log wage based on the information it has about the worker, we use the Kalman filter described in this quantecon lecture {doc}`A First Look at the Kalman filter <kalman>`.
208241

209242
In particular, we want to compute all of the objects in an "innovation representation".
210243

211244
## An Innovations Representation
212245

213-
We have all the objects in hand required to form an innovations representation for the output
214-
process $\{y_t\}_{t=0}^T$ for a worker.
246+
We have all the objects in hand required to form an innovations representation for the output process $\{y_t\}_{t=0}^T$ for a worker.
215247

216248
Let's code that up now.
217249

@@ -227,30 +259,30 @@ where $K_t$ is the Kalman gain matrix at time $t$.
227259
We accomplish this in the following code that uses the [`Kalman`](https://quanteconpy.readthedocs.io/en/latest/tools/kalman.html) class.
228260

229261
```{code-cell} ipython3
262+
# TODO check the names of variables
230263
kalman = Kalman(ss, xhat_0, Σ_0)
231-
Σ_t = np.zeros((*Σ_0.shape, T-1))
232-
y_hat_t = np.zeros(T-1)
233-
x_hat_t = np.zeros((2, T-1))
264+
Σ_t = jnp.zeros((*Σ_0.shape, T-1))
265+
y_hat_t = jnp.zeros(T-1)
266+
x_hat_t = jnp.zeros((2, T-1))
234267
235268
for t in range(1, T):
236269
kalman.update(y[t])
237270
x_hat, Σ = kalman.x_hat, kalman.Sigma
238-
Σ_t[:, :, t-1] = Σ
239-
x_hat_t[:, t-1] = x_hat.reshape(-1)
240-
[y_hat_t[t-1]] = worker.G @ x_hat
271+
Σ_t = Σ_t.at[:, :, t-1].set(Σ)
272+
x_hat_t = x_hat_t.at[:, t-1].set(x_hat.reshape(-1))
273+
y_hat_t = y_hat_t.at[t-1].set((worker.G @ x_hat).item())
241274
242-
x_hat_t = np.concatenate((x[:, 1][:, np.newaxis],
243-
x_hat_t), axis=1)
244-
Σ_t = np.concatenate((worker.Σ_0[:, :, np.newaxis],
245-
Σ_t), axis=2)
275+
# Add the initial
276+
x_hat_t = jnp.concatenate((xhat_0, x_hat_t), axis=1)
277+
Σ_t = jnp.concatenate((worker.Σ_0[:, :, np.newaxis], Σ_t), axis=2)
246278
u_hat_t = x_hat_t[1, :]
247279
```
248280

249-
For a draw of $h_0, u_0$, we plot $E y_t = G \hat x_t $ where $\hat x_t = E [x_t | y^{t-1}]$.
281+
For a draw of $h_0, u_0$, we plot $E[y_t] = G \hat x_t $ where $\hat x_t = E [x_t | y^{t-1}]$.
250282

251-
We also plot $E [u_0 | y^{t-1}]$, which is the firm inference about a worker's hard-wired "work ethic" $u_0$, conditioned on information $y^{t-1}$ that it has about him or her coming into period $t$.
283+
We also plot $\hat u_t = E [u_0 | y^{t-1}]$, which is the firm inference about a worker's hard-wired "work ethic" $u_0$, conditioned on information $y^{t-1}$ that it has about him or her coming into period $t$.
252284

253-
We can watch as the firm's inference $E [u_0 | y^{t-1}]$ of the worker's work ethic converges toward the hidden $u_0$, which is not directly observed by the firm.
285+
We can watch as the firm's inference $E [u_0 | y^{t-1}]$ of the worker's work ethic converges toward the hidden $u_0$, which is not directly observed by the firm.
254286

255287
```{code-cell} ipython3
256288
fig, ax = plt.subplots(1, 2)

0 commit comments

Comments
 (0)