GPyのカーネル関数比較


**目的**
　最適化でGPyの放射基底関数RBF(Radial Basis Function)を利用した事例をネットでよく見かけるが、他にも複数のカーネル関数がある。これらの関数の数学的な説明はあっても使い分けがわからなかったため、1次元のデフォルト設定で、グラフ表示して比較してみた。
　なお、[Some experiments in Gaussian Processes Regression](https://nipunbatra.github.io/blog/ml/2020/03/26/gp.html)のスクリプトを参考に作成した。安直にカーネル関数を並列に記述してみただけである。

　
**環境**

| Item       |    Content    | 
|:----------:|:-------------:|
| Hardware   | Jetson Nano   |
| SDK        | Jetpack 4.2.3 |
| OS         | Ubuntu 18.04  |
| Python     | Ver. 3.6.9    |
| GPy        | Ver. 1.9.9    |
| matplotlib | Ver. 3.2.2    |
| numpy      | Ver. 1.19.2   |

**スクリプト**

```
# Support for maths
import numpy as np
# Plotting tools
from matplotlib import pyplot as plt
# we use the following for plotting figures in jupyter
#%matplotlib inline  #Jupyter notebook使用時

import warnings
warnings.filterwarnings('ignore')

# GPy: Gaussian processes library
import GPy
#from IPython.display import display

# Create a 1-D RBF kernel with default parameters
k01 = GPy.kern.RBF(1)
k02 = GPy.kern.Matern32(1)
k03 = GPy.kern.Matern52(1)
k04 = GPy.kern.ExpQuad(1)
k05 = GPy.kern.RatQuad(1)
k06 = GPy.kern.Exponential(1)
k07 = GPy.kern.Cosine(1)
k08 = GPy.kern.White(1)
k09 = GPy.kern.Linear(1)
k10 = GPy.kern.sde_Brownian(1)
k11 = GPy.kern.Integral(1)
k12 = GPy.kern.Poly(1)
k13 = GPy.kern.Bias(1)
k14 = GPy.kern.StdPeriodic(1)
k15 = GPy.kern.PeriodicExponential(1)

# Our sample space: 100 samples in the interval [-4,4]
X = np.linspace(-4.,4.,100)[:, None] # we need [:, None] to reshape X into a column vector for use in GPy

# First, sample kernel at x' = 0
K01 = k01.K(X, np.array([[0.]])) # k(x,0)
K02 = k02.K(X, np.array([[0.]])) # k(x,0)
K03 = k03.K(X, np.array([[0.]])) # k(x,0)
K04 = k04.K(X, np.array([[0.]])) # k(x,0)
K05 = k05.K(X, np.array([[0.]])) # k(x,0)
K06 = k06.K(X, np.array([[0.]])) # k(x,0)
K07 = k07.K(X, np.array([[0.]])) # k(x,0)
K08 = k08.K(X, np.array([[0.]])) # k(x,0)
K09 = k09.K(X, np.array([[0.]])) # k(x,0)
K10 = k10.K(X, np.array([[0.]])) # k(x,0)
K11 = k11.K(X, np.array([[0.]])) # k(x,0)
K12 = k12.K(X, np.array([[0.]])) # k(x,0)
K13 = k13.K(X, np.array([[0.]])) # k(x,0)
K14 = k14.K(X, np.array([[0.]])) # k(x,0)
K15 = k15.K(X, np.array([[0.]])) # k(x,0)

plt.axes([0.1, 0.1, 0.6, 0.8])

plt.plot(X, K01, label="RBF")
plt.plot(X, K02, label="Matern32")
plt.plot(X, K03, label="Matern52")
plt.plot(X, K04, label="ExpQuad")
plt.plot(X, K05, label="RatQuad")
plt.plot(X, K06, label="Exponential")
plt.plot(X, K07, label="Cosine")
plt.plot(X, K08, label="White")
plt.plot(X, K09, label="Linear")
plt.plot(X, K10, label="sde_Brownian")
plt.plot(X, K11, label="Integral")
plt.plot(X, K12, label="Poly")
plt.plot(X, K13, label="Bias")
plt.plot(X, K14, label="StdPeriodic")
plt.plot(X, K15, label="PeriodicExponential")

plt.title("$\kappa_{Covariance Function}(x,x')$");
plt.legend(bbox_to_anchor=(1.05,1), loc='upper left', borderaxespad=0, fontsize=8)
plt.show()
```
**説明**
16〜30行目：[Gpyの公式説明](https://gpy.readthedocs.io/en/deploy/GPy.kern.html)で、"covariance function"をキーワードで検索し、動作しそうなメソッドを１次元で定義。
52行目：グラフ（Axes)の範囲を左下(0.1,0.1)、右上(0.6,0.8)に設定。
71行目：bbox_to_anchor=(1.05,1)で、凡例の位置を右上に、borderaxespad=0で凡例をグラフの外に配置する。bbox_to_anchor=(1,1)でグラフ(axes)の右上端に一致する。

**結果**
![Figure_2020110704.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/761805/28897b00-e72c-4a42-8642-103ba13c98df.png)
**　　　　　　　　　　　　　　　図1**
図1のうち、X=0でY＝１付近にピークを持ちガウス分布に近いものを図2に表示する。
![Figure_2020110705.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/761805/631a4144-7ea4-d157-7444-fb8d0b6ea0b4.png)
**　　　　　　　　　　　　　　　図2**
　Exponentialが最も鋭い関数だが、それ以外は似たり寄ったりで、X=±2付近を境にして、0付近への集中度に差がある。

**個人的な結論**
　ひとまずRBFで最適化のフレームワークを構築し、そのフレームワークでの動作結果を何度か確認しながら、場合によっては適宜カーネル関数を変更する進め方がよさそうである。