J'ai écrit GP avec numpy

introduction

Ravi de vous rencontrer, je m'appelle Mimura et je serai en charge du 21e jour du calendrier de l'Avent du département Innovation de NTT Docomo Service. J'écrirai un calendrier de l'Avent cette année en tant que bénévole de Docomo, alors j'aimerais écrire un article.

Du coup, connaissez-vous le problème de la régression? Le problème de régression est un problème utilisé dans divers endroits tels que la prévision des cours des actions. DoCoMo traite également ce problème de régression à divers endroits.

Dans cet article, la régression de processus gaussien est l'une des méthodes pour résoudre ce problème de régression, et je vais l'implémenter. Le but de cette fois est de l'implémenter avec numpy, pas une explication théorique. Merci. Pour ceux qui souhaitent connaître le contenu spécifique de cette zone ["Processus Gauss et apprentissage automatique (série professionnelle d'apprentissage automatique)"](https://www.amazon.co.jp/%E3%82%AC%E3%82% A6% E3% 82% B9% E9% 81% 8E% E7% A8% 8B% E3% 81% A8% E6% A9% 9F% E6% A2% B0% E5% AD% A6% E7% BF% 92- % E6% A9% 9F% E6% A2% B0% E5% AD% A6% E7% BF% 92% E3% 83% 97% E3% 83% AD% E3% 83% 95% E3% 82% A7% E3 % 83% 83% E3% 82% B7% E3% 83% A7% E3% 83% 8A% E3% 83% AB% E3% 82% B7% E3% 83% AA% E3% 83% BC% E3% 82 % BA-% E6% 8C% 81% E6% A9% 8B-% E5% A4% A7% E5% 9C% B0 / dp / 4061529269 / ref = sr_1_1? __Mk_ja_JP =% E3% 82% AB% E3% 82% BF% E3% 82% AB% E3% 83% 8A & mots-clés =% E3% 82% AC% E3% 82% A6% E3% 82% B9% E9% 81% 8E% E7% A8% 8B & qid = 1575191954 & sr = 8-1 ](Https://www.amazon.co.jp/ Processus gaussien et apprentissage automatique-Série professionnelle d'apprentissage automatique-Mochihashi-Earth / dp / 4061529269 / ref = sr_1_1? __Mk_ja_JP = Katakana & keywords = Processus gaussien & qid = 1575191954 & sr = 8 -1 "Appel" Processus gaussien et apprentissage automatique (série professionnelle d'apprentissage automatique) "")

De plus, si vous utilisez réellement le processus gaussien, utilisez GPyTorch ou GPy! Enfin, cette fois, nous n'avons pas été en mesure d'optimiser les fonctions du noyau ou d'ajuster les paramètres. Pardon…

Une brève explication de la façon de résoudre le problème de régression

Pour faire simple, le problème de régression simple est "Je veux prédire certaines données $ Y $ à partir de certaines données observables $ X $". Une façon de résoudre ce problème est de préparer une fonction comme $ y = Ax + B $. Si nous pouvons observer la variable $ x_i $, qui est la suivante, nous pouvons prédire $ y_i $.

Cependant, en réalité, il est difficile de l'exprimer avec une fonction simple telle que $ y = Ax + B $. La façon de résoudre ce problème est de rendre la formule difficile et d'améliorer l'expressivité comme $ y = Ax ^ 2 + Bx + C $.

Cette fois, nous exprimerons cette fonction compliquée comme $ y = W ^ T \ phi (x) $. Par exemple, si $ W = [A, B, C], \ phi (x) = [x ^ 2, x ^ 1, x ^ 0] $, alors $ y = Ax ^ 2 + Bx + C $ est bien exprimé. peut faire. En d'autres termes, si vous pouvez rendre $ \ phi (x) $ difficile et trouver $ W $ pour cela, vous pouvez bien prédire $ Y $! !! !! !!

Yay! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!

