はじめに
この実験では、ElasticNet を使用して重み付きサンプルを使ってグラム行列を事前計算する方法を示します。重み付きサンプルを使用する場合、グラム行列を計算する前に、設計行列を中心化し、次に重みベクトルの平方根で再スケーリングする必要があることに注意してください。
VM のヒント
VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。
Jupyter Notebook が読み込み終わるまで数秒待つことがあります。Jupyter Notebook の制限により、操作の検証は自動化できません。
学習中に問題がある場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
データセットの読み込みとサンプル重みの作成
まず、データセットを読み込み、いくつかのサンプル重みを作成します。scikit-learn のmake_regression関数を使って、100,000 個のサンプルを持つランダムな回帰データセットを生成します。その後、対数正規分布の重みベクトルを生成し、サンプルの総数に合計するように正規化します。
import numpy as np
from sklearn.datasets import make_regression
rng = np.random.RandomState(0)
n_samples = int(1e5)
X, y = make_regression(n_samples=n_samples, noise=0.5, random_state=rng)
sample_weight = rng.lognormal(size=n_samples)
## normalize the sample weights
normalized_weights = sample_weight * (n_samples / (sample_weight.sum()))
重み付きサンプルを用たグラム行列の事前計算
precompute オプションとサンプル重みを使ってエラスティックネットを適合させるには、まず、グラム行列を計算する前に、設計行列を中心化し、正規化された重みで再スケーリングする必要があります。設計行列を中心化するには、各行から各特徴列の重み付き平均を引きます。次に、中心化された設計行列を、対応する正規化された重みの平方根で各行を乗算することで再スケーリングします。最後に、再スケーリングされた設計行列とその転置行列の内積をとることでグラム行列を計算します。
X_offset = np.average(X, axis=0, weights=normalized_weights)
X_centered = X - np.average(X, axis=0, weights=normalized_weights)
X_scaled = X_centered * np.sqrt(normalized_weights)[:, np.newaxis]
gram = np.dot(X_scaled.T, X_scaled)
エラスティックネットの適合
これで適合させる作業を進めることができます。エラスティックネット推定器が中心化されていないことに気付かれ、渡したグラム行列が破棄されるのを防ぐために、中心化された設計行列をfitに渡す必要があります。ただし、スケーリングされた設計行列を渡すと、前処理コードが誤って再度スケーリングしてしまいます。また、正規化された重みをfit関数のsample_weightパラメータに渡します。
from sklearn.linear_model import ElasticNet
lm = ElasticNet(alpha=0.01, precompute=gram)
lm.fit(X_centered, y, sample_weight=normalized_weights)
まとめ
この実験では、ElasticNet を使って重み付きサンプルを用いてグラム行列を事前計算する方法を示しました。まず、回帰データセットを読み込み、サンプルの総数に合計するように正規化された対数正規分布の重みベクトルを作成しました。次に、設計行列を中心化し、正規化された重みで再スケーリングし、グラム行列を計算しました。最後に、事前計算されたグラム行列と正規化された重みを使ってエラスティックネットを適合させました。