4
votes

Utilisation de WhiteKernel de scikit-learn pour la régression de processus gaussien

Il existe deux façons de spécifier le niveau de bruit pour la régression de processus gaussien (GPR) dans scikit-learn.

La première consiste à spécifier le paramètre alpha dans le constructeur de la classe GaussianProcessRegressor qui ajoute simplement des valeurs à la diagonale comme prévu.

La deuxième façon est d'incorporer le niveau de bruit dans le noyau avec WhiteKernel .

La documentation de GaussianProcessRegressor (voir documentation ici ) dit que spécifier alpha est "équivalent à ajouter un WhiteKernel avec c = alpha". Cependant, je rencontre un comportement différent et je veux savoir quelle en est la raison (et, bien sûr, quelle est la "bonne" façon ou la "vérité").

Voici un extrait de code tracer deux ajustements de régression différents pour une version perturbée de la fonction f (x) = x ^ 2 bien qu'ils devraient montrer la même chose:

import matplotlib.pyplot as plt
import numpy as np
import numpy.random as rnd
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import ConstantKernel as C, RBF, WhiteKernel


rnd.seed(0)

n = 40
xs = np.linspace(-1, 1, num=n)

noise = 0.1
kernel1 = C()*RBF() + WhiteKernel(noise_level=noise)
kernel2 = C()*RBF()

data = xs**2 + rnd.multivariate_normal(mean=np.zeros(n), cov=noise*np.eye(n))

gpr1 = GaussianProcessRegressor(kernel=kernel1, alpha=0.0, optimizer=None)
gpr1.fit(xs[:, np.newaxis], data)

gpr2 = GaussianProcessRegressor(kernel=kernel2, alpha=noise, optimizer=None)
gpr2.fit(xs[:, np.newaxis], data)

xs_plt = np.linspace(-1., 1., num=100)

for gpr in [gpr1, gpr2]:
    pred, pred_std = gpr.predict(xs_plt[:, np.newaxis], return_std=True)

    plt.figure()
    plt.plot(xs_plt, pred, 'C0', lw=2)
    plt.scatter(xs, data, c='C1', s=20)

    plt.fill_between(xs_plt, pred - 1.96*pred_std, pred + 1.96*pred_std,
                     alpha=0.2, color='C0')

    plt.title("Kernel: %s\n Log-Likelihood: %.3f"
              % (gpr.kernel_, gpr.log_marginal_likelihood(gpr.kernel_.theta)),
              fontsize=12)
    plt.ylim(-1.2, 1.2)
    plt.tight_layout()

plt.show()

I examinait déjà la implémentation dans le package scikit-learn, mais n'a pas été en mesure de découvrir ce qui ne va pas. Ou peut-être que je supervise simplement quelque chose et que les résultats ont un sens parfait.

Est-ce que quelqu'un a une idée de ce qui se passe ici ou a vécu une expérience similaire?

Merci beaucoup!


1 commentaires

Le problème est discuté, résolu et fusionné dans PR # 15990 .


3 Réponses :


4
votes

Je me trompe peut-être ici, mais je pense que l'affirmation «spécifier alpha équivaut à ajouter un WhiteKernel avec c = alpha» »est subtilement incorrecte.

Lors de la définition du bruit de régression GP, ​​le bruit est ajouté uniquement à K , la covariance entre les points d'entraînement. Lors de l'ajout d'un Whitenoise-Kernel, le bruit est également ajouté à K ** , la covariance entre les points de test.

Dans votre cas, les points de test et les points d'entraînement sont identiques. Cependant, les trois matrices différentes sont probablement toujours créées. Cela pourrait conduire à l'écart observé ici.


2 commentaires

Grand merci! Je pense que c'est la bonne réponse. Dire que la réclamation est "subtilement incorrecte" est un euphémisme à mon avis. C'est tout simplement faux :). Btw, mes points de test et d'entraînement sont différents. Cependant, cela ne change pas l'exactitude de votre réponse.


Haha, tu as probablement raison. Je me suis fait une note pour vérifier le code scikit plus en détail plus tard et peut-être corriger le commentaire.



0
votes

Je soutiens que la documentation est incorrecte. Voir github issue # 13267 à ce sujet avec (que j'ai ouvert).

En pratique, ce que je fais, c'est adapter un GP avec le WhiteKernel puis prendre ce niveau de bruit. J'ajoute ensuite cette valeur à alpha et recalcule les variables nécessaires. Une alternative plus simple consiste à créer un nouveau GP avec le jeu alpha et les mêmes échelles de longueur, mais ne lui convient pas.

Je dois noter qu'il n'est pas universellement accepté de savoir si c'est la bonne approche. J'ai eu cette discussion avec un collègue et nous sommes arrivés à la conclusion suivante. Cela concerne les données bei.ng noise provenant d'une erreur expérimentale

  • Si vous souhaitez échantillonner le GP pour prédire ce qu'est une nouvelle expérience avec des mesures plus indépendantes , vous voulez le WhiteKernel
  • Si vous voulez échantillonner la vérité sous-jacente possible, vous ne voulez pas du WhiteKernel puisque vous voulez une réponse fluide

0 commentaires

0
votes

https://gpflow.readthedocs.io/en/awav -documentation / notebooks / regression.html

Vous pouvez peut-être utiliser le package GPflow, qui fait une prédiction séparée pour la fonction latente f et l'observation y (f + bruit).

  • m.predict_f renvoie la moyenne et la variance de la fonction latente (f) aux points Xnew .
  • m.predict_y renvoie la moyenne et la variance d'un nouveau point de données (c'est-à-dire inclut la variance du bruit).

0 commentaires