はじめに
この実験では、リッジ回帰を使ってある次数までの多項式で関数を近似する方法を学びます。1 次元の点 x_i の n_samples が与えられたとき、これを行う 2 つの異なる方法を示します。
PolynomialFeatures:指定された次数までのすべての単項式を生成します。これにより、n_samples行とdegree + 1列のヴァンデルモンド行列が得られます。SplineTransformer:B スプライン基底関数を生成します。B スプラインの基底関数は、次数degreeの逐次多項式関数で、degree+1個の連続するノットの間のみ非ゼロです。
非線形特徴を追加するために make_pipeline 関数を使い、線形モデルで非線形効果をモデル化するのにこれらの変換器がどのように適しているかを示します。関数、訓練点、および多項式特徴と B スプラインを使った補間を描画します。また、両方の変換器のすべての列を個別に描画し、スプラインのノットを表示します。最後に、周期スプラインの使用方法を示します。
VM のヒント
VM の起動が完了したら、左上隅をクリックして ノートブック タブに切り替えて、Jupyter Notebook を使って練習します。
時々、Jupyter Notebook が読み込み終了するまで数秒待つ必要があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。
学習中に問題に遭遇した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
データの準備
近似しようとする関数を定義し、描画用に準備します。
def f(x):
"""Function to be approximated by polynomial interpolation."""
return x * np.sin(x)
## whole range we want to plot
x_plot = np.linspace(-1, 11, 100)
## To make it interesting, we only give a small subset of points to train on.
x_train = np.linspace(0, 10, 100)
rng = np.random.RandomState(0)
x_train = np.sort(rng.choice(x_train, size=20, replace=False))
y_train = f(x_train)
## create 2D-array versions of these arrays to feed to transformers
X_train = x_train[:, np.newaxis]
X_plot = x_plot[:, np.newaxis]
多項式特徴による補間
多項式特徴を生成し、訓練データに対してリッジ回帰モデルを適合させるために PolynomialFeatures を使用します。そして、関数、訓練点、および多項式特徴を使った補間を描画します。
## plot function
lw = 2
fig, ax = plt.subplots()
ax.set_prop_cycle(
color=["black", "teal", "yellowgreen", "gold", "darkorange", "tomato"]
)
ax.plot(x_plot, f(x_plot), linewidth=lw, label="ground truth")
## plot training points
ax.scatter(x_train, y_train, label="training points")
## polynomial features
for degree in [3, 4, 5]:
model = make_pipeline(PolynomialFeatures(degree), Ridge(alpha=1e-3))
model.fit(X_train, y_train)
y_plot = model.predict(X_plot)
ax.plot(x_plot, y_plot, label=f"degree {degree}")
ax.legend(loc="lower center")
ax.set_ylim(-20, 10)
plt.show()
B スプライン補間
B スプライン基底関数を生成し、訓練データに対してリッジ回帰モデルを適合させるために SplineTransformer を使用します。そして、関数、訓練点、および B スプラインを使った補間を描画します。
## B-spline with 4 + 3 - 1 = 6 basis functions
model = make_pipeline(SplineTransformer(n_knots=4, degree=3), Ridge(alpha=1e-3))
model.fit(X_train, y_train)
y_plot = model.predict(X_plot)
ax.plot(x_plot, y_plot, label="B-spline")
ax.legend(loc="lower center")
ax.set_ylim(-20, 10)
plt.show()
変換器の描画
生成された特徴ベースをより深く理解するために、両方の変換器のすべての列を個別に描画します。
fig, axes = plt.subplots(ncols=2, figsize=(16, 5))
pft = PolynomialFeatures(degree=3).fit(X_train)
axes[0].plot(x_plot, pft.transform(X_plot))
axes[0].legend(axes[0].lines, [f"degree {n}" for n in range(4)])
axes[0].set_title("PolynomialFeatures")
splt = SplineTransformer(n_knots=4, degree=3).fit(X_train)
axes[1].plot(x_plot, splt.transform(X_plot))
axes[1].legend(axes[1].lines, [f"spline {n}" for n in range(6)])
axes[1].set_title("SplineTransformer")
## plot knots of spline
knots = splt.bsplines_[0].t
axes[1].vlines(knots[3:-3], ymin=0, ymax=0.8, linestyles="dashed")
plt.show()
周期スプライン
SplineTransformer を使用して結節を手動で指定することで、周期スプラインの使用方法を示します。訓練データに対してリッジ回帰モデルを適合させ、関数、訓練点、および周期スプラインを使った補間を描画します。
def g(x):
"""Function to be approximated by periodic spline interpolation."""
return np.sin(x) - 0.7 * np.cos(x * 3)
y_train = g(x_train)
## Extend the test data into the future:
x_plot_ext = np.linspace(-1, 21, 200)
X_plot_ext = x_plot_ext[:, np.newaxis]
lw = 2
fig, ax = plt.subplots()
ax.set_prop_cycle(color=["black", "tomato", "teal"])
ax.plot(x_plot_ext, g(x_plot_ext), linewidth=lw, label="ground truth")
ax.scatter(x_train, y_train, label="training points")
for transformer, label in [
(SplineTransformer(degree=3, n_knots=10), "spline"),
(
SplineTransformer(
degree=3,
knots=np.linspace(0, 2 * np.pi, 10)[:, None],
extrapolation="periodic",
),
"periodic spline",
),
]:
model = make_pipeline(transformer, Ridge(alpha=1e-3))
model.fit(X_train, y_train)
y_plot_ext = model.predict(X_plot_ext)
ax.plot(x_plot_ext, y_plot_ext, label=label)
ax.legend()
fig.show()
まとめ
この実験では、リッジ回帰を使ってある次数までの多項式で関数を近似する方法を学びました。1 次元の点 x_i の n_samples が与えられた場合のこれを行う 2 つの異なる方法を示しました。非線形特徴を追加するために make_pipeline 関数を使用し、線形モデルで非線形効果をモデル化するのにこれらの変換器がどのように適しているかを示しました。多項式特徴と B スプラインを使って関数、訓練点、および補間を描画しました。また、両方の変換器のすべての列を個別に描画し、スプラインの結節を示しました。最後に、周期スプラインの使用方法を示しました。