1. 程式人生 > >淺析高斯過程迴歸(Gaussian process regression)

淺析高斯過程迴歸(Gaussian process regression)

  • 前言      

       高斯過程迴歸的和其他迴歸演算法的區別是:一般迴歸演算法給定輸入X,希望得到的是對應的Y值,擬合函式可以有多種多樣,線性擬合、多項式擬合等等,而高斯迴歸是要得到函式f(x)的分佈,那麼是如何實現的呢?

        對於資料集 D:(X,Y),令 f(x^{_{i}})=y_{i},從而得到向量f=[f(x_1),f(x_2),...,f(x_n)], 將所需要預測的x_{i}的集合定義為X*,對應的預測值為f*, 根據貝葉斯公式有:

                                                    p(f*|f)=\frac{p(f|f*)p(f*)}{p(f)}=\frac{p(f,f*)}{p(f)}

       高斯迴歸首先要計算資料集中樣本之間的聯合概率分佈, f\sim N(\mu ,K)\muf(x_{1}),f(x_{2}),...,f(x_{n})的均值所組成的向量,K為其協方差矩陣,再根據需要預測的f*的先驗概率分佈 f*\sim N(\mu* ,K*)

f\sim N(\mu ,K),來計算出f*的後驗概率分佈。

       其中共有兩個核心問題:(1)如何計算和方差矩陣(2)如何具體如何計算f*的概率分佈。

{x_1,x_2,...,x_n}的協方差矩陣,一定要注意是自變數x的協方差矩陣,因為我們在進行對x*對應的f(x*)的預測時,是依據x*和{x_1,x_2,...,x_n}之間的協方差,來判斷其y值之間的差異性,從而基於概率公式得出預測值。
       

  • 協方差矩陣的計算

        定義函式 m(x)=E(f(x))k(x,x^{^{T}})=K,則由概率論基本公式可得:

        f(x)\sim N(m(x),k(x,x^{^{T}}))\\

        m(x)=E(f(x))

        k(x,x^{^{T}})=E(f(x)-m(x)(f(x)-m(x))^{T})

       利用這樣的原始公式來計算協方差矩陣K是十分不方便的,我們先來理解一下高斯過程是如何利用Gaussian distribution 來描述樣本的,先來看圖1和圖2:

圖1
圖2

       圖1中很明顯可以看出來y值的大小與自變數x值的取值相關性很小,對於這樣的資料,我們可以給出f(x)的先驗分佈:

                                                                           f(x)\sim N(0,\begin{bmatrix} 1 & & \\ &... & \\& &1 \end{bmatrix})

       其協方差矩陣為對角陣,任意不同x值之間的協方差均設為0
      對於圖2,f(x)受x值影響較大,x值相近,y值也相近,呈現出較高的相關性,我們可以給出其先驗分佈,f(x)\sim N(0,K),通過以上兩個例子我們發現,f(x)的協方差矩陣與x_1,x_2,...,x_n相關度很高,如果我們能夠使得 得到一個 k(x,x^{^{T}})

 函式,只需輸入x,即可得到對應 f(x) 的協方差矩陣,將給我們的計算帶來極大的便利。那麼用什麼樣的函式來取代原始公式才是合理的呢?

       我們需要知道以下兩個定理:

    (1)協方差矩陣必須是半正定陣

    (2)kernel fountion都是半正定陣。這就意味著我們在學習SVM的時候所學過的核函式形式都可以用

       當然應用最廣的是RBF kernel,即如下式:

                                                                k(x,{x}')=\alpha ^{2}exp(-\frac{1}{2l^{2}})(x-{x}')^2)

