@@ -9,9 +9,19 @@ kernelspec:
99 display_name : Python 3 (ipykernel)
1010 language : python
1111 name : python3
12+ translation :
13+ title : 工作搜寻 IX:McCall劳动者的Q学习
14+ headings :
15+ Overview : 概述
16+ Review of McCall Model : McCall 模型回顾
17+ Implied Quality Function $Q$ : 隐含质量函数 $Q$
18+ From Probabilities to Samples : 从概率到样本
19+ Q-Learning : Q-学习
20+ Employed Worker Can't Quit : 禁止在职劳动者辞职的情况
21+ Possible Extensions : 可能的扩展方向
1222---
1323
14- # 工作搜寻 VII :McCall劳动者的Q学习
24+ # 工作搜寻 IX :McCall劳动者的Q学习
1525
1626## 概述
1727
@@ -22,31 +32,37 @@ kernelspec:
2232Q学习算法融合了两个关键思想:
2333
2434* 动态规划的原理
25- * 最小二乘法的递归形式,也称为[ 时序差分学习 (Temporal Difference Learning or TD Learning)] ( https://rl.qiwihui.com/zh-cn/latest/partI/chapter6/temporal_difference_learning.html )
35+ * 最小二乘法的递归形式,也称为[ 时序差分学习 (Temporal Difference Learning or TD Learning)] ( https://en.wikipedia.org/wiki/Temporal_difference_learning )
2636
2737在本讲中,我们将Q学习算法应用到McCall求职模型中,探讨劳动者如何通过这种方法做出最优决策。
2838
29- 我们还将扩展模型,考虑劳动者不仅可以接受或拒绝工作机会,还可以选择辞去当前工作的情况 。
39+ 我们还将扩展模型,考虑劳动者被赋予选择辞去当前工作的情况 。
3040
3141与我们在 {doc}` quantecon 讲座 <mccall_model> ` 中学习的 McCall 劳动者模型的动态规划方法相比,Q-学习算法的一个显著特点是:
3242劳动者不需要完全了解
3343
34- * 工资是如何随机生成的
35- * 接受或拒绝工作机会会带来什么样的奖励
44+ * 生成一系列工资的随机过程
45+ * 说明接受或拒绝工作机会所带来后果的奖励函数
3646
37- Q-学习算法通过统计学习方法来获取这些信息,这通常可以简化为某种形式的最小二乘法 。
47+ Q-学习算法通过统计学习方法来获取这些信息。
3848
39- 在讨论统计学习时,我们需要明确指出学习的目标是什么 。
49+ 统计学习通常可以简化为某种形式的最小二乘法,这里也不例外 。
4050
41- 对于Q-学习来说,学习的对象不是动态规划中常见的价值函数,尽管两者密切相关 。
51+ 每当我们提到 ** 统计学习 ** ,我们就必须说明学习的对象是什么 。
4252
43- 在我们研究的有限状态、有限动作环境中,学习目标是一个称为 ** Q-表 ** (Q-table) 的结构,它是Q-函数 (Q-function) 在有限集合上的具体表现形式 。
53+ 对于Q-学习来说,学习的对象不是动态规划中所关注的 ** 价值函数 ** 。
4454
45- 这些Q-函数(或Q-表)有时也被称为质量函数或质量表 。
55+ 但它是与价值函数密切相关的一个对象 。
4656
47- Q-表的结构很直观:行代表智能体可能处于的各种状态,列代表在每个状态下可以采取的不同行动 。
57+ 在本讲研究的有限动作、有限状态环境中,需要通过统计学习获得的对象是一个称为 ** Q-表 ** (Q-table) 的结构,它是有限集合上 ** Q-函数 ** (Q-function) 的具体表现形式 。
4858
49- 算法的核心是一个类似贝尔曼方程的等式,但它与我们在{doc}` McCall模型讲座<mccall_model> ` 中看到的贝尔曼方程有所不同。
59+ Q-函数(或Q-表)有时也被称为质量函数或质量表。
60+
61+ Q-表的行和列分别对应智能体可能遇到的状态,以及在每个状态下可以采取的行动。
62+
63+ 算法中起重要作用的是一个类似于贝尔曼方程的方程。
64+
65+ 它与我们在{doc}` 这个quantecon讲座<mccall_model> ` 中看到的McCall模型的贝尔曼方程有所不同。
5066
5167在本讲座中,我们将学习一些关于:
5268
@@ -139,8 +155,8 @@ plt.show()
139155mccall_data = [
140156 ('c', float64), # 失业补偿
141157 ('β', float64), # 贴现因子
142- ('w', float64[:]), # 工资值数组, w[i] = 状态i下的工资
143- ('q', float64[:]), # 概率数组
158+ ('w', float64[::1 ]), # array of wage values, w[i] = wage at state i
159+ ('q', float64[::1]) # array of probabilities
144160]
145161
146162
@@ -154,20 +170,20 @@ class McCallModel:
154170
155171 def state_action_values(self, i, v):
156172 """
157- 状态-行动对的值。
173+ The values of state-action pairs.
158174 """
159- # 简化名称
175+ # Simplify names
160176 c, β, w, q = self.c, self.β, self.w, self.q
161- # 评估每个状态-行动对的值
162- # 考虑行动: 接受或拒绝当前offer
177+ # Evaluate value for each state-action pair
178+ # Consider action = accept or reject the current offer
163179 accept = w[i] / (1 - β)
164- reject = c + β * np.sum (v * q)
180+ reject = c + β * (v @ q)
165181
166182 return np.array([accept, reject])
167183
168184 def VFI(self, eps=1e-5, max_iter=500):
169185 """
170- 找到最优价值函数。
186+ Find the optimal value function.
171187 """
172188
173189 n = len(self.w)
@@ -182,16 +198,16 @@ class McCallModel:
182198 if np.max(np.abs(v_next - v))<=eps:
183199 flag=1
184200 break
185- v[:] = v_next
201+ v[:] = v_next # 将内容复制到v中
186202
187203 return v, flag
188204
189205def plot_value_function_seq(mcm, ax, num_plots=8):
190206 """
191- 绘制一系列价值函数。
207+ Plot a sequence of value functions.
192208
193- * mcm: McCallModel的实例
194- * ax: 用于绘图的matplotlib轴对象
209+ * mcm is an instance of McCallModel
210+ * ax is an axes object that implements a plot method.
195211
196212 """
197213
@@ -200,10 +216,10 @@ def plot_value_function_seq(mcm, ax, num_plots=8):
200216 v_next = np.empty_like(v)
201217 for i in range(num_plots):
202218 ax.plot(mcm.w, v, '-', alpha=0.4, label=f"iterate {i}")
203- # 更新猜测值
219+ # Update guess
204220 for i in range(n):
205221 v_next[i] = np.max(mcm.state_action_values(i, v))
206- v[:] = v_next # 将内容复制到v中
222+ v[:] = v_next # copy contents into v
207223
208224 ax.legend(loc='lower right')
209225```
303319 c & +\beta\int\max_{\text{accept, reject}}\left\{ Q(w', \textrm{accept}),Q\left(w',\text{reject}\right)\right\} dF\left(w'\right) - Q\left(w,\text{reject}\right) = 0 \cr
304320\end{aligned}
305321$$ (eq:probtosample1)
322+
306323注意第二行中对$F(w')$的积分。
307324
308325为了开始思考Q-learning,我们可以尝试一个不严谨但有启发性的方法:移除积分符号。
309326
310- 这样,我们可以构建一个差分方程系统,保留{eq}`eq:probtosample1`的第一个方程,但将第二个方程中对 $F(w')$的积分替换为 :
327+ 这样,我们可以构建一个差分方程系统,保留{eq}`eq:probtosample1`的第一个方程,但将第二个方程中去除对 $F(w')$的积分 :
311328
312329$$
313330\begin{aligned}
@@ -320,7 +337,7 @@ $$(eq:probtosample2)
320337
321338但是,也许我们可以借助大数定律,希望它能对一个长时间序列中抽取的$w_t, w_{t+1}$对**平均**成立,这里我们把$w_t$看作$w$,把$w_{t+1}$看作$w'$。
322339
323- Q-learning的基本思想是从$F$中抽取一个长样本序列(虽然我们假设劳动者不知道 $F$,但我们是知道的 )并对递归式进行迭代
340+ Q-learning的基本思想是从$F$中抽取一个长样本序列(虽然我们知道 $F$,但我们假设劳动者不知道 )并对递归式进行迭代,
324341
325342将日期 $t$ 时的 Q 函数估计值 $\hat Q_t$ 映射到日期 $t+1$ 时的改进估计值 $\hat Q_{t+1}$。
326343
@@ -363,9 +380,9 @@ Q-学习通过更新 Q-函数来进行,决策者在模拟生成的工资序列
363380
364381在学习过程中,我们的 McCall 劳动者会采取各种行动,并从这些行动中获得相应的奖励。
365382
366- 在这个过程中,他逐渐学习工资分布这一环境特征,以及与不同决策相关的奖励——包括失业补偿 $c$ 和接受工作后获得的工资现值 。
383+ 他同时了解环境(在此情形下即工资分布)以及奖励函数——在此情形下即失业补偿 $c$ 与工资的现值 。
367384
368- Q学习的核心是一个递归更新过程,其基本形式如下(我们稍后会详细讨论其修改版本 ):
385+ 这一更新算法基于对以下递归式的一个小修改(稍后会加以说明 ):
369386
370387$$
371388\widetilde{Q}^{new}\left(w,a\right)=\widetilde{Q}^{old}\left(w,a\right)+\alpha \widetilde{TD}\left(w,a\right)
380397\end{aligned}
381398$$ (eq:old4)
382399
383- 对于 $a \in \{\textrm{accept}, \textrm{reject}\}$,$\widetilde{TD}(w,a)$ 表示**时序差分误差** (TD error),这是驱动Q值更新的关键因素 。
400+ 对于 $a \in \{\textrm{accept}, \textrm{reject}\}$,$\widetilde{TD}(w,a)$ 表示**时序差分误差** (TD error),这是驱动更新的关键因素 。
384401
385402这个更新机制实际上就是我们在方程 {eq}`eq:old106` 中简要描述的自适应学习系统的具体实现。
386403
387- 然而,方程组 {eq}`eq:old4` 还没有体现算法的一个重要特性:为了促进探索,我们需要通过随机实验来打破纯粹的贪婪策略
388-
389- 我们偶尔将
404+ 方程组 {eq}`eq:old4` 尚未体现出的算法的一个特征是随机**实验**,我们通过偶尔随机地将
390405
391406$$
392407\textrm{argmax}_ {a'\in\mathcal{A}}\widetilde{Q}^{old}\left(w,a'\right)
410425\textrm{argmin}_ {a'\in\mathcal{A}}\widetilde{Q}^{old}\left(w',a'\right)
411426$$
412427
428+ 来添加这一特征。
429+
413430在以下McCall劳动者Q-学习的伪代码的第3步中,我们以概率$\epsilon$激活这种实验:
414431
4154321. 设置一个任意的初始Q表。
420437
421438 - 以概率$1-\epsilon$选择使价值最大化的行动,并且
422439
423- - 以概率 $\epsilon$ 随机选择另一个行动 。
440+ - 以概率 $\epsilon$ 选择另一个行动 。
424441
4254424. 更新与所选行动相关的状态,并根据{eq}`eq:old4`计算 $\widetilde{TD}$,然后根据{eq}`eq:old3`更新 $\widetilde{Q}$。
426443
4274445. 如果需要则抽取新的状态 $w'$,否则采用现有工资,并再次根据{eq}`eq:old3`更新Q表。
428445
429- 6. 当新旧Q表足够接近时停止,即对于给定的 $\delta$,满足 $\lVert\tilde{Q}^{new}-\tilde{Q}^{old}\rVert_{\infty}\leq\delta$,或者当劳动者连续接受 $T$ 期(对于预先规定的 $T$)时停止 。
446+ 6. 当新旧Q表足够接近时停止,即对于给定的 $\delta$,满足 $\lVert\tilde{Q}^{new}-\tilde{Q}^{old}\rVert_{\infty}\leq\delta$,或者当劳动者连续接受达到规定的 $T$ 期时停止 。
430447
4314487. 带着更新后的Q表返回步骤2。
432449
433450重复此程序 $N$ 次回合或直到更新的Q表收敛。
434451
435- 我们将步骤2到7的一次完整过程称为时序差分学习的一个"回合"或"轮次"。
452+ 我们将步骤2到7的一次完整过程称为时序差分学习的一个"回合"或"轮次"(episode或epoch) 。
436453
437454在我们的情境中,每个回合都始于个体抽取一个初始工资报价,即一个新状态。
438455
@@ -442,28 +459,28 @@ Q表通过时序差分学习不断更新。
442459
443460我们重复这个过程直到Q表收敛或达到预设的最大回合数。
444461
445- 多个回合使个体能够从不同起点开始探索,访问那些在单一回合中难以到达的状态 。
462+ 多个回合使个体能够从头开始,并访问那些从上一回合的终止状态出发不太可能访问到的状态 。
446463
447- 例如,如果个体接受了某个工资报价,他就会停留在该就业状态,无法探索其他可能的工资水平 。
464+ 例如,如果个体根据其Q表接受了某个工资报价,他就不太可能再从工资分布的其他部分抽取新的报价 。
448465
449466通过使用$\epsilon$-贪婪策略并增加回合数,Q学习算法在探索新可能性和利用已知信息之间取得平衡。
450467
451- **注意:** 在{eq}`eq:old3`中定义的最优Q表对应的 $\widetilde{TD}$值在所有状态-动作对上都等于零 。我们的Q-learning算法是否能收敛到最优Q表,取决于算法是否能充分探索所有可能的状态 -动作组合。
468+ **注意:** 在{eq}`eq:old3`中自动定义的最优Q表所对应的 $\widetilde{TD}$,对所有状态-动作对都满足$\widetilde{TD}=0$ 。我们的Q-learning算法能否收敛到最优Q表,取决于算法是否足够频繁地访问所有状态 -动作组合。
452469
453470下面我们将这个算法实现为Python类。
454471
455472为了简化,我们用`s`表示介于$0$和$n=50$之间的状态索引,其中$w_s=w[s]$表示对应的工资值。
456473
457- Q表的结构很直观:第一列表示拒绝工资的价值,第二列表示接受工资的价值 。
474+ Q表的第一列表示拒绝工资所对应的价值,第二列表示接受工资所对应的价值 。
458475
459476我们使用`numba`编译来提高计算效率。
460477
461478```{code-cell} ipython3
462479params=[
463480 ('c', float64), # 失业补偿
464481 ('β', float64), # 折现因子
465- ('w', float64[:]), # 工资值数组,w[i] = 状态i的工资
466- ('q', float64[:]), # 概率数组
482+ ('w', float64[:]), # 工资值数组,w[i] = 状态i下的工资
483+ ('q', float64[:]), # 概率数组
467484 ('eps', float64), # epsilon贪婪算法参数
468485 ('δ', float64), # Q表阈值
469486 ('lr', float64), # 学习率α
@@ -612,15 +629,15 @@ w_min, w_max = 10, 60
612629w_new = np.linspace(w_min, w_max, n+1)
613630
614631
615- # 绘制工资报价分布
632+ # plot distribution of wage offer
616633fig, ax = plt.subplots(figsize=(10,6))
617634ax.plot(w_new, q_new, '-o', label='$q(w(i))$')
618635ax.set_xlabel('工资')
619636ax.set_ylabel('概率')
620637
621638plt.show()
622639
623- # 值函数迭代
640+ # VFI
624641mcm = McCallModel(w=w_new, q=q_new)
625642valfunc_VFI, flag = mcm.VFI()
626643```
@@ -666,23 +683,25 @@ def plot_epochs(epochs_to_plot, quit_allowed=1):
666683plot_epochs(epochs_to_plot=[100, 1000, 10000, 100000, 200000])
667684```
668685
669- 从上述图表中,我们可以观察到两个重要现象:
686+ 上述图表表明
670687
671- * Q-learning算法在学习较少出现的工资水平时表现不佳,这反映了算法对样本频率的依赖性
688+ * Q-learning算法在学习那些很少被抽到的工资的Q表时存在困难
672689
673- * 随着训练轮数增加,算法逐渐接近通过值函数迭代得到的 "真实"值函数,表明学习质量随时间提高
690+ * 通过价值函数迭代计算出的 "真实"价值函数,其近似质量会随着训练轮数增加而提升
674691
675692## 禁止在职劳动者辞职的情况
676693
677- 我们之前讨论的时序差分Q-learning版本(见方程{eq}`eq:old4`)允许已就业的劳动者辞去当前工作,从而在当期获得失业补助,并在下期有机会获得新的工作offer。
694+ 前面在方程组 {eq}`eq:old4` 中描述的时序差分Q学习版本允许已就业的劳动者辞职,即作为在职者拒绝其工资,从而在本期获得失业补助,并在下一期抽取一个新的工作机会。
695+
696+ 这是{doc}`这个quantecon讲座 <mccall_model>`中描述的McCall劳动者不会采用的一个选项。
678697
679- 这一选项在{doc}`标准McCall模型<mccall_model>`中并不存在,正如 {cite}`Ljungqvist2012`第6章中关于工作搜寻的分析所证明的那样 。
698+ 有关证明,请参见 {cite}`Ljungqvist2012`第6章关于工作搜寻的内容 。
680699
681- 然而,从学习算法的角度看,允许辞职选项实际上有助于加速学习过程。这是因为辞职选项促进了状态空间的探索,避免了过早地固定在某一决策上(即过早利用而非探索) 。
700+ 但在Q-learning的背景下,赋予劳动者在失业时选择辞职并领取失业补助的选项,结果证明能够加速学习过程,因为这促进了实验探索,而不是仅仅过早地利用已有信息 。
682701
683- 为了展示不允许辞职的情况,我们需要修改策略公式,限制已就业劳动者必须保持其当前工作 。
702+ 为了说明这一点,我们将修改时序差分的公式,以禁止已就业的劳动者辞去她之前已经接受的工作 。
684703
685- 基于这种限制,我们可以得到以下修改后的策略值 :
704+ 在这种可选行动的理解下,我们得到以下时序差分值 :
686705
687706$$
688707\begin{aligned}
691710\end{aligned}
692711$$ (eq:temp-diff)
693712
694- 实际上,当我们将公式 {eq}`eq:temp-diff`与Q学习递归 {eq}`eq:old3`结合使用时,智能体仍然能够最终学习到最优值函数,就像在允许辞职的情况下一样 。
713+ 事实证明,公式 {eq}`eq:temp-diff`与我们的Q学习递归 {eq}`eq:old3`相结合,也能使我们的智能体最终学习到最优价值函数,效果与可以行使重新抽取选项的情形一样好 。
695714
696- 然而,这种学习过程会变得更加缓慢。这是因为一旦个体接受了工资报价,他就失去了在当前回合中继续探索其他状态和更新相应价值估计的机会 。
715+ 但学习速度会更慢,因为一个过早接受工资报价的智能体,会在同一回合中失去探索新状态并调整该状态所关联价值的机会 。
697716
698- 在训练初期阶段(即训练轮数较少时),这种限制往往会导致次优的学习结果 。
717+ 当训练轮数/回合数较少时,这可能导致较差的结果 。
699718
700- 不过,随着我们增加训练轮数,学习误差会逐渐减小,最终结果会越来越接近最优解 。
719+ 但如果我们增加训练轮数/回合数,就可以观察到误差减小,结果也随之改善 。
701720
702- 下面的代码和图表将直观地展示这一学习过程 。
721+ 我们用以下代码和图表来说明这些情形 。
703722
704723```{code-cell} ipython3
705724plot_epochs(epochs_to_plot=[100, 1000, 10000, 100000, 200000], quit_allowed=0)
706725```
707726
708- ## 进一步的研究方向
709-
710- 当我们需要处理连续状态空间的问题时,Q学习算法需要进行适当的扩展。一种常见的方法是采用特定函数形式来近似Q函数和策略函数。
727+ ## 可能的扩展方向
711728
712- 这种思路发展出了**深度Q学习**(Deep Q-Learning)方法,它利用多层神经网络的强大表达能力来逼近复杂的Q函数。神经网络作为通用函数逼近器,能够有效捕捉连续状态空间中的价值信息 。
729+ 要将该算法扩展到处理连续状态空间的问题,一种典型方法是将Q函数和策略函数限制为特定的函数形式 。
713730
714- 在后续的quantecon课程中,我们将深入探讨深度Q学习及其在更复杂经济模型中的应用 。
731+ 这就是**深度Q学习**(deep Q-learning)所采用的方法,其思路是使用多层神经网络作为良好的函数逼近器 。
715732
733+ 我们将在后续的quantecon讲座中讨论这一主题。
0 commit comments