<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    使用python手寫Metropolis-Hastings算法的貝葉斯線性回歸

    VSole2022-07-30 16:18:33

    在學習貝葉斯計算的解馬爾可夫鏈蒙特卡洛(MCMC)模擬時,最簡單的方法是使用PyMC3,構建模型,調用Metropolis優化器。但是使用別人的包我們并不真正理解發生了什么,所以本文通過手寫Metropolis-Hastings來深入的理解MCMC的過程,再次強調我們自己實現該方法并不是并不是為了造輪子,而是為了更好的通過代碼理解該概念。

    貝葉斯線性回歸包含了幾十個概念和定義,這使得我們的整個研究成為一種折磨,并且真正發生的事情。在本文中,我將通過常見Metropolis-Hastings 算法構建一個馬爾可夫鏈,并提供一個實際的使用案例。我們將著重于推斷簡單線性回歸模型的參數(但是這里說“簡單”并不能代表它背后的原理簡單)。我們還可以用任何其他條件分布(泊松/伽馬/負二項或其他)替換正態分布,這樣可以通過MCMC實現幾乎相同的GLM(只更改4或5行代碼)。由于推斷的樣本來自參數的后驗分布,我們可以很自然地使用這些來構建參數的置信區間(在這種情況下,“可信區間”更正確)。

    下面我們將簡要描述為什么使用MCMC方法,提供一個線性回歸模型的MH算法的實現,并將以一個可視化的方式顯示當算法尋找生成數據的參數集時,真正發生了什么。

    數據準備

    設Y和X分別為模型的響應和輸入。線性模型表明,給定輸入的響應的條件分布是正態的。也就是:

    對于合適的參數a(斜率)、b(偏差)和σ(噪聲強度)。

    我們的任務是推斷a, b和σ。

    所以我們首先要知道一些模型需要遵循的“基本規則”。在這個例子中,a, b幾乎可以是任何數值,正的或負的,但σ必須是嚴格正的(因為從來沒有聽說過負標準差的正態分布,對吧?)除此之外,沒有其他任何規則。也許你會說:“我們需要先了解這些是如何分布的”,但是后驗分布的漸近正態性保證告訴我們,只要有足夠的后驗樣本,這些樣本無論如何都是正態分布(如果馬爾可夫鏈達到其平穩分布),所以分布不是我們考慮的必要因素。

    現在讓我們為回歸生成合成數據,這里使用參數a=3, b=20和σ=5。可以通過以下代碼在python中完成:

    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.stats as sc
    # sample x
    np.random.seed(2022)
    x = np.random.rand(100)*30
    # set parameters
    a = 3
    b = 20
    sigma = 5
    # obtain response and add noise
    y = a*x+b
    noise = np.random.randn(100)*sigma
    # create a matrix containing the predictor in the first column
    # and the response in the second
    data = np.vstack((x,y)).T + noise.reshape(-1,1)
    # plot data
    plt.scatter(data[:,0], data[:,1])
    plt.xlabel("x")
    plt.ylabel("y")
    

    合成數據如下圖所示:

    數據的準備已經完成了,下一節將涉及定義 Metropolis Hastings 算法的函數和一組迭代次數的循環。

    算法介紹

    假設θ=[a,b,σ]是算法上面的參數向量,θ '是一組新參數的建議,MH比較參數(θ '和θ)的兩個競爭假設之間的貝葉斯因子(似然和先驗的乘積),并通過條件建議分布的倒數縮放該因子。然后將該因子與均勻分布的隨機變量的值進行比較。這給模型增加了隨機性,使不可能的參數向量有可能被探索,也可能被丟棄(很少)。

    這聽起來有點復雜,讓我們從頭一步一步對它進行代碼的實現。

    Proposal Distribution

    首先,我們定義了一個建議的分布(Proposal Distribution)g(θ′|θ):這是前一個時間步固定參數的分布。在我們的例子中,a和b可以是正的也可以是負的,因此一個自然的選擇就是從一個以前一個迭代步驟為中心的多元正態分布中采樣它們。我們可以從伽馬分布中取樣σ,這些分布的定義我們可以根據實際情況進行選擇,但是一個更好的方法(這里我們將不涉及)是從逆伽馬分布抽樣σ。

    因此,我們可以按照以下方式定義進行Proposal Distribution:

    分布抽樣σ為

    參數 k 用于控制分布在其均值周圍的“擴展”。? 是對gamma 額外調整。k?越大,gamma 的分布越大(我們使用的是 gamma 分布的形狀速率公式因為 scipy 強迫使用形狀比例公式)。功能如下:

    def proposal(prec_theta, search_width = 0.5):
     # this function generates the proposal for the new theta
     # we assume that the distribution of the random variables
     # is normal for the first two and gamma for the third.
     # conditional on the previous value of the accepted parameters (prec_theta)
     out_theta = np.zeros(3)
     out_theta[:2] = sc.multivariate_normal(mean=prec_theta[:2],cov=np.eye(2)*search_width**2).rvs(1)
     #the last component is the noise
     out_theta[2] = sc.gamma(a=prec_theta[2]*search_width*500, scale=1/(500*search_width)).rvs()
     return out_theta
    

    我們可能會可以注意到函數proposal包含兩個參數:prec_theta表示上面說的的參數向量,search_width表示尋找建議的區域。尋找一組良好的參數會在探索(在未探索的區域中搜索新參數集)和開發(在已找到良好參數集的區域中改進搜索)之間進行權衡。所以應該非常小心地設置search_width。search_width值過大會使MCMC收斂到平穩分布。一個小的值可能會阻止算法在合理的時間內找到最優(optima)(需要繪制更多的樣本,更多的訓練時間)。

    似然函數

    似然函數其實就是線性函數,并且給定參數的響應的條件分布是正態的。換句話說,我們將計算正態分布的可能性,其中均值是輸入和系數a和b的乘積,噪聲是σ。在這種情況下,我們將使用對數似然而不是原始似然,這樣可以提高穩定性。

    def lhd(x,theta):
     # x is the data matrix, first column for input and second column for output.
     # theta is a vector containing the parameters for the evaluation
     # remember theta[0] is a, theta[1] is b and theta[2] is sigma
     xs = x[:,0]
     ys = x[:,1]
     lhd_out = sc.norm.logpdf(ys, loc=theta[0]*xs+theta[1], scale=theta[2])
     # then we sum lhd_out (be careful here, we are summing instead of multiplying
     # because we are dealing with the log-likelihood, instead of the raw likelihood).
     lhd_out = np.sum(lhd_out)
     return lhd_out
    

    先驗

    我們不需要在這方面花很多時間。在先驗分布方面,可以選擇任何喜歡的東西。這里需要做的就是確保可能找到推斷的參數的區域具有非零先驗,并且噪聲參數 σ 是非負的。這里的先驗以 log-pdf 的形式表示。

    def prior(theta):
     # evaluate the prior for the parameters on a multivariate gaussian.
     prior_out = sc.multivariate_normal.logpdf(theta[:2],mean=np.array([0,0]), cov=np.eye(2)*100)
     # this needs to be summed to the prior for the sigma, since I assumed independence.
     prior_out += sc.gamma.logpdf(theta[2], a=1, scale=1)
     return prior_out
    

    Proposal Ratio

    Proposal Ratio是在給定新參數向量的情況下觀察到舊參數向量的可能性除以給定舊參數向量的情況下觀察到新參數向量的概率。也就是Proposal Distribution提到的,g(θ|θ′)/g(θ′|θ)。這里將使用log-pdf,這樣可以在概率中具有統一的尺度,并獲得更好的數值穩定性。

    def proposal_ratio(theta_old, theta_new, search_width=10):
     # this is the proposal distribution ratio
     # first, we calculate of the pdf of the proposal distribution at the old value of theta with respect to the new
     # value of theta. And then we do the exact opposite.
     prop_ratio_out = sc.multivariate_normal.logpdf(theta_old[:2],mean=theta_new[:2], cov=np.eye(2)*search_width**2)
     prop_ratio_out += sc.gamma.logpdf(theta_old[2], a=theta_new[2]*walk*500, scale=1/(500*walk))
     prop_ratio_out -= sc.multivariate_normal.logpdf(theta_new[:2],mean=theta_old[:2], cov=np.eye(2)*search_width**2)
     prop_ratio_out -= sc.gamma.logpdf(theta_new[2], a=theta_old[2]*walk*500, scale=1/(500*walk))
     return prop_ratio_out
    

    整合

    把所有信息整合起來。偽代碼如下:

    1)實例化參數向量的初始值

    ... N次,直到收斂

    2)從建議分布中找到一個新的參數向量

    3)計算似然、先驗pdf值和建議似然比的倒數

    4)將3中的所有數量相乘(或log求和),并比較這個比例(線性比例)

    根據從均勻分布中得出的數字。

    5)如果比值較大,則接受新的參數向量。

    否則,新的參數向量將被拒絕。

    6)重復2

    在Python代碼如下:

    np.random.seed(100)
    width = 0.2
    thetas = np.random.rand(3).reshape(1,-1)
    accepted = 0
    rejected = 0
    N = 200000
    for i in range(N):
     # 1) provide a proposal for theta
     theta_new = proposal(thetas[-1,:], search_width=width)
      
     # 2) calculate the likelihood of this proposal and the likelihood
     # for the old value of theta
     log_lik_theta_new = lhd(data,theta_new)
     log_lik_theta = lhd(data,thetas[-1,:])
      
     # 3) evaluate the prior log-pdf at the current and at the old value of theta
     theta_new_prior = prior(theta_new)
     theta_prior = prior(thetas[-1,:])
      
     # 4) finally, we need the proposal distribution ratio
     prop_ratio = proposal_ratio(thetas[-1], theta_new, search_width=width)
      
     # 5) assemble likelihood, priors and proposal distributions
     likelihood_prior_proposal_ratio = log_lik_theta_new - log_lik_theta + \
                  theta_new_prior - theta_prior + prop_ratio
      
     # 6) throw a - possibly infinitely weigthed - coin. The move for Metropolis-Hastings is
     # not deterministic. Here, we exponentiate the likelihood_prior_proposal ratio in order
     # to obtain the probability in linear scale
     if np.exp(likelihood_prior_proposal_ratio) > sc.uniform().rvs():
       thetas = np.vstack((thetas,theta_new))
       accepted += 1
     else:
       rejected += 1
    

    上面的代碼可能會要花費一些時間來運行。修改N來獲得更少的采樣,或編輯寬度以加快探索。

    結果展示

    結果包含在下圖中

    得到的:a(紅色), b(藍色) and σ(紫色)

    參數的直方圖。

    可以看到,樣本的歷史結果非常穩定。平均值和標準偏差是:

    但是有一個問題,我們只在這里提一下:這些樣本高度相關,因此在估計可信區間時可能需要小心。這里的一種解決方案是通過只保留一小部分參數來細化歷史記錄(例如,只保留1 / 10已接受的提議,并丟棄其余的)。

    傳統的線性回歸相比如何呢?

    使用 statsmodels.api.OLS 執行完全相同的計算

    import statsmodels.api as sm
    import pandas as pd
    df = pd.DataFrame(data)
    df.columns = ["a","y"]
    df["b"] = 1
    lm = sm.OLS(df["y"], df[["a","b"]]).fit()
    lm.summary()
    

    結果如下:

    a 和 b 的系數的平均值非常接近 MCMC。標準誤差也可以這樣說,這樣也進一步證明了我們對 MCMC 實現是可行的。

    請注意,這不是最好的解決方案,而只是一個解決方案。因為確實存在并推薦更好的先驗和建議分布的選擇。

    迭代的可視化?

    在 3D 中可視化相當的混亂,所以這里只關注斜率 a 和偏差 b。

    在可視化中,每 10 步顯示一次 MH 的行為:

    紅點代表當前的建議提案,紅點周圍的灰色區域表示與平均值相差 3 個標準差的建議分布(正態)。該提案有一個對角協方差矩陣,這就是我們得到一個圓而不是橢圓。

    藍色線代表被拒絕的動作。

    紅線代表接受的動作

    最上面淺藍點表示從 statsmodels.api.OLS 獲得的參數的平均值。

    貝葉斯python算法
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    在學習貝葉斯計算的解馬爾可夫鏈蒙特卡洛模擬時,最簡單的方法是使用PyMC3,構建模型,調用Metropolis優化器。貝葉斯線性回歸包含了幾十個概念和定義,這使得我們的整個研究成為一種折磨,并且真正發生的事情。
    從本專欄開始,作者正式研究Python深度學習、神經網絡及人工智能相關知識。一.RNN文本分類1.RNN循環神經網絡英文是Recurrent Neural Networks,簡稱RNN。假設有一組數據data0、data1、data2、data3,使用同一個神經網絡預測它們,得到對應的結果。RNN常用于自然語言處理、機器翻譯、語音識別、圖像識別等領域。本文將采用詞向量、TFIDF兩種方式進行實驗。
    一.文本分類文本分類旨在對文本集按照一定的分類體系或標準進行自動分類標記,屬于一種基于分類體系的自動分類。牛亞峰老師將傳統的文本分類流程歸納如下圖所示。在傳統的文本分類中,基本上大部分機器學習方法都在文本分類領域有所應用。本文將采用詞向量、TFIDF兩種方式進行實驗。
    Python人工智能第10篇介紹TF實現CNN圖像分類任務
    當前網絡入侵檢測大多使用人工特征,但是人工特征往往不能適應新型攻擊,重新設計人工特征又需要專家知識。對此,提出了一種算法,該算法從網絡流量數據中提取會話作為樣本,并將樣本送入兩個神經網絡,會話的一系列有時間順序的數據包視為一維序列送入門控循環單元,融合會話的一系列數據包視為二維圖像送入卷積神經網絡。
    DeepExploit 是一種基于強化學習的自動化滲透框架,號稱能夠進行高效滲透,本文對該工具進行了分析并給出改進方向 本部分對DE(將DeepExploit簡稱為DE)利用到的核心工具做簡單介紹,分為metasploit介紹和強化學習算法介紹,均為入門介紹,熟悉的讀者可自行忽略。
    摘 要:互聯網開源信息處理是指從互聯網上的公開信息源獲取數據并分析處理,進而獲得有價值的開源信息的過程。為充分了解國外互聯網開源信息處理的研究現狀,從開源數據采集、預處理、信息分析、決策支撐、相關系統等角度對近年來國外有關研究進行梳理,總結現有研究存在的普遍性問題,對未來研究進行展望。
    當人工智能遇上安全第7篇文章介紹基于機器學習的安全數據集,希望對您有幫助
    在信息安全測試領域,基于機器學習的應用系統深度指紋識別技術對應用系統進行漏洞檢測時,可快速獲取應用系統指紋信息,并且能夠根據系統深度指紋信息進行精確的自適應漏洞檢測。通過研究面向 http 協議的信息收集爬蟲技術、基于字符串匹配的識別技術和目標安全缺陷利用技術,基于目標指紋特征提出并搭建了樸素貝葉斯模型,實現了基于機器學習的應用系統指紋識別技術,識別目標應用系統信息,發現缺陷和自適應漏洞檢測。最后
    本文提出 將網絡安全風險量化評估與戈登—洛布模型結合 起來分析企業的網絡安全預算的收益情況。網絡安全風險是指由于網絡系統存在脆弱 性,因人為或自然的威脅導致安全事件發生所 造成的損失。網絡風險評估就是評估威脅者利 用網絡資產的脆弱性造成網絡資產損失的嚴重 程度。一是對機密性的威脅。二是對完整性的威脅。GL 模型使用安全漏洞概率函數作為條件, 這些函數有兩種類型,一種是線性型,另一種 是指數型。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类