web-dev-qa-db-ja.com

2D入力、1D出力の回帰にscikit-learnのガウスプロセスを正しく使用する方法

投稿する前に、私は多くの検索を行い、 この質問 を見つけました。これはまさに私の問題かもしれません。しかし、私は答えで提案されたものを試してみましたが、残念ながらこれはそれを修正できませんでした、そして私はここに新しいメンバーなので、さらなる説明を要求するコメントを追加できませんでした。

とにかく、私はPythonでscikit-learnを使用してガウスプロセスを使用したいと思います(scikit-learnのドキュメントで提供されている例を使用して)。 (2つのパラメーターの8組)[〜#〜] x [〜#〜]と呼ばれます。1D配列に収集された8つの対応する出力がありますy

#  Inputs: 8 points 
X = np.array([[p1, q1],[p2, q2],[p3, q3],[p4, q4],[p5, q5],[p6, q6],[p7, q7],[p8, q8]])

# Observations: 8 couples
y = np.array([r1,r2,r3,r4,r5,r6,r7,r8])

入力テストスペースを定義しましたx

# Input space
x1 = np.linspace(x1min, x1max) #p
x2 = np.linspace(x2min, x2max) #q
x = (np.array([x1, x2])).T

次に、GPモデルをインスタンス化して、トレーニングデータ(X、y)に適合させ、1D予測y_pred入力スペースでx

from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C

kernel = C(1.0, (1e-3, 1e3)) * RBF([5,5], (1e-2, 1e2))
gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=15)
gp.fit(X, y)
y_pred, MSE = gp.predict(x, return_std=True)

次に、3Dプロットを作成します。

fig = pl.figure()
ax = fig.add_subplot(111, projection='3d')
Xp, Yp = np.meshgrid(x1, x2)
Zp = np.reshape(y_pred,50)

surf = ax.plot_surface(Xp, Yp, Zp, rstride=1, cstride=1, cmap=cm.jet,
linewidth=0, antialiased=False)
pl.show()

これは私が得るものです:

RBF[5,5]

カーネルパラメータを変更すると、上記のポスターと同様に次のような結果が得られます。

RBF[10,10]

これらのプロットは、元のトレーニングポイントからの観測とさえ一致しません([65.1,37]の方が低い応答が得られ、[92.3,54]の方が最も高い応答です)。

私は2DのGPにかなり慣れていないので(Python少し前に開始されました)、ここで何か不足していると思います...

23
Julie

2つの機能を使用して3番目の機能を予測しています。 plot_surfaceのような3Dプロットではなく、hist2dpcolormeshのような3次元に関する情報を表示できる2Dプロットを使用すると、通常はより明確になります。これは、質問と同様のデータ/コードを使用した完全な例です。

from itertools import product
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C

X = np.array([[0,0],[2,0],[4,0],[6,0],[8,0],[10,0],[12,0],[14,0],[16,0],[0,2],
                    [2,2],[4,2],[6,2],[8,2],[10,2],[12,2],[14,2],[16,2]])

y = np.array([-54,-60,-62,-64,-66,-68,-70,-72,-74,-60,-62,-64,-66,
                    -68,-70,-72,-74,-76])

# Input space
x1 = np.linspace(X[:,0].min(), X[:,0].max()) #p
x2 = np.linspace(X[:,1].min(), X[:,1].max()) #q
x = (np.array([x1, x2])).T

kernel = C(1.0, (1e-3, 1e3)) * RBF([5,5], (1e-2, 1e2))
gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=15)

gp.fit(X, y)

x1x2 = np.array(list(product(x1, x2)))
y_pred, MSE = gp.predict(x1x2, return_std=True)

X0p, X1p = x1x2[:,0].reshape(50,50), x1x2[:,1].reshape(50,50)
Zp = np.reshape(y_pred,(50,50))

# alternative way to generate equivalent X0p, X1p, Zp
# X0p, X1p = np.meshgrid(x1, x2)
# Zp = [gp.predict([(X0p[i, j], X1p[i, j]) for i in range(X0p.shape[0])]) for j in range(X0p.shape[1])]
# Zp = np.array(Zp).T

fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111)
ax.pcolormesh(X0p, X1p, Zp)

plt.show()

出力:

enter image description here

ちょっと見栄えがしましたが、私の例のデータもそうでした。一般に、この少数のデータポイントで特に興味深い結果が得られると期待するべきではありません。

また、表面プロットが必要な場合は、pcolormesh行を元々持っていたもの(多かれ少なかれ)に置き換えるだけです。

ax = fig.add_subplot(111, projection='3d')            
surf = ax.plot_surface(X0p, X1p, Zp, rstride=1, cstride=1, cmap='jet', linewidth=0, antialiased=False)

出力:

enter image description here

6
tel

私はまた、scikit-learnガウスプロセスを使用してかなり新しいです。しかし、いくらかの努力の後、なんとか3次元ガウスプロセス回帰を実装することに成功しました。 1次元回帰の例はたくさんありますが、より高い入力次元には何もありません。

おそらく、使用している値を表示できます。

入力を送信する形式で問題が発生することがあります。入力Xを次のようにフォーマットしてみてください:

X = np.array([param1, param2]).T

そして出力を次のようにフォーマットします:

gp.fit(X, y.reshape(-1,1))

また、私が理解したように、実装は平均関数m = 0を想定しています。回帰しようとしている出力が0とは大幅に異なる平均値を示している場合は、それを正規化する必要があります(おそらく問題が解決します)。パラメータスペースの標準化も役立ちます。

7
Argantonio65