首页 > 解决方案 > Scikit-learn:避免高斯过程回归中的过度拟合

问题描述

我正在训练一个高斯过程来学习一组坐标x,y,z和一些时间序列之间的映射。简而言之,我的问题是关于如何防止我的 GP 做 oerfitting,我正面临着一个奇怪的水平。

一些细节:

这是我的代码:

from __future__ import division

import numpy as np
from matplotlib import pyplot as plt

from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import (RBF, Matern, RationalQuadratic, ExpSineSquared, DotProduct, ConstantKernel)                      
# ----------------------------------------------------------------------
number_of_training_samples = 1500
number_of_testing_samples = 500

# read coordinates STANDARDIZED
coords_training_stand = np.loadtxt('coordinates_training_standardized.txt')
coords_testing_stand = np.loadtxt('coordinates_testing_standardized.txt')

# read time series TRAIN/TEST 
timeseries_training = np.loadtxt('timeseries_training.txt')
timeseries_testing = np.loadtxt('timeseries_testing.txt')
number_of_time_components = np.shape(timeseries_training)[1] # 20

# Instantiate a Gaussian Process model
kernel = 1.0 * Matern(nu=1.5, length_scale=np.ones(coords_training_stand.shape[1]))
gp = GaussianProcessRegressor(kernel=kernel)

# placeholder for predictions
pred_timeseries_training = np.zeros((np.shape(timeseries_training)))
pred_timeseries_testing = np.zeros((np.shape(timeseries_testing)))

for i in range(number_of_time_components):
    print("time component", i)

    gp.fit(coords_training_stand, timeseries_training[:,i])

    y_pred, sigma = gp.predict(coords_training_stand, return_std=True)
    y_pred_test, sigma_test = gp.predict(coords_testing_stand, return_std=True)

    pred_timeseries_training[:,i] = y_pred
    pred_timeseries_testing[:,i] = y_pred_test

# plot training
fig, ax = plt.subplots(5, figsize=(10,20))
for i in range(5):
        ax[i].plot(timeseries_training[100*i, :20], color='blue', label='Original train') 
        ax[i].plot(pred_timeseries_training[100*i], color='black', label='GP pred train')
        ax[i].set_xlabel('Time components', fontsize='x-large')
        ax[i].set_ylabel('Amplitude', fontsize='x-large')
        ax[i].set_title('Time series n. {:}'.format(100*i+1), fontsize='x-large')
        ax[i].legend(fontsize='x-large')
plt.subplots_adjust(hspace=1)
plt.show()
plt.close()

# plot testing
fig, ax = plt.subplots(5, figsize=(10,20))
for i in range(5):
        ax[i].plot(timeseries_testing[100*i, :20], color='blue', label='Original test')
        ax[i].plot(pred_timeseries_testing[100*i], color='black', label='GP pred test')
        ax[i].set_xlabel('Time components', fontsize='x-large')
        ax[i].set_ylabel('Amplitude', fontsize='x-large')
        ax[i].set_title('Time series n. {:}'.format(1500+100*i+1), fontsize='x-large')
        ax[i].legend(fontsize='x-large')
plt.subplots_adjust(hspace=1)
plt.show()
plt.close()

这里是来自 TRAINING 集的几个样本和相应的 GP 预测的图(甚至看不到蓝线,对应于原始样本,因为它们完全被 GP 的预测覆盖):

在此处输入图像描述

这里是来自 TESTING 集的一些样本和相应的 GP 预测的图:

在此处输入图像描述

(仅在一种情况下 - 1801 - 预测是好的)。我认为存在非常强烈的过度拟合,我想了解如何避免它。

标签: pythonmachine-learningscikit-learnregression

解决方案


我认为问题不在于高斯过程本身,而在于数据集。

时间序列样本是如何生成的?以及如何将数据集划分为训练集和测试集?

如果你得到一个大的时间序列,然后将它切割成小序列,那么模型就没有足够的真实例子来学习,你可能会遇到很大的过拟合问题。

举例说明:

我有一个大时间序列 t0, t1, t2, t3, ..., t99

我用 [t0,...,t19], [t1,...,t20], [t2,...,t21], ..., [t80,..., t99]

在这种情况下,我所有的样本几乎完全相同,这会导致过度拟合。如果验证集由从该数据集中抽取的一些随机样本组成,那么我将获得非常高的验证准确度,因为模型在数据集中看到几乎完全相同的东西。(我认为这就是你给的例如 1801 可能发生的事情)

因此,请确保数据集中的所有样本都是完全独立的。


推荐阅读