Si ça se termine ici, ce sera contre le sujet, alors je vais expliquer le processus de Gauss à partir d'ici.

Une brève description du processus gaussien

Commençons par faire de $ \ phi (x) $ de $ y = W ^ T \ phi (x) $ une distribution gaussienne. En d'autres termes, essayez $ \ phi (x) = \ exp (- \ frac {(x- \ mu_h) ^ 2} {\ sigma}) $. Le problème de la régression peut encore être résolu.

Cependant, avec cette méthode, la quantité de calcul devient énorme en raison de la malédiction des dimensions. Pour résoudre ce problème, envisagez une méthode pour prendre la valeur attendue en $ W $ et l'intégrer et l'éliminer du modèle.

Si $ w $ est généré à partir d'une distribution gaussienne avec une moyenne de $ 0 $ et une variance de $ \ lambda ^ 2 I $ comme $ y = \ Phi W $, ce sera $ w \ sim N (0, \ lambda ^ 2 I) $. .. Cela signifie que $ y $ est "une transformation linéaire de $ W $ qui suit une distribution gaussienne avec la matrice constante $ \ Phi $".

À ce stade, la valeur attendue et la covariance sont

Sera

De ce résultat, $ y $ suit une distribution gaussienne multivariée de $ y \ sim N (0, \ lambda ^ 2 \ Phi \ Phi ^ 2) $.

$ K = \ lambda ^ 2 \ Phi \ Phi ^ T $ et $ K_ {n, n '} = \ lambda ^ 2 \ phi (X_n) \ phi (X_ {n'}) $ et la moyenne de $ y $ Si vous normalisez à $ 0 $, vous obtenez $ y \ sim N (0, K) $. Même avec cela, le calcul de $ K_ {n, n '} = \ phi (X_n) \ phi (X_ {n'}) $ est toujours lourd ... Mais voici le fameux "Utilisons les astuces du noyau!" L'idée est que $ K_ {n, n '} $ devrait pouvoir être calculé sans avoir à travailler dur pour calculer $ \ phi (X_n) $.

Lorsque vous arrivez à ce point, vous pouvez obtenir plus de données

D=\{(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)\} \\

Après avoir appris sur cette base, qu'arrive-t-il à $ y ^ {new} $ lors de l'observation de nouvelles données $ x ^ {new} $ $ y ^ {new} = w ^ T \ phi (x ^ {new) }) Tout ce que vous avez à faire est de résoudre $.

Pour y parvenir, $ y '= (y_1, y_2, \ cdots, y_N, y ^ {nouveau}), X = (x_1, x_2, \ cdots, x_N, x ^ {nouveau}) $ Cela devient y \ sim N (0, K ') $.

Par ici

\begin{pmatrix}
y \\ 
y^{new}
\end{pmatrix}
\sim 
N\left(0,\begin{pmatrix}
K,k_{new} \\ 
k_{new}^T,k_{new,new}
\end{pmatrix}\right)

Peut être écrit comme. Ici, $ k_ {new} et k_ {new, new} $ sont les suivants.

