scikit-learn中的高斯过程:在训练数据上表现良好,但在测试数据上表现不佳

我编写了一个Python脚本,使用scikit-learn来拟合一些数据的高斯过程。

简而言之:我面临的问题是,虽然高斯过程似乎很好地学习了训练数据集,但对测试数据集的预测却不准确,我认为这背后可能存在一个归一化的问题。

详细来说:我的训练数据集包含1500个时间序列。每个时间序列有50个时间分量。高斯过程学习的是从一组三维坐标x,y,z(代表我的模型的参数)到一个时间序列的映射。换句话说,x,y,z与一个时间序列之间存在一对一的映射,高斯过程学习这种映射。想法是,通过给训练后的高斯过程新的坐标,它们应该能够给出与这些坐标相关联的预测时间序列。

这是我的代码:

from __future__ import divisionimport numpy as npfrom matplotlib import pyplot as pltfrom sklearn.gaussian_process import GaussianProcessRegressorfrom sklearn.gaussian_process.kernels import Materncoordinates_training = np.loadtxt(...) # 从文件中读取训练坐标 x, y, zcoordinates_testing = np.loadtxt(..) # 从文件中读取测试坐标 x, y, z# 对训练和测试数据的坐标进行z-score归一化。# 注意,我使用训练数据集的均值和标准差也来归一化测试数据集mean_coords_training = np.zeros(3)std_coords_training = np.zeros(3)for i in range(3):    mean_coords_training[i] = coordinates_training[:, i].mean()    std_coords_training[i] = coordinates_training[:, i].std()    coordinates_training[:, i] = (coordinates_training[:, i] - mean_coords_training[i])/std_coords_training[i]    coordinates_testing[:, i] = (coordinates_testing[:, i] - mean_coords_training[i])/std_coords_training[i]time_series_training = np.loadtxt(...)# 从文件中读取训练数据的时间序列number_of_time_components = np.shape(time_series_training)[1] # 100个时间分量# 对时间序列进行z-score归一化mean_time_series_training = np.zeros(number_of_time_components)std_time_series_training = np.zeros(number_of_time_components)for i in range(number_of_time_components):    mean_time_series_training[i] = time_series_training[:, i].mean()    std_time_series_training[i] = time_series_training[:, i].std()    time_series_training[:, i] = (time_series_training[:, i] - mean_time_series_training[i])/std_time_series_training[i]time_series_testing = np.loadtxt(...)# 从文件中读取测试数据# 训练和测试数据集的时间分量数相同# 再次使用训练数据的均值和标准差对测试数据进行z-score归一化为 i in range(number_of_time_components):    time_series_testing[:, i] = (time_series_testing[:, i] - mean_time_series_training[i])/std_time_series_training[i]# 高斯过程        pred_time_series_training = np.zeros((np.shape(time_series_training)))pred_time_series_testing = np.zeros((np.shape(time_series_testing)))# 实例化一个高斯过程模型kernel = 1.0 * Matern(nu=1.5)gp = GaussianProcessRegressor(kernel=kernel)for i in range(number_of_time_components):    print("time component", i)    # 使用参数的最大似然估计来拟合数据    gp.fit(coordinates_training, time_series_training[:,i])    # 在网格化的x轴上进行预测(同时请求MSE)    y_pred_train, sigma_train = gp.predict(coordinates_train, return_std=True)    y_pred_test, sigma_test = gp.predict(coordinates_test, return_std=True)    pred_time_series_training[:,i] = y_pred_train*std_time_series_training[i] + mean_time_series_training[i]    pred_time_series_testing[:,i] = y_pred_test*std_time_series_training[i] + mean_time_series_training[i]# 绘制训练数据的图fig, ax = plt.subplots(5, figsize=(10,20))for i in range(5):        ax[i].plot(time_series_training[100*i], color='blue', label='原始训练数据')        ax[i].plot(pred_time_series_training[100*i], color='black', label='高斯过程预测 - 训练数据')# 绘制测试数据的图fig, ax = plt.subplots(5, figsize=(10,20))for i in range(5):        ax[i].plot(features_time_series_testing[100*i], color='blue', label='原始测试数据')        ax[i].plot(pred_time_series_testing[100*i], color='black', label='高斯过程预测 - 测试数据')

这是训练数据表现的示例。 这是测试数据表现的示例。 testing


回答:

首先,你应该使用sklearn的预处理工具来处理你的数据。

from sklearn.preprocessing import StandardScaler

有其他有用的工具来组织数据,但这个特定的工具是用来归一化数据的。其次,你应该使用相同的参数来归一化训练集和测试集,模型会根据数据的“几何形状”来定义参数,如果你用不同的尺度来训练模型,就像是使用了错误的单位系统。

scale = StandardScaler()training_set = scale.fit_transform(data_train)test_set = scale.transform(data_test)

这将对两组数据使用相同的转换。

最后,你需要归一化的是特征而不是目标,我是说要归一化X的输入而不是Y的输出,归一化有助于模型在优化过程中通过改变目标函数的拓扑结构更快地找到答案,输出不影响这一点。

希望这能回答你的问题。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注