Skip to content

[mccall_model] Translation update #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lectures/career.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ kernelspec:
</div>
```

# 职业搜索 V:职业选择建模
# 工作搜寻 V:职业选择建模

```{index} single: Modeling; Career Choice
```
Expand Down
2 changes: 1 addition & 1 deletion lectures/jv.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ kernelspec:
</div>
```

# {index}`在职搜索 VI:在职搜索 <single: Job Search VI: On-the-Job Search>`
# {index}`工作搜寻 VI:在职搜索 <single: Job Search VI: On-the-Job Search>`

```{index} single: Models; On-the-Job Search
```
Expand Down
2 changes: 1 addition & 1 deletion lectures/mccall_fitted_vfi.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ kernelspec:
</div>
```

# 求职搜索 III: 拟合值函数迭代
# 工作搜寻 III: 拟合值函数迭代

```{contents} 目录
:depth: 2
Expand Down
107 changes: 49 additions & 58 deletions lectures/mccall_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ kernelspec:
```

```{epigraph}
"询问一个McCall工人就像与一个失业的朋友对话:
'也许你的期望值定得太高了',或者'为什么你在找到新工作之前就辞掉了原来的工作?'这就是真正的社会科学:试图通过观察人们所处的情况、他们面临的选择来建模,以理解人类行为