其中\alpha為超引數,l是需要通過學習進行確定的引數,那麼我們只需要通過監督學習的方式學習到合適的kernel,即可很方便的計算出f的協方差矩陣。

       如何學習kernel的引數?很簡單kernel k(x,{x}') 優劣的評價標準就是在要f(x)\sim N(m(x),k(x,x^{^{T}}))\\的條件下,讓p(Y|X)最大,為了方便求導我們將目標函式設為logp(Y|X)=log N(\mu ,K_{y}),接下來利用梯度下降法來求最優值即可:

                                                          \frac{\partial logp(Y|X) }{\theta }=\frac{1}{2}y^{T}K_{y}^{-1}\frac{\partial K_{y} }{\theta }K_{y}^{-1}y-\frac{1}{2}tr(K_{y}^{-1}\frac{\partial K_{y} }{\theta })

  • 後驗概率分佈的計算

    圖3

    如圖所示,紅色的點代表已知的資料點,即訓練集 D={(x_{1},f(x_1)),(x_{2},f(x_2)),...,(x_{n},f(x_n)} ,給出 f(x)的先驗分佈:

f(x)\sim N(\mu,K),其中K為協方差矩陣,我們以RBF kernel來計算:K_{ij}=\alpha ^{2}exp((-\frac{1}{2l^{2}})(x_i-x_j)^2)

       綠色的叉代表需要估計的點的X值,我們給定其先驗分佈f(x*)\sim N(\mu *,K(x*,x*)) 

       已知 f(x)\sim N(\mu,K), f(x*)\sim N(\mu *,K(x*,x*)),可計算其其聯合概率分佈的先驗:

                                                                  \bigl(\begin{smallmatrix} f\\ f* \end{smallmatrix}\bigr)\sim (\begin{pmatrix} \mu \\ \mu*\end{pmatrix},\begin{pmatrix} K& K* \\ K*^{T}&K**\end{pmatrix})

其中K**為 f(x*)的協方差矩陣,K**=k(X*,X*)K*=k(X,X*)

圖4

      有了p(f)的先驗分佈,以及上面計算的p(f,f*),根據貝葉斯公式可以計算 p(f*|f)的後驗概率:

                                                    p(f*|f)=\frac{p(f|f*)p(f*)}{p(f)}=\frac{p(f,f*)}{p(f)}

從而得出對於f*的估計,f*\sim (\mu {}',K{}')

                                                   \mu{}'=K^TK^{-1}f

                                                  K{}'=K*^TK^{-1}K*+K**

      圖3擬合的結果如圖5所示,圖5展示的擬合曲線是僅顯示均值的曲線。圖6、圖7展現了高斯過程迴歸對於模型誤差的估計能力,在圖6中在後半部分資料波動較大時,其估計的方差表徵了在這一部分的波動情況;在圖7中也較好的展示了,在位置資料點,高斯過程迴歸對於該點函式值均值和方差的估計。

圖5
圖6
圖7
  • 求解高斯過程的工具sklearn.gaussian_process

在sklearn中提供了十分方便的gaussian_process庫,可以用來進行高斯過程求解,我們可以呼叫GaussianProcessRegressor來進行高斯過程迴歸的求解,函式具體介紹如下:

引數:

kernel:核心物件

核心指定GP的協方差函式。如果通過None,則預設使用核心“1.0 * RBF(1.0)”。請注意,核心的超引數在擬合期間進行了優化。

alpha:float或array-like,可選(預設值:1e-10)

在擬合期間將值新增到核矩陣的對角線。較大的值對應於觀察中增加的噪聲水平。通過確保計算值形成正定矩陣,這還可以防止擬合期間潛在的數值問題。如果傳遞陣列,則它必須具有與用於擬合的資料相同的條目數,並用作與資料點相關的噪聲級別。請注意,這相當於新增帶有c = alpha的WhiteKernel。允許直接將噪聲級別指定為引數主要是為了方便和與Ridge的一致性。

優化器:字串或可呼叫,可選(預設值:“fmin_l_bfgs_b”)

可以是內部支援的優化器之一,用於優化由字串指定的核心引數,也可以是作為可呼叫方傳遞的外部定義的優化器。如果傳遞了callable,它必須具有簽名:

def  優化器(obj_func , initial_theta , bounds ):
    #*'obj_func'是要最大化的目標函式,
    #將超引數theta作為引數和
    #可選標誌eval_gradient,它確定是否
    在函式之外返回
    #grace value #*'initial_theta':theta的初始值,可以
    由本地優化器#使用
    #*'bounds':theta值的界限
    .... 
    #Returned是找到的最好的超引數theta和
    #對應的目標函式的值。
    返回 theta_opt , func_min

預設情況下,使用scipy.optimize中的'fmin_l_bfgs_b'演算法。如果傳遞None,則核心的引數保持固定。可用的內部優化器是:

'fmin_l_bfgs_b'

n_restarts_optimizer:int,optional(預設值:0)

優化程式重新啟動的次數,用於查詢最大化對數邊際可能性的核心引數。優化程式的第一次執行是從核心的初始引數執行的,其餘的那些(如果有的話)來自採樣的log-uniform,從允許的the-value的空間中隨機均勻。如果大於0,則所有邊界必須是有限的。請注意,n_restarts_optimizer == 0表示執行了一次執行。

normalize_y:boolean,optional(預設值:False)

目標值y是否被歸一化,即,觀察到的目標值的平均值變為零。如果預期目標值的平均值與零相差很大,則此引數應設定為True。啟用後,歸一化有效地根據資料修改GP的先驗,這與可能性原則相矛盾; 因此,預設情況下禁用標準化。

copy_X_train:bool,optional(預設值:True)

如果為True,則將訓練資料的持久副本儲存在物件中。否則,僅儲存對訓練資料的引用,如果在外部修改資料,則可能導致預測發生變化。

random_state:int,RandomState例項或None,可選(預設值:None)

用於初始化中心的生成器。如果是int,則random_state是隨機數生成器使用的種子; 如果是RandomState例項,則random_state是隨機數生成器; 如果沒有,隨機數生成器所使用的RandomState例項np.random。

屬性:

X_train_:類似陣列,shape =(n_samples,n_features)

訓練資料中的特徵值(也是預測所需)

y_train_:array-like,shape =(n_samples,[n_output_dims])

訓練資料中的目標值(也是預測所需)

kernel_:核心物件

核心用於預測。核心的結構與作為引數傳遞的核心相同,但具有優化的超引數

L_:類似陣列,shape =(n_samples,n_samples)

下三角形Cholesky分解核心 X_train_

alpha_:array-like,shape =(n_samples,)

核空間中訓練資料點的雙重係數

log_marginal_likelihood_value_:float

對數邊際可能性 self.kernel_.theta

fit(X,y) 擬合高斯過程迴歸模型。
獲取此估算工具的引數。
返回訓練資料的theta的log-marginal似然。
predict(X [,return_std,return_cov]) 使用高斯過程迴歸模型進行預測
sample_y(X [,n_samples,random_state]) 從高斯過程中抽取樣本並在X處進行評估。
score(X,y [,sample_weight]) 返回預測的確定係數R ^ 2。
設定此估算器的引數。

提供了一個簡單的小程式,大家可以用來做一些小實驗:

import numpy as np
import matplotlib.pyplot as plt
import random
from sklearn.gaussian_process import GaussianProcessRegressor
a=np.random.random(50).reshape(50,1)
b=a*2+np.random.random(50).reshape(50,1)
plt.scatter(a,b,marker = 'o', color = 'r', label='3', s = 15)
plt.show()
gaussian=GaussianProcessRegressor()
fiting=gaussian.fit(a,b)
c=np.linspace(0.1,1,100)
d=gaussian.predict(c.reshape(100,1))
plt.scatter(a,b,marker = 'o', color = 'r', label='3', s = 15)
plt.plot(c,d)
plt.show()