网站开发合同付款方式,宜春seo网站推广,个人网站流程,域名购买之后怎么做网站文中内容仅限技术学习与代码实践参考#xff0c;市场存在不确定性#xff0c;技术分析需谨慎验证#xff0c;不构成任何投资建议。 准蒙特卡洛方法
在讨论准蒙特卡洛#xff08;Quasi-Monte Carlo#xff0c;QMC#xff09;之前#xff0c;先简要介绍蒙特卡洛#xff… 文中内容仅限技术学习与代码实践参考市场存在不确定性技术分析需谨慎验证不构成任何投资建议。 准蒙特卡洛方法
在讨论准蒙特卡洛Quasi-Monte CarloQMC之前先简要介绍蒙特卡洛Monte CarloMC方法。蒙特卡洛方法或称蒙特卡洛实验是一类依赖于重复随机抽样以获得数值结果的计算算法。其核心思想是利用随机性来解决本质上可能是确定性的问题。这些方法通常用于物理和数学问题尤其在难以或无法使用其他方法时最为有用。蒙特卡洛方法主要用于以下三类问题优化、数值积分以及从概率分布中生成样本。
生成具有特定属性的随机数比听起来要复杂得多。简单的蒙特卡洛方法旨在生成独立同分布IID的样本点。但生成多组随机点可能会产生截然不同的结果。 在上述图中两种情况下点都是随机生成的且不考虑之前已抽取的点。显然空间的某些区域未被探索到——这在模拟中可能会引发问题因为特定的一组点可能会导致完全不同的行为。
蒙特卡洛方法的一大优势在于其具有已知的收敛特性。让我们来看一个五维空间中的平方和的均值问题 f ( x ) ( ∑ j 1 5 x j ) 2 , f(\mathbf{x}) \left( \sum_{j1}^{5}x_j \right)^2, f(x)(j1∑5xj)2,
其中 x j ∼ U ( 0 , 1 ) x_j \sim \mathcal{U}(0,1) xj∼U(0,1)。该函数的均值是已知的为 μ 5 3 5 ( 5 − 1 ) 4 \mu \frac{5}{3} \frac{5(5-1)}{4} μ3545(5−1)。通过蒙特卡洛抽样我们可以数值计算该均值其近似误差的理论收敛率为 O ( n − 1 / 2 ) O(n^{-1/2}) O(n−1/2)。 尽管收敛性得到了保证但实践者通常希望有一个更具确定性的探索过程。在普通的蒙特卡洛方法中可以通过设置种子来实现可重复的过程。但固定种子会破坏收敛特性某个种子可能适用于某一类问题但对于另一类问题则可能失效。
为了以一种确定性的方式遍历空间通常会使用覆盖所有参数维度的规则网格也称为饱和设计。让我们考虑单位超立方体其所有边界范围均为 0 到 1。现在如果点之间的距离为 0.1则填充单位区间的所需点数为 10。在二维超立方体中相同的间距需要 100 个点而在三维中则需要 1000 个点。随着维度的增加填充空间所需的实验次数呈指数增长这种现象被称为“维度的诅咒”。 import numpy as npdisc 10x1 np.linspace(0, 1, disc)x2 np.linspace(0, 1, disc)x3 np.linspace(0, 1, disc)x1, x2, x3 np.meshgrid(x1, x2, x3)为了缓解这一问题设计了准蒙特卡洛QMC方法。这些方法是确定性的能够很好地覆盖空间并且其中一些方法可以继续使用并保持良好的特性。与蒙特卡洛方法的主要区别在于QMC 方法生成的点并非独立同分布而是知道之前的点。因此某些方法也被称为序列。 上图展示了两组各包含 256 个点的样本。左侧是普通蒙特卡洛设计而右侧是使用 Sobol’ 方法的 QMC 设计。我们可以清楚地看到QMC 版本更加均匀。点在边界附近采样得更好且几乎没有聚类或间隙。
评估均匀性的一种方法是使用一种称为“离散度”的度量。在这里Sobol’ 点的离散度优于普通蒙特卡洛。
回到均值计算的问题QMC 方法的误差收敛率也更好。对于此类函数它们可以达到 O ( n − 1 ) O(n^{-1}) O(n−1) 的收敛率对于非常光滑的函数收敛率甚至更好。下图显示了 Sobol’ 方法的收敛率为 O ( n − 1 ) O(n^{-1}) O(n−1) 更多数学细节可参考 scipy.stats.qmc 的文档。
计算离散度
让我们考虑两组点。从下图可以看出左侧的设计比右侧的设计覆盖了更多的空间。这可以通过 scipy.stats.qmc.discrepancy 度量来量化。离散度越低样本越均匀。 import numpy as npfrom scipy.stats import qmcspace_1 np.array([[1, 3], [2, 6], [3, 2], [4, 5], [5, 1], [6, 4]])space_2 np.array([[1, 5], [2, 4], [3, 3], [4, 2], [5, 1], [6, 6]])l_bounds [0.5, 0.5]u_bounds [6.5, 6.5]space_1 qmc.scale(space_1, l_bounds, u_bounds, reverseTrue)space_2 qmc.scale(space_2, l_bounds, u_bounds, reverseTrue)qmc.discrepancy(space_1)
0.008142039609053464qmc.discrepancy(space_2)
0.010456854423869011使用 QMC 引擎
这里我们来看两种最常用的 QMC 方法scipy.stats.qmc.Sobol 和 scipy.stats.qmc.Halton 序列。
Sobol 和 Halton 序列。
from scipy.stats import qmc
import numpy as npimport matplotlib.pyplot as pltrng np.random.default_rng()n_sample 256
dim 2sample {}# Sobol
engine qmc.Sobol(ddim, seedrng)
sample[Sobol] engine.random(n_sample)# Halton
engine qmc.Halton(ddim, seedrng)
sample[Halton] engine.random(n_sample)fig, axs plt.subplots(1, 2, figsize(8, 4))for i, kind in enumerate(sample):axs[i].scatter(sample[kind][:, 0], sample[kind][:, 1])axs[i].set_aspect(equal)axs[i].set_xlabel(r$x_1$)axs[i].set_ylabel(r$x_2$)axs[i].set_title(f{kind}—$C^2 ${qmc.discrepancy(sample[kind]):.2})plt.tight_layout()
plt.show()警告
QMC 方法需要特别注意用户必须阅读文档以避免常见陷阱。例如Sobol’ 方法要求点的数量必须是 2 的幂。此外稀疏化、燃烧或其他点的选择方式可能会破坏序列的特性从而导致生成的点集并不比蒙特卡洛方法更好。
QMC 引擎是状态感知的。这意味着你可以继续生成序列跳过某些点或者重置它。让我们从 scipy.stats.qmc.Halton 中取出 5 个点。然后再次请求一组 5 个点 from scipy.stats import qmcengine qmc.Halton(d2)engine.random(5)
array([[0.22166437, 0.07980522], # random[0.72166437, 0.93165708],[0.47166437, 0.41313856],[0.97166437, 0.19091633],[0.01853937, 0.74647189]])engine.random(5)
array([[0.51853937, 0.52424967], # random[0.26853937, 0.30202745],[0.76853937, 0.857583 ],[0.14353937, 0.63536078],[0.64353937, 0.01807683]])现在我们重置序列。再次请求 5 个点将得到相同的前 5 个点 engine.reset()engine.random(5)
array([[0.22166437, 0.07980522], # random[0.72166437, 0.93165708],[0.47166437, 0.41313856],[0.97166437, 0.19091633],[0.01853937, 0.74647189]])这里我们通过快速前进序列来获取相同的第二组 5 个点 engine.reset()engine.fast_forward(5)engine.random(5)
array([[0.51853937, 0.52424967], # random[0.26853937, 0.30202745],[0.76853937, 0.857583 ],[0.14353937, 0.63536078],[0.64353937, 0.01807683]])注意
默认情况下scipy.stats.qmc.Sobol 和 scipy.stats.qmc.Halton 均为随机化的。随机化版本的收敛特性更好并且可以防止在高维中出现条纹或明显的点模式。实际上没有理由不使用随机化版本。
创建 QMC 引擎即继承 QMCEngine
要创建自己的 scipy.stats.qmc.QMCEngine需要定义一些方法。以下是一个基于 numpy.random.Generator 的示例 import numpy as npfrom scipy.stats import qmcclass RandomEngine(qmc.QMCEngine):
... def __init__(self, d, seedNone):
... super().__init__(dd, seedseed)
... self.rng np.random.default_rng(self.rng_seed)
...
...
... def _random(self, n1, *, workers1):
... return self.rng.random((n, self.d))
...
...
... def reset(self):
... self.rng np.random.default_rng(self.rng_seed)
... self.num_generated 0
... return self
...
...
... def fast_forward(self, n):
... self.random(n)
... return self然后像使用其他 QMC 引擎一样使用它 engine RandomEngine(2)engine.random(5)
array([[0.22733602, 0.31675834], # random[0.79736546, 0.67625467],[0.39110955, 0.33281393],[0.59830875, 0.18673419],[0.67275604, 0.94180287]])engine.reset()engine.random(5)
array([[0.22733602, 0.31675834], # random[0.79736546, 0.67625467],[0.39110955, 0.33281393],[0.59830875, 0.18673419],[0.67275604, 0.94180287]])使用 QMC 的指南 QMC 有规则务必阅读文档否则你可能无法获得比蒙特卡洛方法更好的效果。 如果需要 恰好 2 m 2^m 2m 个点请使用 scipy.stats.qmc.Sobol。 scipy.stats.qmc.Halton 允许采样或跳过任意数量的点但代价是收敛速度比 Sobol’ 更慢。 永远不要删除序列的前几个点。这会破坏其特性。 总是使用随机化版本。 如果使用基于拉丁超立方采样的方法则无法在不失去拉丁超立方特性的情况下添加点。有一些方法可以做到但尚未实现。 风险提示与免责声明 本文内容基于公开信息研究整理不构成任何形式的投资建议。历史表现不应作为未来收益保证市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险投资须谨慎。