一、簡介
Gaussian Process,又稱高斯過程,是一種常用於機器學習、模式識別領域的統計模型。它是對於一組樣本數據的分布進行建模,而這組數據可以是從一個射箭比賽的得分表到一些產品的銷售數據都可以當作它的輸入數據,它的本質目的是通過估計樣本數據的分布來預測未知數據的分布和位置。
高斯過程在貝葉斯框架下對於一個潛在函數f(x)的分布進行建模,使得這個函數能夠被用在回歸和分類的場景中。高斯過程雖然和神經網路相比,運算速度較慢,但它不需要對函數進行參數化的變化,更加自然地處理非線性函數變換。
二、高斯過程的基本概念
1.高斯分布
高斯分布是機器學習中經常用到的概率分布之一,又稱正態分布。它的分布規律滿足鐘形曲線,這是由於它服從一個均值為μ、方差為σ的分布。
在高斯過程中,我們採用高斯分布來描述一個無限維隨機向量的分布,給定無限多個變數的聯合概率分布。
2.協方差函數(kernel function)
通過協方差函數可以給出樣本之間的關聯程度,同時形成有效的數據插值。例如,我們可以用RBF協方差函數來構造高斯過程,由此可以得到與最近鄰距離有關的數據相似度。協方差函數決定了函數值之間的相關性或者說關聯度。例如,對於無限維的高斯過程,協方差就指定了雜訊的分布。
3.樣本點與擬合函數
我們用一組樣本點來對高斯過程進行模型訓練,通過樣本點來構建一個擬合函數f(x),使得這個函數可以用來對未知點進行預測。在高斯過程中,我們可以認為擬合函數滿足高斯分布,擬合函數的均值和方差可以由樣本點來計算獲得。
三、高斯過程的應用
1.回歸問題
高斯過程可以作為回歸問題的一種解決辦法。在回歸問題中,我們關注的是連續變數的預測問題。在通過樣本點構造高斯過程的擬合函數後,我們可以根據給定的輸入變數,通過擬合函數來得到相應的輸出值。
2.分類問題
高斯過程也可以用於二元和多元分類問題。通過建立一個高斯過程分類器,可以通過樣本點的分布來判定測試點的類別。由於高斯過程是對於函數的連續性和可導性進行處理的,因而在分類問題中一般比邏輯回歸更好的表現效果。
四、代碼說明
1.高斯過程回歸
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normal
# RBF 協方差函數
def RBF_kernel(X1, X2, l=1.0, sigma_f=1.0):
# 計算距離矩陣
dist_matrix = np.sum(X1**2,1).reshape(-1,1) + np.sum(X2**2,1) - 2*np.dot(X1,X2.T)
return sigma_f**2 * np.exp(-0.5 * dist_matrix / l**2)
class GP_regression(object):
def __init__(self, kernel=RBF_kernel):
self.kernel = kernel
def fit(self, X_train, y_train, noise=1e-8):
self.X_train = X_train
self.y_train = y_train
self.noise = noise
# 計算訓練數據協方差矩陣
K = self.kernel(X_train, X_train)
self.K = K + noise * np.eye(K.shape[0])
self.K_inv = np.linalg.inv(self.K)
return self
def predict(self, X_test):
# 計算測試數據與訓練數據協方差矩陣
k_trans = self.kernel(self.X_train, X_test)
# 計算預測值與方差
y_mean = k_trans.T.dot(self.K_inv).dot(self.y_train)
cov = self.kernel(X_test, X_test) - k_trans.T.dot(self.K_inv).dot(k_trans)
return y_mean, cov
# 畫出擬合曲線與置信區間
def plot_gp(X, y, X_test, y_mean, cov):
plt.scatter(X, y)
plt.plot(X_test, y_mean, 'r')
plt.fill_between(X_test.flat, y_mean-1.96*np.sqrt(np.diag(cov)), y_mean+1.96*np.sqrt(np.diag(cov)), alpha=0.1)
plt.show()
# 模擬數據
X_train = np.array([1.0, 3.0, 5.0, 6.0, 7.0, 8.0]).reshape(-1,1)
y_train = np.sin(X_train) + np.random.normal(0, 0.2, size=(6,1))
# 預測數據集
X_test = np.arange(0, 10, 0.1).reshape(-1,1)
gp = GP_regression()
gp.fit(X_train, y_train)
y_mean, cov = gp.predict(X_test)
plot_gp(X_train, y_train, X_test, y_mean, cov)
2.高斯過程分類
import numpy as np
from scipy.stats import multivariate_normal
# 協方差函數
def kernel(X1, X2, l=1.0, sigma_f=1.0):
# 計算距離矩陣
dist_matrix = np.sum(X1**2,1).reshape(-1,1) + np.sum(X2**2,1) - 2*np.dot(X1,X2.T)
return sigma_f**2 * np.exp(-0.5 * dist_matrix / l**2)
class GP_classification(object):
def __init__(self, kernel=kernel):
self.kernel = kernel
def fit(self, X_train, y_train, noise=1e-8):
self.X_train = X_train
self.y_train = y_train[:,None]
self.noise = noise
# 計算訓練數據協方差矩陣
K = self.kernel(X_train, X_train)
self.K = K + noise * np.eye(K.shape[0])
self.K_inv = np.linalg.inv(self.K)
return self
def predict(self, X_test):
# 計算測試數據與訓練數據協方差矩陣
k_trans = self.kernel(self.X_train, X_test)
# 計算預測值與方差
y_mean = k_trans.T.dot(self.K_inv).dot(self.y_train)
cov = self.kernel(X_test, X_test) - k_trans.T.dot(self.K_inv).dot(k_trans)
return y_mean, cov
def predict_proba(self, X_test):
# 計算測試點均值和方差
y_mean, cov = self.predict(X_test)
# 計算預測概率
p = multivariate_normal.cdf(0, mean=y_mean.flatten(), cov=cov, allow_singular=True)
# 轉換成二分類的概率
p = np.stack([1-p, p], axis=1)
return p
# 模擬數據
X = np.random.uniform(-3., 3., size=(200, 1))
y = np.sin(X) + np.random.normal(0, 0.1, size=(200, 1))
y = np.where(y>=0, 1, 0)
# 預測數據集
X_test = np.linspace(-5., 5., 100).reshape(-1,1)
gp = GP_classification()
gp.fit(X, y)
P_test = gp.predict_proba(X_test)
plt.scatter(X, y, alpha=0.5)
plt.plot(X_test, P_test[:, 1], label='p(y=1|x)')
plt.plot(X_test, P_test[:, 0], label='p(y=0|x)')
plt.legend()
plt.show()
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/292110.html
微信掃一掃
支付寶掃一掃