PyMC3 API 解读(一)—— find_MAP() 函数

特此声明:本博文为我的另一片博文 PyMC3 概率编程入门 的从博文,之前属于其中的一部分内容,但是因为该篇主博文内容较多,整体比较繁杂,阅读体验感较差,并且今后对该主博文会做更新,将其作为学习笔记。因此出于学习目的,我决定将主博文定位为入门 PyMC3 概率编程的学习脉络与框架部分,而将其中的细节于诸多从博文中展示,这样既符合模块化思维,又提升主博文的阅读体验,以防自己和观看的同学们在繁杂的内容中找不到重点。因为该篇博文是从博文,所以会和主博文有一定的联系,不过我会尽量将知识点独立地剥离出来,如果大家有什么不清楚的地方,请在评论区提出,我会尽快修改,有兴趣的同学可以移步至主博文阅读一下。

find_MAP() 函数

通过本篇博文我们来了解一下 find_MAP() 函数,这个函数的参数比较多,接下来对这些参数一个一个来解释,帮助大家弄清楚它们分别代表什么意思:

find_MAP(start=None, vars=None, method="L-BFGS-B", return_raw=False, include_transformed=True,
			progressbar=True, maxeval=5000, model=None, *args, **kwargs)
  • startdict 类型,表示开始进行数值优化的初始值的字典,默认是模型自带的测试点,一般以 start={'theta':10} 的形式进行传参的话,这就表示数值优化时参数 theta 从 10 开始迭代优化;

  • varslist 类型,表示需要优化的变量的列表,默认是认定模型内所有的连续型变量都要优化,比如说如果变量 theta 需要进行优化,那我们就通过 vars=[theta] 的方式进行传参;

  • methodstring 类型,表示进行数值优化时用到的优化算法,默认是 L-BFGS-B 算法,当然也可以使用其他算法像 BFGS、POWELL 等,比如说变量是离散类型的时候使用 POWELL 算法效果会更好,不过这里的这些算法实现时都是调用 scipy.optimize 的函数,因此也可以通过 fmin=scipy.optimize.fmin_l_bfgs_b 这样的形式来告诉模型要用的优化算法,但是这种形式不推荐用了,因为在以后的版本不会再用 fmin 这个参数了,所以推荐使用 method 参数;

  • return_rawbool 类型,表示是否返回所有的输出值,默认为 False,刚刚也讲了算法实现时都是调用 scipy.optimize 的函数,而这些函数的输出内容一般比较多,因此选择 False 可以帮助我们筛选掉一部分输出;

  • include_transformedbool 类型,表示是否输出除原始变量外自动转换的变量,默认为 True,这个参数我之前也没搞太懂,当时我发现,当它设为 False 时,输出确实只有一开始定义的变量了,比如说当它为 True 时,输出为 {'theta_log__':array(……),'theta':array(……)},而当它为 False 时输出为 {'theta':array(……)},后来询问了老师之后知道,这个参数是指是否在输出中包含代数变换后的变量,如果我们的变量 theta 服从逆伽马分布,属于有界变量,则 PyMC3 会自动对其进行代数变换生成一个 FreeRV —— theta_log__,当 include_transformed 参数为 True 时,就意味着打印 theta_log__,输出为 {'theta_log__':array(……),'theta':array(……)},如果看到这里对该参数还是有一些不理解,请阅读主博文第二部分 6 知识扩展,或许能解决你的疑问;

  • progressbarbool 类型,表示是在命令行中显示程序运行时的进度条,默认为 True,进度条的样式通常如下所示,logp 表示分布在初始值时对应的对数似然,grad 表示数值优化时的梯度的一种输出形式,对于这种输出形式,我一开始简单地以为,grad 仅仅表示每轮迭代的梯度的平均值,但后来查看源码后发现并不是这样,不过至少确定一个事实,grad 是一个 numpy array 的二范数,以及 grad 确实和迭代的梯度紧密相关,因此在后文中统一以 grad 梯度称呼它,我们也可以把它当成梯度来理解它,但是对于它到底是什么的这个问题还有待研究:
    在这里插入图片描述
    这里的 logp 虽然是负数,但因为 log 函数是递增函数,因此还是 logp 越大表示对应的似然越大,表示初始值越接近极大似然点估计的值。

    而 grad 梯度是在优化过程中得出的,它则是越小表示初始值离极大似然点估计的值越近,它可以简单的理解为导数,导数可正可负,因此进度条上对于 grad 梯度显示的是一个二范数的形式,数学中的函数图像的极值点对应的导数为 0 ,因此当你看到你的进度条的 grad 梯度为 0 时,那么恭喜你,你的直觉非常准,初始值设置的非常好。

    我们来看一下另一个初始值对应的进度条,这样对比一下可以帮助理解,可以看到,当初始值设置为 1 时,它对应的 logp 是非常小的,而优化时得出的 grad 梯度是非常大的,这说明初始值 1 与极大似然点估计的值还有很大距离,每一轮迭代需要使用较大的梯度才能最终得到理想的点估计值:
    在这里插入图片描述

  • maxevalint 类型,表示数值优化过程中迭代的最大轮数,默认为 5000,不过有时候用不到这么多轮,比如说上面的两个进度条显示的分别时迭代了 6 轮和 10 轮;

  • modelModel 类型,表示当前的模型,如果 find_MAP() 函数是在 with pm.Model() 上下文管理器中,那这个参数就不用指定,如果不在则需要指定,否则会报错;

  • *args, **kwargs:额外的参数将会传给 scipy.optimize 的优化算法函数,帮助配置优化项。

