Гауссовские процессы в scikit-learn: хорошая производительность на тренировочных данных, плохая производительность на тестовых данных - PullRequest
0 голосов
/ 26 октября 2019

Я написал скрипт на Python, который использует scikit-learn для подгонки гауссовских процессов к некоторым данным.

Вкратце: проблема, с которой я сталкиваюсь, заключается в том, что, хотя гауссовские процессы, похоже, очень хорошо изучают учебный набор данных, прогнозы для тестового набора данных не верны, и мне кажется, что существует проблема нормализацииэто.

IN DETAIL: мой набор данных для обучения представляет собой набор 1500 временных рядов. Каждый временной ряд имеет 50 временных компонентов. Отображение, полученное с помощью процессов Гаусса, находится между набором из трех координат x,y,z (которые представляют параметры моей модели) и одним временным рядом. Другими словами, существует соотношение 1: 1 между x,y,z и одним временным рядом, и терапевты изучают это отображение. Идея состоит в том, что, давая обученным терапевтам новые координаты, они смогут дать мне прогнозируемый временной ряд, связанный с этими координатами.

Вот мой код:

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 Matern

coordinates_training = np.loadtxt(...) # read coordinates training x, y, z from file
coordinates_testing = np.loadtxt(..) # read coordinates testing x, y, z from file

# z-score of the coordinates for the training and testing data.
# Note I am using the mean and std of the training dataset ALSO to normalize the testing dataset

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(...)# reading time series of training data from file
number_of_time_components = np.shape(time_series_training)[1] # 100 time components

# z_score of the time series
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(...)# reading test data from file
# the number of time components is the same for training and testing dataset

# z-score of testing data, again using mean and std of training data
for 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]

# GPs        

pred_time_series_training = np.zeros((np.shape(time_series_training)))
pred_time_series_testing = np.zeros((np.shape(time_series_testing)))

# Instantiate a Gaussian Process model
kernel = 1.0 * Matern(nu=1.5)
gp = GaussianProcessRegressor(kernel=kernel)

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

    # Fit to data using Maximum Likelihood Estimation of the parameters
    gp.fit(coordinates_training, time_series_training[:,i])

    # Make the prediction on the meshed x-axis (ask for MSE as well)
    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]


# plot training
fig, ax = plt.subplots(5, figsize=(10,20))
for i in range(5):
        ax[i].plot(time_series_training[100*i], color='blue', label='Original training')
        ax[i].plot(pred_time_series_training[100*i], color='black', label='GP predicted - training')

# plot testing
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='Original testing')
        ax[i].plot(pred_time_series_testing[100*i], color='black', label='GP predicted - testing')

Вот примеры выступления на тренировочных данных. Вот примеры производительности по данным тестирования. testing

1 Ответ

0 голосов
/ 29 октября 2019

сначала вы должны использовать инструмент предварительной обработки sklearn для обработки ваших данных.

from sklearn.preprocessing import StandardScaler

Существуют и другие полезные инструменты для упорядочивания, но это специфический инструмент для нормализации данных. Во-вторых, вы должны нормализовать тренировочный набор и тестовый набор с теми же параметрами ¡¡¡модель будет соответствовать «геометрии» данных для определения параметров, если вы тренируете модель с другим масштабом, как если бы вы использовали неправильную систему единиц.

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

это будет использовать ту же трансформацию в наборах.

и, наконец, вам нужно нормализовать функции, а не traget, я имею в виду нормализовать записи X, а не вывод Y,нормализация помогает модели быстрее находить ответ, меняя топологию целевой функции в процессе оптимизации, на который это не влияет.

Надеюсь, это ответит на ваш вопрос.

...