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!
3 Réponses :
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.
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.
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
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).
Le problème est discuté, résolu et fusionné dans PR # 15990 .