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
   """
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章