\left\{ 
\begin{array}{}
k_{new} &=(k(x^{new},x_1),k(x^{new},x_2),\cdots,k(x^{new},x_N))^T \\
k_{new,new}&= (k(x^{new},x^{new}))
\end{array}
\right.

ici

\begin{pmatrix}
y_1 \\ 
y_2
\end{pmatrix}
\sim N\left(
\begin{pmatrix}
\mu_1 \\ 
\mu_2
\end{pmatrix}
,
\begin{pmatrix}
\Sigma_{1,1},\Sigma_{1,2} \\
\Sigma_{2,1},\Sigma_{2,2}
\end{pmatrix}
\right)

Quand il y avait la formulep(y_2|y_1)Àp(y_2|y_1)=N(\mu_2+\Sigma_{2,1}\Sigma_{1,1}^{-1}(y_1-\mu_1),\Sigma_{2,2}-\Sigma_{2,1}\Sigma_{2,1}^{-1}\Sigma_{1,2})On sait qu'il peut être exprimé par. Cette fois\mu_1=0,\mu_2=0Alorsp(y_2|y_1)=N(\Sigma_{2,1}\Sigma_{1,1}^{-1}y_1,\Sigma_{2,2}-\Sigma_{2,1}\Sigma_{2,1}^{-1}\Sigma_{1,2})Il peut être exprimé par.

C'était si long, mais en d'autres termes

p(y^{new}|X^{new},D)=N(k_{new}^TK^{-1}y,k_{new,new}-k_{new}^TK^{-1}k_{new})

Il ne vous reste plus qu'à mettre en œuvre! !! !!

Mettons-le en œuvre!

p(y^{new}|X^{new},D)=N(k_{new}^TK^{-1}y,k_{new,new}-k_{new}^TK^{-1}k_{new})

Je viens de découvrir que je devrais mettre en œuvre cela.

Aussi, $ K, k_ {nouveau}, k_ {nouveau, nouveau} $

\left\{ 
\begin{array}{}
K   &=\left[\begin{array}{}
k(x_1,x_1),k(x_1,x_2),\cdots,k(x_1,x_N) \\
k(x_2,x_1),k(x_2,x_2),\cdots,k(x_2,x_N) \\
\cdots \\
k(x_N,x_1),k(x_N,x_2),\cdots,k(x_N,x_N)
\end{array}
\right] \\
k_{new} &=(k(x^{new},x_1),k(x^{new},x_2),\cdots,k(x^{new},x_N))^T \\
k_{new,new}&= (k(x^{new},x^{new}))
\end{array}
\right.

était.

k(x,x')=\theta_1\exp \left(-\frac{(x-x')^2}{\theta_2}\right)+\theta_3\delta(x,x')

Ensuite, la fonction du noyau est

def RBF(X,X_):
    theta_1  = 1
    theta_2  = 0.2
    theta_3  = 0.01
    distance =  ((X - X_)**2).sum(-1)
    if distance.shape[0] == distance.shape[1]:
        return theta_1 * np.exp(-1 * distance/theta_2) + theta_3 * np.eye(len(X))[:,:X.shape[1]]
    else:
        return theta_1 * np.exp(-1 * distance/theta_2) 

Vous pouvez écrire avec.

Utilisons ceci pour calculer $ K ^ {-1}, k_ {nouveau}, k_ {nouveau, nouveau} $. Tout d'abord, calculez $ K ^ {-1} $.

X_    = np.array([X for _ in range(len(X))])
K     = RBF(X_,X_.transpose(1,0,2)) 
inv_K = np.linalg.inv(K)

Puis calculez $ k_ {new} $ et $ k_ {new, new} $.

X__        = np.array([X      for _ in range(len(Test_X))])
Test_X__   = np.array([Test_X for _ in range(len(X))]).transpose(1,0,2)
Test_X__a  = np.array([Test_X for _ in range(len(Test_X))]).transpose(1,0,2)
k          = RBF(X__,Test_X__)
k__        = RBF(Test_X__a,Test_X__a)

finalement

p(y^{new}|X^{new},D)=N(k_{new}^TK^{-1}y,k_{new,new}-k_{new}^TK^{-1}k_{new})

Pour générer à partir de

Y_result   = np.random.multivariate_normal(k.dot(inv_K).dot(Y),k__ - k.dot(inv_K).dot(k.T))

Il suffit d'appeler

Expérimentez avec les données de vélos en libre-service à New York

Utilisez les données de partage de vélos de New York (https://www.citibikenyc.com/system-data) pour prédire votre image. Cette fois, j'ai essayé de visualiser le nombre de vélos retournés de 8h00 à 12h00 le 30 juin.

Il est normalisé logarithmiquement au nombre retourné pour plus de clarté.

plot_demand.png

Visualisons-le en utilisant le processus gaussien Alors ça ressemble à ça.

GP_result_port.png

L'étoile est la position du port. Pour une visualisation facile, 0 $ et moins sont complétés par 0 $.

Les résultats montrent qu'il y a une forte demande dans le centre. On a déduit qu'il y a une forte demande cette fois parce que diverses valeurs sont échantillonnées dans la position où il n'y a pas de port parce que la dispersion est grande. De cette façon, la bonne chose à propos du processus gaussien est que vous pouvez non seulement prédire où il n'y a pas de données, mais aussi calculer la variance de cette partie.

finalement

Vous pouvez résoudre le problème de régression de cette manière, alors pourquoi ne pas l'essayer une fois?

Recommended Posts

J'ai écrit GP avec numpy
J'ai écrit matplotlib
J'ai fait un jeu de vie avec Numpy
J'ai fait un graphique de nombres aléatoires avec Numpy
J'ai joué avec wordcloud!
Moyenne mobile avec numpy
Premiers pas avec Numpy
Apprenez avec Chemo Informatics NumPy
Concaténation de matrices avec Numpy
Code de bourdonnement avec numpy
Effectuer une analyse de régression avec NumPy
Étendre NumPy avec Rust
Je voulais aussi vérifier les indices de type avec numpy
J'ai essayé Smith en standardisant une matrice entière avec Numpy
Je t'ai écrit pour regarder le signal avec Go
Régression du noyau avec Numpy uniquement
J'ai essayé fp-growth avec python
J'ai essayé de gratter avec Python
J'ai écrit python en japonais
J'ai écrit le code pour la génération de phrases japonaises avec DeZero
Implémentation CNN avec juste numpy
Génération artificielle de données avec numpy
J'ai essayé Learning-to-Rank avec Elasticsearch!
[Python] Méthode de calcul avec numpy
J'ai fait un blackjack avec du python!
J'ai écrit rapidement un programme pour étudier la DI avec Python ①
Essayez l'opération matricielle avec NumPy
J'ai écrit la grammaire de base de Python dans Jupyter Lab
Animation de l'équation de diffusion avec NumPy
J'ai essayé le clustering avec PyCaret
Simulation de remboursement de dette avec numpy
Implémentation de SMO avec Python + NumPy
Coller les chaînes avec Numpy
J'ai essayé d'implémenter VQE avec Blueqat
Je veux changer le drapeau japonais en drapeau des Palaos avec Numpy
Gérez les tableaux numpy avec f2py
J'ai écrit le fonctionnement de base de Numpy dans Jupyter Lab.
Je ne peux pas effectuer de recherche avec # google-map. ..
Utilisez OpenBLAS avec numpy, scipy
J'ai mesuré l'IMC avec tkinter
J'ai essayé gRPC avec Python
J'ai créé COVID19_simulator avec JupyterLab
J'ai essayé de gratter avec du python
J'ai créé Word2Vec avec Pytorch
J'ai fait un blackjack avec Python.
J'ai écrit le fonctionnement de base de matplotlib dans Jupyter Lab
J'ai créé wordcloud avec Python.
Implémentation de la régression logistique avec NumPy
J'ai écrit un script pour vous aider à démarrer avec AtCoder à grande vitesse!
J'ai écrit le fonctionnement de base de Pandas dans Jupyter Lab (partie 1)
J'ai écrit le fonctionnement de base de Pandas dans Jupyter Lab (partie 2)
Effectuez un ajustement carré minimum avec numpy.
pyenv-vertualenv n'installe pas correctement la série python3
J'ai essayé de résumer des phrases avec summpy
J'ai essayé l'apprentissage automatique avec liblinear
J'ai essayé webScraping avec python.
J'ai essayé de déplacer de la nourriture avec SinGAN
La fonction numpy que j'ai apprise cette année