"以及他们自己所认为的优缺点。" -- 罗伯特·卢卡斯(小)
"询问一个McCall工人就像与一个失业的朋友对话:'也许你的期望值定得太高了',或者'为什么你在找到新工作之前就辞掉了原来的工作?'这就是真正的社会科学:试图通过观察人们所处的情况、他们面临的选择、以及他们自己所认为的优缺点来建模,以理解人类行为。" -- 小罗伯特·卢卡斯
```

除了Anaconda中已有的内容外,本讲座还需要以下库:
Expand All @@ -46,15 +43,15 @@ McCall 搜索模型 {cite}`McCall1970` 帮助改变了经济学家思考劳动

为了阐明"非自愿"失业等概念,McCall 从以下因素建模了失业工人的决策问题:

* 当前和可能的未来工资
* 不耐心程度
* 当前工资和可能的未来工资
* 耐心程度
* 失业补助

为了解决这个决策问题,McCall 使用了动态规划。

在这里,我们将建立 McCall 的模型并使用动态规划来分析它。
在本讲中,我们将建立 McCall 的模型并使用动态规划来分析它。

我们将看到,McCall 的模型不仅本身很有趣,而且也是学习动态规划的绝佳载体
我们将看到,McCall 的模型不仅本身很有趣,而且是学习动态规划的绝佳载体

让我们从一些导入开始:

Expand All @@ -65,7 +62,7 @@ FONTPATH = "fonts/SourceHanSerifSC-SemiBold.otf"
mpl.font_manager.fontManager.addfont(FONTPATH)
plt.rcParams['font.family'] = ['Source Han Serif SC']

plt.rcParams["figure.figsize"] = (11, 5) #set default figure size
plt.rcParams["figure.figsize"] = (11, 5) #设置默认图片尺寸
import numpy as np
from numba import jit, float64
from numba.experimental import jitclass
Expand All @@ -78,35 +75,35 @@ from quantecon.distributions import BetaBinomial
```{index} single: Models; McCall
```

一个失业者在每个时期都会收到工资为$w_t$的工作机会。
一个失业者在每个时期都会收到一个工资为$w_t$的工作机会。

在本讲中,我们采用以下简单环境:

* 工资序列$\{w_t\}_{t \geq 0}$是独立同分布的,其中$q(w)$是在有限集合$\mathbb{W}$中观察到工资$w$的概率。
* 代理人在$t$期开始时观察到$w_t$。
* 代理人知道$\{w_t\}$是具有共同分布$q$的独立同分布序列,并可以利用这一点计算期望值。
* 失业者在$t$期的开始观察到$w_t$。
* 失业者知道$\{w_t\}$是具有共同分布$q$的独立同分布序列,并可以利用这一点计算期望值。

(在后续讲座中,我们将放宽这些假设。)

在时间$t$,我们的代理人有两个选择
在时间$t$,失业者有两个选择

1. 接受工作机会并以固定工资$w_t$永久工作。
1. 接受工作机会,并以固定工资$w_t$永久工作。
1. 拒绝工作机会,获得失业补助$c$,并在下一期重新考虑。

代理人具有无限生命,目标是最大化预期的折现收益总和
假设失业者具有无限长的生命,其目标是最大化折现收益总和的期望值

$$
\mathbb{E} \sum_{t=0}^{\infty} \beta^t y_t
$$

常数$\beta$位于$(0, 1)$之间,被称为**折现因子**。

$\beta$ 越小,代理人对未来效用的折现程度相对于当前效用就越高
$\beta$ 越小,未来效用的折现值越高

变量 $y_t$ 是收入,等于
变量 $y_t$ 是收入,

* 就业时的工资 $w_t$
* 失业时的失业补助金 $c$
* 当就业时,它等于工资 $w_t$
* 当失业时,它等于失业补助金 $c$


### 权衡取舍
Expand Down Expand Up @@ -136,15 +133,15 @@ $\beta$ 越小,代理人对未来效用的折现程度相对于当前效用就

为此,让$v^*(w)$表示当工资为$w \in \mathbb{W}$时,一个失业工人在当前时期开始时的总生命周期*价值*。

具体来说,该个体手头有工资offer $w$。
具体来说,我们考虑这样一种情况:一个失业者现在面临一个工资为 $w$ 的工作机会

更准确地说,$v^*(w)$表示当处于这种情况下的个体在当前和未来所有时间点做出*最优*决策时,目标函数{eq}`objective`的价值。
那么,$v^*(w)$表示的是该失业者在当前和未来所有时间点做出*最优*决策时,目标函数{eq}`objective`的价值。

当然,计算$v^*(w)$并不简单,因为我们还不知道哪些决策是最优的,哪些不是!

但是可以将$v^*$看作一个函数,它为每个可能的工资$s$分配在手头有该offer时可获得的最大生命周期价值
但是可以将$v^*$看作一个函数,它为每个可能的工资$w$分配在持有该工作机会时可获得的最大终身价值

一个关键的观察是,这个函数$v^*$必须满足以下递归关系
一个关键点是,这个函数$v^*$必须满足以下递归关系: 对于 $\mathbb{W}$ 中的每一个可能的 $w$,我们有

```{math}
:label: odu_pv
Expand All @@ -156,33 +153,29 @@ v^*(w)
\right\}
```

对于 $\mathbb{W}$ 中的每一个可能的 $w$。

这个重要的方程是**贝尔曼方程**的一个版本,这个方程在经济动态学和其他涉及长期规划的领域中无处不在。

其背后的直观理解如下:

* max运算中的第一项是接受当前报价的终身收益,因为
* max运算中的第一项是接受当前工作机会的终身收益,因为

$$
\frac{w}{1 - \beta} = w + \beta w + \beta^2 w + \cdots
$$

* max运算中的第二项是**延续价值**,即拒绝当前报价并在随后所有时期做出最优行为的终身收益
* max运算中的第二项是**延续值**,即拒绝当前工作机会并在随后所有时期做出最优行为的终身收益。

如果我们优化并从这两个选项中选择最佳选项,我们就能获得当前报价 $w$ 下的最大终身价值。
通过从这两个选项中选择最优的一个,我们就能得到在当前工资报价 $w$ 下的最大终身价值。

但这恰恰就是 {eq}`odu_pv` 左边的 $v^*(w)$。
而这恰恰就是 {eq}`odu_pv` 左边的 $v^*(w)$。

### 最优策略

假设现在我们能够求解 {eq}`odu_pv` 得到未知函数 $v^*$。

一旦我们掌握了这个函数,我们就可以做出最优行为(即做出
一旦我们掌握了这个函数,我们就可以做出最优行为(即在接受和拒绝之间做出正确选择)。

在右侧选择最大值(在接受和拒绝之间)。

我们只需要在{eq}`odu_pv`右侧选择最大值即可。
我们只需要在{eq}`odu_pv`的右侧选择最大值即可。

最优行动最好被理解为一个**策略**,它通常是一个从状态到行动的映射。

Expand Down Expand Up @@ -218,7 +211,7 @@ $$

这里的 $\bar w$(称为*保留工资*)是一个取决于 $\beta, c$ 和工资分布的常数。

代理应当当且仅当当前工资报价超过保留工资时接受
失业者当且仅当当前工作机会的工资超过保留工资时接受该工作

根据{eq}`reswage`,如果我们能计算出价值函数,就能计算出这个保留工资。

Expand Down Expand Up @@ -270,7 +263,7 @@ v'(i)
v(j) q (j)
\right\}
\quad
\text{for } i = 1, \ldots, n
\text{对于 } i = 1, \ldots, n
```