关于 find_MAP() 函数,下面也给出了它在源码中的说明和参数解释,大家可以参考一下:

def find_MAP(start=None, vars=None, method="L-BFGS-B", return_raw=False, include_transformed=True,
			progressbar=True, maxeval=5000, model=None, *args, **kwargs)
    
   """
   Finds the local maximum a posteriori point given a model.

   find_MAP should not be used to initialize the NUTS sampler. Simply call pymc3.sample() and it will automatically initialize NUTS in a better way.

   Parameters
   ----------
   start : `dict` of parameter values (Defaults to `model.test_point`)
   vars : list
       List of variables to optimize and set to optimum (Defaults to all continuous).
   method : string or callable
       Optimization algorithm (Defaults to 'L-BFGS-B' unless
       discrete variables are specified in `vars`, then
       `Powell` which will perform better).  For instructions on use of a callable,
       refer to SciPy's documentation of `optimize.minimize`.
   return_raw : bool
       Whether to return the full output of scipy.optimize.minimize (Defaults to `False`)
   include_transformed : bool
       Flag for reporting automatically transformed variables in addition
       to original variables (defaults to True).
   progressbar : bool
       Whether or not to display a progress bar in the command line.
   maxeval : int
       The maximum number of times the posterior distribution is evaluated.
   model : Model (optional if in `with` context)
   *args, **kwargs
       Extra args passed to scipy.optimize.minimize
   """
unordered_map 的 find() 函数用于在容器中查找指定的键,并返回一个指向该键值对的迭代器。如果找到了指定的键,则返回指向该键值对的迭代器;如果未找到,则返回指向 unordered_map 结尾的迭代器(即 end() 迭代器)。 下面是使用 find() 函数在 unordered_map 中查找键的示例代码: ```cpp #include <iostream> #include <unordered_map> int main() { std::unordered_map<std::string, int> myMap; myMap["apple"] = 1; myMap["banana"] = 2; myMap["orange"] = 3; // 使用 find() 函数查找键为 "banana" 的键值对 auto it = myMap.find("banana"); if (it != myMap.end()) { std::cout << "找到了键为 'banana' 的键值对,值为:" << it->second << std::endl; } else { std::cout << "未找到键为 'banana' 的键值对" << std::endl; } // 使用 find() 函数查找不存在的键 auto it2 = myMap.find("grape"); if (it2 != myMap.end()) { std::cout << "找到了键为 'grape' 的键值对,值为:" << it2->second << std::endl; } else { std::cout << "未找到键为 'grape' 的键值对" << std::endl; } return 0; } ``` 在上述示例代码中,我们创建了一个 unordered_map,并向其中插入了三对键值对。然后,我们使用 find() 函数分别查找键为 "banana" 和 "grape" 的键值对。通过判断迭代器是否等于 end() 迭代器,我们可以确定是否找到了指定的键。 注意,find() 函数的时间复杂度是 O(1),即常数时间复杂度。因为 unordered_map 使用哈希表实现,可以通过哈希函数快速定位键值对。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值