質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.40%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

486閲覧

sklearnにおけるガウス過程のパラメータについて

himizu

総合スコア12

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

1クリップ

投稿2023/07/11 05:58

実現したいこと

sklearnのガウス過程に関するモジュールを使用してできたモデルから得られるハイパーパラメータの理解

  • sklearn によるガウス過程の機械学習モデルからハイパーパラメータを取得し、自作の関数により機械学習モデルを再現したい。

前提

pythonでガウス過程による回帰をおこなっています。
下のサイトを真似したモデルを作成しました。
rbfカーネル、ガウス分布に従うノイズを仮定しています。
https://qiita.com/meltyyyyy/items/5a058ecc81e010876a39
イメージ説明

このθ1, θ2, θ3をsklearnのモデルから取得したいのです。
問題を再現するための全コードはhttps://github.com/takuto1105/tmp/blob/main/practice6.py
にあります。

試したこと

次のようなデータに対して回帰を行います。また下の図を図1とします。

python

1def objective(x): 2 return 2 * np.sin(x) + 3 * np.cos(2 * x) + 5 * np.sin(2 / 3 * x)

イメージ説明

sklearn を使用しないとき

上のサイトにあるカーネル関数をもちいて回帰した結果、ハイパーパラメータは
θ1 = 3.9479622, θ2=21.52594284, θ3 = 2.17656223
となり、結果は下のグラフのようになります。これを図2とします。objectiveは全データです。mean, standard deviationはそれぞれテストデータにおける期待値と標準偏差を2倍したものです。この時のカーネル関数を下に示します。

イメージ説明

python

1def rbf(x, x_prime, theta_1, theta_2): 2 """RBF Kernel 3 4 Args: 5 x (float): data 6 x_prime (float): data 7 theta_1 (float): hyper parameter 8 theta_2 (float): hyper parameter 9 """ 10 return theta_1 * np.exp(-1 * (x - x_prime)**2 / theta_2) 11 12def kernel(x, x_prime, noise, theta_1, theta_2, theta_3): 13 # delta function 14 if noise: 15 delta = theta_3 16 else: 17 delta = 0 18 return rbf(x, x_prime, theta_1=theta_1, theta_2=theta_2) + delta

sklearnを使用したとき

sklearnでは次のようにカーネル関数を定義しました。そして上と同様に、データにたいしてフィッティングをおこないました。
その結果をいかに示します。このグラフを図3とします。先ほどの図2と同様の結果ではないですが、作成されたモデルから適切に式(1)のθ1, θ2, θ3に該当するハイパーパラメータを取り出し、上の先ほどの(sklearn をしようしないときの)関数に代入すれば、この図3のグラフが再現できることを期待します。

python

1import sklearn.gaussian_process as gp 2 3kk = gp.kernels.ConstantKernel() * gp.kernels.RBF() + gp.kernels.WhiteKernel() 4model = gp.GaussianProcessRegressor(kernel=kk)

イメージ説明

sklearn を用いて作成したモデルからハイパーパラメータを取得し、モデルを再現する。

sklearnを使用して作成したモデルのパラメータは以下のようにして見ることができます。

python

1print(model.kernel_.get_params())

output

1{'k1': 11.1**2 * RBF(length_scale=1.54), 'k2': WhiteKernel(noise_level=1e-05), 'k1__k1': 11.1**2, 'k1__k2': RBF(length_scale=1.54), 'k1__k1__constant_value': 123.596671302672, 'k1__k1__constant_value_bounds': (1e-05, 100000.0), 'k1__k2__length_scale': 1.5360820440644833, 'k1__k2__length_scale_bounds': (1e-05, 100000.0), 'k2__noise_level': 9.999999999999997e-06, 'k2__noise_level_bounds': (1e-05, 100000.0)}

このときhttps://scikit-learn.org/stable/modules/generated/sklearn.gaussian_process.kernels.ConstantKernel.html
より式(1)のθ1とk1__k1__constant_valueは等しく、また
https://scikit-learn.org/stable/modules/generated/sklearn.gaussian_process.kernels.RBF.html
よりk1__k2__length_scaleが上のサイトの式
イメージ説明
のlに該当すると考えられます。すると式(1)のθ2とlには下のような関係が成り立つと考えられます。
イメージ説明
また、k2__noise_levelはθ3とどのような関係にあるのかわからず、とりあえず、θ3に等しいとしました。
つまり、コードでは下のようになります。このときθ1 = 123.596671302672, θ2=4.7190960921946425, θ3 = 9.999999999999997e-06となり先ほどのsklearn を使用しない場合のθ1 = 3.9479622, θ2=21.52594284, θ3 = 2.17656223と大きく異なることがわかります。当然結果も下のグラフのように全くsklearnにより作成したモデルの結果、図3を再現することは出来ませんでした。どのようにしたら再現できるようになるのでしょうか?

python

1theta1 = model.kernel_.get_params()['k1__k1__constant_value'] 2theta2 = 2 * model.kernel_.get_params()['k1__k2__length_scale']**2 3theta3 = model.kernel_.get_params()['k2__noise_level']

イメージ説明

退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

himizu

2023/07/11 23:43

コメントありがとうございます。k1やk2のような変数はあるのですが、おっしゃる通りget_paramsとまったく同じものですね。
jbpb0

2023/07/15 14:03 編集

「図3」で「standard deviation」の幅が全然見えないのは変だなぁと思って、コードを実行して「std」の数値を確認したらすごく小さいので、「model.fit(...」のすぐ前(上)に params = {'kernel__k2__noise_level_bounds': (0.5, 100000.0)} model.set_params(**params) を追加して、「std」が小さくならないように下限を制限したら、「図3」で「standard deviation」が見えるようになり、最後のグラフの見た目も似てきました ただし、似てきたけど「図3」と同じではないし、数値も一致しませんが
himizu

2023/07/16 05:22

コメントありがとうございます。 アドバイスを参考に他のパラメータをいじってみましたが、完全に同じにするのは難しそうですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.40%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問