第3步:计算 $v$ 和 $v'$ 之间的差异度量,例如 $\max_i |v(i)- v'(i)|$。
Expand All @@ -279,13 +272,13 @@ v'(i)

第5步:返回 $v$。

对于较小的容差,返回的函数 $v$ 是值函数 $v^*$ 的近似值。
对于较小的容差,返回的函数 $v$ 是价值函数 $v^*$ 的近似值。

下面的理论将详细说明这一点。

### 不动点理论

这些想法背后的数学原理是什么
这个算法背后的数学原理是什么

首先,通过以下方式定义从 $\mathbb R^n$ 到自身的映射 $T$:

Expand All @@ -308,19 +301,19 @@ v'(i)

* 这是从初始猜测 $v$ 开始,应用 $k$ 次 $T$ 的结果

可以证明,$T$ 在 $\mathbb R^n$ 上满足[巴拿赫不动点定理](https://en.wikipedia.org/wiki/Banach_fixed-point_theorem)的条件。
可以证明,$T$ 在 $\mathbb R^n$ 上满足[巴拿赫不动点定理](https://baike.baidu.com/item/%E5%B7%B4%E6%8B%BF%E8%B5%AB%E4%B8%8D%E5%8A%A8%E7%82%B9%E5%AE%9A%E7%90%86/9492042)的条件。

其中一个推论是 $T$ 在 $\mathbb R^n$ 中有唯一的不动点。
一个推论是 $T$ 在 $\mathbb R^n$ 中有唯一的不动点。

* 即存在唯一的向量 $\bar v$ 使得 $T \bar v = \bar v$。

此外,从 $T$ 的定义可以直接得出这个不动点就是 $v^*$。
而且,从 $T$ 的定义可以直接得出这个不动点就是 $v^*$。

巴拿赫收缩映射定理的第二个推论是,无论 $v$ 取何值,序列 $\{ T^k v \}$ 都会收敛到不动点 $v^*$。

### 实现

对于状态过程的分布 $q$,我们的默认选择是[Beta-二项分布](https://en.wikipedia.org/wiki/Beta-binomial_distribution)。
对于状态过程的分布 $q$,我们的默认选择是[Beta-二项分布](https://docs.scipy.org.cn/doc/scipy/tutorial/stats/discrete_betabinom.html)。

```{code-cell} ipython3
n, a, b = 50, 200, 100 # 默认参数
Expand All @@ -347,7 +340,7 @@ plt.show()

我们将使用Numba来加速我们的代码。

* 特别参见[我们关于Numba的讲座](https://python-programming.quantecon.org/numba.html)中对`@jitclass`的讨论。
* 参见[我们关于Numba的讲座](https://python-programming.quantecon.org/numba.html)中对`@jitclass`的讨论。

以下内容通过提供一些类型来帮助Numba

Expand All @@ -360,9 +353,7 @@ mccall_data = [
]
```

这是一个用于存储数据并计算状态-动作对值的类,
即计算贝尔曼方程 {eq}`odu_pv2p` 右侧最大括号中的值,
基于当前状态和任意可行动作。
这是一个用于存储数据并计算状态-行动对的值的类,即基于当前状态和任意可行的行动,计算贝尔曼方程 {eq}`odu_pv2p` 右侧最大值括号中的值。

类中包含了默认参数值。

Expand All @@ -381,8 +372,8 @@ class McCallModel:
"""
# 简化名称
c, β, w, q = self.c, self.β, self.w, self.q
# 评估每个状态-动作对的值
# 考虑动作 = 接受或拒绝当前报价
# 评估每个状态-行动对的值
# 考虑行动 = 接受或拒绝当前报价
accept = w[i] / (1 - β)
reject = c + β * np.sum(v * q)

Expand Down Expand Up @@ -430,7 +421,7 @@ plot_value_function_seq(mcm, ax)
plt.show()
```

你可以看到收敛正在发生:连续的迭代值越来越接近。
你可以看到收敛的发生:连续的迭代值越来越接近。

这里有一个更严谨的迭代计算极限的方法,它会持续计算直到连续迭代之间的测量偏差小于容差值。

Expand Down Expand Up @@ -469,7 +460,7 @@ def compute_reservation_wage(mcm,
return (1 - β) * (c + β * np.sum(v * q))
```

下一行计算在默认参数下的保留工资
现在我们计算在默认参数下的保留工资

```{code-cell} ipython3
compute_reservation_wage(mcm)
Expand Down Expand Up @@ -522,7 +513,7 @@ plt.show()

但对于我们的McCall搜索模型来说,还有一个更简单的方法,可以避免计算价值函数。

让 $h$ 表示继续值
让 $h$ 表示延续值

```{math}
:label: j1
Expand Down Expand Up @@ -581,7 +572,7 @@ h'

我们可以再次使用巴拿赫不动点定理来证明这个过程总是收敛的。

这里的一个重大区别是,我们是在对一个标量 $h$ 进行迭代,而不是对一个 $n$ 维向量 $v(i), i = 1, \ldots, n$ 进行迭代。
与之前的方法相比,这里有一个重要区别:我们现在是对单个标量 $h$ 进行迭代,而不是像之前那样对 $n$ 维向量 $v(i), i = 1, \ldots, n$ 进行迭代,这使得计算过程更加简单

以下是实现代码:

Expand Down Expand Up @@ -614,7 +605,7 @@ def compute_reservation_wage_two(mcm,
return (1 - β) * h
```

你可以使用以下代码来解决下面的练习
你可以使用以上代码来完成下面的练习

## 练习

Expand All @@ -625,7 +616,7 @@ def compute_reservation_wage_two(mcm,

> `c_vals = np.linspace(10, 40, 25)`

也就是说,让代理人从失业状态开始,根据给定参数计算其保留工资,然后模拟看需要多长时间才能接受工作。
也就是说,让失业者从失业状态开始,根据给定参数计算其保留工资,然后模拟看需要多长时间才能接受工作。

重复多次并取平均值。

Expand All @@ -636,7 +627,7 @@ def compute_reservation_wage_two(mcm,
:class: dropdown
```

这是一个解决方案
参考答案

```{code-cell} ipython3
cdf = np.cumsum(q_default)
Expand Down Expand Up @@ -689,7 +680,7 @@ plt.show()

本练习的目的是展示如何将上文使用的离散工资分布替换为连续分布。

这是一个重要的主题,因为许多常用的分布都是连续的(即具有密度函数)。
这是一个重要内容,因为许多常用的分布都是连续的(即具有密度函数)。

幸运的是,在我们的简单模型中理论变化很小。

Expand Down Expand Up @@ -742,7 +733,7 @@ h
:class: dropdown
```

这是一个解决方案
参考答案

```{code-cell} ipython3
mccall_data_continuous = [
Expand Down Expand Up @@ -771,7 +762,7 @@ def compute_reservation_wage_continuous(mcmc, max_iter=500, tol=1e-5):

c, β, σ, μ, w_draws = mcmc.c, mcmc.β, mcmc.σ, mcmc.μ, mcmc.w_draws

h = np.mean(w_draws) / (1 - β) # 初始猜测
h = np.mean(w_draws) / (1 - β) # 初始值猜测
i = 0
error = tol + 1
while i < max_iter and error > tol:
Expand All @@ -791,7 +782,7 @@ def compute_reservation_wage_continuous(mcmc, max_iter=500, tol=1e-5):

现在我们研究保留工资如何随着 $c$ 和 $\beta$ 变化。

我们将使用等高线图来进行这项研究
我们将使用等值线图来分析这个问题

```{code-cell} ipython3
grid_size = 25
Expand Down
2 changes: 1 addition & 1 deletion lectures/mccall_q.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ kernelspec:
name: python3
---

# 求职搜索 VII:McCall工人的Q学习
# 工作搜寻 VII:McCall工人的Q学习

## 概述

Expand Down
Loading