Python实战:高斯过程回归(GPR)中核函数的选择与交叉验证
深入浅出:高斯过程回归(GPR)中核函数的选择与优化
1. 啥是高斯过程回归?
2. 核函数:GPR的“灵魂”
3. 如何选择合适的核函数?
4. 交叉验证:找到“最佳”核函数
5. Python实战:GPR核函数选择与交叉验证
6. 总结与进阶
深入浅出:高斯过程回归(GPR)中核函数的选择与优化
大家好!今天咱们聊聊高斯过程回归(Gaussian Process Regression,简称GPR)中一个核心问题——核函数的选择。别担心,我们会用大白话,加上Python代码实操,保证你能听懂、学会、用得上。
1. 啥是高斯过程回归?
在机器学习的世界里,很多时候我们需要根据已有的数据去预测未知的数据。比如,根据过去几天的气温,预测明天的气温;或者根据房屋的面积、位置,预测房价。GPR就是一种强大的预测工具,尤其擅长处理那些数据量不大,但又希望得到比较靠谱预测结果的情况。
你可以把GPR想象成一个“超级函数”,这个函数不仅能给出预测值,还能告诉你这个预测值有多靠谱(也就是预测的不确定性)。这就像你问一个专家问题,他不仅告诉你答案,还告诉你他对这个答案有多大的把握。
GPR的核心思想是假设数据背后有一个“看不见”的函数在支配着,而这个函数服从高斯过程。啥是高斯过程?简单来说,就是一堆“相关联”的随机变量,它们之间的关系由一个叫做“核函数”的东西来决定。
2. 核函数:GPR的“灵魂”
核函数,你可以把它理解成GPR的“灵魂”。它决定了GPR如何“看待”数据之间的关系。不同的核函数,就像不同的“眼镜”,会让GPR看到不同的数据“风景”。
举个例子,假设我们要预测房价,有两个房子,面积分别是100平和105平。如果我们用一个“认为面积越接近,房价就越接近”的核函数,那么GPR就会认为这两个房子的房价应该很接近。反之,如果我们用一个“认为面积差一点,房价就可能差很多”的核函数,那么GPR可能就会给出差异很大的预测结果。
常见的核函数有这么几种:
- 径向基函数(RBF)核:也叫高斯核,是最常用的核函数之一。它认为两个数据点越接近,它们的值就越相似。你可以通过调整一个叫做“长度尺度”的参数来控制“接近”的程度。
- 线性核:认为数据之间存在线性关系。如果你觉得数据大致呈线性趋势,可以用这个核。
- 周期核:适合处理具有周期性变化的数据,比如季节性气温、股票价格等。
- Matern核:比RBF核更灵活,可以通过一个参数来控制函数的平滑程度。
- 有理二次核(Rational Quadratic): 相当于不同长度尺度的RBF核的加权和。
当然,还有很多其他的核函数,甚至可以把不同的核函数组合起来,创造出更强大的“混合核”。
3. 如何选择合适的核函数?
问题来了,面对这么多核函数,到底该选哪个呢?
没有“一招鲜吃遍天”的万能核函数。选择核函数,就像选择合适的衣服,要根据具体情况来定。
一般来说,可以遵循以下几个原则:
- 先验知识:如果你对数据背后的规律有一些了解,可以根据这些知识来选择核函数。比如,你知道数据有周期性,那就试试周期核。
- 数据可视化:把数据画出来看看,观察数据的分布、趋势,有助于选择核函数。
- 尝试不同的核函数:实践出真知!多试几个核函数,看看哪个效果最好。
- 奥卡姆剃刀原理:如无必要,勿增实体。尽量选择简单的核函数,避免过度拟合。
4. 交叉验证:找到“最佳”核函数
在机器学习中,我们通常会把数据分成“训练集”和“测试集”。训练集用来“训练”模型,测试集用来“检验”模型的效果。但是,如果我们在测试集上调整核函数,就相当于“偷看”了测试集,这样得到的模型可能会“过拟合”,在实际应用中效果反而不好。
为了解决这个问题,我们可以使用“交叉验证”的方法。交叉验证的思路是:把训练集再分成几份,轮流用其中一份做“验证集”,剩下的做“训练集”。这样,我们就可以在不“偷看”测试集的情况下,评估不同核函数的效果,选出“最佳”的那个。
常见的交叉验证方法有:
- K折交叉验证:把训练集分成K份,轮流用其中一份做验证集,剩下的K-1份做训练集。通常K取5或10。
- 留一交叉验证:每次只留一个数据点做验证集,剩下的做训练集。这种方法适用于数据量很小的情况。
5. Python实战:GPR核函数选择与交叉验证
说了这么多,不如动手试试。下面,我们用Python的scikit-learn
库来演示如何使用GPR,以及如何通过交叉验证选择核函数。
import numpy as np import matplotlib.pyplot as plt from sklearn.gaussian_process import GaussianProcessRegressor from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C, Matern, RationalQuadratic, ExpSineSquared from sklearn.model_selection import KFold, cross_val_score # 构造一些模拟数据 np.random.seed(0) X = np.linspace(0, 10, 50).reshape(-1, 1) y = np.sin(X[:, 0]) + np.random.normal(0, 0.5, X.shape[0]) # 定义一些候选的核函数 kernels = [ 1.0 * RBF(length_scale=1.0, length_scale_bounds=(1e-1, 10.0)), 1.0 * Matern(length_scale=1.0, length_scale_bounds=(1e-1, 10.0), nu=1.5), 1.0 * RationalQuadratic(length_scale=1.0, alpha=0.1), 1.0 * ExpSineSquared(length_scale=1.0, periodicity=3.0, length_scale_bounds=(0.1, 10.0), periodicity_bounds=(1.0, 10.0)), C(1.0, (1e-3, 1e3)) * RBF(10, (1e-2, 1e2)) ] # 使用K折交叉验证选择核函数 kf = KFold(n_splits=5, shuffle=True, random_state=0) best_kernel = None best_score = -np.inf for kernel in kernels: gpr = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10, alpha=0.1) scores = cross_val_score(gpr, X, y, cv=kf, scoring='neg_mean_squared_error') # 使用负均方误差作为评估指标 mean_score = scores.mean() print(f"Kernel: {kernel}, Mean score: {mean_score}") if mean_score > best_score: best_score = mean_score best_kernel = kernel print(f"\nBest kernel: {best_kernel}") # 使用最佳核函数训练模型并进行预测 gpr = GaussianProcessRegressor(kernel=best_kernel, n_restarts_optimizer=10, alpha=0.1) gpr.fit(X, y) X_test = np.linspace(0, 12, 200).reshape(-1, 1) y_pred, sigma = gpr.predict(X_test, return_std=True) # 绘制预测结果 plt.figure(figsize=(10, 6)) plt.scatter(X, y, c='k', label='Training data') plt.plot(X_test, y_pred, 'r-', label='Prediction') plt.fill_between(X_test[:, 0], y_pred - sigma, y_pred + sigma, alpha=0.2, color='r', label='95% confidence interval') plt.xlabel('X') plt.ylabel('y') plt.title(f'GPR with {best_kernel}') plt.legend() plt.show()
这段代码做了这么几件事:
- 构造数据:我们用一个sin函数加上一些噪声,模拟了一组数据。
- 定义核函数:我们定义了几个候选的核函数,包括RBF核、Matern核、RationalQuadratic核和ExpSineSquared核以及一个复合核。
- 交叉验证:我们使用5折交叉验证,对每个核函数进行评估。评估指标是“负均方误差”(Negative Mean Squared Error),这个值越大,说明模型的预测效果越好。
- 选择最佳核函数:我们选出“负均方误差”最大的那个核函数,作为最佳核函数。
- 训练与预测:我们使用最佳核函数,重新训练GPR模型,并对一些新的数据点进行预测。
- 可视化:我们把原始数据、预测结果、以及预测的95%置信区间画出来。
运行这段代码,你会看到不同核函数的交叉验证得分,以及最终的预测结果图。通过比较不同核函数的预测效果,你可以更直观地理解核函数的作用。
6. 总结与进阶
今天,我们一起学习了GPR中核函数的选择问题,并通过Python代码进行了实战演练。希望这些内容能帮助你更好地理解和应用GPR。
当然,GPR还有很多更高级的用法,比如:
- 超参数优化:核函数通常有一些参数(比如RBF核的长度尺度),这些参数也会影响GPR的性能。我们可以通过优化这些参数,进一步提高模型的预测效果。
- 多维输入:GPR不仅可以处理一维输入,还可以处理多维输入。比如,我们可以同时考虑房屋的面积、位置、朝向等多个因素来预测房价。
- 与其他机器学习方法结合:GPR可以与其他机器学习方法结合使用,比如与神经网络结合,构建更强大的模型。
如果你对这些内容感兴趣,可以继续深入研究。记住,学习机器学习,最重要的就是多动手实践,多思考,多总结。祝你在机器学习的道路上越走越远!