一、简介
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/n/292110.html